[systemd-devel] [PATCH] nspawn: document how to enter the namespace

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Sat Jan 12 13:55:04 PST 2013


systemd-nspawn will now print the PID of the child.
---
To be applied after Linux 3.8 is released and after util-linux
decided on the interface to setns(). Current unshare invocation
is ugly and unwieldy. A seperate command (enter), was proposed...
So I'm holding this in my queue for now.

Zbyszek

 man/systemd-nspawn.xml | 16 ++++++++++++++++
 src/nspawn/nspawn.c    | 26 ++++++++++++++++++++------
 2 files changed, 36 insertions(+), 6 deletions(-)

diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index db2d417..99a94da 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -315,7 +315,22 @@
                 distribution into the directory
                 <filename>~/debian-tree/</filename> and then spawns a
                 shell in a namespace container in it.</para>
+        </refsect1>
+
+        <refsect1>
+                <title>Example 3</title>
+
+                <para>To enter the container, PID of one of the
+                processes sharing the new namespaces must be used.
+                <command>systemd-nspawn</command> prints the PID
+                (as viewed from the outside) of the launched process,
+                and it can be used to enter the container.</para>
+
+                <programlisting># unshare --{mount,uts,ipc,pid,net}=$PID bash</programlisting>
 
+                <para><citerefentry><refentrytitle>unshare</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                is part of util-linux. Kernel support for entering namespaces
+                was added in Linux 3.8.</para>
         </refsect1>
 
         <refsect1>
@@ -330,6 +345,7 @@
                 <para>
                         <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>chroot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+                        <citerefentry><refentrytitle>unshare</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>yum</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
                         <citerefentry><refentrytitle>debootstrap</refentrytitle><manvolnum>8</manvolnum></citerefentry>
                 </para>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 98b583d..04a11c9 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -33,6 +33,7 @@
 #include <sys/prctl.h>
 #include <sys/capability.h>
 #include <getopt.h>
+#include <sys/poll.h>
 #include <sys/epoll.h>
 #include <termios.h>
 #include <sys/signalfd.h>
@@ -1192,12 +1193,11 @@ int main(int argc, char *argv[]) {
 
         for (;;) {
                 siginfo_t status;
+                int pipefd[2];
 
-                if (saved_attr_valid) {
-                        if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
-                                log_error("Failed to set terminal attributes: %m");
-                                goto finish;
-                        }
+                if(pipe2(pipefd, O_NONBLOCK|O_CLOEXEC) < 0) {
+                        log_error("pipe2(): %m");
+                        goto finish;
                 }
 
                 pid = syscall(__NR_clone, SIGCHLD|CLONE_NEWIPC|CLONE_NEWNS|CLONE_NEWPID|CLONE_NEWUTS|(arg_private_network ? CLONE_NEWNET : 0), NULL);
@@ -1212,7 +1212,6 @@ int main(int argc, char *argv[]) {
 
                 if (pid == 0) {
                         /* child */
-
                         const char *home = NULL;
                         uid_t uid = (uid_t) -1;
                         gid_t gid = (gid_t) -1;
@@ -1233,9 +1232,20 @@ int main(int argc, char *argv[]) {
                         envp[2] = strv_find_prefix(environ, "TERM=");
                         n_env = 3;
 
+                        close(pipefd[1]);
+                        fd_wait_for_event(pipefd[0], POLLHUP, -1);
+                        close(pipefd[0]);
+
                         close_nointr_nofail(master);
                         master = -1;
 
+                        if (saved_attr_valid) {
+                                if (tcsetattr(STDIN_FILENO, TCSANOW, &raw_attr) < 0) {
+                                        log_error("Failed to set terminal attributes: %m");
+                                        goto child_fail;
+                                }
+                        }
+
                         close_nointr(STDIN_FILENO);
                         close_nointr(STDOUT_FILENO);
                         close_nointr(STDERR_FILENO);
@@ -1470,6 +1480,10 @@ int main(int argc, char *argv[]) {
                         _exit(EXIT_FAILURE);
                 }
 
+                log_info("Init process in the container running as PID %d", pid);
+                close(pipefd[0]);
+                close(pipefd[1]);
+
                 fdset_free(fds);
                 fds = NULL;
 
-- 
1.7.11.7



More information about the systemd-devel mailing list