* [PATCH] sys-tools: Add setns utility to sys-tools
@ 2012-12-19 19:06 Neil Horman
2012-12-19 20:16 ` Mantas M.
` (4 more replies)
0 siblings, 5 replies; 16+ messages in thread
From: Neil Horman @ 2012-12-19 19:06 UTC (permalink / raw)
To: util-linux; +Cc: Neil Horman, Karel Zak
Like the unshare command, which lets a user from the command line detach from
specific namespaces of the parent process, and execute a command, setns provides
a frontend to the setns(2) syscall, which allows a user to migrate a process to
the namespaces of other processes, prior to calling exec on a command.
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Karel Zak <kzak@redhat.com>
---
configure.ac | 11 +++++
sys-utils/Makemodule.am | 5 ++
sys-utils/setns.1 | 38 +++++++++++++++
sys-utils/setns.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 177 insertions(+)
create mode 100644 sys-utils/setns.1
create mode 100644 sys-utils/setns.c
diff --git a/configure.ac b/configure.ac
index 9c08fc0..829594d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -862,6 +862,17 @@ if test "x$build_unshare" = xyes; then
AC_CHECK_FUNCS([unshare])
fi
+AC_ARG_ENABLE([setns],
+ AS_HELP_STRING([--disable-setns], [do not build setns]),
+ [], enable_unshare=check
+)
+UL_BUILD_INIT([setns])
+UL_REQUIRES_LINUX([setns])
+UL_REQUIRES_SYSCALL_CHECK([setns], [UL_CHECK_SYSCALL([setns])])
+AM_CONDITIONAL(BUILD_SETNS, test "x$build_setns" = xyes)
+if test "x$build_setns" = xyes; then
+ AC_CHECK_FUNCS([setns])
+fi
AC_ARG_ENABLE([arch],
AS_HELP_STRING([--enable-arch], [do build arch]),
diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 33112fb..6d11ab3 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -283,6 +283,11 @@ dist_man_MANS += sys-utils/switch_root.8
switch_root_SOURCES = sys-utils/switch_root.c
endif
+if BUILD_SETNS
+usrbin_exec_PROGRAMS += setns
+setns_SOURCES = sys-utils/setns.c
+endif
+
if BUILD_UNSHARE
usrbin_exec_PROGRAMS += unshare
dist_man_MANS += sys-utils/unshare.1
diff --git a/sys-utils/setns.1 b/sys-utils/setns.1
new file mode 100644
index 0000000..ad8c386
--- /dev/null
+++ b/sys-utils/setns.1
@@ -0,0 +1,38 @@
+.\" Process this file with
+.\" groff -man -Tascii lscpu.1
+.\"
+.TH SETNS 1 "December 2012" "util-linux" "User Commands"
+.SH NAME
+setns \- run program with namespaces of another process
+.SH SYNOPSIS
+.B setns
+.RI [ options ]
+program
+.RI [ arguments ]
+.SH DESCRIPTION
+Migrates to the namespaces of the specified pid/namespace pairs, and executes a
+child process.
+.SH OPTIONS
+.TP
+.BR \-h , " \-\-help"
+Print a help message,
+.TP
+.BR \-u\ <pid> , " \-\-uts=<pid>"
+Migrate to the uts namespace of <pid>
+.TP
+.BR \-i\ <pid> , " \-\-ipc=<pid>"
+Migrate to the ipc namespace of <pid>
+.TP
+.BR \-n\ <pid> , " \-\-net\<pid>"
+Migrate to the net namespace of <pid>
+.SH SEE ALSO
+.BR unshare (2),
+.BR setns (2),
+.BR clone (2)
+.SH BUGS
+None known so far.
+.SH AUTHOR
+Neil Horman <nhorman@tuxdriver.com>
+.SH AVAILABILITY
+The setns command is part of the util-linux package and is available from
+ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/sys-utils/setns.c b/sys-utils/setns.c
new file mode 100644
index 0000000..8e20748
--- /dev/null
+++ b/sys-utils/setns.c
@@ -0,0 +1,123 @@
+/*
+ * setns(1) - command-line interface for setns(2)
+ *
+ * Copyright (C) 2012 Neil Horman <nhorman@tuxdriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sched.h>
+
+/*
+ * Note: The long option strings are used
+ * to build a path via /proc/<pid>/ns, so they must
+ * match the corresponding namespace
+ */
+struct option lopts[] = {
+ {"help", 0, NULL, 'h'},
+ {"ipc", 1, NULL, 'i'},
+ {"net", 1, NULL, 'n'},
+ {"uts", 1, NULL, 'u'},
+ {0, 0, 0, 0},
+};
+
+static void usage(char **argv)
+{
+ printf("%s [--ipc|-i=<pid>] [--net|-n=pid] [--uts|-u=pid] <command>\n",
+ argv[0]);
+}
+
+static int switch_namespace(const char *name, unsigned long pid)
+{
+ int fd;
+ char path[256];
+
+ sprintf(path, "/proc/%d/ns/%s", (int)pid, name);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ return -1;
+
+ if (setns(fd, 0) < 0) {
+ char buf[512];
+ sprintf(buf,"Setns failed for %s on pid %d: ", name, (int)pid);
+ perror(buf);
+ return -1;
+ }
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ int longind;
+ int execind = argc+1;
+ unsigned long pid;
+ int rc = 0;
+
+ while ((opt = getopt_long(argc, argv,
+ "hi:n:u:", lopts, &longind)) != -1) {
+
+ switch (opt) {
+ case '?':
+ usage(argv);
+ exit(0);
+ case 'h':
+ usage(argv);
+ exit(0);
+
+ case 'i':
+ case 'n':
+ case 'u':
+ pid = strtoul(optarg, NULL, 10);
+ if (pid == ULONG_MAX) {
+ rc = 1;
+ printf("%s pid not properly specified\n",
+ lopts[longind].name);
+ goto out;
+ }
+ rc = switch_namespace(lopts[longind].name, pid);
+ if (rc < 0)
+ goto out;
+ break;
+
+ }
+ }
+
+ if (optind == argc) {
+ printf("no executable specified\n");
+ rc = 1;
+ goto out;
+ }
+ execind = optind;
+
+ rc = execvp(argv[execind], &argv[execind]);
+ if (rc < 0) {
+ char buf[512];
+ sprintf("execv of %s failed: ", argv[execind]);
+ perror(buf);
+ }
+out:
+ return rc;
+}
+
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] sys-tools: Add setns utility to sys-tools
2012-12-19 19:06 [PATCH] sys-tools: Add setns utility to sys-tools Neil Horman
@ 2012-12-19 20:16 ` Mantas M.
2012-12-19 21:01 ` Neil Horman
` (3 subsequent siblings)
4 siblings, 0 replies; 16+ messages in thread
From: Mantas M. @ 2012-12-19 20:16 UTC (permalink / raw)
To: util-linux
On 2012-12-19 21:06, Neil Horman wrote:
> ...
> +.BR \-u\ <pid> , " \-\-uts=<pid>"
> +Migrate to the uts namespace of <pid>
> +.TP
> +.BR \-i\ <pid> , " \-\-ipc=<pid>"
> +Migrate to the ipc namespace of <pid>
> +.TP
> +.BR \-n\ <pid> , " \-\-net\<pid>"
> +Migrate to the net namespace of <pid>
Wouldn't it be more useful to accept an arbitrary path, and just hand it
to setns(2)? That way, the utility would automatically gain support for
new namespace types (for example `setns /proc/$pid/ns/mount`), and would
allow joining namespaces that are linked outside /proc.
For example, I seem to remember someone saying that `mount --bind
/proc/$pid/ns/net /tmp/foo-namespace` can be used to make that
particular namespace persist even after the process quits. Then `setns
/tmp/foo-namespace someprogram` could be used to join that namespace again.
--
Mantas Mikulėnas <grawity@gmail.com>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] sys-tools: Add setns utility to sys-tools
2012-12-19 19:06 [PATCH] sys-tools: Add setns utility to sys-tools Neil Horman
2012-12-19 20:16 ` Mantas M.
@ 2012-12-19 21:01 ` Neil Horman
2012-12-19 23:15 ` Sami Kerola
2012-12-20 9:24 ` Karel Zak
` (2 subsequent siblings)
4 siblings, 1 reply; 16+ messages in thread
From: Neil Horman @ 2012-12-19 21:01 UTC (permalink / raw)
To: util-linux; +Cc: Karel Zak, grawity
>>On 2012-12-19 21:06, Neil Horman wrote:
>> ...
>> +.BR \-u\ <pid> , " \-\-uts=<pid>"
>> +Migrate to the uts namespace of <pid>
>> +.TP
>> +.BR \-i\ <pid> , " \-\-ipc=<pid>"
>> +Migrate to the ipc namespace of <pid>
>> +.TP
>> +.BR \-n\ <pid> , " \-\-net\<pid>"
>> +Migrate to the net namespace of <pid>
>
>Wouldn't it be more useful to accept an arbitrary path, and just hand it
>to setns(2)? That way, the utility would automatically gain support for
>new namespace types (for example `setns /proc/$pid/ns/mount`), and would
>allow joining namespaces that are linked outside /proc.
>
>For example, I seem to remember someone saying that `mount --bind
>/proc/$pid/ns/net /tmp/foo-namespace` can be used to make that
>particular namespace persist even after the process quits. Then `setns
>/tmp/foo-namespace someprogram` could be used to join that namespace again.
Yeah, that makes sense, I'll respin this tomorrow, and repost. I'm also going
to batch the namespace switches, by opening all the file descriptors first, then
calling setns on them. It was pointed out to me by doing them one by one like
this, if you setns the mount namespace you might loose access to the paths that
were specified.
Thanks!
Neil
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] sys-tools: Add setns utility to sys-tools
2012-12-19 21:01 ` Neil Horman
@ 2012-12-19 23:15 ` Sami Kerola
0 siblings, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2012-12-19 23:15 UTC (permalink / raw)
To: Neil Horman; +Cc: util-linux, Karel Zak, grawity
[-- Attachment #1: Type: text/plain, Size: 1870 bytes --]
On Wed, Dec 19, 2012 at 9:01 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
>>>On 2012-12-19 21:06, Neil Horman wrote:
>>> ...
>>> +.BR \-u\ <pid> , " \-\-uts=<pid>"
>>> +Migrate to the uts namespace of <pid>
>>> +.TP
>>> +.BR \-i\ <pid> , " \-\-ipc=<pid>"
>>> +Migrate to the ipc namespace of <pid>
>>> +.TP
>>> +.BR \-n\ <pid> , " \-\-net\<pid>"
>>> +Migrate to the net namespace of <pid>
>>
>>Wouldn't it be more useful to accept an arbitrary path, and just hand it
>>to setns(2)? That way, the utility would automatically gain support for
>>new namespace types (for example `setns /proc/$pid/ns/mount`), and would
>>allow joining namespaces that are linked outside /proc.
>>
>>For example, I seem to remember someone saying that `mount --bind
>>/proc/$pid/ns/net /tmp/foo-namespace` can be used to make that
>>particular namespace persist even after the process quits. Then `setns
>>/tmp/foo-namespace someprogram` could be used to join that namespace again.
>
> Yeah, that makes sense, I'll respin this tomorrow, and repost. I'm also going
> to batch the namespace switches, by opening all the file descriptors first, then
> calling setns on them. It was pointed out to me by doing them one by one like
> this, if you setns the mount namespace you might loose access to the paths that
> were specified.
Hi Neil, and others,
I reviewed patch, and altered it to match with util-linux
Documentation/howto-* stuff. While doing that I notice two bugs. Short
option made cores to be dropped, as the long option index was zero.
The command also tried to parse options of command it later executed.
Short option string got + character to fix that. I also included man
page to be part of distribution package.
p.s. See attachent for the modified patch. I know I should in-line it,
but the gmail is not making it easy.
--
Sami Kerola
http://www.iki.fi/kerolasa/
[-- Attachment #2: 0001-setns-add-new-command.txt --]
[-- Type: text/plain, Size: 7190 bytes --]
From 632c7e16a199c053f94709ab5e00d3531b86e081 Mon Sep 17 00:00:00 2001
From: Neil Horman <nhorman@tuxdriver.com>
Date: Wed, 19 Dec 2012 14:06:46 -0500
Subject: [PATCH] setns: add new command
Organization: Lastminute.com
Like the unshare command, which lets a user from the command line detach
from specific namespaces of the parent process, and execute a command,
setns provides a frontend to the setns(2) syscall, which allows a user to
migrate a process to the namespaces of other processes, prior to calling
exec on a command.
CC: Karel Zak <kzak@redhat.com>
Reviewed-by: Sami Kerola <kerolasa@iki.fi>
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
---
.gitignore | 1 +
configure.ac | 11 +++++
sys-utils/Makemodule.am | 7 +++
sys-utils/setns.1 | 51 +++++++++++++++++++
sys-utils/setns.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 197 insertions(+)
create mode 100644 sys-utils/setns.1
create mode 100644 sys-utils/setns.c
diff --git a/.gitignore b/.gitignore
index e85eb07..63f77c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -146,6 +146,7 @@ tests/run.sh.trs
/script
/scriptreplay
/setarch
+/setns
/setsid
/setterm
/sfdisk
diff --git a/configure.ac b/configure.ac
index 9c08fc0..829594d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -862,6 +862,17 @@ if test "x$build_unshare" = xyes; then
AC_CHECK_FUNCS([unshare])
fi
+AC_ARG_ENABLE([setns],
+ AS_HELP_STRING([--disable-setns], [do not build setns]),
+ [], enable_unshare=check
+)
+UL_BUILD_INIT([setns])
+UL_REQUIRES_LINUX([setns])
+UL_REQUIRES_SYSCALL_CHECK([setns], [UL_CHECK_SYSCALL([setns])])
+AM_CONDITIONAL(BUILD_SETNS, test "x$build_setns" = xyes)
+if test "x$build_setns" = xyes; then
+ AC_CHECK_FUNCS([setns])
+fi
AC_ARG_ENABLE([arch],
AS_HELP_STRING([--enable-arch], [do build arch]),
diff --git a/sys-utils/Makemodule.am b/sys-utils/Makemodule.am
index 33112fb..e517c93 100644
--- a/sys-utils/Makemodule.am
+++ b/sys-utils/Makemodule.am
@@ -283,6 +283,13 @@ dist_man_MANS += sys-utils/switch_root.8
switch_root_SOURCES = sys-utils/switch_root.c
endif
+if BUILD_SETNS
+usrbin_exec_PROGRAMS += setns
+setns_SOURCES = sys-utils/setns.c
+setns_LDADD = $(LDADD) libcommon.la
+dist_man_MANS += sys-utils/setns.1
+endif
+
if BUILD_UNSHARE
usrbin_exec_PROGRAMS += unshare
dist_man_MANS += sys-utils/unshare.1
diff --git a/sys-utils/setns.1 b/sys-utils/setns.1
new file mode 100644
index 0000000..7e492ff
--- /dev/null
+++ b/sys-utils/setns.1
@@ -0,0 +1,51 @@
+.TH SETNS 1 "December 2012" "util-linux" "User Commands"
+.SH NAME
+setns \- run program with namespaces of another process
+.SH SYNOPSIS
+.B setns
+.RI [ options ]
+program
+.RI [ arguments ]
+.SH DESCRIPTION
+Migrates to the namespaces of the specified pid/\:namespace pairs, and executes
+a child process.
+.SH OPTIONS
+.TP
+\fB\-u\fR, \fB\-\-uts\fR \fIpid\fR
+Migrate to the
+.B uts
+namespace of
+.IR pid .
+.TP
+\fB\-i\fR, \fB\-\-ipc\fR \fIpid\fR
+Migrate to the
+.B ipc
+namespace of
+.IR pid .
+.TP
+\fB\-n\fR, \fB\-\-net\fR \fIpid\fR
+Migrate to the
+.B net
+namespace of
+.IR pid .
+.TP
+\fB\-V\fR, \fB\-\-version\fR
+Display version information and exit.
+.TP
+\fB\-h\fR, \fB\-\-help\fR
+Display help and exit.
+.SH SEE ALSO
+.BR unshare (2),
+.BR setns (2),
+.BR clone (2),
+.UR http://lwn.net\:/Articles\:/407495/
+.UE
+.SH AUTHOR
+.MT nhorman@tuxdriver.com
+Neil Horman
+.ME
+.SH AVAILABILITY
+The setns command is part of the util-linux package and is available from
+.UR ftp://\:ftp.kernel.org\:/pub\:/linux\:/utils\:/util-linux/
+Linux Kernel Archive
+.UE .
diff --git a/sys-utils/setns.c b/sys-utils/setns.c
new file mode 100644
index 0000000..8ac9309
--- /dev/null
+++ b/sys-utils/setns.c
@@ -0,0 +1,127 @@
+/*
+ * setns - command-line interface for setns(2)
+ *
+ * Copyright (C) 2012 Neil Horman <nhorman@tuxdriver.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <sched.h>
+
+#include "nls.h"
+#include "c.h"
+#include "strutils.h"
+#include "xalloc.h"
+
+static void __attribute__((__noreturn__)) usage(FILE *out)
+{
+ fputs(USAGE_HEADER, out);
+ fprintf(out, " %s [options] [command]\n", program_invocation_short_name);
+ fputs(USAGE_OPTIONS, out);
+ fputs(_(" -i, --ipc <pid> migrate to the ipc namespace\n"), out);
+ fputs(_(" -n, --net <pid> migrate to the net namespace\n"), out);
+ fputs(_(" -u, --uts <pid> migrate to the uts namespace\n"), out);
+ fputs(USAGE_SEPARATOR, out);
+ fputs(USAGE_HELP, out);
+ fputs(USAGE_VERSION, out);
+ fprintf(out, USAGE_MAN_TAIL("setns(1)"));
+ exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
+}
+
+static void switch_namespace(const char *name, unsigned long pid)
+{
+ int fd;
+ char *path;
+
+ xasprintf(&path, "/proc/%lu/ns/%s", pid, name);
+
+ fd = open(path, O_RDONLY);
+ if (fd < 0)
+ err(EXIT_FAILURE, _("cannot open %s"), path);
+
+ if (setns(fd, 0) < 0)
+ err(EXIT_FAILURE, _("setns failed for %s on pid %lu"), name, pid);
+}
+
+int main(int argc, char **argv)
+{
+ int opt;
+ int execind = argc + 1;
+ unsigned long pid;
+ const char *target;
+
+ static const struct option lopts[] = {
+ {"help", no_argument, NULL, 'h'},
+ {"version", no_argument, NULL, 'V'},
+ {"ipc", required_argument, NULL, 'i'},
+ {"net", required_argument, NULL, 'n'},
+ {"uts", required_argument, NULL, 'u'},
+ {NULL, 0, NULL, 0}
+ };
+ enum {
+ SETNS_IPC = 0,
+ SETNS_NET,
+ SETNS_UTS
+ };
+ const char *setns_types[] = {
+ [SETNS_IPC] = "ipc",
+ [SETNS_NET] = "net",
+ [SETNS_UTS] = "uts"
+ };
+
+ while ((opt = getopt_long(argc, argv,
+ "+hVi:n:u:", lopts, NULL)) != -1) {
+ switch (opt) {
+ case 'h':
+ usage(stdout);
+ case 'V':
+ printf(UTIL_LINUX_VERSION);
+ return EXIT_SUCCESS;
+ case 'i':
+ target = setns_types[SETNS_IPC];
+ goto parse_opt;
+ case 'n':
+ target = setns_types[SETNS_NET];
+ goto parse_opt;
+ case 'u':
+ target = setns_types[SETNS_UTS];
+ parse_opt:
+ pid = strtoul_or_err(optarg,
+ _("failed to parse argument"));
+ switch_namespace(target, pid);
+ break;
+ default:
+ usage(stderr);
+ }
+ }
+
+ if (optind == argc)
+ errx(EXIT_FAILURE, _("no executable specified"));
+
+ execind = optind;
+
+ if (execvp(argv[execind], &argv[execind]) < 0)
+ err(EXIT_FAILURE, _("executing %s failed"), argv[execind]);
+
+ return EXIT_SUCCESS;
+}
--
1.8.0.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH] sys-tools: Add setns utility to sys-tools
2012-12-19 19:06 [PATCH] sys-tools: Add setns utility to sys-tools Neil Horman
2012-12-19 20:16 ` Mantas M.
2012-12-19 21:01 ` Neil Horman
@ 2012-12-20 9:24 ` Karel Zak
2012-12-20 11:17 ` Sami Kerola
2012-12-20 15:34 ` Neil Horman
2012-12-20 18:22 ` [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces Neil Horman
2012-12-28 16:22 ` [PATCH v3] " Neil Horman
4 siblings, 2 replies; 16+ messages in thread
From: Karel Zak @ 2012-12-20 9:24 UTC (permalink / raw)
To: Neil Horman; +Cc: util-linux
On Wed, Dec 19, 2012 at 02:06:46PM -0500, Neil Horman wrote:
> Like the unshare command, which lets a user from the command line detach from
> specific namespaces of the parent process, and execute a command, setns provides
> a frontend to the setns(2) syscall, which allows a user to migrate a process to
> the namespaces of other processes, prior to calling exec on a command.
Do we really need a new command? Can't we extend unshare(1)?
create a new namespace:
unshare --{mount,ipc,...} <program> [<args>]
move to already existing namespace:
unshare --namespace <pid> --{ipc,...} <program> [<args>]
>From user's point of view in both cases the <program> will be unshared
from the current namespace so the util name seems OK.
IMHO it seems better then add a new command.
If you really want to support direct namespace paths (/proc/<pid>/ns/<nsname>)
then we can use
unshare --namespace <path> <program> [<args>]
anyway this way should be optional and not required. It's naive to
expect that everyone remembers and understands all the /proc tricks.
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] sys-tools: Add setns utility to sys-tools
2012-12-20 9:24 ` Karel Zak
@ 2012-12-20 11:17 ` Sami Kerola
2012-12-20 15:34 ` Neil Horman
1 sibling, 0 replies; 16+ messages in thread
From: Sami Kerola @ 2012-12-20 11:17 UTC (permalink / raw)
To: Karel Zak; +Cc: Neil Horman, util-linux
On Thu, Dec 20, 2012 at 9:24 AM, Karel Zak <kzak@redhat.com> wrote:
> On Wed, Dec 19, 2012 at 02:06:46PM -0500, Neil Horman wrote:
>> Like the unshare command, which lets a user from the command line detach from
>> specific namespaces of the parent process, and execute a command, setns provides
>> a frontend to the setns(2) syscall, which allows a user to migrate a process to
>> the namespaces of other processes, prior to calling exec on a command.
>
> Do we really need a new command? Can't we extend unshare(1)?
IMHO adding functionality to existing command is probably better. What
comes to adjusted patch from yesterday it is there just in case new
command becomes more preferred option.
> create a new namespace:
>
> unshare --{mount,ipc,...} <program> [<args>]
>
> move to already existing namespace:
>
> unshare --namespace <pid> --{ipc,...} <program> [<args>]
>
>
> From user's point of view in both cases the <program> will be unshared
> from the current namespace so the util name seems OK.
>
> IMHO it seems better then add a new command.
>
>
> If you really want to support direct namespace paths (/proc/<pid>/ns/<nsname>)
> then we can use
>
> unshare --namespace <path> <program> [<args>]
>
> anyway this way should be optional and not required. It's naive to
> expect that everyone remembers and understands all the /proc tricks.
No matter where the support for setns(2) is added I think there is
need for two things.
1) Builds must not break when setns(2) does not exist.
2) Good documentation.
For the second some sort of explanation and/or example when and why
anyone would use this would be nice.
--
Sami Kerola
http://www.iki.fi/kerolasa/
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH] sys-tools: Add setns utility to sys-tools
2012-12-20 9:24 ` Karel Zak
2012-12-20 11:17 ` Sami Kerola
@ 2012-12-20 15:34 ` Neil Horman
1 sibling, 0 replies; 16+ messages in thread
From: Neil Horman @ 2012-12-20 15:34 UTC (permalink / raw)
To: Karel Zak; +Cc: util-linux
On Thu, Dec 20, 2012 at 10:24:39AM +0100, Karel Zak wrote:
> On Wed, Dec 19, 2012 at 02:06:46PM -0500, Neil Horman wrote:
> > Like the unshare command, which lets a user from the command line detach from
> > specific namespaces of the parent process, and execute a command, setns provides
> > a frontend to the setns(2) syscall, which allows a user to migrate a process to
> > the namespaces of other processes, prior to calling exec on a command.
>
> Do we really need a new command? Can't we extend unshare(1)?
>
> create a new namespace:
>
> unshare --{mount,ipc,...} <program> [<args>]
>
> move to already existing namespace:
>
> unshare --namespace <pid> --{ipc,...} <program> [<args>]
>
>
> From user's point of view in both cases the <program> will be unshared
> from the current namespace so the util name seems OK.
>
> IMHO it seems better then add a new command.
>
>
> If you really want to support direct namespace paths (/proc/<pid>/ns/<nsname>)
> then we can use
>
> unshare --namespace <path> <program> [<args>]
>
> anyway this way should be optional and not required. It's naive to
> expect that everyone remembers and understands all the /proc tricks.
>
Ok, fair enough, I can rewrite this to extend unshare
Neil
> Karel
>
> --
> Karel Zak <kzak@redhat.com>
> http://karelzak.blogspot.com
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-19 19:06 [PATCH] sys-tools: Add setns utility to sys-tools Neil Horman
` (2 preceding siblings ...)
2012-12-20 9:24 ` Karel Zak
@ 2012-12-20 18:22 ` Neil Horman
2012-12-28 12:54 ` Ángel González
2012-12-28 16:22 ` [PATCH v3] " Neil Horman
4 siblings, 1 reply; 16+ messages in thread
From: Neil Horman @ 2012-12-20 18:22 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa, grawity, Neil Horman, Karel Zak
In addition to the unshare syscall, there exists the setns syscall, which allows
processes to migrate to the namepsaces of other processes. Add this
functionality into the unshare command, as they operate in a fairly simmilar
fashion.
Note: There was discussion of adding a path based namespace argument to unshare
in the origional discussion thread, but I opted to leave that out as it didn't
seem to fit in nicely with the current argument pattern. I figure we can always
add that in later if we need to
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Karel Zak <kzak@redhat.com>
---
sys-utils/unshare.1 | 31 +++++++++++++---------
sys-utils/unshare.c | 74 ++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 78 insertions(+), 27 deletions(-)
diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1
index 1325e34..2478f04 100644
--- a/sys-utils/unshare.1
+++ b/sys-utils/unshare.1
@@ -3,15 +3,15 @@
.\"
.TH UNSHARE 1 "October 2008" "util-linux" "User Commands"
.SH NAME
-unshare \- run program with some namespaces unshared from parent
+unshare \- run program with some namespaces unshared or changed from parent
.SH SYNOPSIS
.B unshare
.RI [ options ]
program
.RI [ arguments ]
.SH DESCRIPTION
-Unshares specified namespaces from parent process and then executes specified
-program. Unshareable namespaces are:
+Unshares or migrates specified namespaces from parent process and then executes specified
+program. Available namespaces are:
.TP
.BR "mount namespace"
mounting and unmounting filesystems will not affect rest of the system
@@ -32,32 +32,39 @@ rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, sockets
etc. (\fBCLONE_NEWNET\fP flag).
.TP
See the \fBclone\fR(2) for exact semantics of the flags.
+.TP
.SH OPTIONS
.TP
.BR \-h , " \-\-help"
Print a help message,
.TP
-.BR \-m , " \-\-mount"
-Unshare the mount namespace,
+.BR \-m\ [pid] , " \-\-mount[=pid]"
+Unshare the mount namespace, or, when a pid is specified, migrate the mount
+namespace to the one attached to the specified pid
.TP
-.BR \-u , " \-\-uts"
-Unshare the UTC namespace,
+.BR \-u\ [pid] , " \-\-uts[=pid]"
+Unshare the UTC namespace, or, when a pid is specified, migrate the uts
+namespace to the one attached to the specified pid
.TP
-.BR \-i , " \-\-ipc"
-Unshare the IPC namespace,
+.BR \-i\ [pid] , " \-\-ipc[=pid]"
+Unshare the IPC namespace, or, when a pid is specified, migrate the ipc
+namespace to the one attached to the specified pid
.TP
-.BR \-n , " \-\-net"
-Unshare the network namespace.
+.BR \-n\ [pid] , " \-\-net[=pid]"
+Unshare the network namespace, or, when a pid is specified, migrate the net
+namespace to the one attached to the specified pid
.SH NOTES
The unshare command drops potential privileges before executing the
target program. This allows to setuid unshare.
.SH SEE ALSO
.BR unshare (2),
+.BR setns (2),
.BR clone (2)
.SH BUGS
None known so far.
-.SH AUTHOR
+.SH AUTHORS
Mikhail Gusarov <dottedmag@dottedmag.net>
+Neil Horman <nhorman@tuxdriver.com>
.SH AVAILABILITY
The unshare command is part of the util-linux package and is available from
ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
index 9de997b..f0af2c5 100644
--- a/sys-utils/unshare.c
+++ b/sys-utils/unshare.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <getopt.h>
#include "nls.h"
#include "c.h"
@@ -42,6 +43,9 @@
# define CLONE_NEWNET 0x40000000
#endif
+#define NUM_ENTRIES 128
+static int ns_pids[128];
+
#ifndef HAVE_UNSHARE
# include <sys/syscall.h>
@@ -60,10 +64,10 @@ 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"
- " -u, --uts unshare UTS namespace (hostname etc)\n"
- " -i, --ipc unshare System V IPC namespace\n"
- " -n, --net unshare network namespace\n"), out);
+ fputs(_(" -m, --mount unshare|migrate mounts namespace\n"
+ " -u, --uts unshare|migrate UTS namespace (hostname etc)\n"
+ " -i, --ipc unshare|migrate System V IPC namespace\n"
+ " -n, --net unshare|migrate network namespace\n"), out);
fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out);
@@ -73,28 +77,42 @@ static void usage(int status)
exit(status);
}
+static void close_files(void)
+{
+ int i;
+ for (i=0; ns_pids[i] > 0; i++)
+ close(ns_pids[i]);
+ close_stdout();
+}
+
int main(int argc, char *argv[])
{
static const struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V'},
- { "mount", no_argument, 0, 'm' },
- { "uts", no_argument, 0, 'u' },
- { "ipc", no_argument, 0, 'i' },
- { "net", no_argument, 0, 'n' },
+ { "mount", optional_argument, 0, 'm' },
+ { "uts", optional_argument, 0, 'u' },
+ { "ipc", optional_argument, 0, 'i' },
+ { "net", optional_argument, 0, 'n' },
{ NULL, 0, 0, 0 }
};
int unshare_flags = 0;
-
+ int nscount = 0;
int c;
+ char *ns;
+ unsigned long pid;
+ char path[512];
+ memset(ns_pids, 0, sizeof(int)*NUM_ENTRIES);
setlocale(LC_MESSAGES, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ atexit(close_files);
+
+ while((c = getopt_long(argc, argv, "hVm:u:i:n:", longopts, NULL)) != -1) {
+ ns = NULL;
- while((c = getopt_long(argc, argv, "hVmuin", longopts, NULL)) != -1) {
switch(c) {
case 'h':
usage(EXIT_SUCCESS);
@@ -102,25 +120,51 @@ int main(int argc, char *argv[])
printf(UTIL_LINUX_VERSION);
return EXIT_SUCCESS;
case 'm':
- unshare_flags |= CLONE_NEWNS;
+ ns = "mount";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWNS;
break;
case 'u':
- unshare_flags |= CLONE_NEWUTS;
+ ns = "uts";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWUTS;
break;
case 'i':
- unshare_flags |= CLONE_NEWIPC;
+ ns = "ipc";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWIPC;
break;
case 'n':
- unshare_flags |= CLONE_NEWNET;
+ ns = "net";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWNET;
break;
default:
usage(EXIT_FAILURE);
}
+
+ if (optarg && ns) {
+ if (nscount >= NUM_ENTRIES)
+ err(EXIT_FAILURE, _("Too many new namespaces specified"));
+ pid = strtoul(optarg, NULL, 10);
+ if (pid == ULONG_MAX)
+ err(EXIT_FAILURE, _("%s pid improperly specified"), ns);
+ sprintf(path, "/proc/%d/ns/%s", (int)pid, ns);
+ ns_pids[nscount] = open(path, O_RDONLY);
+ if (ns_pids[nscount] < 0)
+ err(EXIT_FAILURE, _("could not open %s"), path);
+ nscount++;
+ }
+
}
if(optind >= argc)
usage(EXIT_FAILURE);
+ for (nscount = 0; ns_pids[nscount] > 0; nscount++)
+ if (-1 == setns(ns_pids[nscount], 0))
+ err(EXIT_FAILURE, _("setns failed"));
+
if(-1 == unshare(unshare_flags))
err(EXIT_FAILURE, _("unshare failed"));
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-20 18:22 ` [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces Neil Horman
@ 2012-12-28 12:54 ` Ángel González
2012-12-28 16:12 ` Neil Horman
0 siblings, 1 reply; 16+ messages in thread
From: Ángel González @ 2012-12-28 12:54 UTC (permalink / raw)
To: Neil Horman; +Cc: util-linux, kerolasa, grawity, Karel Zak
On 20/12/12 19:22, Neil Horman wrote:
> case 'm':
> - unshare_flags |= CLONE_NEWNS;
> + ns = "mount";
> + if (!optarg)
> + unshare_flags |= CLONE_NEWNS;
> break;
Is this right? I don't have a /proc/<task>/ns/mount locally nor is it
documented in
http://git.kernel.org/?p=docs/man-pages/man-pages.git;a=blob;f=man5/proc.5
However looking at
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=fs/proc/namespaces.c
there is a reference to mntns_operations, which is defined in
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=fs/proc/namespaces.c
but seems to be called "mnt", not "mount"
There are also pid and user namespaces there, but support for those are
better handled in a different patch IMHO.
> + sprintf(path, "/proc/%d/ns/%s", (int)pid, ns);
> + ns_pids[nscount] = open(path, O_RDONLY);
> + if (ns_pids[nscount] < 0)
> + err(EXIT_FAILURE, _("could not open %s"), path);
> + nscount++;
What about err(EXIT_FAILURE, _("The kernel doesn't seem to support %s
migrations: could not open %s"), ns, path); ?
Mention in the man page the kernel version from which each namespace can
be migrated.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-28 12:54 ` Ángel González
@ 2012-12-28 16:12 ` Neil Horman
2012-12-28 19:33 ` Ángel González
0 siblings, 1 reply; 16+ messages in thread
From: Neil Horman @ 2012-12-28 16:12 UTC (permalink / raw)
To: Ángel González; +Cc: util-linux, kerolasa, grawity, Karel Zak
On Fri, Dec 28, 2012 at 01:54:45PM +0100, Ángel González wrote:
> On 20/12/12 19:22, Neil Horman wrote:
> > case 'm':
> > - unshare_flags |= CLONE_NEWNS;
> > + ns = "mount";
> > + if (!optarg)
> > + unshare_flags |= CLONE_NEWNS;
> > break;
>
> Is this right? I don't have a /proc/<task>/ns/mount locally nor is it
> documented in
> http://git.kernel.org/?p=docs/man-pages/man-pages.git;a=blob;f=man5/proc.5
>
> However looking at
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=fs/proc/namespaces.c
> there is a reference to mntns_operations, which is defined in
> http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=blob;f=fs/proc/namespaces.c
>
> but seems to be called "mnt", not "mount"
>
Shoot, I thought Biederman was going to call it mount, not mnt, I'll fix that
shortly.
> There are also pid and user namespaces there, but support for those are
> better handled in a different patch IMHO.
>
I'm not really sure what you mean by a different patch here. Why would I add
support for setns for other pid/uts namespaces in a different patch?
>
> > + sprintf(path, "/proc/%d/ns/%s", (int)pid, ns);
> > + ns_pids[nscount] = open(path, O_RDONLY);
> > + if (ns_pids[nscount] < 0)
> > + err(EXIT_FAILURE, _("could not open %s"), path);
> > + nscount++;
>
> What about err(EXIT_FAILURE, _("The kernel doesn't seem to support %s
> migrations: could not open %s"), ns, path); ?
>
Sure, I can do that.
> Mention in the man page the kernel version from which each namespace can
> be migrated.
>
Yeah, ok
Neil
> --
> To unsubscribe from this list: send the line "unsubscribe util-linux" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v3] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-19 19:06 [PATCH] sys-tools: Add setns utility to sys-tools Neil Horman
` (3 preceding siblings ...)
2012-12-20 18:22 ` [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces Neil Horman
@ 2012-12-28 16:22 ` Neil Horman
2013-01-02 21:33 ` Neil Horman
2013-01-07 14:05 ` Karel Zak
4 siblings, 2 replies; 16+ messages in thread
From: Neil Horman @ 2012-12-28 16:22 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa, grawity, ingenit, Neil Horman, Karel Zak
In addition to the unshare syscall, there exists the setns syscall, which allows
processes to migrate to the namepsaces of other processes. Add this
functionality into the unshare command, as they operate in a fairly simmilar
fashion.
Note: There was discussion of adding a path based namespace argument to unshare
in the origional discussion thread, but I opted to leave that out as it didn't
seem to fit in nicely with the current argument pattern. I figure we can always
add that in later if we need to
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Karel Zak <kzak@redhat.com>
---
sys-utils/unshare.1 | 34 +++++++++++++++---------
sys-utils/unshare.c | 74 ++++++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 81 insertions(+), 27 deletions(-)
diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1
index 1325e34..e0393f7 100644
--- a/sys-utils/unshare.1
+++ b/sys-utils/unshare.1
@@ -3,15 +3,15 @@
.\"
.TH UNSHARE 1 "October 2008" "util-linux" "User Commands"
.SH NAME
-unshare \- run program with some namespaces unshared from parent
+unshare \- run program with some namespaces unshared or changed from parent
.SH SYNOPSIS
.B unshare
.RI [ options ]
program
.RI [ arguments ]
.SH DESCRIPTION
-Unshares specified namespaces from parent process and then executes specified
-program. Unshareable namespaces are:
+Unshares or migrates specified namespaces from parent process and then executes specified
+program. Available namespaces are:
.TP
.BR "mount namespace"
mounting and unmounting filesystems will not affect rest of the system
@@ -32,32 +32,42 @@ rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, sockets
etc. (\fBCLONE_NEWNET\fP flag).
.TP
See the \fBclone\fR(2) for exact semantics of the flags.
+.TP
.SH OPTIONS
.TP
.BR \-h , " \-\-help"
Print a help message,
.TP
-.BR \-m , " \-\-mount"
-Unshare the mount namespace,
+.BR \-m\ [pid] , " \-\-mount[=pid]"
+Unshare the mount namespace, or, when a pid is specified, migrate the mount
+namespace to the one attached to the specified pid
.TP
-.BR \-u , " \-\-uts"
-Unshare the UTC namespace,
+.BR \-u\ [pid] , " \-\-uts[=pid]"
+Unshare the UTC namespace, or, when a pid is specified, migrate the uts
+namespace to the one attached to the specified pid
.TP
-.BR \-i , " \-\-ipc"
-Unshare the IPC namespace,
+.BR \-i\ [pid] , " \-\-ipc[=pid]"
+Unshare the IPC namespace, or, when a pid is specified, migrate the ipc
+namespace to the one attached to the specified pid
.TP
-.BR \-n , " \-\-net"
-Unshare the network namespace.
+.BR \-n\ [pid] , " \-\-net[=pid]"
+Unshare the network namespace, or, when a pid is specified, migrate the net
+namespace to the one attached to the specified pid
.SH NOTES
The unshare command drops potential privileges before executing the
target program. This allows to setuid unshare.
+.P
+Support for migrating processes between mnt and pid namespace is available in
+kernels 3.8 and later
.SH SEE ALSO
.BR unshare (2),
+.BR setns (2),
.BR clone (2)
.SH BUGS
None known so far.
-.SH AUTHOR
+.SH AUTHORS
Mikhail Gusarov <dottedmag@dottedmag.net>
+Neil Horman <nhorman@tuxdriver.com>
.SH AVAILABILITY
The unshare command is part of the util-linux package and is available from
ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
index 9de997b..e67986a 100644
--- a/sys-utils/unshare.c
+++ b/sys-utils/unshare.c
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
+#include <getopt.h>
#include "nls.h"
#include "c.h"
@@ -42,6 +43,9 @@
# define CLONE_NEWNET 0x40000000
#endif
+#define NUM_ENTRIES 128
+static int ns_pids[128];
+
#ifndef HAVE_UNSHARE
# include <sys/syscall.h>
@@ -60,10 +64,10 @@ 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"
- " -u, --uts unshare UTS namespace (hostname etc)\n"
- " -i, --ipc unshare System V IPC namespace\n"
- " -n, --net unshare network namespace\n"), out);
+ fputs(_(" -m, --mount unshare|migrate mounts namespace\n"
+ " -u, --uts unshare|migrate UTS namespace (hostname etc)\n"
+ " -i, --ipc unshare|migrate System V IPC namespace\n"
+ " -n, --net unshare|migrate network namespace\n"), out);
fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out);
@@ -73,28 +77,42 @@ static void usage(int status)
exit(status);
}
+static void close_files(void)
+{
+ int i;
+ for (i=0; ns_pids[i] > 0; i++)
+ close(ns_pids[i]);
+ close_stdout();
+}
+
int main(int argc, char *argv[])
{
static const struct option longopts[] = {
{ "help", no_argument, 0, 'h' },
{ "version", no_argument, 0, 'V'},
- { "mount", no_argument, 0, 'm' },
- { "uts", no_argument, 0, 'u' },
- { "ipc", no_argument, 0, 'i' },
- { "net", no_argument, 0, 'n' },
+ { "mount", optional_argument, 0, 'm' },
+ { "uts", optional_argument, 0, 'u' },
+ { "ipc", optional_argument, 0, 'i' },
+ { "net", optional_argument, 0, 'n' },
{ NULL, 0, 0, 0 }
};
int unshare_flags = 0;
-
+ int nscount = 0;
int c;
+ char *ns;
+ unsigned long pid;
+ char path[512];
+ memset(ns_pids, 0, sizeof(int)*NUM_ENTRIES);
setlocale(LC_MESSAGES, "");
bindtextdomain(PACKAGE, LOCALEDIR);
textdomain(PACKAGE);
- atexit(close_stdout);
+ atexit(close_files);
+
+ while((c = getopt_long(argc, argv, "hVm:u:i:n:", longopts, NULL)) != -1) {
+ ns = NULL;
- while((c = getopt_long(argc, argv, "hVmuin", longopts, NULL)) != -1) {
switch(c) {
case 'h':
usage(EXIT_SUCCESS);
@@ -102,25 +120,51 @@ int main(int argc, char *argv[])
printf(UTIL_LINUX_VERSION);
return EXIT_SUCCESS;
case 'm':
- unshare_flags |= CLONE_NEWNS;
+ ns = "mnt";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWNS;
break;
case 'u':
- unshare_flags |= CLONE_NEWUTS;
+ ns = "uts";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWUTS;
break;
case 'i':
- unshare_flags |= CLONE_NEWIPC;
+ ns = "ipc";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWIPC;
break;
case 'n':
- unshare_flags |= CLONE_NEWNET;
+ ns = "net";
+ if (!optarg)
+ unshare_flags |= CLONE_NEWNET;
break;
default:
usage(EXIT_FAILURE);
}
+
+ if (optarg && ns) {
+ if (nscount >= NUM_ENTRIES)
+ err(EXIT_FAILURE, _("Too many new namespaces specified"));
+ pid = strtoul(optarg, NULL, 10);
+ if (pid == ULONG_MAX)
+ err(EXIT_FAILURE, _("%s pid improperly specified"), ns);
+ sprintf(path, "/proc/%d/ns/%s", (int)pid, ns);
+ ns_pids[nscount] = open(path, O_RDONLY);
+ if (ns_pids[nscount] < 0)
+ err(EXIT_FAILURE, _("Can not migrate %s: Can't open %s"), ns, path);
+ nscount++;
+ }
+
}
if(optind >= argc)
usage(EXIT_FAILURE);
+ for (nscount = 0; ns_pids[nscount] > 0; nscount++)
+ if (-1 == setns(ns_pids[nscount], 0))
+ err(EXIT_FAILURE, _("setns failed"));
+
if(-1 == unshare(unshare_flags))
err(EXIT_FAILURE, _("unshare failed"));
--
1.7.11.7
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-28 16:12 ` Neil Horman
@ 2012-12-28 19:33 ` Ángel González
2012-12-28 21:26 ` Neil Horman
0 siblings, 1 reply; 16+ messages in thread
From: Ángel González @ 2012-12-28 19:33 UTC (permalink / raw)
To: Neil Horman; +Cc: util-linux, kerolasa, grawity, Karel Zak
>> There are also pid and user namespaces there, but support for those are
>> better handled in a different patch IMHO.
>>
> I'm not really sure what you mean by a different patch here. Why would I add
> support for setns for other pid/uts namespaces in a different patch?
Because unshare doesn't currently support launching processes in a new
pid or user namespace. :)
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-28 19:33 ` Ángel González
@ 2012-12-28 21:26 ` Neil Horman
0 siblings, 0 replies; 16+ messages in thread
From: Neil Horman @ 2012-12-28 21:26 UTC (permalink / raw)
To: Ángel González; +Cc: util-linux, kerolasa, grawity, Karel Zak
On Fri, Dec 28, 2012 at 08:33:49PM +0100, Ángel González wrote:
> >> There are also pid and user namespaces there, but support for those are
> >> better handled in a different patch IMHO.
> >>
> > I'm not really sure what you mean by a different patch here. Why would I add
> > support for setns for other pid/uts namespaces in a different patch?
>
> Because unshare doesn't currently support launching processes in a new
> pid or user namespace. :)
>
Oh, I see what you mean, sorry. Yes, I agree, we can add support for both
unsharing and setns abilities when the 3.8 kernel is released.
Neil
>
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-28 16:22 ` [PATCH v3] " Neil Horman
@ 2013-01-02 21:33 ` Neil Horman
2013-01-07 14:05 ` Karel Zak
1 sibling, 0 replies; 16+ messages in thread
From: Neil Horman @ 2013-01-02 21:33 UTC (permalink / raw)
To: util-linux; +Cc: kerolasa, grawity, ingenit, Karel Zak
On Fri, Dec 28, 2012 at 11:22:18AM -0500, Neil Horman wrote:
> In addition to the unshare syscall, there exists the setns syscall, which allows
> processes to migrate to the namepsaces of other processes. Add this
> functionality into the unshare command, as they operate in a fairly simmilar
> fashion.
>
> Note: There was discussion of adding a path based namespace argument to unshare
> in the origional discussion thread, but I opted to leave that out as it didn't
> seem to fit in nicely with the current argument pattern. I figure we can always
> add that in later if we need to
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Karel Zak <kzak@redhat.com>
Ping, any further thoughts here?
Neil
> ---
> sys-utils/unshare.1 | 34 +++++++++++++++---------
> sys-utils/unshare.c | 74 ++++++++++++++++++++++++++++++++++++++++++-----------
> 2 files changed, 81 insertions(+), 27 deletions(-)
>
> diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1
> index 1325e34..e0393f7 100644
> --- a/sys-utils/unshare.1
> +++ b/sys-utils/unshare.1
> @@ -3,15 +3,15 @@
> .\"
> .TH UNSHARE 1 "October 2008" "util-linux" "User Commands"
> .SH NAME
> -unshare \- run program with some namespaces unshared from parent
> +unshare \- run program with some namespaces unshared or changed from parent
> .SH SYNOPSIS
> .B unshare
> .RI [ options ]
> program
> .RI [ arguments ]
> .SH DESCRIPTION
> -Unshares specified namespaces from parent process and then executes specified
> -program. Unshareable namespaces are:
> +Unshares or migrates specified namespaces from parent process and then executes specified
> +program. Available namespaces are:
> .TP
> .BR "mount namespace"
> mounting and unmounting filesystems will not affect rest of the system
> @@ -32,32 +32,42 @@ rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, sockets
> etc. (\fBCLONE_NEWNET\fP flag).
> .TP
> See the \fBclone\fR(2) for exact semantics of the flags.
> +.TP
> .SH OPTIONS
> .TP
> .BR \-h , " \-\-help"
> Print a help message,
> .TP
> -.BR \-m , " \-\-mount"
> -Unshare the mount namespace,
> +.BR \-m\ [pid] , " \-\-mount[=pid]"
> +Unshare the mount namespace, or, when a pid is specified, migrate the mount
> +namespace to the one attached to the specified pid
> .TP
> -.BR \-u , " \-\-uts"
> -Unshare the UTC namespace,
> +.BR \-u\ [pid] , " \-\-uts[=pid]"
> +Unshare the UTC namespace, or, when a pid is specified, migrate the uts
> +namespace to the one attached to the specified pid
> .TP
> -.BR \-i , " \-\-ipc"
> -Unshare the IPC namespace,
> +.BR \-i\ [pid] , " \-\-ipc[=pid]"
> +Unshare the IPC namespace, or, when a pid is specified, migrate the ipc
> +namespace to the one attached to the specified pid
> .TP
> -.BR \-n , " \-\-net"
> -Unshare the network namespace.
> +.BR \-n\ [pid] , " \-\-net[=pid]"
> +Unshare the network namespace, or, when a pid is specified, migrate the net
> +namespace to the one attached to the specified pid
> .SH NOTES
> The unshare command drops potential privileges before executing the
> target program. This allows to setuid unshare.
> +.P
> +Support for migrating processes between mnt and pid namespace is available in
> +kernels 3.8 and later
> .SH SEE ALSO
> .BR unshare (2),
> +.BR setns (2),
> .BR clone (2)
> .SH BUGS
> None known so far.
> -.SH AUTHOR
> +.SH AUTHORS
> Mikhail Gusarov <dottedmag@dottedmag.net>
> +Neil Horman <nhorman@tuxdriver.com>
> .SH AVAILABILITY
> The unshare command is part of the util-linux package and is available from
> ftp://ftp.kernel.org/pub/linux/utils/util-linux/.
> diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
> index 9de997b..e67986a 100644
> --- a/sys-utils/unshare.c
> +++ b/sys-utils/unshare.c
> @@ -24,6 +24,7 @@
> #include <stdio.h>
> #include <stdlib.h>
> #include <unistd.h>
> +#include <getopt.h>
>
> #include "nls.h"
> #include "c.h"
> @@ -42,6 +43,9 @@
> # define CLONE_NEWNET 0x40000000
> #endif
>
> +#define NUM_ENTRIES 128
> +static int ns_pids[128];
> +
> #ifndef HAVE_UNSHARE
> # include <sys/syscall.h>
>
> @@ -60,10 +64,10 @@ 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"
> - " -u, --uts unshare UTS namespace (hostname etc)\n"
> - " -i, --ipc unshare System V IPC namespace\n"
> - " -n, --net unshare network namespace\n"), out);
> + fputs(_(" -m, --mount unshare|migrate mounts namespace\n"
> + " -u, --uts unshare|migrate UTS namespace (hostname etc)\n"
> + " -i, --ipc unshare|migrate System V IPC namespace\n"
> + " -n, --net unshare|migrate network namespace\n"), out);
>
> fputs(USAGE_SEPARATOR, out);
> fputs(USAGE_HELP, out);
> @@ -73,28 +77,42 @@ static void usage(int status)
> exit(status);
> }
>
> +static void close_files(void)
> +{
> + int i;
> + for (i=0; ns_pids[i] > 0; i++)
> + close(ns_pids[i]);
> + close_stdout();
> +}
> +
> int main(int argc, char *argv[])
> {
> static const struct option longopts[] = {
> { "help", no_argument, 0, 'h' },
> { "version", no_argument, 0, 'V'},
> - { "mount", no_argument, 0, 'm' },
> - { "uts", no_argument, 0, 'u' },
> - { "ipc", no_argument, 0, 'i' },
> - { "net", no_argument, 0, 'n' },
> + { "mount", optional_argument, 0, 'm' },
> + { "uts", optional_argument, 0, 'u' },
> + { "ipc", optional_argument, 0, 'i' },
> + { "net", optional_argument, 0, 'n' },
> { NULL, 0, 0, 0 }
> };
>
> int unshare_flags = 0;
> -
> + int nscount = 0;
> int c;
> + char *ns;
> + unsigned long pid;
> + char path[512];
>
> + memset(ns_pids, 0, sizeof(int)*NUM_ENTRIES);
> setlocale(LC_MESSAGES, "");
> bindtextdomain(PACKAGE, LOCALEDIR);
> textdomain(PACKAGE);
> - atexit(close_stdout);
> + atexit(close_files);
> +
> + while((c = getopt_long(argc, argv, "hVm:u:i:n:", longopts, NULL)) != -1) {
> + ns = NULL;
>
> - while((c = getopt_long(argc, argv, "hVmuin", longopts, NULL)) != -1) {
> switch(c) {
> case 'h':
> usage(EXIT_SUCCESS);
> @@ -102,25 +120,51 @@ int main(int argc, char *argv[])
> printf(UTIL_LINUX_VERSION);
> return EXIT_SUCCESS;
> case 'm':
> - unshare_flags |= CLONE_NEWNS;
> + ns = "mnt";
> + if (!optarg)
> + unshare_flags |= CLONE_NEWNS;
> break;
> case 'u':
> - unshare_flags |= CLONE_NEWUTS;
> + ns = "uts";
> + if (!optarg)
> + unshare_flags |= CLONE_NEWUTS;
> break;
> case 'i':
> - unshare_flags |= CLONE_NEWIPC;
> + ns = "ipc";
> + if (!optarg)
> + unshare_flags |= CLONE_NEWIPC;
> break;
> case 'n':
> - unshare_flags |= CLONE_NEWNET;
> + ns = "net";
> + if (!optarg)
> + unshare_flags |= CLONE_NEWNET;
> break;
> default:
> usage(EXIT_FAILURE);
> }
> +
> + if (optarg && ns) {
> + if (nscount >= NUM_ENTRIES)
> + err(EXIT_FAILURE, _("Too many new namespaces specified"));
> + pid = strtoul(optarg, NULL, 10);
> + if (pid == ULONG_MAX)
> + err(EXIT_FAILURE, _("%s pid improperly specified"), ns);
> + sprintf(path, "/proc/%d/ns/%s", (int)pid, ns);
> + ns_pids[nscount] = open(path, O_RDONLY);
> + if (ns_pids[nscount] < 0)
> + err(EXIT_FAILURE, _("Can not migrate %s: Can't open %s"), ns, path);
> + nscount++;
> + }
> +
> }
>
> if(optind >= argc)
> usage(EXIT_FAILURE);
>
> + for (nscount = 0; ns_pids[nscount] > 0; nscount++)
> + if (-1 == setns(ns_pids[nscount], 0))
> + err(EXIT_FAILURE, _("setns failed"));
> +
> if(-1 == unshare(unshare_flags))
> err(EXIT_FAILURE, _("unshare failed"));
>
> --
> 1.7.11.7
>
>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3] sys-tools: Enhance unshare command to support the switching of namespaces
2012-12-28 16:22 ` [PATCH v3] " Neil Horman
2013-01-02 21:33 ` Neil Horman
@ 2013-01-07 14:05 ` Karel Zak
2013-01-07 14:58 ` Neil Horman
1 sibling, 1 reply; 16+ messages in thread
From: Karel Zak @ 2013-01-07 14:05 UTC (permalink / raw)
To: Neil Horman; +Cc: util-linux, kerolasa, grawity, ingenit
On Fri, Dec 28, 2012 at 11:22:18AM -0500, Neil Horman wrote:
> sys-utils/unshare.1 | 34 +++++++++++++++---------
> sys-utils/unshare.c | 74 ++++++++++++++++++++++++++++++++++++++++++-----------
> 2 files changed, 81 insertions(+), 27 deletions(-)
Applied with some changes, please check/verify the changes in git, thanks.
> +static void close_files(void)
> +{
> + int i;
> + for (i=0; ns_pids[i] > 0; i++)
> + close(ns_pids[i]);
> + close_stdout();
> +}
this is unnecessary, but O_CLOEXEC is probably good idea
> + while((c = getopt_long(argc, argv, "hVm:u:i:n:", longopts, NULL)) != -1) {
> + ns = NULL;
optional argument means "::" not ":"
> + if (optarg && ns) {
> + if (nscount >= NUM_ENTRIES)
> + err(EXIT_FAILURE, _("Too many new namespaces specified"));
> + pid = strtoul(optarg, NULL, 10);
for the short options the 'optarg' starts with '=', so you need
optarg++
> + for (nscount = 0; ns_pids[nscount] > 0; nscount++)
> + if (-1 == setns(ns_pids[nscount], 0))
> + err(EXIT_FAILURE, _("setns failed"));
> +
> if(-1 == unshare(unshare_flags))
> err(EXIT_FAILURE, _("unshare failed"));
it seems that unshare() should not be called if unshare_flags == 0
Karel
--
Karel Zak <kzak@redhat.com>
http://karelzak.blogspot.com
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v3] sys-tools: Enhance unshare command to support the switching of namespaces
2013-01-07 14:05 ` Karel Zak
@ 2013-01-07 14:58 ` Neil Horman
0 siblings, 0 replies; 16+ messages in thread
From: Neil Horman @ 2013-01-07 14:58 UTC (permalink / raw)
To: Karel Zak; +Cc: util-linux, kerolasa, grawity, ingenit
On Mon, Jan 07, 2013 at 03:05:23PM +0100, Karel Zak wrote:
> On Fri, Dec 28, 2012 at 11:22:18AM -0500, Neil Horman wrote:
> > sys-utils/unshare.1 | 34 +++++++++++++++---------
> > sys-utils/unshare.c | 74 ++++++++++++++++++++++++++++++++++++++++++-----------
> > 2 files changed, 81 insertions(+), 27 deletions(-)
>
> Applied with some changes, please check/verify the changes in git, thanks.
>
> > +static void close_files(void)
> > +{
> > + int i;
> > + for (i=0; ns_pids[i] > 0; i++)
> > + close(ns_pids[i]);
> > + close_stdout();
> > +}
>
> this is unnecessary, but O_CLOEXEC is probably good idea
>
> > + while((c = getopt_long(argc, argv, "hVm:u:i:n:", longopts, NULL)) != -1) {
> > + ns = NULL;
>
> optional argument means "::" not ":"
>
> > + if (optarg && ns) {
> > + if (nscount >= NUM_ENTRIES)
> > + err(EXIT_FAILURE, _("Too many new namespaces specified"));
> > + pid = strtoul(optarg, NULL, 10);
>
> for the short options the 'optarg' starts with '=', so you need
> optarg++
>
> > + for (nscount = 0; ns_pids[nscount] > 0; nscount++)
> > + if (-1 == setns(ns_pids[nscount], 0))
> > + err(EXIT_FAILURE, _("setns failed"));
> > +
> > if(-1 == unshare(unshare_flags))
> > err(EXIT_FAILURE, _("unshare failed"));
>
> it seems that unshare() should not be called if unshare_flags == 0
Your changes look fine. FWIW, theres no need to check that unshare_flags is 0
(not that it matters if you do). The man page documents (and the implementation
inforces that unshare(0) is a no-op.
Thanks!
Neil
>
> Karel
>
> --
> Karel Zak <kzak@redhat.com>
> http://karelzak.blogspot.com
>
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2013-01-07 14:58 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-12-19 19:06 [PATCH] sys-tools: Add setns utility to sys-tools Neil Horman
2012-12-19 20:16 ` Mantas M.
2012-12-19 21:01 ` Neil Horman
2012-12-19 23:15 ` Sami Kerola
2012-12-20 9:24 ` Karel Zak
2012-12-20 11:17 ` Sami Kerola
2012-12-20 15:34 ` Neil Horman
2012-12-20 18:22 ` [PATCH v2] sys-tools: Enhance unshare command to support the switching of namespaces Neil Horman
2012-12-28 12:54 ` Ángel González
2012-12-28 16:12 ` Neil Horman
2012-12-28 19:33 ` Ángel González
2012-12-28 21:26 ` Neil Horman
2012-12-28 16:22 ` [PATCH v3] " Neil Horman
2013-01-02 21:33 ` Neil Horman
2013-01-07 14:05 ` Karel Zak
2013-01-07 14:58 ` Neil Horman
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox