summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@lukeshu.com>2017-06-14 16:22:06 -0400
committerLuke Shumaker <lukeshu@parabola.nu>2018-08-16 21:55:16 -0400
commitbbf44a337c677bb5235340060ed46208153e0112 (patch)
treee9a6b3e1ca76e4b6f7edfe699b2dfff711c136f9
parent6285ec4b89a7e571119aa853ca3f4bc62ae1c8f0 (diff)
nspawn: Track the inner child and outer child PIDs separately
-rw-r--r--src/nspawn/nspawn.c73
1 files changed, 40 insertions, 33 deletions
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index daf179b18b..5e35a47956 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3625,7 +3625,8 @@ static int run(int master,
FDSet *fds,
char veth_name[IFNAMSIZ], bool *veth_created,
union in_addr_union *exposed,
- pid_t *pid, int *ret) {
+ pid_t *helper_pid, pid_t *main_pid,
+ int *ret) {
static const struct sigaction sa = {
.sa_handler = nop_signal_handler,
@@ -3724,13 +3725,13 @@ static int run(int master,
}
}
- *pid = raw_clone(SIGCHLD|CLONE_NEWNS);
- if (*pid < 0)
+ *helper_pid = raw_clone(SIGCHLD|CLONE_NEWNS);
+ if (*helper_pid < 0)
return log_error_errno(errno, "clone() failed%s: %m",
errno == EINVAL ?
", do you have namespace support enabled in your kernel? (You need UTS, IPC, PID and NET namespacing built in)" : "");
- if (*pid == 0) {
+ if (*helper_pid == 0) {
/* The outer child only has a file system namespace. */
barrier_set_role(&barrier, BARRIER_CHILD);
@@ -3822,17 +3823,18 @@ static int run(int master,
}
/* Wait for the outer child. */
- r = wait_for_terminate_and_check("(sd-namespace)", *pid, WAIT_LOG_ABNORMAL);
+ r = wait_for_terminate_and_check("(sd-namespace)", *helper_pid, WAIT_LOG_ABNORMAL);
+ *helper_pid = 0;
if (r < 0)
return r;
if (r != EXIT_SUCCESS)
return -EIO;
/* And now retrieve the PID of the inner child. */
- l = recv(pid_socket_pair[0], pid, sizeof *pid, 0);
+ l = recv(pid_socket_pair[0], main_pid, sizeof *main_pid, 0);
if (l < 0)
return log_error_errno(errno, "Failed to read inner child PID: %m");
- if (l != sizeof *pid) {
+ if (l != sizeof *main_pid) {
log_error("Short read while reading inner child PID.");
return -EIO;
}
@@ -3852,7 +3854,7 @@ static int run(int master,
return log_error_errno(notify_socket,
"Failed to receive notification socket from the outer child: %m");
- log_debug("Init process invoked as PID "PID_FMT, *pid);
+ 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 */
@@ -3860,7 +3862,7 @@ static int run(int master,
return -ESRCH;
}
- r = setup_uid_map(*pid);
+ r = setup_uid_map(*main_pid);
if (r < 0)
return r;
@@ -3876,12 +3878,12 @@ static int run(int master,
}
}
- r = move_network_interfaces(*pid, arg_network_interfaces);
+ r = move_network_interfaces(*main_pid, arg_network_interfaces);
if (r < 0)
return r;
if (arg_network_veth) {
- r = setup_veth(arg_machine, *pid, veth_name,
+ r = setup_veth(arg_machine, *main_pid, veth_name,
arg_network_bridge || arg_network_zone);
if (r < 0)
return r;
@@ -3905,7 +3907,7 @@ static int run(int master,
}
}
- r = setup_veth_extra(arg_machine, *pid, arg_network_veth_extra);
+ r = setup_veth_extra(arg_machine, *main_pid, arg_network_veth_extra);
if (r < 0)
return r;
@@ -3915,11 +3917,11 @@ static int run(int master,
remove them on its own, since they cannot be referenced by anything yet. */
*veth_created = true;
- r = setup_macvlan(arg_machine, *pid, arg_network_macvlan);
+ r = setup_macvlan(arg_machine, *main_pid, arg_network_macvlan);
if (r < 0)
return r;
- r = setup_ipvlan(arg_machine, *pid, arg_network_ipvlan);
+ r = setup_ipvlan(arg_machine, *main_pid, arg_network_ipvlan);
if (r < 0)
return r;
}
@@ -3942,7 +3944,7 @@ static int run(int master,
NULL,
"org.freedesktop.systemd1.Scope",
"RequestStop",
- on_request_stop, NULL, PID_TO_PTR(*pid));
+ on_request_stop, NULL, PID_TO_PTR(*main_pid));
if (r < 0)
return log_error_errno(r, "Failed to request RequestStop match: %m");
}
@@ -3951,7 +3953,7 @@ static int run(int master,
r = register_machine(
bus,
arg_machine,
- *pid,
+ *main_pid,
arg_directory,
arg_uuid,
ifi,
@@ -3968,7 +3970,7 @@ static int run(int master,
r = allocate_scope(
bus,
arg_machine,
- *pid,
+ *main_pid,
arg_slice,
arg_custom_mounts, arg_n_custom_mounts,
arg_kill_signal,
@@ -3979,7 +3981,7 @@ static int run(int master,
} else if (arg_slice || arg_property)
log_notice("Machine and scope registration turned off, --slice= and --property= settings will have no effect.");
- r = cgroup_setup(*pid, outer_cgver, arg_inner_cgver, arg_uid_shift, arg_keep_unit);
+ r = cgroup_setup(*main_pid, outer_cgver, arg_inner_cgver, arg_uid_shift, arg_keep_unit);
if (r < 0)
return r;
@@ -4010,7 +4012,7 @@ static int run(int master,
return log_error_errno(r, "Failed to attach bus to event loop: %m");
}
- r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*pid), &notify_event_source);
+ r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*main_pid), &notify_event_source);
if (r < 0)
return r;
@@ -4026,14 +4028,14 @@ static int run(int master,
sd_notifyf(false,
"STATUS=Container running.\n"
- "X_NSPAWN_LEADER_PID=" PID_FMT, *pid);
+ "X_NSPAWN_LEADER_PID=" PID_FMT, *main_pid);
if (!arg_notify_ready)
(void) sd_notify(false, "READY=1\n");
if (arg_kill_signal > 0) {
/* Try to kill the init system on SIGINT or SIGTERM */
- (void) sd_event_add_signal(event, NULL, SIGINT, on_orderly_shutdown, PID_TO_PTR(*pid));
- (void) sd_event_add_signal(event, NULL, SIGTERM, on_orderly_shutdown, PID_TO_PTR(*pid));
+ (void) sd_event_add_signal(event, NULL, SIGINT, on_orderly_shutdown, PID_TO_PTR(*main_pid));
+ (void) sd_event_add_signal(event, NULL, SIGTERM, on_orderly_shutdown, PID_TO_PTR(*main_pid));
} else {
/* Immediately exit */
(void) sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
@@ -4041,7 +4043,7 @@ static int run(int master,
}
/* Exit when the child exits */
- (void) sd_event_add_signal(event, NULL, SIGCHLD, on_sigchld, PID_TO_PTR(*pid));
+ (void) sd_event_add_signal(event, NULL, SIGCHLD, on_sigchld, PID_TO_PTR(*main_pid));
if (arg_expose_ports) {
r = expose_port_watch_rtnl(event, rtnl_socket_pair[0], on_address_change, exposed, &rtnl);
@@ -4072,13 +4074,13 @@ static int run(int master,
/* Kill if it is not dead yet anyway */
if (arg_register && !arg_keep_unit && bus)
- terminate_machine(bus, *pid);
+ terminate_machine(bus, *main_pid);
/* Normally redundant, but better safe than sorry */
- (void) kill(*pid, SIGKILL);
+ (void) kill(*main_pid, SIGKILL);
- r = wait_for_container(*pid, &container_status);
- *pid = 0;
+ r = wait_for_container(*main_pid, &container_status);
+ *main_pid = 0;
if (r < 0)
/* We failed to wait for the container, or the container exited abnormally. */
@@ -4185,7 +4187,7 @@ int main(int argc, char *argv[]) {
int r, n_fd_passed, ret = EXIT_SUCCESS;
char veth_name[IFNAMSIZ] = "";
bool secondary = false, remove_directory = false, remove_image = false;
- pid_t pid = 0;
+ pid_t helper_pid = 0, main_pid = 0;
union in_addr_union exposed = {};
_cleanup_(release_lock_file) LockFile tree_global_lock = LOCK_FILE_INIT, tree_local_lock = LOCK_FILE_INIT;
bool interactive, veth_created = false, remove_tmprootdir = false;
@@ -4526,7 +4528,8 @@ int main(int argc, char *argv[]) {
fds,
veth_name, &veth_created,
&exposed,
- &pid, &ret);
+ &helper_pid, &main_pid,
+ &ret);
if (r <= 0)
break;
}
@@ -4536,8 +4539,10 @@ finish:
r == 0 && ret == EXIT_FORCE_RESTART ? "STOPPING=1\nSTATUS=Restarting..." :
"STOPPING=1\nSTATUS=Terminating...");
- if (pid > 0)
- (void) kill(pid, SIGKILL);
+ if (helper_pid > 0)
+ (void) kill(helper_pid, SIGKILL);
+ if (main_pid > 0)
+ (void) kill(main_pid, SIGKILL);
/* Try to flush whatever is still queued in the pty */
if (master >= 0) {
@@ -4545,8 +4550,10 @@ finish:
master = safe_close(master);
}
- if (pid > 0)
- (void) wait_for_terminate(pid, NULL);
+ if (helper_pid > 0)
+ (void) wait_for_terminate(helper_pid, NULL);
+ if (main_pid > 0)
+ (void) wait_for_terminate(main_pid, NULL);
pager_close();