User:Kentnl/Tips/Cleaning up preserved use

From Gentoo Wiki
Jump to: navigation, search

Here's how I clean up preserved use messages.

Understanding preserved-use messages

Its important to note that when you see this section in portage's output:

!!! existing preserved libs:
>>> package: app-text/poppler-0.77.0
 *  - /usr/lib64/libpoppler.so.79
 *  - /usr/lib64/libpoppler.so.79.0.0
 *      used by /usr/bin/inkscape (media-gfx/inkscape-0.92.4)
 *      used by /usr/bin/inkview (media-gfx/inkscape-0.92.4)
 *      used by /usr/libexec/cups/filter/pdftoijs (net-print/cups-filters-1.21.6)
 *      used by /usr/libexec/cups/filter/pdftoraster (net-print/cups-filters-1.21.6)
>>> package: dev-libs/libffi-3.3_rc0
 *  - /usr/lib64/libffi.so.6
 *  - /usr/lib64/libffi.so.6.0.4
 *      used by /opt/vagrant/embedded/gems/gems/ffi-1.9.6/ext/ffi_c/ffi_c.so (app-emulation/vagrant-bin-1.7.2)
 *      used by /opt/vagrant/embedded/gems/gems/ffi-1.9.6/lib/ffi_c.so (app-emulation/vagrant-bin-1.7.2)
 *      used by /opt/vagrant/embedded/lib/ruby/2.0.0/x86_64-linux/fiddle.so (app-emulation/vagrant-bin-1.7.2)
 *      used by /usr/lib64/lua/5.1/lgi/corelgilua51.so (dev-lua/lgi-0.9.0)

That this is an indication that the packages in question probably should have been scheduled by portage to be reinstalled, but, for whatever reason, didn't.

Generally, packages that are aware of this use "Subslot operator's" in their dependencies, so one would expect from the above list, that:

  • media-gfx/inkscape and net-print/cups-filters mentions app-text/poppler somewhere with either :SOMESLOT* or :SOMESLOT= in them.
  • app-emulation/vagrant-bin and dev-lua/lgi mentions dev-libs/ffi somewhere with either :SOMESLOT* or :SOMESLOT= in them.

When these get installed into your local package database ("the VDB", /var/db/pkg), the :SOMESLOT= variant gets tweaked to the flavour of the slot that was present during installation, for instance dev-lang/perl:0= gets translated into dev-lang/perl:0/5.24 during installation, indicating that "this package" requires the 5.24 flavour of dev-lang/perl:0

This incidentally is also what causes the reams of upgrade problems people regularly see with this syntax.

The Cure

The cure is to simply rebuild the packages listed, which then recompiles them against the ambient version that is presently installed, which then installs the package with the updated :SOMESLOT/SOMESUBSLOT

Executing The Cure

The easiest way of solving this problem is with >=app-portage/portage-utils-0.80_pre20190620:

qdepends --nocolor --query --quiet --quiet --format "%{CAT}/%{PN}:%{SLOT}" "^SOMECAT/SOMEPACKAGE:SOMESLOT/SOMESUBSLOT"

( yes, you need to specify quiet twice )

This syntax, where SOMECAT/SOMEPACKAGE:SOMESLOT describes the "problem package" and where SOMESUBSLOT is the desired subslot(flavour) of that slot, will query the portage database and reveal all packages that are currently installed which have obvious indicators in them that they should be rebuilt.

The "magic" glue here is the caret (^) at the start before SOMECAT.

This is the "anti-slot", in that, it finds all packages installed have the SOMECAT/SOMEPACKAGE:SOMESLOT dependency, but have a value of SOMESUBSLOT other than the indicated one ( and this is critical, as these are the packages that are "old" and need rebuilding )

Take the earlier example:

>>> package: app-text/poppler-0.77.0
 *  - /usr/lib64/libpoppler.so.79
 *  - /usr/lib64/libpoppler.so.79.0.0
 *      used by /usr/bin/inkscape (media-gfx/inkscape-0.92.4)
 *      used by /usr/bin/inkview (media-gfx/inkscape-0.92.4)
 *      used by /usr/libexec/cups/filter/pdftoijs (net-print/cups-filters-1.21.6)
 *      used by /usr/libexec/cups/filter/pdftoraster (net-print/cups-filters-1.21.6)

This means I want to find all packages that are broken and declare they need app-text/poppler

I consult eix:

eix app-text/poppler
[I] app-text/poppler
     Available versions:  0.77.0(0/88)^t **9999(0/9999)^t {cairo cjk curl cxx debug doc +introspection +jpeg +jpeg2k +lcms nss png qt5 tiff +utils}
     Installed versions:  0.77.0(0/88)^t(08:00:06 26/06/19)(cairo cxx introspection jpeg jpeg2k lcms png qt5 tiff utils -cjk -curl -debug -doc -nss)
     Homepage:            https://poppler.freedesktop.org/
     Description:         PDF rendering library based on the xpdf-3.0 code base

