.\" %%%LICENSE_END
.\"
.\"
-.TH USER_NAMESPACES 7 2018-02-02 "Linux" "Linux Programmer's Manual"
+.TH USER_NAMESPACES 7 2019-03-06 "Linux" "Linux Programmer's Manual"
.SH NAME
user_namespaces \- overview of Linux user namespaces
.SH DESCRIPTION
that process to the mount the cgroup version 2 filesystem and
cgroup version 1 named hierarchies
(i.e., cgroup filesystems mounted with the
-.BR """none,name="""
+.IR """none,name="""
option).
.PP
Holding
.BR NS_GET_USERNS
.BR ioctl (2)
operation can be used to discover the user namespace
-that owns a a nonuser namespace; see
+that owns a nonuser namespace; see
.BR ioctl_ns (2).
.\"
.\" ============================================================
/* A simple error\-handling function: print an error message based
on the value in \(aqerrno\(aq and terminate the calling process */
-#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \\
+#define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e
} while (0)
struct child_args {
static void
usage(char *pname)
{
- fprintf(stderr, "Usage: %s [options] cmd [arg...]\\n\\n", pname);
+ fprintf(stderr, "Usage: %s [options] cmd [arg...]\en\en", pname);
fprintf(stderr, "Create a child process that executes a shell "
- "command in a new user namespace,\\n"
- "and possibly also other new namespace(s).\\n\\n");
- fprintf(stderr, "Options can be:\\n\\n");
+ "command in a new user namespace,\en"
+ "and possibly also other new namespace(s).\en\en");
+ fprintf(stderr, "Options can be:\en\en");
#define fpe(str) fprintf(stderr, " %s", str);
- fpe("\-i New IPC namespace\\n");
- fpe("\-m New mount namespace\\n");
- fpe("\-n New network namespace\\n");
- fpe("\-p New PID namespace\\n");
- fpe("\-u New UTS namespace\\n");
- fpe("\-U New user namespace\\n");
- fpe("\-M uid_map Specify UID map for user namespace\\n");
- fpe("\-G gid_map Specify GID map for user namespace\\n");
- fpe("\-z Map user\(aqs UID and GID to 0 in user namespace\\n");
- fpe(" (equivalent to: \-M \(aq0 <uid> 1\(aq \-G \(aq0 <gid> 1\(aq)\\n");
- fpe("\-v Display verbose messages\\n");
- fpe("\\n");
- fpe("If \-z, \-M, or \-G is specified, \-U is required.\\n");
- fpe("It is not permitted to specify both \-z and either \-M or \-G.\\n");
- fpe("\\n");
- fpe("Map strings for \-M and \-G consist of records of the form:\\n");
- fpe("\\n");
- fpe(" ID\-inside\-ns ID\-outside\-ns len\\n");
- fpe("\\n");
+ fpe("\-i New IPC namespace\en");
+ fpe("\-m New mount namespace\en");
+ fpe("\-n New network namespace\en");
+ fpe("\-p New PID namespace\en");
+ fpe("\-u New UTS namespace\en");
+ fpe("\-U New user namespace\en");
+ fpe("\-M uid_map Specify UID map for user namespace\en");
+ fpe("\-G gid_map Specify GID map for user namespace\en");
+ fpe("\-z Map user\(aqs UID and GID to 0 in user namespace\en");
+ fpe(" (equivalent to: \-M \(aq0 <uid> 1\(aq \-G \(aq0 <gid> 1\(aq)\en");
+ fpe("\-v Display verbose messages\en");
+ fpe("\en");
+ fpe("If \-z, \-M, or \-G is specified, \-U is required.\en");
+ fpe("It is not permitted to specify both \-z and either \-M or \-G.\en");
+ fpe("\en");
+ fpe("Map strings for \-M and \-G consist of records of the form:\en");
+ fpe("\en");
+ fpe(" ID\-inside\-ns ID\-outside\-ns len\en");
+ fpe("\en");
fpe("A map string can contain multiple records, separated"
- " by commas;\\n");
+ " by commas;\en");
fpe("the commas are replaced by newlines before writing"
- " to map files.\\n");
+ " to map files.\en");
exit(EXIT_FAILURE);
}
map_len = strlen(mapping);
for (j = 0; j < map_len; j++)
if (mapping[j] == \(aq,\(aq)
- mapping[j] = \(aq\\n\(aq;
+ mapping[j] = \(aq\en\(aq;
fd = open(map_file, O_RDWR);
if (fd == \-1) {
- fprintf(stderr, "ERROR: open %s: %s\\n", map_file,
+ fprintf(stderr, "ERROR: open %s: %s\en", map_file,
strerror(errno));
exit(EXIT_FAILURE);
}
if (write(fd, mapping, map_len) != map_len) {
- fprintf(stderr, "ERROR: write %s: %s\\n", map_file,
+ fprintf(stderr, "ERROR: write %s: %s\en", map_file,
strerror(errno));
exit(EXIT_FAILURE);
}
user know. */
if (errno != ENOENT)
- fprintf(stderr, "ERROR: open %s: %s\\n", setgroups_path,
+ fprintf(stderr, "ERROR: open %s: %s\en", setgroups_path,
strerror(errno));
return;
}
if (write(fd, str, strlen(str)) == \-1)
- fprintf(stderr, "ERROR: write %s: %s\\n", setgroups_path,
+ fprintf(stderr, "ERROR: write %s: %s\en", setgroups_path,
strerror(errno));
close(fd);
when parent closes its descriptor */
if (read(args\->pipe_fd[0], &ch, 1) != 0) {
fprintf(stderr,
- "Failure in child: read from pipe returned != 0\\n");
+ "Failure in child: read from pipe returned != 0\en");
exit(EXIT_FAILURE);
}
/* Execute a shell command */
- printf("About to exec %s\\n", args\->argv[0]);
+ printf("About to exec %s\en", args\->argv[0]);
execvp(args\->argv[0], args\->argv);
errExit("execvp");
}
/* Parent falls through to here */
if (verbose)
- printf("%s: PID of child created by clone() is %ld\\n",
+ printf("%s: PID of child created by clone() is %ld\en",
argv[0], (long) child_pid);
/* Update the UID and GID maps in the child */
errExit("waitpid");
if (verbose)
- printf("%s: terminating\\n", argv[0]);
+ printf("%s: terminating\en", argv[0]);
exit(EXIT_SUCCESS);
}