setns(2) System Calls Manual setns(2) setns - C (libc, -lc) #define _GNU_SOURCE /* feature_test_macros(7) */ #include int setns(int fd, int nstype); The setns() system call allows the calling thread to move into different namespaces. The fd argument is one of the following: o a file descriptor referring to one of the magic links in a /proc/pid/ns/ directory (or a bind mount to such a link); o a PID file descriptor (see pidfd_open(2)). The nstype argument is interpreted differently in each case. fd refers to a /proc/pid/ns/ link If fd refers to a /proc/pid/ns/ link, then setns() reassociates the calling thread with the namespace associated with that link, subject to any constraints imposed by the nstype argument. In this usage, each call to setns() changes just one of the caller's namespace memberships. nstype , . : 0 . CLONE_NEWCGROUP ( Linux 4.6) fd cgroup. CLONE_NEWIPC ( Linux 3.0) fd IPC. CLONE_NEWNET ( Linux 3.0) fd network. CLONE_NEWNS ( Linux 3.8) fd mount. CLONE_NEWPID ( Linux 3.8) fd PID . CLONE_NEWTIME ( Linux 5.8) fd must refer to a time namespace. CLONE_NEWUSER ( Linux 3.8) fd user. CLONE_NEWUTS ( Linux 3.0) fd UTS. nstype 0 , ( ) fd. nstype , fd. , ( fd, , , UNIX). fd is a PID file descriptor Since Linux 5.8, fd may refer to a PID file descriptor obtained from pidfd_open(2) or clone(2). In this usage, setns() atomically moves the calling thread into one or more of the same namespaces as the thread referred to by fd. The nstype argument is a bit mask specified by ORing together one or more of the CLONE_NEW* namespace constants listed above. The caller is moved into each of the target thread's namespaces that is specified in nstype; the caller's memberships in the remaining namespaces are left unchanged. For example, the following code would move the caller into the same user, network, and UTS namespaces as PID 1234, but would leave the caller's other namespace memberships unchanged: int fd = pidfd_open(1234, 0); setns(fd, CLONE_NEWUSER | CLONE_NEWNET | CLONE_NEWUTS); : CAP_SYS_ADMIN ( , ). , ID . setns(). setns() . , , setns(). , , , (, CLONE_FS clone(2)) . user_namespaces(7). , CAP_SYS_CHROOT CAP_SYS_ADMIN CAP_SYS_ADMIN , . , (, CLONE_FS clone(2)) . user_namespaces(7). PID PID c , CAP_SYS_ADMIN PID. Reassociating the PID namespace has somewhat different from other namespace types. Reassociating the calling thread with a PID namespace changes only the PID namespace that subsequently created child processes of the caller will be placed in; it does not change the PID namespace of the caller itself. Reassociating with a PID namespace is allowed only if the target PID namespace is a descendant (child, grandchild, etc.) of, or is the same as, the current PID namespace of the caller. PID pid_namespaces(7). cgroup cgroup c , CAP_SYS_ADMIN cgroup. setns() cgroup cgroup . Network, IPC, time, and UTS namespaces In order to reassociate itself with a new network, IPC, time, or UTS namespace, the caller must have the CAP_SYS_ADMIN capability both in its own user namespace and in the user namespace that owns the target namespace. setns() 0. -1, errno . EBADF fd . EINVAL fd , nstype. EINVAL . EINVAL PID (, . .). EINVAL , . EINVAL (CLONE_FS) ( , ) . EINVAL . EINVAL fd is a PID file descriptor and nstype is invalid (e.g., it is 0). ENOMEM . EPERM . ESRCH fd is a PID file descriptor but the process it refers to no longer exists (i.e., it has terminated and been waited on). Linux. Linux 3.0, glibc 2.14. For further information on the /proc/pid/ns/ magic links, see namespaces(7). , using clone(2), setns(). , , . /proc/pid/ns/. . , setns() . ( ns_exec) CLONE_NEWUTS clone(2) ( newuts). clone(2) . UTS. , UTS , , . $ su # # Password: # ./newuts bizarro & [1] 3549 clone() returned 3550 uts.nodename in child: bizarro uts.nodename in parent: antero # uname -n # antero , , . , -- , : # ./ns_exec /proc/3550/ns/uts /bin/bash # uname -n # , ns_exec bizarro #define _GNU_SOURCE #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd; if (argc < 3) { fprintf(stderr, "%s /proc/PID/ns/FILE cmd args...\n", argv[0]); exit(EXIT_FAILURE); } /* Get file descriptor for namespace; the file descriptor is opened with O_CLOEXEC so as to ensure that it is not inherited by the program that is later executed. */ fd = open(argv[1], O_RDONLY | O_CLOEXEC); if (fd == -1) err(EXIT_FAILURE, "open"); if (setns(fd, 0) == -1) /* Join that namespace */ err(EXIT_FAILURE, "setns"); execvp(argv[2], &argv[2]); /* Execute a command in namespace */ err(EXIT_FAILURE, "execvp"); } nsenter(1), clone(2), fork(2), unshare(2), vfork(2), namespaces(7), unix(7) () Alexander Golubev , Azamat Hackimov , Hotellook, Nikita , Spiros Georgaras , Vladislav , Yuri Kozlov ; GNU (GNU General Public License - GPL, 3 ) , - . - , , () () () <>. Linux 6.9.1 15 2024 . setns(2)