diff options
author | Karel Zak | 2013-07-03 12:28:16 +0200 |
---|---|---|
committer | Karel Zak | 2013-07-09 11:02:48 +0200 |
commit | 6728ca101e7edc223a8eb99201197831d8daa61f (patch) | |
tree | e3c5450e53c2904f1e5a9203d0fa26e3163393d2 /sys-utils/unshare.c | |
parent | unshare: add --fork options for pid namespaces (diff) | |
download | kernel-qcow2-util-linux-6728ca101e7edc223a8eb99201197831d8daa61f.tar.gz kernel-qcow2-util-linux-6728ca101e7edc223a8eb99201197831d8daa61f.tar.xz kernel-qcow2-util-linux-6728ca101e7edc223a8eb99201197831d8daa61f.zip |
unshare: add --mount-proc for pid namespaces
Based on patch from Mike Frysinger <vapier@gentoo.org>.
Mike Frysinger wrote:
When it comes to pid namespaces, it's also useful for /proc to reflect
the current namespace. Again, this is easy to pull off, but annoying
to force everyone to do it themselves. So let's add a --mount-proc to
do the magic for us. The downside is that this also implies creating
a mount namespace as mounting the new pid namespace /proc over top the
system one will quickly break all other processes on the system.
Signed-off-by: Karel Zak <kzak@redhat.com>
Acked-by: Mike Frysinger <vapier@gentoo.or>
Diffstat (limited to 'sys-utils/unshare.c')
-rw-r--r-- | sys-utils/unshare.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c index a889eee9f..a64b776e8 100644 --- a/sys-utils/unshare.c +++ b/sys-utils/unshare.c @@ -25,6 +25,7 @@ #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> +#include <sys/mount.h> #include "nls.h" #include "c.h" @@ -41,13 +42,14 @@ static void usage(int status) _(" %s [options] <program> [args...]\n"), program_invocation_short_name); fputs(USAGE_OPTIONS, out); - fputs(_(" -m, --mount unshare mounts namespace\n"), out); - fputs(_(" -u, --uts unshare UTS namespace (hostname etc)\n"), out); - fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); - fputs(_(" -n, --net unshare network namespace\n"), out); - fputs(_(" -p, --pid unshare pid namespace\n"), out); - fputs(_(" -U, --user unshare user namespace\n"), out); - fputs(_(" -f, --fork fork before launching <program>\n"), out); + fputs(_(" -m, --mount unshare mounts namespace\n"), out); + fputs(_(" -u, --uts unshare UTS namespace (hostname etc)\n"), out); + fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); + fputs(_(" -n, --net unshare network namespace\n"), out); + fputs(_(" -p, --pid unshare pid namespace\n"), out); + fputs(_(" -U, --user unshare user namespace\n"), out); + fputs(_(" -f, --fork fork before launching <program>\n"), out); + fputs(_(" --mount-proc[=<dir>] mount proc filesystem first (implies --mount)\n"), out); fputs(USAGE_SEPARATOR, out); fputs(USAGE_HELP, out); @@ -59,6 +61,9 @@ static void usage(int status) int main(int argc, char *argv[]) { + enum { + OPT_MOUNTPROC = CHAR_MAX + 1 + }; static const struct option longopts[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'V'}, @@ -69,11 +74,13 @@ int main(int argc, char *argv[]) { "pid", no_argument, 0, 'p' }, { "user", no_argument, 0, 'U' }, { "fork", no_argument, 0, 'f' }, + { "mount-proc", optional_argument, 0, OPT_MOUNTPROC }, { NULL, 0, 0, 0 } }; int unshare_flags = 0; int c, forkit = 0; + const char *procmnt = NULL; setlocale(LC_MESSAGES, ""); bindtextdomain(PACKAGE, LOCALEDIR); @@ -108,6 +115,10 @@ int main(int argc, char *argv[]) case 'U': unshare_flags |= CLONE_NEWUSER; break; + case OPT_MOUNTPROC: + unshare_flags |= CLONE_NEWNS; + procmnt = optarg ? optarg : "/proc"; + break; default: usage(EXIT_FAILURE); } @@ -136,6 +147,11 @@ int main(int argc, char *argv[]) } } + if (procmnt && + (mount("none", procmnt, NULL, MS_PRIVATE|MS_REC, NULL) != 0 || + mount("proc", procmnt, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) != 0)) + err(EXIT_FAILURE, _("mount %s failed"), procmnt); + if (optind < argc) { execvp(argv[optind], argv + optind); err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]); |