diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2017-06-16 16:53:00 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@lukeshu.com> | 2017-06-16 17:06:57 -0400 |
commit | 76b7be5e7e8bd15b549aa12eabbe3a36fdc4e924 (patch) | |
tree | 098e1bdc51eb8954d6f4035d8d0e4a7192e9a602 | |
parent | c4f1e6445be169b5f4d0016de11016bd0c17a39c (diff) |
nspawn: Don't expect the outer child die until after the inner is cgroupified
-rw-r--r-- | src/nspawn/nspawn.c | 55 |
1 files changed, 24 insertions, 31 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 2c3fc4659a..5c4341e0ee 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2674,15 +2674,15 @@ static int inner_child( assert(directory); assert(kmsg_socket >= 0); - if (arg_userns_mode != USER_NAMESPACE_NO) { - /* Tell the parent, that it now can write the UID map. */ - (void) barrier_place(barrier); /* #1 */ + /* Tell the parent that it can now configure our process; write + * the UID map (if use_userns), place us in the correct cgroup (if + * use_cgns), et c. */ + (void) barrier_place(barrier); /* #1 */ - /* Wait until the parent wrote the UID map */ - if (!barrier_place_and_sync(barrier)) { /* #2 */ - log_error("Parent died too early"); - return -ESRCH; - } + /* Wait until the parent says that we are fully configured. */ + if (!barrier_place_and_sync(barrier)) { /* #2 */ + log_error("Parent died too early"); + return -ESRCH; } r = reset_uid_gid(); @@ -2702,13 +2702,6 @@ static int inner_child( if (r < 0) return r; - /* Wait until we are cgroup-ified, so that we - * can mount the right cgroup path writable */ - if (!barrier_place_and_sync(barrier)) { /* #3 */ - log_error("Parent died too early"); - return -ESRCH; - } - if (arg_use_cgns) { r = unshare(CLONE_NEWCGROUP); if (r < 0) @@ -2814,7 +2807,7 @@ static int inner_child( /* Let the parent know that we are ready and * wait until the parent is ready with the * setup, too... */ - if (!barrier_place_and_sync(barrier)) { /* #4 */ + if (!barrier_place_and_sync(barrier)) { /* #3 */ log_error("Parent died too early"); return -ESRCH; } @@ -3765,12 +3758,6 @@ static int run(int master, } } - /* Wait for the outer child. */ - r = wait_for_terminate_and_warn("namespace helper", *helper_pid, NULL); - *helper_pid = 0; - if (r != 0) - return r < 0 ? r : -EIO; - /* And now retrieve the PID of the inner child. */ l = recv(pid_socket_pair[0], main_pid, sizeof *main_pid, 0); if (l < 0) @@ -3797,17 +3784,16 @@ static int run(int master, log_debug("Init process invoked as PID "PID_FMT, *main_pid); - if (arg_userns_mode != USER_NAMESPACE_NO) { - if (!barrier_place_and_sync(&barrier)) { /* #1 */ - log_error("Child died too early."); - return -ESRCH; - } + /* Wait until the child gives us the OK to configure it. */ + if (!barrier_place_and_sync(&barrier)) { /* #1 */ + log_error("Child died too early."); + return -ESRCH; + } + if (arg_userns_mode != USER_NAMESPACE_NO) { r = setup_uid_map(*main_pid); if (r < 0) return r; - - (void) barrier_place(&barrier); /* #2 */ } if (arg_private_network) { @@ -3881,11 +3867,18 @@ static int run(int master, if (r < 0) return r; + + /* Wait for the outer child. */ + r = wait_for_terminate_and_warn("namespace helper", *helper_pid, NULL); + *helper_pid = 0; + if (r != 0) + return r < 0 ? r : -EIO; + /* Notify the child that the parent is ready with all * its setup (including cgroup-ification), and that * the child can now hand over control to the code to * run inside the container. */ - (void) barrier_place(&barrier); /* #3 */ + (void) barrier_place(&barrier); /* #2 */ /* Block SIGCHLD here, before notifying child. * process_pty() will handle it with the other signals. */ @@ -3905,7 +3898,7 @@ static int run(int master, return r; /* Let the child know that we are ready and wait that the child is completely ready now. */ - if (!barrier_place_and_sync(&barrier)) { /* #4 */ + if (!barrier_place_and_sync(&barrier)) { /* #3 */ log_error("Child died too early."); return -ESRCH; } |