chiark / gitweb /
nspawn: print PID and show how to enter the namespace
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sat, 12 Jan 2013 21:55:04 +0000 (16:55 -0500)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 14 Feb 2013 15:40:45 +0000 (10:40 -0500)
systemd-nspawn will now print the PID of the child.
An example showing how to enter the container is added
to the man page.

Support for nsenter without an explicit command was
added in https://github.com/karelzak/util-linux/commit/5758069
(post v2.22.2). So this example requires both a new kernel
and the latest util-linux.

man/systemd-nspawn.xml
src/nspawn/nspawn.c

index 6a01ffd450aff17b573633131960762212205160..5cba40bcd427ef7fdbcd086ffbccd59bb7daa1e9 100644 (file)
 
         <refsynopsisdiv>
                 <cmdsynopsis>
-                        <command>systemd-nspawn <arg choice="opt" rep="repeat">OPTIONS</arg> <arg choice="opt">COMMAND</arg> <arg choice="opt" rep="repeat">ARGS</arg></command>
+                        <command>systemd-nspawn</command>
+                        <arg choice="opt" rep="repeat">OPTIONS</arg>
+                        <arg choice="opt">COMMAND</arg>
+                        <arg choice="opt" rep="repeat">ARGS</arg>
                 </cmdsynopsis>
         </refsynopsisdiv>
 
                 see each other. The PID namespace separation of the
                 two containers is complete and the containers will
                 share very few runtime objects except for the
-                underlying file system.</para>
+                underlying file system. It is however possible to
+                enter an existing container, see
+                <link linkend='example-nsenter'>Example 4</link> below.
+                </para>
 
                 <para><command>systemd-nspawn</command> implements the
                 <ulink
                 distribution into the directory
                 <filename>~/debian-tree/</filename> and then spawns a
                 shell in a namespace container in it.</para>
-
         </refsect1>
 
         <refsect1>
                 boots an OS in a namespace container in it.</para>
         </refsect1>
 
+        <refsect1 id='example-nsenter'>
+                <title>Example 4</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># nsenter -muinpt $PID</programlisting>
+
+                <para><citerefentry><refentrytitle>nsenter</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                is part of
+                <ulink url="https://github.com/karelzak/util-linux">util-linux</ulink>.
+                Kernel support for entering namespaces was added in
+                Linux 3.8.</para>
+        </refsect1>
+
         <refsect1>
                 <title>Exit status</title>
 
                 <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>,
                         <citerefentry><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>
index 1d602a5b31ee88beb0c7b7a2e13687ac7dffa96e..2fec9023a1a8a5212483138db3da5f02ed5ff109 100644 (file)
@@ -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>
@@ -1204,12 +1205,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);
@@ -1224,7 +1224,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;
@@ -1245,9 +1244,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);
@@ -1482,6 +1492,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;