新しいインストール名前空間に分岐するか、既存の名前空間を入力する場合。
外部インストール名前空間のファイル記述子を保存できます。たとえば、外部マウントネームスペースでプロセスを見つけて開き、[kdevtmpfs]
それを非常に簡単に実証できます/proc/$PID/root
。 (このディレクトリに変更して実行すると、素晴らしいエラーメッセージが表示され、戻り値が表示される/bin/pwd
ようです。)/usr/bin/pwd: couldn't find directory entry in ‘..’ with matching i-node
strace
getcwd()
(unreachable)/
新しいマウントネームスペースを入力するときに、プロセスが現在のマウントネームスペース(現在のディレクトリと現在のルート)に保持している既存の参照に何が起こるかを定義します。
これらの参照のどれも変更されていない場合は、新しいマウント名前空間を入力することは意味がありません。たとえば、/path/to/file
プロセスのルートがまだ以前のインストール名前空間を指している場合、ファイルを開くと以前のインストール名前空間で開きます。
unshare
もう一度CLONEWNSのあるclone()の場合(コマンドと同様)とsetns()の場合(nsenter
コマンドと同様)を理解したいと思います。
ベストアンサー1
現在の作業ディレクトリとルートディレクトリの両方が、入力したインストール名前空間のルートファイルシステムにリセットされます。
chroot
たとえば、を実行してエスケープできるかどうかをテストしましたnsenter -m --target $$
。
(通知:chroot
まだルートである間に脱出するのは簡単です。 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,
};