Bug#1108193: apt: Ordering issue with libc6:i386 on amd64-m-a system breaks partial upgrade ("just apt and dpkg") from bookworm to trixie
Helmut Grohne
helmut at subdivi.de
Wed Jun 25 14:13:23 BST 2025
Hi,
I talked to Aurelien on IRC. This mail gives some context and summarizes
our discussion.
On Mon, Jun 23, 2025 at 04:58:34PM +0200, Helmut Grohne wrote:
> On Sun, Jun 22, 2025 at 11:05:03PM +0200, Helmut Grohne wrote:
> > mmdebstrap --variant=apt --architectures=amd64,i386 --include=systemd-timesyncd,libc6-dbg:i386 --chrooted-customize-hook='sed -i -e s/bookworm/trixie/ /etc/apt/sources.list && apt update && apt-get -y install apt' bookworm /dev/null
>
> Further observations.
> * We may install libc6 instead of apt.
> * We may include systemd-container instead of systemd-timesyncd.
> * If we include systemd-resolved or systemd-boot instead of
> systemd-timesyncd, the problem does not reproduce.
> * trixie's libc6 Breaks: system (<< trixie).
This is a key ingredient to the problem.
> * trixie's systemd Pre-Depends: libsystemd-shared (= ...)
> * trixie's libsystemd-shared Depends: libc6 (>= trixie)
> * All of systemd-container, systemd-resolved, systemd-boot and
> * systemd-timesyncd Conflicts: systemd (<< trixie).
> * In the apt log you may see that apt unpacks libsystemd-shared and
> only then considers deconfiguring systemd (which Depends:
> libsystemd-shared (= ...)). Why is that legal?
Fundamentally, apt has no chance in this situation, because libc6
Breaks: systemd (<< trixie) and systemd Pre-Depends: libc6 (>= trixie).
Configuring systemd before unpacking systemd violates the Breaks, doing
it the other way round violates the Pre-Depends. apt end up in a
situation where it temporarily has to do something bad. It tends to
involve further packages (such as systemd-timesyncd) to make the upgrade
fail, but that's the fundamental situation.
So let's look into why we have these relations.
systemctl is used in lots of maintainer scripts without issueing a
direct dependency on systemd. As a result of this practice, systemctl
needs to practically work at all times in a similar way that essential
packages must work at all times. If we were to demote the Pre-Depends
to Depends, apt would be entitled to unpack systemd before libc6 and
then other maintainer scripts could fail expecting a working systemctl.
We very much want the unpack order enforced by Pre-Depends. What we'd
not need here is having libc6 configured prior to unpacking systemd. I
am now wondering whether systemd could:
Depends: libc6 (>= trixie)
Conflicts: libc6 (<< trixie)
Those Conflicts sound very risky, and I haven't given this approach a
try. Is this worth pursuing or do we readily rule it out for some
reason? I note that this would get us into a Breaks + Conflicts cycle
and while that is solvable in theory (unpack conflicted, unpack broken,
configure both), apt tends to solve it by temporarily removing one and
we wouldn't want it to remove either not even temporarily.
The other side is what I discussed with Aurelien and much of what
follows is due to him (thank you). systemd needs to be restarted when
upgrading libc6, because it uses nss modules. Failing to do so results
in e.g. #993821. The way to restart systemd has changed over time. For
instance, restarting user managers and other daemons such as resolved
has become a thing. Due to these changes, the responsibility of
restarting was eventually transferred to systemd via means of a dpkg
trigger (see #1074607) and the Breaks ensures that systemd can handle
the trigger. The Breaks declaration shall ensure that systemd ends up
being restarted, but what also does is require that systemd.postinst is
run before libc6.postinst. We observe that we do not expect to bump the
Breaks version in forky as it is an artifact of transitioning to dpkg
triggers, so in later dist-upgrades the cycle at hand is expected to
disappear. If we are trying to relax it, we'd have to re-add code for
restarting systemd to libc6.postinst:
if the installed systemd does not support triggers; then
# Expect a bookworm systemd:
# * If it were older, we'd be doing a skip upgrade.
# * If it is newer (e.g. backports), it supports triggers.
restart systemd the bookworm way
# https://sources.debian.org/src/systemd/252.36-1~deb12u1/debian/systemd.postinst/#L77
fi
I note that this is the code that Aurelien spent effort on to get
removed from libc6 and moved into glibc. He expressed that he does not
like this approach (for obvious reasons).
As far as I can see, these are the options to fix the root cause and I
see no alternatives. If we end up deciding that neither is sensible,
the next option is to whack-a-mole upgrade failures. The way to go here
is having systemd packages stop Conflicting with systemd. Originally,
those were Breaks+Replaces and they were upgraded to Conflicts
(overriding my objections) to mitigate /usr-move file loss. I think we
can downgrade them to Breaks+Replaces by adding a few protective
diversions to systemd. In situations where there are no such Conflicts,
apt tends to run into the problematic login less often, but this is far
from fixing it once and for all.
I also looked for further instances of the problem with mutual
relations by analyzing package metadata. I'm attaching the script that
produces the following output:
libc6 breaks systemd pre-depends
texlive-base conflicts texlive-extra-utils breaks
libreoffice-common conflicts libreoffice-base pre-depends
libreoffice-common conflicts libreoffice-base-nogui pre-depends
libreoffice-common conflicts libreoffice-calc pre-depends
libreoffice-common conflicts libreoffice-calc-nogui pre-depends
libreoffice-common conflicts libreoffice-draw pre-depends
libreoffice-common conflicts libreoffice-draw-nogui pre-depends
libreoffice-common conflicts libreoffice-gnome pre-depends
libreoffice-common conflicts libreoffice-impress pre-depends
libreoffice-common conflicts libreoffice-impress-nogui pre-depends
libreoffice-common conflicts libreoffice-math pre-depends
libreoffice-common conflicts libreoffice-math-nogui pre-depends
libreoffice-common conflicts libreoffice-report-builder pre-depends
libreoffice-common conflicts libreoffice-writer pre-depends
libreoffice-common conflicts libreoffice-writer-nogui pre-depends
libreoffice-common breaks libreoffice-gnome pre-depends
libreoffice-common breaks libreoffice-report-builder pre-depends
samba-ad-dc conflicts samba breaks
Generally, I think we may tolerate temporary removals in all but libc6
vs systemd. In case of texlive-base vs texlive-latex-extra I saw a
temporary removal in an attempted upgrade and in case of samba-ad-dc vs
samba, I saw a temporary deconfiguration. I'm also partially guilty of
the libreoffice situation as I recommended pre-depends on Rene as a
means of avoiding mutual Breaks + Conflicts. Not sure if mutual
Conflicts + Pre-Depends is any better.
Helmut
-------------- next part --------------
A non-text attachment was scrubbed...
Name: conflictsbreaks.py
Type: text/x-python
Size: 2445 bytes
Desc: not available
URL: <http://alioth-lists.debian.net/pipermail/pkg-systemd-maintainers/attachments/20250625/a930e53d/attachment.py>
More information about the Pkg-systemd-maintainers
mailing list