簡短的回答:它看起來像的mount propagation類型設置不正確。
說明
起初,你的根掛載點的傳播類型,應該是MS_SHARED
,作爲啓動設置由systemd。 這可以通過查看/proc/$PID/mountinfo
的可選字段來觀察。 例如,像這樣可以預料:
$ cat /proc/self/mountinfo
. . .
25 0 8:6// rw,relatime shared:1 - ext4 /dev/sda6 rw,errors=remount-ro,data=ordered
^^^^^^
. . .
通知的加下劃線(由我)shared:1
場以上,表明/
當前傳播類型掛載點是MS_SHARED
,並且對等體組 ID是1
(在我們的例子中,我們根本不會在乎同伴組ID)。
當使用clone(2)
上的CLONE_NEWNS
標誌時,會創建一個新的掛載名稱空間,該空間將初始化爲調用者的掛載名稱空間的副本。 新名稱空間的新複製掛載點將與其在調用程序的掛載名稱空間中各自的原始掛載點加入同一對等組。
其父傳播類型爲MS_SHARED
的新安裝點的傳播類型也爲MS_SHARED
。因此,當您的「包含」進程mount()
是循環設備上的文件系統時,安裝程序默認爲MS_SHARED
。之後,它下面的所有掛載也會傳播到「主」進程的命名空間,這就是「主」進程可以看到它們的原因。
對於你的要求得到滿足(爲「主」過程中沒有看見「載」進程的掛載點),你所尋求的掛載傳播類型是MS_SLAVE
或MS_PRIVATE
,這取決於你是否希望你的「載」進程的根掛載點分別接收來自其他對等體的傳播事件。 顯然,MS_PRIVATE
提供比MS_SLAVE
更大的隔離度。
因此,在你的情況下,它應該是足以改變「載」進程的根的傳播類型,掛載點MS_PRIVATE
或MS_SLAVE
之前掛載文件系統的其餘部分,所以坐騎將不會傳播到「主」進程的名字空間。
代碼
起初,一會嘗試來正確設置傳播類型當「包含」的過程產生其根掛載點。
不過,我注意到在man 8 mount
以下(引用):
注意的是,Linux內核不允許更改多個 傳播標誌使用單個安裝(2)系統調用和標誌 不能與其他安裝選項混合使用。
由於util-linux 2.23的安裝命令允許使用幾個 傳播標誌一起,並與其他安裝 操作一起使用。此功能是實驗性的。當前面的安裝 操作成功時,傳播標誌是 由附加安裝(2)系統調用應用。
看你的代碼中,「載」的過程,之後mount()
■循環設備上的文件系統,它會發出chroot()
它。在這一點上,你可以通過注射這種mount(2)
呼叫建立其傳播類型:
if (chroot(".") < 0) {
// handle error
}
if (mount("/", "/", c->fstype, MS_PRIVATE, "") < 0) {
// handle error
}
if (mkdir(...)) {
// handle error
}
現在傳播類型設置爲MS_PRIVATE
,所有後續坐騎「載」過程/
下確實將不會傳播,因此在「主」進程的名稱空間中不可見,正如您在/proc/mounts
或/proc/$PID/mountinfo
中觀察到的那樣。
資源
這是一個很好的答案,謝謝! – dmitrievanthony