eix tells me I have version 0.77.0 installed, which has the slot/sublot of 0/88

So my goal here is to find things that depend on a slot of 0/ ANYTHING OTHER THAN 88

Using condensed args:

qdepends -CQqq -F "%{CAT}/%{PN}:%{SLOT}" "^app-text/poppler:0/88"
net-print/cups-filters:0
media-gfx/inkscape:0

Which, you'll see matches my package-preserved list exactly :)

I can then feed that directly to portage:

sudo emerge --ignore-default-opts -va1 $( qdepends -CQqq -F "%{CAT}/%{PN}:%{SLOT}" "^app-text/poppler:0/88" )

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

Calculating dependencies... done!
[ebuild     U  ] net-print/cups-filters-1.25.0::gentoo [1.21.6::gentoo] USE="dbus foomatic jpeg png postscript tiff -ipp_autosetup -ldap -pclm -pdf -perl -static-libs -test -zeroconf" 0 KiB
[ebuild   R    ] media-gfx/inkscape-0.92.4::gentoo  USE="dbus jpeg nls openmp -cdr -dia -exif -gnome -imagemagick -inkjar -latex -lcms -postscript -spell -static-libs -visio -wpg" PYTHON_TARGETS="python2_7" 0 KiB

Total: 2 packages (1 upgrade, 1 reinstall), Size of downloads: 0 KiB

Would you like to merge these packages? [Yes/No] y

This is good! :)

( The --ignore-default-opts stuff is to side-step any complex situations that could be introduced by custom settings, and the -va1 choice is also to indicate explicitly that these packages are to be reinstalled, regardless, and this combination aims to keep the number of packages that are reinstalled to an absolute minimum, though, you could probably go further in telling portage not to be clever with combinations of --autounmask n, --autounmask-keep-keywords y, --autounmask-keep-masks y, at least then it will only choke if it can't find a solution that doesn't involve vetoing your stability policy, or vetoing your choice of USE flags )

Some time later, after emerge completes:

!!! existing preserved libs:
>>> package: dev-libs/libffi-3.3_rc0
 *  - /usr/lib64/libffi.so.6
 *  - /usr/lib64/libffi.so.6.0.4
 *      used by /opt/vagrant/embedded/gems/gems/ffi-1.9.6/ext/ffi_c/ffi_c.so (app-emulation/vagrant-bin-1.7.2)
 *      used by /opt/vagrant/embedded/gems/gems/ffi-1.9.6/lib/ffi_c.so (app-emulation/vagrant-bin-1.7.2)
 *      used by /opt/vagrant/embedded/lib/ruby/2.0.0/x86_64-linux/fiddle.so (app-emulation/vagrant-bin-1.7.2)
 *      used by /usr/lib64/lua/5.1/lgi/corelgilua51.so (dev-lua/lgi-0.9.0)
>>> package: dev-libs/openssl-1.1.0j-r1

And in the output of inkscape:

>>> Safely unmerging already-installed instance...
<<< !needed  sym /usr/lib64/libpoppler.so.79
<<< !needed  obj /usr/lib64/libpoppler.so.79.0.0
No package files given... Grabbing a set.

That's a win! :)

Why I don't just use @preserved-rebuild

A lot of my philosophy here is about breaking larger problems into smaller subsets that can be solved in isolation.

The larger your graph of installation candidates, the more certain portage will be to find something in it confusing, and choke, potentially choking in ways that distract you from where the real problem lies.

For instance, portage may not be able to provide an upgrade plan that upgrades 3 components, A, B and C simultaneously, especially if there's a weak cycle between them. It may be that C requires A, and A requires B, and B requires C, and that confuses portage. However, you can sometimes unconfuse portage by telling it not to upgrade one of these components, which breaks this cycle, as "I already have C, its just an old version of C" might be adequate for installing B, and that makes installing A possible, without first needing a C which requires a newer A.

Then, after portage has successfully built A & B, you can upgrade C ( as the newer A is now available ).

Additionally, @preserved-rebuild has special magic in it that means it can "Somewhat work", even if all the packages in question entirely lack relevant subslot dependencies.

This approach aims to weed out and identify these packages by virtue of not auto-fixing them, letting them fall out and get stuck in this list.

One can then use this as guidance to identify the packages that need fixing, and the nature of those fixes, and filing relevant bugs, and hopefully, others will get those packages auto-rebuilt in some (distant?) future.

This approach also has the virtue of detecting and fixing cases of packages that don't show up in @preserved-rebuild, of which, perl modules are an example case ( this basically renders most cases of "run perl-cleaner after forcing a no-depends upgrade of perl" obsolete )

P.S.

This approach also works for breaking slot conflicts that occur during emerge, but that's a more complicated matter ;)

And there's no @automagic-just-make-it-work-portage-for-@world set you can fall back to when slot conflicts ruin your day.

But the lesson to learn here is there is one tool that can help identify and solve this situation, both retroactively (in the case of preserved rebuilds) and pro-actively (in the case of subslot upgrades)