dwww Home | Manual pages | Find package

NS_GET_USERNS(2const)                                     NS_GET_USERNS(2const)

NAME
       NS_GET_USERNS, NS_GET_PARENT - discovering namespace relationships

SYNOPSIS
       #include <linux/nsfs.h>  /* Definition of NS_GET_* constants */
       #include <sys/ioctl.h>

       int ioctl(int fd, unsigned long op);

DESCRIPTION
       The  following  ioctl(2)  operations  are provided to allow discovery of
       namespace relationships (see user_namespaces(7) and pid_namespaces(7)).

       In each case, fd refers to a /proc/pid/ns/* file.  Both  operations  re-
       turn a new file descriptor on success.

       NS_GET_USERNS
              Returns  a  file  descriptor that refers to the owning user name-
              space for the namespace referred to by fd.

       NS_GET_PARENT
              Returns a file descriptor that refers to the parent namespace  of
              the  namespace  referred  to by fd.  This operation is valid only
              for hierarchical namespaces (i.e., PID and user namespaces).  For
              user namespaces, NS_GET_PARENT is synonymous with NS_GET_USERNS.

       The new file descriptor returned by these operations is opened with  the
       O_RDONLY and O_CLOEXEC (close-on-exec; see fcntl(2)) flags.

       By applying fstat(2) to the returned file descriptor, one obtains a stat
       structure  whose  st_dev  (resident  device)  and  st_ino (inode number)
       fields together identify the owning/parent namespace.  This inode number
       can be matched with the inode number of another  /proc/pid/ns/{pid,user}
       file to determine whether that is the owning/parent namespace.

RETURN VALUE
       On  success,  a  file descriptor is returned.  Or error, -1 is returned,
       and errno is set to indicate the error.

ERRORS
       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.

       ENOTTY The operation is not supported by this kernel version.

       Additionally,  the  NS_GET_PARENT  operation can fail with the following
       error:

       EINVAL fd refers to a nonhierarchical namespace.

STANDARDS
       Linux.

HISTORY
       NS_GET_USERNS
              Linux 4.9.

       NS_GET_PARENT
              Linux 4.9.

EXAMPLES
       The example shown below uses the 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:

           $ ./ns_show /proc/self/ns/user p
           The parent namespace is outside your namespace scope

       Create a process running sleep(1) that resides in new user and UTS name-
       spaces,  and  show that the new UTS namespace is associated with the new
       user namespace:

           $ unshare -Uu sleep 1000 &
           [1] 23235
           $ ./ns_show /proc/23235/ns/uts u
           Device/Inode of owning user namespace is: [0,3] / 4026532448
           $ readlink /proc/23235/ns/user
           user:[4026532448]

       Then show that the parent of the new user namespace in the preceding ex-
       ample is the initial user namespace:

           $ readlink /proc/self/ns/user
           user:[4026531837]
           $ ./ns_show /proc/23235/ns/user p
           Device/Inode of parent namespace is: [0,3] / 4026531837

       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.

           $ PS1="sh2$ " unshare -U bash
           sh2$ ./ns_show /proc/self/ns/user p
           The parent namespace is outside your namespace scope
           sh2$ ./ns_show /proc/self/ns/uts u
           The owning user namespace is outside your namespace scope

   Program source

       /* ns_show.c

          Licensed under the GNU General Public License v2 or later.
       */
       #include <errno.h>
       #include <fcntl.h>
       #include <linux/nsfs.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <string.h>
       #include <sys/ioctl.h>
       #include <sys/stat.h>
       #include <sys/sysmacros.h>
       #include <unistd.h>

       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);
       }

SEE ALSO
       ioctl(2), ioctl_nsfs(2)

Linux man-pages 6.9.1              2024-06-15             NS_GET_USERNS(2const)

Generated by dwww version 1.16 on Tue Dec 16 04:32:12 CET 2025.