Blame man2/ioctl_ns.2

Packit 7cfc04
.\" Copyright (c) 2017 by Michael Kerrisk <mtk.manpages@gmail.com>
Packit 7cfc04
.\"
Packit 7cfc04
.\" %%%LICENSE_START(VERBATIM)
Packit 7cfc04
.\" Permission is granted to make and distribute verbatim copies of this
Packit 7cfc04
.\" manual provided the copyright notice and this permission notice are
Packit 7cfc04
.\" preserved on all copies.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Permission is granted to copy and distribute modified versions of this
Packit 7cfc04
.\" manual under the conditions for verbatim copying, provided that the
Packit 7cfc04
.\" entire resulting derived work is distributed under the terms of a
Packit 7cfc04
.\" permission notice identical to this one.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Since the Linux kernel and libraries are constantly changing, this
Packit 7cfc04
.\" manual page may be incorrect or out-of-date.  The author(s) assume no
Packit 7cfc04
.\" responsibility for errors or omissions, or for damages resulting from
Packit 7cfc04
.\" the use of the information contained herein.  The author(s) may not
Packit 7cfc04
.\" have taken the same level of care in the production of this manual,
Packit 7cfc04
.\" which is licensed free of charge, as they might when working
Packit 7cfc04
.\" professionally.
Packit 7cfc04
.\"
Packit 7cfc04
.\" Formatted or processed versions of this manual, if unaccompanied by
Packit 7cfc04
.\" the source, must acknowledge the copyright and authors of this work.
Packit 7cfc04
.\" %%%LICENSE_END
Packit 7cfc04
.\"
Packit 7cfc04
.\"
Packit 7cfc04
.TH IOCTL_NS 2 2017-09-15 "Linux" "Linux Programmer's Manual"
Packit 7cfc04
.SH NAME
Packit 7cfc04
ioctl_ns \- ioctl() operations for Linux namespaces
Packit 7cfc04
.SH DESCRIPTION
Packit 7cfc04
.\" ============================================================
Packit 7cfc04
.\"
Packit 7cfc04
.SS Discovering namespace relationships
Packit 7cfc04
The following
Packit 7cfc04
.BR ioctl (2)
Packit 7cfc04
operations are provided to allow discovery of namespace relationships (see
Packit 7cfc04
.BR user_namespaces (7)
Packit 7cfc04
and
Packit 7cfc04
.BR pid_namespaces (7)).
Packit 7cfc04
The form of the calls is:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
new_fd = ioctl(fd, request);
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
In each case,
Packit 7cfc04
.I fd
Packit 7cfc04
refers to a
Packit 7cfc04
.IR /proc/[pid]/ns/*
Packit 7cfc04
file.
Packit 7cfc04
Both operations return a new file descriptor on success.
Packit 7cfc04
.TP
Packit 7cfc04
.BR NS_GET_USERNS " (since Linux 4.9)"
Packit 7cfc04
.\" commit bcac25a58bfc6bd79191ac5d7afb49bea96da8c9
Packit 7cfc04
.\" commit 6786741dbf99e44fb0c0ed85a37582b8a26f1c3b
Packit 7cfc04
Returns a file descriptor that refers to the owning user namespace
Packit 7cfc04
for the namespace referred to by
Packit 7cfc04
.IR fd .
Packit 7cfc04
.TP
Packit 7cfc04
.BR NS_GET_PARENT " (since Linux 4.9)"
Packit 7cfc04
.\" commit a7306ed8d94af729ecef8b6e37506a1c6fc14788
Packit 7cfc04
Returns a file descriptor that refers to the parent namespace of
Packit 7cfc04
the namespace referred to by
Packit 7cfc04
.IR fd .
Packit 7cfc04
This operation is valid only for hierarchical namespaces
Packit 7cfc04
(i.e., PID and user namespaces).
Packit 7cfc04
For user namespaces,
Packit 7cfc04
.BR NS_GET_PARENT
Packit 7cfc04
is synonymous with
Packit 7cfc04
.BR NS_GET_USERNS .
Packit 7cfc04
.PP
Packit 7cfc04
The new file descriptor returned by these operations is opened with the
Packit 7cfc04
.BR O_RDONLY
Packit 7cfc04
and
Packit 7cfc04
.BR O_CLOEXEC
Packit 7cfc04
(close-on-exec; see
Packit 7cfc04
.BR fcntl (2))
Packit 7cfc04
flags.
Packit 7cfc04
.PP
Packit 7cfc04
By applying
Packit 7cfc04
.BR fstat (2)
Packit 7cfc04
to the returned file descriptor, one obtains a
Packit 7cfc04
.I stat
Packit 7cfc04
structure whose
Packit 7cfc04
.I st_dev
Packit 7cfc04
(resident device) and
Packit 7cfc04
.I st_ino
Packit 7cfc04
(inode number) fields together identify the owning/parent namespace.
Packit 7cfc04
This inode number can be matched with the inode number of another
Packit 7cfc04
.IR /proc/[pid]/ns/{pid,user}
Packit 7cfc04
file to determine whether that is the owning/parent namespace.
Packit 7cfc04
.PP
Packit 7cfc04
Either of these
Packit 7cfc04
.BR ioctl (2)
Packit 7cfc04
operations can fail with the following errors:
Packit 7cfc04
.TP
Packit 7cfc04
.B EPERM
Packit 7cfc04
The requested namespace is outside of the caller's namespace scope.
Packit 7cfc04
This error can occur if, for example, the owning user namespace is an
Packit 7cfc04
ancestor of the caller's current user namespace.
Packit 7cfc04
It can also occur on attempts to obtain the parent of the initial
Packit 7cfc04
user or PID namespace.
Packit 7cfc04
.TP
Packit 7cfc04
.B ENOTTY
Packit 7cfc04
The operation is not supported by this kernel version.
Packit 7cfc04
.PP
Packit 7cfc04
Additionally, the
Packit 7cfc04
.B NS_GET_PARENT
Packit 7cfc04
operation can fail with the following error:
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
.I fd
Packit 7cfc04
refers to a nonhierarchical namespace.
Packit 7cfc04
.PP
Packit 7cfc04
See the EXAMPLE section for an example of the use of these operations.
Packit 7cfc04
.\" ============================================================
Packit 7cfc04
.\"
Packit 7cfc04
.SS Discovering the namespace type
Packit 7cfc04
The
Packit 7cfc04
.B NS_GET_NSTYPE
Packit 7cfc04
.\" commit e5ff5ce6e20ee22511398bb31fb912466cf82a36
Packit 7cfc04
operation (available since Linux 4.11) can be used to discover
Packit 7cfc04
the type of namespace referred to by the file descriptor
Packit 7cfc04
.IR fd :
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
nstype = ioctl(fd, NS_GET_NSTYPE);
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
.I fd
Packit 7cfc04
refers to a
Packit 7cfc04
.IR /proc/[pid]/ns/*
Packit 7cfc04
file.
Packit 7cfc04
.PP
Packit 7cfc04
The return value is one of the
Packit 7cfc04
.BR CLONE_NEW*
Packit 7cfc04
values that can be specified to
Packit 7cfc04
.BR clone (2)
Packit 7cfc04
or
Packit 7cfc04
.BR unshare (2)
Packit 7cfc04
in order to create a namespace.
Packit 7cfc04
.\" ============================================================
Packit 7cfc04
.\"
Packit 7cfc04
.SS Discovering the owner of a user namespace
Packit 7cfc04
The
Packit 7cfc04
.B NS_GET_OWNER_UID
Packit 7cfc04
.\" commit 015bb305b8ebe8d601a238ab70ebdc394c7a19ba
Packit 7cfc04
operation (available since Linux 4.11) can be used to discover
Packit 7cfc04
the owner user ID of a user namespace (i.e., the effective user ID
Packit 7cfc04
of the process that created the user namespace).
Packit 7cfc04
The form of the call is:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
uid_t uid;
Packit 7cfc04
ioctl(fd, NS_GET_OWNER_UID, &uid);
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
.I fd
Packit 7cfc04
refers to a
Packit 7cfc04
.IR /proc/[pid]/ns/user
Packit 7cfc04
file.
Packit 7cfc04
.PP
Packit 7cfc04
The owner user ID is returned in the
Packit 7cfc04
.I uid_t
Packit 7cfc04
pointed to by the third argument.
Packit 7cfc04
.PP
Packit 7cfc04
This operation can fail with the following error:
Packit 7cfc04
.TP
Packit 7cfc04
.B EINVAL
Packit 7cfc04
.I fd
Packit 7cfc04
does not refer to a user namespace.
Packit 7cfc04
.SH ERRORS
Packit 7cfc04
Any of the above
Packit 7cfc04
.BR ioctl ()
Packit 7cfc04
operations can return the following errors:
Packit 7cfc04
.TP
Packit 7cfc04
.B ENOTTY
Packit 7cfc04
.I fd
Packit 7cfc04
does not refer to a
Packit 7cfc04
.I /proc/[pid]/ns/*
Packit 7cfc04
file.
Packit 7cfc04
.SH CONFORMING TO
Packit 7cfc04
Namespaces and the operations described on this page are a Linux-specific.
Packit 7cfc04
.SH EXAMPLE
Packit 7cfc04
The example shown below uses the
Packit 7cfc04
.BR ioctl (2)
Packit 7cfc04
operations described above to perform simple
Packit 7cfc04
discovery of namespace relationships.
Packit 7cfc04
The following shell sessions show various examples of the use
Packit 7cfc04
of this program.
Packit 7cfc04
.PP
Packit 7cfc04
Trying to get the parent of the initial user namespace fails,
Packit 7cfc04
since it has no parent:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
$ \fB./ns_show /proc/self/ns/user p\fP
Packit 7cfc04
The parent namespace is outside your namespace scope
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
Create a process running
Packit 7cfc04
.BR sleep (1)
Packit 7cfc04
that resides in new user and UTS namespaces,
Packit 7cfc04
and show that the new UTS namespace is associated with the new user namespace:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
$ \fBunshare \-Uu sleep 1000 &\fP
Packit 7cfc04
[1] 23235
Packit 7cfc04
$ \fB./ns_show /proc/23235/ns/uts u\fP
Packit 7cfc04
Device/Inode of owning user namespace is: [0,3] / 4026532448
Packit 7cfc04
$ \fBreadlink /proc/23235/ns/user \fP
Packit 7cfc04
user:[4026532448]
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
Then show that the parent of the new user namespace in the preceding
Packit 7cfc04
example is the initial user namespace:
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
$ \fBreadlink /proc/self/ns/user\fP
Packit 7cfc04
user:[4026531837]
Packit 7cfc04
$ \fB./ns_show /proc/23235/ns/user p\fP
Packit 7cfc04
Device/Inode of parent namespace is: [0,3] / 4026531837
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.PP
Packit 7cfc04
Start a shell in a new user namespace, and show that from within
Packit 7cfc04
this shell, the parent user namespace can't be discovered.
Packit 7cfc04
Similarly, the UTS namespace
Packit 7cfc04
(which is associated with the initial user namespace)
Packit 7cfc04
can't be discovered.
Packit 7cfc04
.PP
Packit 7cfc04
.in +4n
Packit 7cfc04
.EX
Packit 7cfc04
$ \fBPS1="sh2$ " unshare \-U bash\fP
Packit 7cfc04
sh2$ \fB./ns_show /proc/self/ns/user p\fP
Packit 7cfc04
The parent namespace is outside your namespace scope
Packit 7cfc04
sh2$ \fB./ns_show /proc/self/ns/uts u\fP
Packit 7cfc04
The owning user namespace is outside your namespace scope
Packit 7cfc04
.EE
Packit 7cfc04
.in
Packit 7cfc04
.SS Program source
Packit 7cfc04
\&
Packit 7cfc04
.EX
Packit 7cfc04
/* ns_show.c
Packit 7cfc04
Packit 7cfc04
   Licensed under the GNU General Public License v2 or later.
Packit 7cfc04
*/
Packit 7cfc04
#include <stdlib.h>
Packit 7cfc04
#include <unistd.h>
Packit 7cfc04
#include <stdio.h>
Packit 7cfc04
#include <fcntl.h>
Packit 7cfc04
#include <string.h>
Packit 7cfc04
#include <sys/stat.h>
Packit 7cfc04
#include <sys/ioctl.h>
Packit 7cfc04
#include <errno.h>
Packit 7cfc04
#include <sys/sysmacros.h>
Packit 7cfc04
Packit 7cfc04
#ifndef NS_GET_USERNS
Packit 7cfc04
#define NSIO    0xb7
Packit 7cfc04
#define NS_GET_USERNS   _IO(NSIO, 0x1)
Packit 7cfc04
#define NS_GET_PARENT   _IO(NSIO, 0x2)
Packit 7cfc04
#endif
Packit 7cfc04
Packit 7cfc04
int
Packit 7cfc04
main(int argc, char *argv[])
Packit 7cfc04
{
Packit 7cfc04
    int fd, userns_fd, parent_fd;
Packit 7cfc04
    struct stat sb;
Packit 7cfc04
Packit 7cfc04
    if (argc < 2) {
Packit 7cfc04
        fprintf(stderr, "Usage: %s /proc/[pid]/ns/[file] [p|u]\\n",
Packit 7cfc04
                argv[0]);
Packit 7cfc04
        fprintf(stderr, "\\nDisplay the result of one or both "
Packit 7cfc04
                "of NS_GET_USERNS (u) or NS_GET_PARENT (p)\\n"
Packit 7cfc04
                "for the specified /proc/[pid]/ns/[file]. If neither "
Packit 7cfc04
                "\(aqp\(aq nor \(aqu\(aq is specified,\\n"
Packit 7cfc04
                "NS_GET_USERNS is the default.\\n");
Packit 7cfc04
        exit(EXIT_FAILURE);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    /* Obtain a file descriptor for the \(aqns\(aq file specified
Packit 7cfc04
       in argv[1] */
Packit 7cfc04
Packit 7cfc04
    fd = open(argv[1], O_RDONLY);
Packit 7cfc04
    if (fd == \-1) {
Packit 7cfc04
        perror("open");
Packit 7cfc04
        exit(EXIT_FAILURE);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    /* Obtain a file descriptor for the owning user namespace and
Packit 7cfc04
       then obtain and display the inode number of that namespace */
Packit 7cfc04
Packit 7cfc04
    if (argc < 3 || strchr(argv[2], \(aqu\(aq)) {
Packit 7cfc04
        userns_fd = ioctl(fd, NS_GET_USERNS);
Packit 7cfc04
Packit 7cfc04
        if (userns_fd == \-1) {
Packit 7cfc04
            if (errno == EPERM)
Packit 7cfc04
                printf("The owning user namespace is outside "
Packit 7cfc04
                        "your namespace scope\\n");
Packit 7cfc04
            else
Packit 7cfc04
               perror("ioctl\-NS_GET_USERNS");
Packit 7cfc04
            exit(EXIT_FAILURE);
Packit 7cfc04
         }
Packit 7cfc04
Packit 7cfc04
        if (fstat(userns_fd, &sb) == \-1) {
Packit 7cfc04
            perror("fstat\-userns");
Packit 7cfc04
            exit(EXIT_FAILURE);
Packit 7cfc04
        }
Packit 7cfc04
        printf("Device/Inode of owning user namespace is: "
Packit 7cfc04
                "[%lx,%lx] / %ld\\n",
Packit 7cfc04
                (long) major(sb.st_dev), (long) minor(sb.st_dev),
Packit 7cfc04
                (long) sb.st_ino);
Packit 7cfc04
Packit 7cfc04
        close(userns_fd);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    /* Obtain a file descriptor for the parent namespace and
Packit 7cfc04
       then obtain and display the inode number of that namespace */
Packit 7cfc04
Packit 7cfc04
    if (argc > 2 && strchr(argv[2], \(aqp\(aq)) {
Packit 7cfc04
        parent_fd = ioctl(fd, NS_GET_PARENT);
Packit 7cfc04
Packit 7cfc04
        if (parent_fd == \-1) {
Packit 7cfc04
            if (errno == EINVAL)
Packit 7cfc04
                printf("Can\(aq get parent namespace of a "
Packit 7cfc04
                        "nonhierarchical namespace\\n");
Packit 7cfc04
            else if (errno == EPERM)
Packit 7cfc04
                printf("The parent namespace is outside "
Packit 7cfc04
                        "your namespace scope\\n");
Packit 7cfc04
            else
Packit 7cfc04
                perror("ioctl\-NS_GET_PARENT");
Packit 7cfc04
            exit(EXIT_FAILURE);
Packit 7cfc04
        }
Packit 7cfc04
Packit 7cfc04
        if (fstat(parent_fd, &sb) == \-1) {
Packit 7cfc04
            perror("fstat\-parentns");
Packit 7cfc04
            exit(EXIT_FAILURE);
Packit 7cfc04
        }
Packit 7cfc04
        printf("Device/Inode of parent namespace is: [%lx,%lx] / %ld\\n",
Packit 7cfc04
                (long) major(sb.st_dev), (long) minor(sb.st_dev),
Packit 7cfc04
                (long) sb.st_ino);
Packit 7cfc04
Packit 7cfc04
        close(parent_fd);
Packit 7cfc04
    }
Packit 7cfc04
Packit 7cfc04
    exit(EXIT_SUCCESS);
Packit 7cfc04
}
Packit 7cfc04
.EE
Packit 7cfc04
.SH SEE ALSO
Packit 7cfc04
.BR fstat (2),
Packit 7cfc04
.BR ioctl (2),
Packit 7cfc04
.BR proc (5),
Packit 7cfc04
.BR namespaces (7)
Packit 7cfc04
.SH COLOPHON
Packit 7cfc04
This page is part of release 4.15 of the Linux
Packit 7cfc04
.I man-pages
Packit 7cfc04
project.
Packit 7cfc04
A description of the project,
Packit 7cfc04
information about reporting bugs,
Packit 7cfc04
and the latest version of this page,
Packit 7cfc04
can be found at
Packit 7cfc04
\%https://www.kernel.org/doc/man\-pages/.