summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd-nspawn.xml30
-rw-r--r--src/nspawn/nspawn.c26
2 files changed, 47 insertions, 9 deletions
diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index 6a01ffd450..5cba40bcd4 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -49,7 +49,10 @@
<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>
@@ -114,7 +117,10 @@
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
@@ -318,7 +324,6 @@
distribution into the directory
<filename>~/debian-tree/</filename> and then spawns a
shell in a namespace container in it.</para>
-
</refsect1>
<refsect1>
@@ -332,6 +337,24 @@
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>
@@ -344,6 +367,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>,
<citerefentry><refentrytitle>pacman</refentrytitle><manvolnum>8</manvolnum></citerefentry>
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 1d602a5b31..2fec9023a1 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>
@@ -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;