首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么使用` `unshare -m`启动的进程会影响主机中的挂载?

为什么使用` `unshare -m`启动的进程会影响主机中的挂载?
EN

Stack Overflow用户
提问于 2019-05-22 18:36:38
回答 1查看 463关注 0票数 1

下面是我所做的:

代码语言:javascript
复制
$ 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将递归地将所有挂载的传播设置为私有(请参阅代码herehere)。当我使用--propagation unchanged运行它时,unshare根本不会设置挂载的传播,它只会使用CLONE_NEWNS调用unshare() syscall,在这种情况下,由启动的shell创建的挂载将在主机挂载命名空间中可见,如您在上面的示例中所见。

所以我的问题是,既然它是挂载传播来隔离挂载/装载操作,那么我们为什么需要CLONE_NEWNS呢?或者CLONE_NEWNS仅用于隔离不同挂载名称空间的设置挂载传播(而不是挂载/装载操作)?

EN

回答 1

Stack Overflow用户

发布于 2019-05-23 01:42:13

装载传播类型确定是否将装载点下的装载点的新装载和卸载传播回父命名空间。默认情况下,所有挂载点都标记为共享挂载。如果创建新的命名空间并保持传播类型不变,则这些装载下的新装载将传播回父级。但是,如果在父命名空间中存在私有挂载点,则挂载点本身将被复制到新的命名空间,但新的挂载不会传播回父命名空间。

让我们举个例子:

代码语言:javascript
复制
# 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",表示共享挂载点。现在:

代码语言:javascript
复制
# 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

一切都很好。现在,让我们在新名称空间中的这些挂载点下创建子挂载:

代码语言:javascript
复制
# 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,并看到私有挂载点下的新子挂载尚未传播。或者退出新的名称空间,就像您所做的那样:

代码语言:javascript
复制
# 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

在新的命名空间下,您还可以将共享挂载点设为私有:

代码语言:javascript
复制
# mount --make-private /tmp/shared-mount

在现实生活中,它甚至比这更复杂。很好的补充阅读:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56254904

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档