ioctl_ns(2) System Calls Manual ioctl_ns(2) ioctl_ns - ioctl() Linux ioctl(2) ( user_namespaces(7) pid_namespaces(7)). : new_fd = ioctl(fd, request); fd /proc/pid/ns/*. . NS_GET_USERNS ( Linux 4.9) , , , fd. NS_GET_PARENT ( Linux 4.9) , , fd. , (. ., PID ). NS_GET_PARENT NS_GET_USERNS. , , O_RDONLY O_CLOEXEC (close-on-exec; fcntl(2)). fstat(2) , stat, st_dev ( ) st_ino ( ) / . /proc/pid/ns/{pid,user}, / . ioctl(2) : EPERM . , , , . PID. ENOTTY . , NS_GET_PARENT : EINVAL fd . . NS_GET_NSTYPE (, Linux 4.11) , fd: nstype = ioctl(fd, NS_GET_NSTYPE); fd /proc/pid/ns/*. CLONE_NEW*, clone(2) unshare(2) . NS_GET_OWNER_UID (, Linux 4.11) ID (. ., ID , ). : uid_t uid; ioctl(fd, NS_GET_OWNER_UID, &uid); fd /proc/pid/ns/user. ID uid_t. : EINVAL fd . ioctl() : ENOTTY fd does not refer to a /proc/pid/ns/* file. Linux. , , ioctl(2), . . , : $ ./ns_show /proc/self/ns/user p , sleep(1), UTS, , UTS : $ unshare -Uu sleep 1000 & [1] 23235 $ ./ns_show /proc/23235/ns/uts u /, : [0,3] / 4026532448 $ readlink /proc/23235/ns/user user:[4026532448] , : $ readlink /proc/self/ns/user user:[4026531837] $ ./ns_show /proc/23235/ns/user p / : [0,3] / 4026531837 , . UTS ( ). $ PS1="sh2$ " unshare -U bash sh2$ ./ns_show /proc/self/ns/user p sh2$ ./ns_show /proc/self/ns/uts u /* ns_show.c Licensed under the GNU General Public License v2 or later. */ #include #include #include #include #include #include #include #include #include #include #include int main(int argc, char *argv[]) { int fd, userns_fd, parent_fd; struct stat sb; if (argc < 2) { fprintf(stderr, "Usage: %s /proc/[pid]/ns/[file] [p|u]\n", argv[0]); fprintf(stderr, "\nDisplay the result of one or both " "of NS_GET_USERNS (u) or NS_GET_PARENT (p)\n" "for the specified /proc/[pid]/ns/[file]. If neither " "'p' nor 'u' is specified,\n" "NS_GET_USERNS is the default.\n"); exit(EXIT_FAILURE); } /* Obtain a file descriptor for the 'ns' file specified in argv[1]. */ fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } /* Obtain a file descriptor for the owning user namespace and then obtain and display the inode number of that namespace. */ if (argc < 3 || strchr(argv[2], 'u')) { userns_fd = ioctl(fd, NS_GET_USERNS); if (userns_fd == -1) { if (errno == EPERM) printf("The owning user namespace is outside " "your namespace scope\n"); else perror("ioctl-NS_GET_USERNS"); exit(EXIT_FAILURE); } if (fstat(userns_fd, &sb) == -1) { perror("fstat-userns"); exit(EXIT_FAILURE); } printf("Device/Inode of owning user namespace is: " "[%x,%x] / %ju\n", major(sb.st_dev), minor(sb.st_dev), (uintmax_t) sb.st_ino); close(userns_fd); } /* Obtain a file descriptor for the parent namespace and then obtain and display the inode number of that namespace. */ if (argc > 2 && strchr(argv[2], 'p')) { parent_fd = ioctl(fd, NS_GET_PARENT); if (parent_fd == -1) { if (errno == EINVAL) printf("Can' get parent namespace of a " "nonhierarchical namespace\n"); else if (errno == EPERM) printf("The parent namespace is outside " "your namespace scope\n"); else perror("ioctl-NS_GET_PARENT"); exit(EXIT_FAILURE); } if (fstat(parent_fd, &sb) == -1) { perror("fstat-parentns"); exit(EXIT_FAILURE); } printf("Device/Inode of parent namespace is: [%x,%x] / %ju\n", major(sb.st_dev), minor(sb.st_dev), (uintmax_t) sb.st_ino); close(parent_fd); } exit(EXIT_SUCCESS); } . fstat(2), ioctl(2), proc(5), namespaces(7) Azamat Hackimov , Dmitriy S. Seregin , Yuri Kozlov ; GNU 3 , . . , , . Linux man-pages 6.06 31 2023 . ioctl_ns(2)