X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsocket.c;h=da85ca7e8b96bc658865ae2ee60446b729c824d4;hb=b56e57470c92f123044ea690b5404bdd730ddaa6;hp=d0568c9b52074bdb18888f56e8b39283dbf24023;hpb=049f86421bfe8afcbb00c7ee5a76fd14841f8bbf;p=elogind.git diff --git a/src/socket.c b/src/socket.c index d0568c9b5..da85ca7e8 100644 --- a/src/socket.c +++ b/src/socket.c @@ -54,7 +54,7 @@ static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = { [SOCKET_STOP_POST] = UNIT_DEACTIVATING, [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING, [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING, - [SOCKET_MAINTENANCE] = UNIT_MAINTENANCE + [SOCKET_FAILED] = UNIT_FAILED }; static void socket_init(Unit *u) { @@ -385,7 +385,7 @@ static void socket_dump(Unit *u, FILE *f, const char *prefix) { prefix, s->directory_mode, prefix, yes_no(s->keep_alive), prefix, yes_no(s->free_bind), - prefix, s->tcp_congestion); + prefix, strna(s->tcp_congestion)); if (s->control_pid > 0) fprintf(f, @@ -964,7 +964,7 @@ static void socket_enter_dead(Socket *s, bool success) { if (!success) s->failure = true; - socket_set_state(s, s->failure ? SOCKET_MAINTENANCE : SOCKET_DEAD); + socket_set_state(s, s->failure ? SOCKET_FAILED : SOCKET_DEAD); } static void socket_enter_signal(Socket *s, SocketState state, bool success); @@ -997,7 +997,8 @@ fail: static void socket_enter_signal(Socket *s, SocketState state, bool success) { int r; - bool sent = false; + Set *pid_set = NULL; + bool wait_for_exit = false; assert(s); @@ -1007,23 +1008,39 @@ static void socket_enter_signal(Socket *s, SocketState state, bool success) { if (s->exec_context.kill_mode != KILL_NONE) { int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? s->exec_context.kill_signal : SIGKILL; - if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) { + if (s->control_pid > 0) { + if (kill(s->exec_context.kill_mode == KILL_PROCESS_GROUP ? + -s->control_pid : + s->control_pid, sig) < 0 && errno != ESRCH) - if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig)) < 0) { - if (r != -EAGAIN && r != -ESRCH) - goto fail; - } else - sent = true; + log_warning("Failed to kill control process %li: %m", (long) s->control_pid); + else + wait_for_exit = true; } - if (!sent && s->control_pid > 0) - if (kill(s->exec_context.kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH) { - r = -errno; + if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) { + + if (!(pid_set = set_new(trivial_hash_func, trivial_compare_func))) { + r = -ENOMEM; goto fail; } + + /* Exclude the control pid from being killed via the cgroup */ + if (s->control_pid > 0) + if ((r = set_put(pid_set, LONG_TO_PTR(s->control_pid))) < 0) + goto fail; + + if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig, pid_set)) < 0) { + if (r != -EAGAIN && r != -ESRCH && r != -ENOENT) + log_warning("Failed to kill control group: %s", strerror(-r)); + } else if (r > 0) + wait_for_exit = true; + + set_free(pid_set); + } } - if (sent && s->control_pid > 0) { + if (wait_for_exit) { if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) goto fail; @@ -1042,6 +1059,9 @@ fail: socket_enter_stop_post(s, false); else socket_enter_dead(s, false); + + if (pid_set) + set_free(pid_set); } static void socket_enter_stop_pre(Socket *s, bool success) { @@ -1147,7 +1167,7 @@ static void socket_enter_running(Socket *s, int cfd) { /* We don't take connections anymore if we are supposed to * shut down anyway */ - if (s->meta.job && s->meta.job->type == JOB_STOP) { + if (unit_pending_inactive(UNIT(s))) { if (cfd >= 0) close_nointr_nofail(cfd); else { @@ -1295,12 +1315,12 @@ static int socket_start(Unit *u) { /* If the service is alredy actvie we cannot start the * socket */ if (s->service->state != SERVICE_DEAD && - s->service->state != SERVICE_MAINTENANCE && + s->service->state != SERVICE_FAILED && s->service->state != SERVICE_AUTO_RESTART) return -EBUSY; } - assert(s->state == SOCKET_DEAD || s->state == SOCKET_MAINTENANCE); + assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED); s->failure = false; socket_enter_start_pre(s); @@ -1650,7 +1670,7 @@ static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) { break; case SOCKET_FINAL_SIGKILL: - log_warning("%s still around after SIGKILL (2). Entering maintenance mode.", u->meta.id); + log_warning("%s still around after SIGKILL (2). Entering failed mode.", u->meta.id); socket_enter_dead(s, false); break; @@ -1719,12 +1739,12 @@ void socket_connection_unref(Socket *s) { log_debug("%s: One connection closed, %u left.", s->meta.id, s->n_connections); } -static void socket_reset_maintenance(Unit *u) { +static void socket_reset_failed(Unit *u) { Socket *s = SOCKET(u); assert(s); - if (s->state == SOCKET_MAINTENANCE) + if (s->state == SOCKET_FAILED) socket_set_state(s, SOCKET_DEAD); s->failure = false; @@ -1742,7 +1762,7 @@ static const char* const socket_state_table[_SOCKET_STATE_MAX] = { [SOCKET_STOP_POST] = "stop-post", [SOCKET_FINAL_SIGTERM] = "final-sigterm", [SOCKET_FINAL_SIGKILL] = "final-sigkill", - [SOCKET_MAINTENANCE] = "maintenance" + [SOCKET_FAILED] = "failed" }; DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState); @@ -1782,7 +1802,7 @@ const UnitVTable socket_vtable = { .sigchld_event = socket_sigchld_event, .timer_event = socket_timer_event, - .reset_maintenance = socket_reset_maintenance, + .reset_failed = socket_reset_failed, .bus_interface = "org.freedesktop.systemd1.Socket", .bus_message_handler = bus_socket_message_handler,