![掛載命名空間中的pivot_root(".", ".") 的奇怪行為](https://rvso.com/image/168809/%E6%8E%9B%E8%BC%89%E5%91%BD%E5%90%8D%E7%A9%BA%E9%96%93%E4%B8%AD%E7%9A%84pivot_root(%22.%22%2C%20%22.%22)%20%E7%9A%84%E5%A5%87%E6%80%AA%E8%A1%8C%E7%82%BA.png)
我正在嘗試了解容器,並偶然發現了 LXC 開發人員顯然發現的一個技巧,請參閱此運行 PR:您可以呼叫pivot_root(".", ".")
它,從而避免需要將舊根目錄放入目錄中。然而,這使得掛載命名空間表現得很奇怪:
unshare --user --map-root-user --mount bash -c "
mount --bind containerfs bindmountpoint
cd bindmountpoint
pivot_root . .
# this is fine:
ls -l /
# this is not fine:
ls -l /..
"
的父級,透過or.
訪問或指向根掛載命名空間的根(我還沒有嘗試嵌套)!它並不指向nor的父級,而是指向根/外部掛載命名空間的根。./..
/..
/proc/<any>/cwd/..
containerfs
bindmountpoint
同樣,當我嘗試時nsenter --user --preserve-credentials --mount --target=<pid>
,這個新進程將其 CWD 放置在根安裝命名空間的根目錄下。
當我 時,這一切都不會發生pivot_root(".", "oldroot")
。透過檔案描述子或umount -l /
.unmount卸載舊根時,該行為也會消失umount -l /proc/1/cwd
。
我還嘗試了來自自訂 C 程式的系統呼叫序列,因為pivot_root
僅提供了有關當前進程的保證(因此我在同一進程中執行所有操作)。該行為與上面顯示的使用 CLI 工具的多進程步驟相同。
在 5.3 核心上測試。
當我跑步時發生了什麼事pivot_root(".", ".")
?
答案1
pivot_root(new_root, put_old)
將呼叫程序的舊根目錄(必須是掛載的根目錄)移到put_old
,並放置new_root
在它的位置。然後,它將當前目錄和設定為舊根目錄的每個進程的根設定為new_root
。
因此,在pivot_root(".", ".")
新的根目錄之後,舊的根目錄將安裝在其之上。
每當..
解析為安裝有另一個目錄的目錄時,它實際上解析為安裝在頂部的目錄。這與歷史上的 Unix 和 Linux 行為相匹配,其中..
,除了檔案系統的根目錄之外,在路徑遍歷中沒有特殊處理,並且由儲存在磁碟上的目錄條目實現。
這不是掛載命名空間轉義。
答案2
看起來像一個真正的錯誤...
檢查您的發行版中的最新內核,並報告其完整詳細資訊(附上您的測試程式!)。