새 설치 네임스페이스로 분기하거나 기존 네임스페이스를 입력하는 경우.
외부 설치 네임스페이스의 파일 설명자를 저장할 수 있습니다. 예를 들어 외부 마운트 네임스페이스에서 프로세스를 찾아 열어 [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
프로세스의 루트가 여전히 이전 설치 네임스페이스를 가리키는 경우 파일을 열면 이전 설치 네임스페이스에서 열립니다.
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,
};