입력 마운트 네임스페이스의 작동 방식을 이해할 수 없습니다.

입력 마운트 네임스페이스의 작동 방식을 이해할 수 없습니다.

새 설치 네임스페이스로 분기하거나 기존 네임스페이스를 입력하는 경우.

외부 설치 네임스페이스의 파일 설명자를 저장할 수 있습니다. 예를 들어 외부 마운트 네임스페이스에서 프로세스를 찾아 열어 [kdevtmpfs]이를 매우 쉽게 시연 할 수 있습니다 /proc/$PID/root. (이 디렉토리로 변경하고 실행하면 멋진 오류 메시지가 인쇄 되고 반환값이 표시되는 /bin/pwd것 같습니다 .)/usr/bin/pwd: couldn't find directory entry in ‘..’ with matching i-nodestracegetcwd()(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,
};

관련 정보