我不明白如何輸入掛載命名空間
如果您分叉到一個新的掛載命名空間,或者輸入一個現有的命名空間。
可以保存來自外部掛載命名空間的文件描述符。您可以通過在外部掛載命名空間中找到一個程序(例如
[kdevtmpfs]
, 並打開/proc/$PID/root
. (如果我切換到這個目錄並執行/bin/pwd
,它似乎會列印出令人敬畏的錯誤消息/usr/bin/pwd: couldn't find directory entry in ‘..’ with matching i-node
,並strace
顯示getcwd()
返回(unreachable)/
)。請定義當進入新的掛載命名空間時,程序對目前掛載命名空間(目前目錄和目前根(chroot))持有的現有引用會發生什麼。
如果這些引用都沒有被修改,那麼進入一個新的掛載命名空間就沒有多大意義了。例如
/path/to/file
,如果程序的根仍指向舊的掛載命名空間,則打開文件將從舊的掛載命名空間打開。同樣,我想了解帶有 CLONENEWNS 的 clone() 的情況(如
unshare
命令)和 setns() 的情況(如nsenter
命令)。
目前工作目錄和根目錄都被重置為進入的掛載命名空間的根文件系統。
例如,我測試過我可以
chroot
通過執行nsenter -m --target $$
.(提醒:
chroot
當您仍然是 root 時很容易逃脫。man chroot
記錄眾所周知的這樣做方式)。來源
https://elixir.bootlin.com/linux/latest/source/fs/namespace.c?v=4.17#L3507
static int mntns_install(struct nsproxy *nsproxy, struct ns_common *ns) { struct fs_struct *fs = current->fs;
注意:
current
表示目前任務 - 目前執行緒/程序。
->fs
將是該任務的文件系統數據 - 這在同一程序中的執行緒任務之間共享。例如,您將在下面看到更改工作目錄是對->fs
.例如,更改工作目錄會影響同一程序的所有執行緒。像這樣的 POSIX 兼容執行緒是使用 clone() 的 CLONE_FS 標誌實現的。
struct mnt_namespace *mnt_ns = to_mnt_ns(ns), *old_mnt_ns; struct path root; int err; ... /* Find the root */ err = vfs_path_lookup(mnt_ns->root->mnt.mnt_root, &mnt_ns->root->mnt, "/", LOOKUP_DOWN, &root);
這是有問題的行:
/* Update the pwd and root */ set_fs_pwd(fs, &root); set_fs_root(fs, &root); ... } ... const struct proc_ns_operations mntns_operations = { .name = "mnt", .type = CLONE_NEWNS, .get = mntns_get, .put = mntns_put, .install = mntns_install, .owner = mntns_owner, };