Using Blockers to Adjust Merge Order and Avoid Conflicts

Gentoo users often think of blockers [1] negatively since it can be annoying to resolve them manually. Since portage-2.1.2, in some cases emerge can automatically adjust merge order to resolve blockers so that the user doesn’t have to know about them.

Often, the conflict is caused by 2 packages installing files in the same location. A fairly common case that can be resolved automatically is when a file moves from one package to another between versions. For example, udev versions between 111 and 113 install the file /etc/udev.d/rules.d/64-device-mapper.rules which is also installed by device-mapper-1.02.19-r1. If a user upgrades to device-mapper-1.02.19-r1 while a version of udev between 111 and 113 is still installed, a file collision will occur [2]. It’s best to avoid file collisions since the version that one package installs is not necessarily compatible with the version that another package installs. The collision can be avoided automatically by adding RDEPEND="!~sys-fs/udev-111 !~sys-fs/udev-112 !~sys-fs/udev-113" to the device-mapper-1.02.19-r1 ebuild. This causes the merge order to be adjusted so that udev is upgraded before device-mapper. The colliding file is uninstalled during the udev upgrade and then reinstalled during the device-mapper upgrade.

These are the packages that would be merged, in order:

Calculating dependencies… done!
[ebuild U ] sys-fs/udev-114 [113]
[ebuild U ] sys-fs/device-mapper-1.02.19-r1 [1.02.19]

File collisions aren’t the only situation where blockers can be useful to adjust merge order. For example, some stage tarballs contain a minimal version of perl than has the “build” USE flag enabled. Some packages such as Test-Harness that depend on perl can not be built until perl is rebuilt without that flag. This type of conflict can be represented in the perl ebuild with RDEPEND="build? ( !perl-core/Test-Harness )". The merge order will be automatically adjusted so that perl is rebuilt before Test-Harness is installed.

These are the packages that would be merged, in order:

Calculating dependencies… done!
[ebuild R ] dev-lang/perl-5.8.8-r2 USE=”-build*”
[ebuild N ] perl-core/Test-Harness-2.64

[1] A blocker is a type of ebuild dependency that represents a conflict between 2 packages.
[2] File collisions can be detected by adding “collision-protect” to the FEATURES variable in /etc/make.conf.

5 thoughts on “Using Blockers to Adjust Merge Order and Avoid Conflicts”

  1. This is very cool stuff Zack.

    This will go a long way to making some upgrade paths much saner. Boy, if we had this a year ago, the new Java system upgrade would have been much smoother 🙂 Hopefully this tactic can get more widely propogated / documented so developers will take advantage of it in the future.

    Keep up the good work!

  2. That’s fantastic. I am often confused by blockers myself, it’s great to see portage figuring out how to avoid them. Thanks!

  3. It’s a good idea, but I can’t help but feel the information is going in the wrong place. Perl shouldn’t need to know every package that’s incompatible with it; those packages should be the ones saying they don’t work with perl.

  4. The relationship between perl and Test-Harness could be represented as a USE based dependency inside the Test-Harness ebuild, like DEPEND=”dev-lang/perl[-build]”. Anyway, the blocker approach serves as a potentially useful illustration.

  5. Hey, thanks a lot for this great, helpful post. Blockers are definitely confusing at times, so this is a great help.

Comments are closed.