I'm using mount --rbind to prepare a chroot. When I'm done using the chroot, I'd like to be able to unmount the bind mounts I made for it. I'm trying to use the solution suggested in various places of unmounting the rbound mounts in reverse order. I'm running sys-apps/systemd-212-r5, and while this works when I boot with sys-apps/openrc-0.12.4, it behaves incorrectly under systemd: some targets fail to unmount, and the targets that do get unmounted, are also unmounted from their original locations. (...causing havoc with systemd if /sys is unmounted, so much that systemd won't even shut down.) To demonstrate the problem via /dev: ~ # mkdir foo ~ # ./rbind-test.sh ~ # rmdir foo rbind-test.openrc.out is the output of OpenRC behaving as desired. rbind-test.systemd.out is the output of systemd: - /root/foo/pts fails to unmount. - /root/foo/{shm,mqueue,hugepages} are all unmounted from /dev. I tested this from a root tty shell immediately after boot. lsof | grep foo showed nothing. /etc/mtab is a symlink to /proc/self/mounts. emerge --info shows a hardened kernel, but this also happens on sys-kernel/gentoo-sources-3.12.21-r1.
Created attachment 380638 [details] emerge --info
Created attachment 380640 [details] rbind-test.sh
Created attachment 380642 [details] rbind-test.openrc.out
Created attachment 380644 [details] rbind-test.systemd.out
Forgot to mention: using mount --bind to manually mount subdirectories, unmounting under systemd works okay: ~ # mount --bind /dev foo ~ # mount --bind /dev/pts foo/pts ~ # mount --bind /dev/shm foo/shm ~ # mount | grep -e /dev -e /foo | grep -v /sda devtmpfs on /dev type devtmpfs (rw,nosuid,size=1869668k,nr_inodes=467417,mode=755) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620) hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime) mqueue on /dev/mqueue type mqueue (rw,relatime) devtmpfs on /root/foo type devtmpfs (rw,nosuid,size=1869668k,nr_inodes=467417,mode=755) devpts on /root/foo/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620) tmpfs on /root/foo/shm type tmpfs (rw,nosuid,nodev) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) ~ # umount foo/pts ~ # umount foo/shm ~ # umount foo ~ # mount | grep -e /dev -e /foo | grep -v /sda devtmpfs on /dev type devtmpfs (rw,nosuid,size=1869668k,nr_inodes=467417,mode=755) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620) hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime) mqueue on /dev/mqueue type mqueue (rw,relatime)
This seems to be some quirk of shared subtrees. systemd mounts everything as shared by default. See mount(8) for more info. If you run this before trying to umount the bind mounts, it should work ok. mount --make-rprivate /foo You can also make this the default using a simple oneshot service unit. http://lists.freedesktop.org/archives/systemd-devel/2013-February/008586.html I'm not sure if this umount behavior with recursive shared bind mounts is a bug, or intentional behavior. However, that would be a topic for a kernel mailing list.
I had completely missed the different subtree mount modes, thanks for the insight. Reading /usr/src/linux/Documentation/filesystems/sharedsubtree.txt, it sounds like umounts being propagated is intended for 'shared' mounts. Also thanks for the reference to making this system-wide -- I should look into this, but for now I've settled on this to unmount: mount | cut -d' ' -f3 | while read mountpoint; do if [[ $mountpoint = ${chrootBase}* ]]; then mount --make-rprivate "$mountpoint" fi done mount | cut -d' ' -f3 | tac | while read mountpoint; do if [[ $mountpoint = ${chrootBase}* ]]; then umount "$mountpoint" fi done Closing, as I'm not trying to change systemd in this bug :).