return -EINVAL;
}
- if (s->exec_context.pam_name && s->kill_mode != KILL_CONTROL_GROUP) {
+ if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", s->meta.id);
return -EINVAL;
}
if (u->meta.load_state == UNIT_LOADED) {
if (have_non_accept_socket(s)) {
- if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)))
+ if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)) < 0)
return r;
if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service), true)) < 0)
"%sSocket State: %s\n"
"%sBindIPv6Only: %s\n"
"%sBacklog: %u\n"
- "%sKillMode: %s\n"
"%sSocketMode: %04o\n"
"%sDirectoryMode: %04o\n"
"%sKeepAlive: %s\n"
prefix, socket_state_to_string(s->state),
prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
prefix, s->backlog,
- prefix, kill_mode_to_string(s->kill_mode),
prefix, s->socket_mode,
prefix, s->directory_mode,
prefix, yes_no(s->keep_alive),
if (!success)
s->failure = true;
- if (s->kill_mode != KILL_NONE) {
- int sig = (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_FINAL_SIGTERM) ? SIGTERM : SIGKILL;
+ 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->kill_mode == KILL_CONTROL_GROUP) {
+ if (s->exec_context.kill_mode == KILL_CONTROL_GROUP) {
if ((r = cgroup_bonding_kill_list(s->meta.cgroup_bondings, sig)) < 0) {
if (r != -EAGAIN && r != -ESRCH)
}
if (!sent && s->control_pid > 0)
- if (kill(s->kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH) {
+ if (kill(s->exec_context.kill_mode == KILL_PROCESS ? s->control_pid : -s->control_pid, sig) < 0 && errno != ESRCH) {
r = -errno;
goto fail;
}
assert(s);
- /* We cannot fulfill this request right now, try again later
- * please! */
- if (s->state == SOCKET_START_PRE ||
- s->state == SOCKET_START_POST)
- return -EAGAIN;
-
/* Already on it */
if (s->state == SOCKET_STOP_PRE ||
s->state == SOCKET_STOP_PRE_SIGTERM ||
s->state == SOCKET_STOP_PRE_SIGKILL ||
s->state == SOCKET_STOP_POST ||
s->state == SOCKET_FINAL_SIGTERM ||
- s->state == SOCKET_FINAL_SIGTERM)
+ s->state == SOCKET_FINAL_SIGKILL)
return 0;
+ /* If there's already something running we go directly into
+ * kill mode. */
+ if (s->state == SOCKET_START_PRE ||
+ s->state == SOCKET_START_POST) {
+ socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, true);
+ return -EAGAIN;
+ }
+
assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
socket_enter_stop_pre(s, true);
s->control_pid = 0;
success = is_clean_exit(code, status);
- s->failure = s->failure || !success;
- if (s->control_command)
+ if (s->control_command) {
exec_status_exit(&s->control_command->exec_status, pid, code, status);
+ if (s->control_command->ignore)
+ success = true;
+ }
+
log_debug("%s control process exited, code=%s status=%i", u->meta.id, sigchld_code_to_string(code), status);
+ s->failure = s->failure || !success;
if (s->control_command && s->control_command->command_next && success) {
log_debug("%s running next command for state %s", u->meta.id, socket_state_to_string(s->state));