[FIX] the chroot had no /dev/shm, and systemd links man pages too

nss failed with

  ImportError: This platform lacks a functioning sem_open implementation.
  https://github.com/python/cpython/issues/48020

multiprocessing.Semaphore is built on POSIX named semaphores, which glibc
implements as files under /dev/shm. The chroot had no such mount, sem_open
returned ENOSYS, and CPython reported it as the PLATFORM lacking the feature --
which reads like an s390x limitation and is a missing tmpfs.

`mount --bind /dev` does not carry submounts. That is why /dev/pts already had a
line of its own, and /dev/shm was simply missing from the same list. Mounted as
its own tmpfs, mode 1777, and added to the umount order ahead of /dev.

systemd's man page hook listed mv and rm and missed ln, so package_systemd() got
one step further and stopped on a symlink between two man pages where neither
exists. Sixteenth instance, and the lesson is narrower than the last: the
procedure said grep for the output PATHS, and the paths were found -- what was
missed was a VERB. Seven moves and links now, up from five.

--- FR ---

nss échouait sur

  ImportError: This platform lacks a functioning sem_open implementation.
  https://github.com/python/cpython/issues/48020

multiprocessing.Semaphore repose sur les sémaphores nommés POSIX, que glibc
implémente en fichiers sous /dev/shm. Le chroot n'avait pas ce montage, sem_open
renvoyait ENOSYS, et CPython l'a rapporté comme une absence de la PLATEFORME — ce
qui se lit comme une limite de s390x et n'est qu'un tmpfs manquant.

`mount --bind /dev` ne porte pas les sous-montages. C'est pourquoi /dev/pts avait
déjà sa ligne, et /dev/shm manquait simplement dans la même liste. Monté en tmpfs
propre, mode 1777, et ajouté au démontage avant /dev.

Le hook des pages de manuel de systemd listait mv et rm et oubliait ln :
package_systemd() est allé un cran plus loin et s'est arrêté sur un lien entre
deux pages dont aucune n'existe. Seizième occurrence, et la leçon est plus fine
que la précédente : la procédure disait de chercher les CHEMINS de sortie, et les
chemins étaient trouvés — ce qui manquait était un VERBE. Sept déplacements et
liens désormais, contre cinq.

Assisted-by: Claude Opus 5
This commit is contained in:
Mathieu Benoit 2026-08-24 00:29:13 -04:00
parent 61abc5aef9
commit 0e00b161c4
2 changed files with 33 additions and 5 deletions

View file

@ -344,7 +344,16 @@ for i in range(len(lines) - 1, -1, -1):
l = lines[i]
if "share/man" not in l and not re.search(r"\bman[0-9]\b", l):
continue
if re.match(r"^[ \t]*mv ", l):
# `ln` as well as `mv`. The first version listed mv and rm and missed it, so
# package_systemd() got one step further and stopped on
#
# ln: failed to create symbolic link '.../man/man8/...'
#
# a symlink between two man pages where neither exists. Sixteenth instance of
# this shape, and the lesson is narrower than the last: the procedure said
# grep for the output PATHS, and the paths were found -- what was missed was
# a VERB.
if re.match(r"^[ \t]*(mv|ln) ", l):
j = i
while lines[j].rstrip().endswith("\\"):
j += 1
@ -359,8 +368,8 @@ assert rm_n >= 1, "systemd: no man page removals found"
io.open("PKGBUILD", "w", encoding="utf-8").write("\n".join(lines))
print(" %d move(s) neutralised, %d removal(s) made tolerant" % (mv_n, rm_n))
ZZPY
grep -qE "^[[:space:]]*mv .*(share/man|\bman[0-9]\b)" PKGBUILD && {
echo "systemd: a man page move survived" >&2; exit 1; }
grep -qE "^[[:space:]]*(mv|ln) .*(share/man|\bman[0-9]\b)" PKGBUILD && {
echo "systemd: a man page move or link survived" >&2; exit 1; }
# Scoped to man paths. The first version of this guard matched any `rm` without
# a dash and condemned correct code -- systemd's package() removes plenty of
# things that have nothing to do with documentation. Same mistake as the blanket

View file

@ -516,13 +516,32 @@ mount_chroot() {
# /dev/pts is not optional: without it any build step that opens a pty --
# and gcc's testsuite driver does -- fails in a way that names the pty and
# not the missing mount.
for m in proc sys dev dev/pts; do
for m in proc sys dev dev/pts dev/shm; do
sudo mkdir -p "$ROOT/$m"
done
mountpoint -q "$ROOT/proc" || sudo mount -t proc proc "$ROOT/proc"
mountpoint -q "$ROOT/sys" || sudo mount -t sysfs sys "$ROOT/sys"
mountpoint -q "$ROOT/dev" || sudo mount --bind /dev "$ROOT/dev"
mountpoint -q "$ROOT/dev/pts" || sudo mount -t devpts devpts "$ROOT/dev/pts"
# /dev/shm, for the same reason /dev/pts needs its own line: `mount --bind
# /dev` does NOT carry submounts, and both of these are separate mounts on
# the host.
#
# nss failed with
#
# ImportError: This platform lacks a functioning sem_open implementation.
# https://github.com/python/cpython/issues/48020
#
# multiprocessing.Semaphore is built on POSIX named semaphores, which glibc
# implements as files under /dev/shm. Without the mount, sem_open returns
# ENOSYS and CPython reports it as the PLATFORM lacking the feature -- which
# reads like an s390x limitation and is a missing tmpfs.
#
# A tmpfs of its own rather than a bind: nothing here shares semaphores with
# anything outside the chroot. Mode 1777 because unprivileged builds write
# into it.
mountpoint -q "$ROOT/dev/shm" ||
sudo mount -t tmpfs -o mode=1777,nosuid,nodev tmpfs "$ROOT/dev/shm"
# Sources and PKGBUILDs, already fetched by stage 1. Bind-mounting them
# means the chroot needs no network at all, which is worth having: this
# host cannot reach dev.gnupg.org, and a build that silently re-fetches
@ -532,7 +551,7 @@ mount_chroot() {
}
umount_chroot() {
for m in repo2 build dev/pts dev sys proc; do
for m in repo2 build dev/shm dev/pts dev sys proc; do
mountpoint -q "$ROOT/$m" && sudo umount -l "$ROOT/$m"
done
return 0