In unshare mode, make all mounts private recursively

This emulates what unshare(1) does by default or by passing
--propagation=private explicitly. Mounting and unmounting filesystems
will affect mounts outside the namespace which are marked as shared (see
last column of `findmnt -o+PROPAGATION`). Since mmdebstrap's goal is to
isolate the mounts in the new namespace, we perform the equivalent of

    mount(NULL, "/", MS_REC | MS_PRIVATE, NULL);

from util-linux/sys-utils/unshare.c:set_propagation() which is in shell:

    mount --make-rprivate /

See mount_namespaces(7) for details. Without setting this, unmounting
/sys (and its sub-mounts) in unshare mode as root user will also unmount
the sub-mounts of /sys on the outside of the namespace. This breaks
tests/unshare-as-root-user which will fail to shut down with the following
errors in the log:

[FAILED] Failed unmounting mnt.mount - /mnt.
[FAILED] Failed unmounting run-lock.mount - Legacy Locks Directory /run/lock.
[...]
[  OK  ] Reached target poweroff.target - System Power Off.

Afterwards it will stall indefinitely. Stopping mmdebstrap from messing
with the /sys mounts on the outside stops this behaviour and allows to
cleanly shut down the virtual machine.

Thanks: Helmut Grohne
This commit is contained in:
Johannes Schauer Marin Rodrigues 2024-06-02 07:44:17 +02:00
parent 84f80673f4
commit 821c2e1328
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1

View file

@ -1177,6 +1177,8 @@ sub setup_mounts {
eval { eval {
if (any { $_ eq $options->{mode} } ('root', 'unshare')) { if (any { $_ eq $options->{mode} } ('root', 'unshare')) {
0 == system('mount', "--make-rprivate", "/")
or warning("mount --make-rprivate / failed: $?");
# if more than essential should be installed, make the system look # if more than essential should be installed, make the system look
# more like a real one by creating or bind-mounting the device # more like a real one by creating or bind-mounting the device
# nodes # nodes