以下是我所做的:
$ sudo unshare -m --propagation unchanged sh # Run a shell with `unshare` in a separate mount namespace
# cd /tmp
# mkdir foo bar
# mount --bind foo bar # This mount is supposed to be only visible in this separate mount namespace, right?
# exit # Back to the original shell
$ cat /proc/self/mountinfo | grep foo # Why can I see it here???
272 26 8:1 /tmp/foo /tmp/bar rw,relatime shared:1 - ext4 /dev/sda1 rw,errors=remount-ro,data=ordered
我知道在运行
sudo unshare -m sh
时它会按预期工作,但这是因为默认情况下unshare
会递归地将所有mount的传播设置为私有(请参见代码here和here)。当我用--propagation unchanged
运行它时,unshare
根本不会设置mount的传播,它只会用unshare()
调用CLONE_NEWNS
系统调用,在这种情况下,启动的shell所做的装载将在主机装载命名空间中可见,如您在上面的示例中所见。所以我的问题是,既然是挂载传播来隔离挂载/挂载操作,那么我们为什么需要
CLONE_NEWNS
?或者CLONE_NEWNS
仅用于隔离不同装载命名空间的设置装载传播(而不是装载/装载操作)? 最佳答案
装载传播类型确定是否将装载点下的新装载和卸载的装载点传播回父命名空间。默认情况下,所有装载点都标记为共享装载。如果创建新命名空间并保持传播类型不变,则这些装载下的新装载将传播回父级。但是,如果父命名空间中存在私有装入点,则装入点本身将复制到新命名空间,但新装入不会传播回父命名空间。
举个例子:
# mkdir -p /tmp/shared-mount
# mount --bind --make-shared /tmp/shared-mount /tmp/shared-mount
# mkdir -p /tmp/private-mount
# mount --bind --make-private /tmp/private-mount /tmp/private-mount
# grep "/tmp" /proc/self/mountinfo
406 29 8:5 /tmp/shared-mount /tmp/shared-mount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
420 29 8:5 /tmp/private-mount /tmp/private-mount rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
注意“shared:1”,表示一个共享装载点。现在:
# unshare -m --propagation unchanged /bin/bash
# grep "/tmp" /proc/self/mountinfo
551 432 8:5 /tmp/shared-mount /tmp/shared-mount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
552 432 8:5 /tmp/private-mount /tmp/private-mount rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
一切都好。现在,让我们在新命名空间中的这些装入点下创建子装入:
# mkdir -p /tmp/shared-mount/submount
# mount --bind /tmp/shared-mount/submount /tmp/shared-mount/submount
# mkdir -p /tmp/private-mount/submount
# mount --bind /tmp/private-mount/submount /tmp/private-mount/submount
# grep "/tmp" /proc/self/mountinfo
551 432 8:5 /tmp/shared-mount /tmp/shared-mount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
552 432 8:5 /tmp/private-mount /tmp/private-mount rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
553 551 8:5 /tmp/shared-mount/submount /tmp/shared-mount/submount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
555 432 8:5 /tmp/shared-mount/submount /tmp/shared-mount/submount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
577 552 8:5 /tmp/private-mount/submount /tmp/private-mount/submount rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
现在,您可以从父命名空间下的另一个shell观察
/proc/self/mountinfo
,并看到私有装载点下的新子装载尚未传播。或者像您那样退出新的命名空间:# exit
# grep "/tmp" /proc/self/mountinfo
406 29 8:5 /tmp/shared-mount /tmp/shared-mount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
420 29 8:5 /tmp/private-mount /tmp/private-mount rw,relatime - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
556 406 8:5 /tmp/shared-mount/submount /tmp/shared-mount/submount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
554 29 8:5 /tmp/shared-mount/submount /tmp/shared-mount/submount rw,relatime shared:1 - ext4 /dev/sda5 rw,errors=remount-ro,data=ordered
在新的命名空间下,还可以将共享装载点设为私有:
# mount --make-private /tmp/shared-mount
在现实生活中,它甚至比这更复杂。良好的附加阅读:
https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt
http://man7.org/linux/man-pages/man7/mount_namespaces.7.html
http://man7.org/linux/man-pages/man5/proc.5.html(关于mountinfo)
关于linux - 为什么用`unshare -m`启动的进程会影响主机中的挂载?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/56254904/