mirror of https://github.com/mkerrisk/man-pages
namespaces.7: Remove content split out into ioctl_ns(2)
Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
parent
008f58d5e8
commit
e0ab72cb98
|
@ -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 <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#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),
|
||||
|
|
Loading…
Reference in New Issue