Bug#1110696: libglib2.0-0t64: Purging libglib2.0-0:i386 removed gschemas.compiled
Simon McVittie
smcv at debian.org
Sun Aug 10 10:50:40 BST 2025
On Sun, 10 Aug 2025 at 15:14:47 +0800, Tianyu Chen wrote:
>This is a similar bug to #1065022. but a more corner case.
>
>During the t64 transition, purging libglib2.0-0 removed
>/usr/share/glib-2.0/schemas/gschemas.compiled, libglib2.0-0t64 added a
>preinst script removing all libglib2.0-0:$arch.postrm to prevent file
>loss. [1]
Context for the dpkg team (in cc): GLib uses dpkg triggers to maintain
some functionally-necessary cache files which list data files and
plugins installed by dependent packages in a more efficient format,
which is quite a standard pattern for use of dpkg triggers. When the
last instance of GLib is removed, these cache files should also be
removed (otherwise they will hang around on the system indefinitely,
wasting a small amount of disk space), and the current implementation is
to do that during purge.
Unfortunately, the GLib in releases <= bookworm assumed that the package
containing GLib 2 would always be libglib2.0-0; this didn't account for
ABI-breaking transitions like time64, which renamed that package to
libglib2.0-0t64. As a result it is harmful to run the postrm of the old
GLib after a new GLib has been installed. Newer GLib releases avoid this
happening by having the libglib2.0-0t64 preinst delete the faulty
libglib2.0-0 postrm.
>Sometime before the t64 transition, I decided to drop all :i386 packages
>on my laptop. I removed [but did not purge] all i386 packages,
>[and then ran] $(dpkg --remove-architecture i386).
I'm a little surprised that dpkg allows this: I would have expected it
not to allow the i386 architecture to be removed until all i386 packages
had been fully removed, i.e. purged?
>In the [preinst] script, [libglib2.0-0t64] uses:
>
> for arch in $(dpkg --print-architecture) $(dpkg --print-foreign-architectures)
>
>to loop through all architectures, which should look good, but I encountered
>a corner case here.
So, yes, the problem here was that libglib2.0-0t64 disarms the faulty
maintainer scripts of libglib2.0-0 on architectures that are still
enabled, but does not disarm the maintainer script of architectures that
dpkg no longer allows installing on this system (in this case i386), and
dpkg can still end up running those maintainer scripts when old packages
are purged.
dpkg team: is there a good way to ask dpkg for a full list of
architectures that might conceivably have a package installed?
I suppose there's
dpkg-query -W -f '${Architecture}\n' | sort -u | grep -v '^all$'
but, ugh. (Would that be considered a reasonable thing to do in a
maintscript?) Or is there a better way?
With hindsight, it would probably have been a good safety-catch
against accidents if the postrm refused to remove the cache files as
long as one of the files that contributes to the cache exists:
- don't delete /usr/share/glib-2.0/schemas/gschemas.compiled if at least
one file /usr/share/glib-2.0/schemas/*.xml exists;
- don't delete /usr/lib/${multiarch}/gio/modules/giomodule.cache if at
least one file /usr/lib/${multiarch}/gio/modules/*.so exists
Obviously we can't make that change retroactively without a time machine,
but we could make that change in testing/unstable, in trixie via
trixie-pu, and even in bookworm via bookworm-pu, which would mean that
at least users with a fully upgraded (old)stable can't encounter this.
Also with hindsight, it would perhaps have been better if
libglib2.0-0:*.postrm cleaned up the cache files during remove, rather
than during purge, which would not have solved the original issue but
would at least have avoided the action-at-a-distance of deferring
their deletion until the packages are finally purged?
I think the ideal solution to this would be if dpkg had a way for
packages to declare that they (perhaps jointly) "own" a generated file
(prior art: I believe this is what RPM %ghost files are for), so that
*dpkg* could be responsible for deleting the generated file at the
reference-count transition from 1 to 0 owners. This would fit very
nicely with triggers: declare a trigger on the inputs, and declare the
generated file as a ghost file. But, again, in the absence of a time
machine, new feature development in dpkg won't solve the immediate
problem with GLib.
>I've fixed this by dpkg-reconfigure libglib2.0-0t64, which runs
>glib-compile-schemas.
I confirm that running `dpkg-reconfigure libglib2.0-0t64` is a good
workaround for this issue: that brings back the deleted file
/usr/share/glib-2.0/schemas/gschemas.compiled.
smcv
More information about the pkg-gnome-maintainers
mailing list