Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On Mon, 20 May 2024 at 15:11, Johannes Schauer Marin Rodrigues wrote: > > Hi, > > Quoting Aurelien Jarno (2024-05-20 11:49:32) > > > > > That's all legacy stuff and I really don't want to touch it anymore. > > > > > Going from the other side, maybe libc6.postinst could use something > > > > > more reliable than ischroot()? Is systemd-detect-virt able to figure > > > > > out the situation a bit better? > > > > Nope. > > > What's the output? With SYSTEMD_LOG_LEVEL=debug exported > > In sbuild using unshare chroot running in a VM: > > > > | SYSTEMD_LOG_LEVEL=debug /usr/bin/systemd-detect-virt > > | Failed to read $container of PID 1, ignoring: Permission denied > > | Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy > > | Found container virtualization none. > > | Virtualization QEMU found in DMI (/sys/class/dmi/id/sys_vendor) > > | UML virtualization not found in /proc/cpuinfo. > > | Virtualization XEN not found, /proc/xen does not exist > > | Virtualization found, CPUID=KVMKVMKVM > > | Found VM virtualization kvm > > | kvm > > would it help (and be correct) if PID 1 in sbuild unshare mode would have the > "container" environment variable set to something? And/or if sbuild unshare > mode would create the file /run/systemd/container with some content? > > I'd need input from somebody who knows how containers (if this is one) are > supposed to work. :) Does it run in PID + mount + user namespaces, on a different filesystem than the host? If so, then yeah it does look like a container
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
Hi, Quoting Aurelien Jarno (2024-05-20 11:49:32) > > > > That's all legacy stuff and I really don't want to touch it anymore. > > > > Going from the other side, maybe libc6.postinst could use something > > > > more reliable than ischroot()? Is systemd-detect-virt able to figure > > > > out the situation a bit better? > > > Nope. > > What's the output? With SYSTEMD_LOG_LEVEL=debug exported > In sbuild using unshare chroot running in a VM: > > | SYSTEMD_LOG_LEVEL=debug /usr/bin/systemd-detect-virt > | Failed to read $container of PID 1, ignoring: Permission denied > | Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy > | Found container virtualization none. > | Virtualization QEMU found in DMI (/sys/class/dmi/id/sys_vendor) > | UML virtualization not found in /proc/cpuinfo. > | Virtualization XEN not found, /proc/xen does not exist > | Virtualization found, CPUID=KVMKVMKVM > | Found VM virtualization kvm > | kvm would it help (and be correct) if PID 1 in sbuild unshare mode would have the "container" environment variable set to something? And/or if sbuild unshare mode would create the file /run/systemd/container with some content? I'd need input from somebody who knows how containers (if this is one) are supposed to work. :) Thanks! cheers, josch signature.asc Description: signature
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On Mon, 20 May 2024 at 10:42, Aurelien Jarno wrote: > > On 2024-05-20 10:38, Chris Hofstaedtler wrote: > > * Johannes Schauer Marin Rodrigues [240520 07:35]: > > > [..] But maybe it [glibc's postinst] should be doing some > > > more involved checks about what PID 1 is? It could then make sure to only > > > call > > > systemd telinit if systemd is pid 1. [..] > > > > Well, that would probably suck. Putting the knowledge when to call > > telinit, and a specific telinit, into a ton of different things > > makes all those things hard to get right, hard to update, the usual. > > On the glibc side, this part has always been a pain to handle (a bit > less since upstart got removed). And the systemd decision to increase > the use of dlopen() will make this step even more necessary. > > Therefore I wonder if it could be solved using the trigger mechanism, > basically glibc saying "I got upgraded" and the packages, being systemd, > sysv or any other system can then decide what to do instead of > hardcoding that on the glibc side. > > That would also simplify the chrootless case a bit. Each package's postinst already needs to do the right thing on upgrade, so yeah that sounds like a good idea to me.
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On Mon, 20 May 2024 at 10:49, Aurelien Jarno wrote: > > On 2024-05-20 10:40, Luca Boccassi wrote: > > On Mon, 20 May 2024 at 10:37, Aurelien Jarno wrote: > > > > > > On 2024-05-20 10:22, Luca Boccassi wrote: > > > > On Mon, 20 May 2024 at 10:20, Johannes Schauer Marin Rodrigues > > > > wrote: > > > > > > > > > > Hi, > > > > > > > > > > Quoting Chris Hofstaedtler (2024-05-20 10:38:04) > > > > > > * Johannes Schauer Marin Rodrigues [240520 > > > > > > 07:35]: > > > > > > > [..] But maybe it [glibc's postinst] should be doing some > > > > > > > more involved checks about what PID 1 is? It could then make sure > > > > > > > to only call > > > > > > > systemd telinit if systemd is pid 1. [..] > > > > > > > > > > > > Well, that would probably suck. Putting the knowledge when to call > > > > > > telinit, and a specific telinit, into a ton of different things > > > > > > makes all those things hard to get right, hard to update, the usual. > > > > > > > > > > > > I've checked the sysvinit and the systemd implementations now, and > > > > > > they are not that different. Both try to talk to their respective > > > > > > pid1 daemons first using their respective communication socket. > > > > > > > > > > > > But then, if that doesn't work, they diverge: > > > > > > - sysvinit's telinit just gives up > > > > > > - systemd's telinit, *as an explicit fallback*, sends signals. > > > > > > > > > > > > systemd's telinit (aka systemctl) helpfully exits if it detects > > > > > > being in a chroot, before doing any of that. > > > > > > > > > > > > IWSTM systemd's telinit could, if called as telinit, not do the > > > > > > fallback to stick with sysvinit's behaviour? > > > > > > > > > > > > As a bonus, sysvinit's telinit could also gain the chroot check, > > > > > > and glibc's > > > > > > postinst (and other places) can become simpler again. > > > > > > > > > > via irc, jochen also pointed out: telinit could be the component > > > > > which checks > > > > > what PID 1 actually is and only do its thing after it confirmed that > > > > > it is > > > > > indeed an init system like systemd that is providing PID 1? > > > > > > > > That's all legacy stuff and I really don't want to touch it anymore. > > > > Going from the other side, maybe libc6.postinst could use something > > > > more reliable than ischroot()? Is systemd-detect-virt able to figure > > > > out the situation a bit better? > > > > > > Nope. > > > > What's the output? With SYSTEMD_LOG_LEVEL=debug exported > > In sbuild using unshare chroot running in a VM: > > | SYSTEMD_LOG_LEVEL=debug /usr/bin/systemd-detect-virt > | Failed to read $container of PID 1, ignoring: Permission denied > | Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy > | Found container virtualization none. > | Virtualization QEMU found in DMI (/sys/class/dmi/id/sys_vendor) > | UML virtualization not found in /proc/cpuinfo. > | Virtualization XEN not found, /proc/xen does not exist > | Virtualization found, CPUID=KVMKVMKVM > | Found VM virtualization kvm > | kvm Is sbuild running unshare with a user namespace (-U)? If so, systemd-detect-virt --private-users should catch that
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On 2024-05-20 10:40, Luca Boccassi wrote: > On Mon, 20 May 2024 at 10:37, Aurelien Jarno wrote: > > > > On 2024-05-20 10:22, Luca Boccassi wrote: > > > On Mon, 20 May 2024 at 10:20, Johannes Schauer Marin Rodrigues > > > wrote: > > > > > > > > Hi, > > > > > > > > Quoting Chris Hofstaedtler (2024-05-20 10:38:04) > > > > > * Johannes Schauer Marin Rodrigues [240520 07:35]: > > > > > > [..] But maybe it [glibc's postinst] should be doing some > > > > > > more involved checks about what PID 1 is? It could then make sure > > > > > > to only call > > > > > > systemd telinit if systemd is pid 1. [..] > > > > > > > > > > Well, that would probably suck. Putting the knowledge when to call > > > > > telinit, and a specific telinit, into a ton of different things > > > > > makes all those things hard to get right, hard to update, the usual. > > > > > > > > > > I've checked the sysvinit and the systemd implementations now, and > > > > > they are not that different. Both try to talk to their respective > > > > > pid1 daemons first using their respective communication socket. > > > > > > > > > > But then, if that doesn't work, they diverge: > > > > > - sysvinit's telinit just gives up > > > > > - systemd's telinit, *as an explicit fallback*, sends signals. > > > > > > > > > > systemd's telinit (aka systemctl) helpfully exits if it detects > > > > > being in a chroot, before doing any of that. > > > > > > > > > > IWSTM systemd's telinit could, if called as telinit, not do the > > > > > fallback to stick with sysvinit's behaviour? > > > > > > > > > > As a bonus, sysvinit's telinit could also gain the chroot check, and > > > > > glibc's > > > > > postinst (and other places) can become simpler again. > > > > > > > > via irc, jochen also pointed out: telinit could be the component which > > > > checks > > > > what PID 1 actually is and only do its thing after it confirmed that it > > > > is > > > > indeed an init system like systemd that is providing PID 1? > > > > > > That's all legacy stuff and I really don't want to touch it anymore. > > > Going from the other side, maybe libc6.postinst could use something > > > more reliable than ischroot()? Is systemd-detect-virt able to figure > > > out the situation a bit better? > > > > Nope. > > What's the output? With SYSTEMD_LOG_LEVEL=debug exported In sbuild using unshare chroot running in a VM: | SYSTEMD_LOG_LEVEL=debug /usr/bin/systemd-detect-virt | Failed to read $container of PID 1, ignoring: Permission denied | Found cgroup2 on /sys/fs/cgroup/, full unified hierarchy | Found container virtualization none. | Virtualization QEMU found in DMI (/sys/class/dmi/id/sys_vendor) | UML virtualization not found in /proc/cpuinfo. | Virtualization XEN not found, /proc/xen does not exist | Virtualization found, CPUID=KVMKVMKVM | Found VM virtualization kvm | kvm -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://aurel32.net
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On Mon, 20 May 2024 at 10:37, Aurelien Jarno wrote: > > On 2024-05-20 10:22, Luca Boccassi wrote: > > On Mon, 20 May 2024 at 10:20, Johannes Schauer Marin Rodrigues > > wrote: > > > > > > Hi, > > > > > > Quoting Chris Hofstaedtler (2024-05-20 10:38:04) > > > > * Johannes Schauer Marin Rodrigues [240520 07:35]: > > > > > [..] But maybe it [glibc's postinst] should be doing some > > > > > more involved checks about what PID 1 is? It could then make sure to > > > > > only call > > > > > systemd telinit if systemd is pid 1. [..] > > > > > > > > Well, that would probably suck. Putting the knowledge when to call > > > > telinit, and a specific telinit, into a ton of different things > > > > makes all those things hard to get right, hard to update, the usual. > > > > > > > > I've checked the sysvinit and the systemd implementations now, and > > > > they are not that different. Both try to talk to their respective > > > > pid1 daemons first using their respective communication socket. > > > > > > > > But then, if that doesn't work, they diverge: > > > > - sysvinit's telinit just gives up > > > > - systemd's telinit, *as an explicit fallback*, sends signals. > > > > > > > > systemd's telinit (aka systemctl) helpfully exits if it detects > > > > being in a chroot, before doing any of that. > > > > > > > > IWSTM systemd's telinit could, if called as telinit, not do the > > > > fallback to stick with sysvinit's behaviour? > > > > > > > > As a bonus, sysvinit's telinit could also gain the chroot check, and > > > > glibc's > > > > postinst (and other places) can become simpler again. > > > > > > via irc, jochen also pointed out: telinit could be the component which > > > checks > > > what PID 1 actually is and only do its thing after it confirmed that it is > > > indeed an init system like systemd that is providing PID 1? > > > > That's all legacy stuff and I really don't want to touch it anymore. > > Going from the other side, maybe libc6.postinst could use something > > more reliable than ischroot()? Is systemd-detect-virt able to figure > > out the situation a bit better? > > Nope. What's the output? With SYSTEMD_LOG_LEVEL=debug exported
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On 2024-05-20 10:38, Chris Hofstaedtler wrote: > * Johannes Schauer Marin Rodrigues [240520 07:35]: > > [..] But maybe it [glibc's postinst] should be doing some > > more involved checks about what PID 1 is? It could then make sure to only > > call > > systemd telinit if systemd is pid 1. [..] > > Well, that would probably suck. Putting the knowledge when to call > telinit, and a specific telinit, into a ton of different things > makes all those things hard to get right, hard to update, the usual. On the glibc side, this part has always been a pain to handle (a bit less since upstart got removed). And the systemd decision to increase the use of dlopen() will make this step even more necessary. Therefore I wonder if it could be solved using the trigger mechanism, basically glibc saying "I got upgraded" and the packages, being systemd, sysv or any other system can then decide what to do instead of hardcoding that on the glibc side. That would also simplify the chrootless case a bit. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://aurel32.net
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On 2024-05-20 10:22, Luca Boccassi wrote: > On Mon, 20 May 2024 at 10:20, Johannes Schauer Marin Rodrigues > wrote: > > > > Hi, > > > > Quoting Chris Hofstaedtler (2024-05-20 10:38:04) > > > * Johannes Schauer Marin Rodrigues [240520 07:35]: > > > > [..] But maybe it [glibc's postinst] should be doing some > > > > more involved checks about what PID 1 is? It could then make sure to > > > > only call > > > > systemd telinit if systemd is pid 1. [..] > > > > > > Well, that would probably suck. Putting the knowledge when to call > > > telinit, and a specific telinit, into a ton of different things > > > makes all those things hard to get right, hard to update, the usual. > > > > > > I've checked the sysvinit and the systemd implementations now, and > > > they are not that different. Both try to talk to their respective > > > pid1 daemons first using their respective communication socket. > > > > > > But then, if that doesn't work, they diverge: > > > - sysvinit's telinit just gives up > > > - systemd's telinit, *as an explicit fallback*, sends signals. > > > > > > systemd's telinit (aka systemctl) helpfully exits if it detects > > > being in a chroot, before doing any of that. > > > > > > IWSTM systemd's telinit could, if called as telinit, not do the > > > fallback to stick with sysvinit's behaviour? > > > > > > As a bonus, sysvinit's telinit could also gain the chroot check, and > > > glibc's > > > postinst (and other places) can become simpler again. > > > > via irc, jochen also pointed out: telinit could be the component which > > checks > > what PID 1 actually is and only do its thing after it confirmed that it is > > indeed an init system like systemd that is providing PID 1? > > That's all legacy stuff and I really don't want to touch it anymore. > Going from the other side, maybe libc6.postinst could use something > more reliable than ischroot()? Is systemd-detect-virt able to figure > out the situation a bit better? Nope. -- Aurelien Jarno GPG: 4096R/1DDD8C9B aurel...@aurel32.net http://aurel32.net
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On Mon, 20 May 2024 at 10:20, Johannes Schauer Marin Rodrigues wrote: > > Hi, > > Quoting Chris Hofstaedtler (2024-05-20 10:38:04) > > * Johannes Schauer Marin Rodrigues [240520 07:35]: > > > [..] But maybe it [glibc's postinst] should be doing some > > > more involved checks about what PID 1 is? It could then make sure to only > > > call > > > systemd telinit if systemd is pid 1. [..] > > > > Well, that would probably suck. Putting the knowledge when to call > > telinit, and a specific telinit, into a ton of different things > > makes all those things hard to get right, hard to update, the usual. > > > > I've checked the sysvinit and the systemd implementations now, and > > they are not that different. Both try to talk to their respective > > pid1 daemons first using their respective communication socket. > > > > But then, if that doesn't work, they diverge: > > - sysvinit's telinit just gives up > > - systemd's telinit, *as an explicit fallback*, sends signals. > > > > systemd's telinit (aka systemctl) helpfully exits if it detects > > being in a chroot, before doing any of that. > > > > IWSTM systemd's telinit could, if called as telinit, not do the > > fallback to stick with sysvinit's behaviour? > > > > As a bonus, sysvinit's telinit could also gain the chroot check, and glibc's > > postinst (and other places) can become simpler again. > > via irc, jochen also pointed out: telinit could be the component which checks > what PID 1 actually is and only do its thing after it confirmed that it is > indeed an init system like systemd that is providing PID 1? That's all legacy stuff and I really don't want to touch it anymore. Going from the other side, maybe libc6.postinst could use something more reliable than ischroot()? Is systemd-detect-virt able to figure out the situation a bit better?
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
Hi, Quoting Chris Hofstaedtler (2024-05-20 10:38:04) > * Johannes Schauer Marin Rodrigues [240520 07:35]: > > [..] But maybe it [glibc's postinst] should be doing some > > more involved checks about what PID 1 is? It could then make sure to only > > call > > systemd telinit if systemd is pid 1. [..] > > Well, that would probably suck. Putting the knowledge when to call > telinit, and a specific telinit, into a ton of different things > makes all those things hard to get right, hard to update, the usual. > > I've checked the sysvinit and the systemd implementations now, and > they are not that different. Both try to talk to their respective > pid1 daemons first using their respective communication socket. > > But then, if that doesn't work, they diverge: > - sysvinit's telinit just gives up > - systemd's telinit, *as an explicit fallback*, sends signals. > > systemd's telinit (aka systemctl) helpfully exits if it detects > being in a chroot, before doing any of that. > > IWSTM systemd's telinit could, if called as telinit, not do the > fallback to stick with sysvinit's behaviour? > > As a bonus, sysvinit's telinit could also gain the chroot check, and glibc's > postinst (and other places) can become simpler again. via irc, jochen also pointed out: telinit could be the component which checks what PID 1 actually is and only do its thing after it confirmed that it is indeed an init system like systemd that is providing PID 1? Thanks! cheers, josch signature.asc Description: signature
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
* Johannes Schauer Marin Rodrigues [240520 07:35]: > [..] But maybe it [glibc's postinst] should be doing some > more involved checks about what PID 1 is? It could then make sure to only call > systemd telinit if systemd is pid 1. [..] Well, that would probably suck. Putting the knowledge when to call telinit, and a specific telinit, into a ton of different things makes all those things hard to get right, hard to update, the usual. I've checked the sysvinit and the systemd implementations now, and they are not that different. Both try to talk to their respective pid1 daemons first using their respective communication socket. But then, if that doesn't work, they diverge: - sysvinit's telinit just gives up - systemd's telinit, *as an explicit fallback*, sends signals. systemd's telinit (aka systemctl) helpfully exits if it detects being in a chroot, before doing any of that. IWSTM systemd's telinit could, if called as telinit, not do the fallback to stick with sysvinit's behaviour? As a bonus, sysvinit's telinit could also gain the chroot check, and glibc's postinst (and other places) can become simpler again. Chris
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
Quoting Helmut Grohne (2024-05-20 07:17:54) > Hi Chris, > > On Mon, May 20, 2024 at 01:02:32AM +0200, Chris Hofstaedtler wrote: > > "..., when using telinit from systemd-sysv" > > > > It would seem like a reasonable assumption that systemd-sysv's > > telinit uses systemd-specific stuff, like SIGTERM. > > That also is an interesting angle to it. sbuild didn't ask for systemd-sysv > to be installed. this might shift the bug back to glibc postinst, no? Currently, it just checks the exit of ischroot before calling telinit. But maybe it should be doing some more involved checks about what PID 1 is? It could then make sure to only call systemd telinit if systemd is pid 1. And sysvinit telinit if sysvinit is pid 1 and not call telinit at all in unknown cases. Is it too much to ask for glibc postinst to know about the PID 1 providers? Thanks! cheers, josch signature.asc Description: signature
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
Hi Chris, On Mon, May 20, 2024 at 01:02:32AM +0200, Chris Hofstaedtler wrote: > "..., when using telinit from systemd-sysv" > > It would seem like a reasonable assumption that systemd-sysv's > telinit uses systemd-specific stuff, like SIGTERM. That also is an interesting angle to it. sbuild didn't ask for systemd-sysv to be installed. It was installed due to Build-Depends of some package. A different package might depend on sysvinit-core where telinit writes to /run/initctl. Other telinit may do different things. Handling all of telinit internals in one pid1 does not seem reasonable to me, so the consequence of this would be that you shouldn't install telinit in a build chroot and we could file bugs about any package doing so. A particular consequence of this would be that you couldn't use libpam-systemd or dbus-user-session in transitive Build-Depends. We'd render a significant number of packages bd-uninstallable. On the other hand, you have exactly the same problems when switching your pid1 implementation (where we urgently advise rebooting to avoid these kind of problems). That said, a sysvinit-core telinit likely wouldn't break a container's tini/dumb-init nor break a systemd running as pid1. Helmut
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On Sun, May 19, 2024 at 11:12:35PM +0200, Helmut Grohne wrote: > Hi Luca, > > On Sun, May 19, 2024 at 06:04:38PM +0100, Luca Boccassi wrote: > > On Sun, 19 May 2024 18:42:17 +0200 Helmut Grohne > > wrote: > > > the init process should handle SIGTERM more like an init system would > > handle that > > > > This seems the obvious answer to me. sbuild is setting up a system such > > that its component runs as pid1, so it needs to behave like a pid1. We > > know this is special and requires supporting a number of interfaces. If > > a program doesn't, then it shouldn't be running as pid1 in a namespace. > > Did you mean "... so it needs to behave like a systemd"? "..., when using telinit from systemd-sysv" It would seem like a reasonable assumption that systemd-sysv's telinit uses systemd-specific stuff, like SIGTERM. Chris
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
Hi Luca, On Sun, May 19, 2024 at 06:04:38PM +0100, Luca Boccassi wrote: > On Sun, 19 May 2024 18:42:17 +0200 Helmut Grohne > wrote: > > the init process should handle SIGTERM more like an init system would > handle that > > This seems the obvious answer to me. sbuild is setting up a system such > that its component runs as pid1, so it needs to behave like a pid1. We > know this is special and requires supporting a number of interfaces. If > a program doesn't, then it shouldn't be running as pid1 in a namespace. Die you mean "... so it needs to behave like a systemd"? sysvinit does not document SIGTERM as a supported signal. https://manpages.debian.org/bookworm/sysvinit-core/init.8.en.html Neither does runit. https://manpages.debian.org/bookworm/runit/runit.8.en.html#SIGNALS Nor did upstart. https://sources.debian.org/src/upstart/0.6.6-1/init/main.c/#L249 Or dumb-init (forwards all signals to its children). Or tini (forwards all signals to its children). https://github.com/krallin/tini/blob/master/src/tini.c#L525 Or busybox (see busybox init --help). But openrc-init and it then performs a shutdown. https://sources.debian.org/src/openrc/0.54-2/src/openrc-init/openrc-init.c/#L210 As far as my research goes, this handling of SIGTERM is specific to systemd and not a generic assumption of pid1. Helmut
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
On Sun, 19 May 2024 18:42:17 +0200 Helmut Grohne wrote: > the init process should handle SIGTERM more like an init system would handle that This seems the obvious answer to me. sbuild is setting up a system such that its component runs as pid1, so it needs to behave like a pid1. We know this is special and requires supporting a number of interfaces. If a program doesn't, then it shouldn't be running as pid1 in a namespace. -- Kind regards, Luca Boccassi signature.asc Description: This is a digitally signed message part
Bug#1071462: installing/upgrading libc6 does not work in sbuild when systemd is installed as ischroot declines
Package: sbuild,debianutils,libc6,systemd-sysv Severity: important Hello lots of maintainers, I am faced with a very crazy interaction bug. Roughly speaking, when you use sbuild to build a package and your build-depends happen to include systemd-sysv and you happen to install (cross building) or upgrade libc6, installing build-depends reliably fails. Since upgrading libc6 is a thing, I guess that this now affects buildds and is why I file this at important severity. Regenerating buildd chroots, will "heal" buildds, so it is self-recovering there. Without further ado, let's dive into the details. The issue is reproducible using mmdebstrap: mmdebstrap unstable --verbose --architectures amd64,arm64 --variant=apt /dev/null --include=systemd-sysv,libc6:arm64 --essential-hook='ln -sf /bin/false $1/usr/bin/ischroot' This is using a cross build setting, because libc6 is installed early during bootstrap and reproducing the bug takes configuring libc6 after systemd-sysv has been unpacked. So I simply install a foreign libc6 and apt happens to configure it late enough in my tests. So we now look into libc6.postinst. We take the "$1" = "configure" branch. We eventually run into: | # Restart init. Currently handles chroots, systemd and upstart, and | # assumes anything else is going to not fail at behaving like | # sysvinit: | TELINIT=yes | if ischroot 2>/dev/null; then | # Don't bother trying to re-exec init from a chroot: | TELINIT=no I note that mmdebstrap creates a number of namespaces and then externally runs apt. If I understand things correctly, it also runs an external dpkg --root ... without --force-scripts-chrootless. Hence dpkg performs a chroot for every maintainer script and ischroot correctly detects this, so we would be setting TELINIT=no if I were not replacing it in the --essential-hook. In sbuild, the namespace setup is different. apt is entirely run inside the namespace. ischroot compares /proc/1/mountinfo to /proc/self/mountinfo. If both are readable and equal, it concludes that we're not in a chroot. If they differ, it concludes that we are in a chroot. For mmdebstrap, pid 1 happens to be a mmdebstrap process in the initial namespace and the ischroot process sees fewer mounts. Hence it concludes success there. For sbuild, pid 1 is a runuser process already running chrooted. Hence the mountinfo files equal and ischroot concludes that we are not running in a chroot. | elif [ -n "${DPKG_ROOT:-}" ]; then | # Do not re-exec init if we are operating on a chroot from outside: | TELINIT=no In neither case DPKG_ROOT is non-empty. | elif [ -d /run/systemd/system ]; then | # Restart systemd on upgrade, but carefully. | # The restart is wanted because of LP: #1942276 and Bug: #993821 | # The care is needed because of https://bugs.debian.org/753725 | # (if systemd --help fails the system might still be quite broken but | # that seems better than the kernel panic that results if systemd | # cannot reexec itself). | TELINIT=no In neither case /run/systemd/system exists. | if systemd --help >/dev/null 2>/dev/null; then | systemctl daemon-reexec | else | echo "Error: Could not restart systemd, systemd binary not working" >&2 | fi | fi | if [ "$TELINIT" = "yes" ]; then | telinit u 2>/dev/null || true ; sleep 1 | fi And finally we run telinit u when running inside sbuild or faking ischroot in mmdebstrap. Running telinit u doesn't go well. This actually has been a known problem with different symptoms recently. Earlier, cross build nodes would get stuck in libc6.postinst hanging in telinit forever. The reason was that telinit was re-executing itself over and over again attempting to forward to another init system but always returning back to itself. This has been fixed by Luca Boccassi: https://github.com/systemd/systemd/pull/31251 and #1063147 telinit no longer reexecs itself and rather does what it is supposed to do: kill(1, SIGTERM). Sadly this doesn't go well. In case of sbuild, we kill the runuser process. It exits non-zero and sbuild considers this a failure to install Build-Depends. This is bad. So I'm not exactly sure which part is broken here. We might argue that sbuild is setting up a container that looks too much like a container and should have pid 1 outside the chroot area or that the init process should handle SIGTERM more like an init system would handle that. We might argue that ischroot should detect init-less application container environments. We might argue that libc6 should ischroot is not meant for detecting application containers and libc6.postinst asks the wrong question and should be skipping telinit for such environments as well. We might argute that telinit should not kill a pid 1 that isn't systemd. At this time, I am really unsure which of these four packages we consider at fault.