diff options
author | Luke Shumaker <lukeshu@lukeshu.com> | 2017-06-14 16:22:06 -0400 |
---|---|---|
committer | Luke Shumaker <lukeshu@parabola.nu> | 2018-08-16 21:55:16 -0400 |
commit | bbf44a337c677bb5235340060ed46208153e0112 (patch) | |
tree | e9a6b3e1ca76e4b6f7edfe699b2dfff711c136f9 | |
parent | 6285ec4b89a7e571119aa853ca3f4bc62ae1c8f0 (diff) |
nspawn: Track the inner child and outer child PIDs separately
-rw-r--r-- | src/nspawn/nspawn.c | 73 |
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), ¬ify_event_source); + r = setup_sd_notify_parent(event, notify_socket, PID_TO_PTR(*main_pid), ¬ify_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(); |