summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilip Sequeira <phsequei@gmail.com>2018-04-05 14:04:27 +0000
committerLuke Shumaker <lukeshu@lukeshu.com>2018-07-19 12:20:57 -0400
commit01f208ccd06fb0fe547d8ee46cf8d35f51fc83d1 (patch)
tree111114a2ef4bbe95b3b5e4a6b319a2bdeb86f23a
parentf398c546c6fc43121131f41acec56b5a851bd35e (diff)
nspawn: wait for network namespace creation before interface setup (#8633)
Otherwise, network interfaces can be "moved" into the container's namespace while it's still the same as the host namespace, in which case e.g. host0 for a veth ends up on the host side instead of inside the container. Regression introduced in 0441378080489e4ab6704cd0a2d78cb1ceaca899. Fixes #8599. (cherry picked from commit 7511655807e90aa33ea7b71991401a79ec36bb41)
-rw-r--r--src/nspawn/nspawn.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 4b941edaea..8959fd3172 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -2330,6 +2330,9 @@ static int inner_child(
r = unshare(CLONE_NEWNET);
if (r < 0)
return log_error_errno(errno, "Failed to unshare network namespace: %m");
+
+ /* Tell the parent that it can setup network interfaces. */
+ (void) barrier_place(barrier); /* #3 */
}
r = mount_sysfs(NULL, arg_mount_settings);
@@ -2338,7 +2341,7 @@ static int inner_child(
/* Wait until we are cgroup-ified, so that we
* can mount the right cgroup path writable */
- if (!barrier_place_and_sync(barrier)) { /* #3 */
+ if (!barrier_place_and_sync(barrier)) { /* #4 */
log_error("Parent died too early");
return -ESRCH;
}
@@ -2449,7 +2452,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)) { /* #5 */
log_error("Parent died too early");
return -ESRCH;
}
@@ -3557,6 +3560,14 @@ static int run(int master,
if (arg_private_network) {
+ if (!arg_network_namespace_path) {
+ /* Wait until the child has unshared its network namespace. */
+ if (!barrier_place_and_sync(&barrier)) { /* #3 */
+ log_error("Child died too early");
+ return -ESRCH;
+ }
+ }
+
r = move_network_interfaces(*pid, arg_network_interfaces);
if (r < 0)
return r;
@@ -3680,7 +3691,7 @@ static int run(int master,
* 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); /* #4 */
/* Block SIGCHLD here, before notifying child.
* process_pty() will handle it with the other signals. */
@@ -3708,7 +3719,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)) { /* #5 */
log_error("Child died too early.");
return -ESRCH;
}