diff --git a/man7/namespaces.7 b/man7/namespaces.7 index beaf8f35f..6227d8a68 100644 --- a/man7/namespaces.7 +++ b/man7/namespaces.7 @@ -323,272 +323,16 @@ and Use of UTS namespaces requires a kernel that is configured with the .B CONFIG_UTS_NS option. -.\" -.\" ============================================================ -.\" -.SS Discovering namespace relationships -Since Linux 4.9, -.\" commit bcac25a58bfc6bd79191ac5d7afb49bea96da8c9 -.\" commit 6786741dbf99e44fb0c0ed85a37582b8a26f1c3b -.\" commit a7306ed8d94af729ecef8b6e37506a1c6fc14788 -.\" commit 6ad92bf63e45f97e306da48cd1cbce6e4fef1e5d -two -.BR ioctl (2) -operations are provided to allow discovery of namespace relationships -(see -.BR user_namespaces (7) -and -.BR pid_namespaces (7)). -The form of the calls is: - - new_fd = ioctl(fd, request); - -In each case, -.I fd -refers to a -.IR /proc/[pid]/ns/* -file. -Both operations return a new file descriptor on success. -.TP -.BR NS_GET_USERNS -Returns a file descriptor that refers to the owning user namespace -for the namespace referred to by -.IR fd . -.TP -.BR NS_GET_PARENT -Returns a file descriptor that refers to the parent namespace of -the namespace referred to by -.IR fd . -This operation is valid only for hierarchical namespaces -(i.e., PID and user namespaces). -For user namespaces, -.BR NS_GET_PARENT -is synonymous with -.BR NS_GET_USERNS . -.PP -The new file descriptor returned by these operations is opened with the -.BR O_RDONLY -and -.BR O_CLOEXEC -(close-on-exec; see -.BR fcntl (2)) -flags. -.PP -By applying -.BR fstat (2) -to the returned file descriptor, one obtains a -.I stat -structure whose -.I st_dev -(resident device) and -.I st_ino -(inode number) fields together identify the owning/parent namespace. -This inode number can be matched with the inode number of another -.IR /proc/[pid]/ns/{pid,user} -file to determine whether that is the owning/parent namespace. - -Either of these -.BR ioctl (2) -operations can fail with the following errors: -.TP -.B EPERM -The requested namespace is outside of the caller's namespace scope. -This error can occur if, for example, the owning user namespace is an -ancestor of the caller's current user namespace. -It can also occur on attempts to obtain the parent of the initial -user or PID namespace. -.TP -.B ENOTTY -The operation is not supported by this kernel version. -.PP -Additionally, the -.B NS_GET_PARENT -operation can fail with the following error: -.TP -.B EINVAL -.I fd -refers to a nonhierarchical namespace. -.PP -See the EXAMPLE section for an example of the use of these operations. -.SH CONFORMING TO -Namespaces are a Linux-specific feature. +.fi .SH EXAMPLE -For one example, +See .BR user_namespaces (7). - -The example shown below uses the -.BR ioctl (2) -operations described above to perform simple -discovery of namespace relationships. -The following shell sessions show various examples of the use -of this program. - -Trying to get the parent of the initial user namespace fails, -since it has no parent: - -.nf -.in +4n -$ \fB./ns_show /proc/self/ns/user p\fP -The parent namespace is outside your namespace scope -.in -.fi - -Create a process running -.BR sleep (1) -that resides in new user and UTS namespaces, -and show that the new UTS namespace is associated with the new user namespace: - -.nf -.in +4n -$ \fBunshare \-Uu sleep 1000 &\fP -[1] 23235 -$ \fB./ns_show /proc/23235/ns/uts u\fP -Device/Inode of owning user namespace is: [0,3] / 4026532448 -$ \fBreadlink /proc/23235/ns/user \fP -user:[4026532448] -.in -.fi - -Then show that the parent of the new user namespace in the preceding -example is the initial user namespace: - -.nf -.in +4n -$ \fBreadlink /proc/self/ns/user\fP -user:[4026531837] -$ \fB./ns_show /proc/23235/ns/user p\fP -Device/Inode of parent namespace is: [0,3] / 4026531837 -.in -.fi - -Start a shell in a new user namespace, and show that from within -this shell, the parent user namespace can't be discovered. -Similarly, the UTS namespace -(which is associated with the initial user namespace) -can't be discovered. - -.nf -.in +4n -$ \fBPS1="sh2$ " unshare \-U bash\fP -sh2$ \fB./ns_show /proc/self/ns/user p\fP -The parent namespace is outside your namespace scope -sh2$ \fB./ns_show /proc/self/ns/uts u\fP -The owning user namespace is outside your namespace scope -.in -.fi -.SS Program source -\& -.nf -/* ns_show.c - - Licensed under the GNU General Public License v2 or later. -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef NS_GET_USERNS -#define NSIO 0xb7 -#define NS_GET_USERNS _IO(NSIO, 0x1) -#define NS_GET_PARENT _IO(NSIO, 0x2) -#endif - -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 " - "\(aqp\(aq nor \(aqu\(aq is specified,\\n" - "NS_GET_USERNS is the default.\\n"); - exit(EXIT_FAILURE); - } - - /* Obtain a file descriptor for the \(aqns\(aq 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], \(aqu\(aq)) { - 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: " - "[%lx,%lx] / %ld\\n", - (long) major(sb.st_dev), (long) minor(sb.st_dev), - (long) 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], \(aqp\(aq)) { - parent_fd = ioctl(fd, NS_GET_PARENT); - - if (parent_fd == \-1) { - if (errno == EINVAL) - printf("Can\(aq 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: [%lx,%lx] / %ld\\n", - (long) major(sb.st_dev), (long) minor(sb.st_dev), - (long) sb.st_ino); - - close(parent_fd); - } - - exit(EXIT_SUCCESS); -} -.fi .SH SEE ALSO .BR nsenter (1), .BR readlink (1), .BR unshare (1), .BR clone (2), +.BR ioctl_ns (2), .BR setns (2), .BR unshare (2), .BR proc (5),