X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=service.c;h=298cc27edb56595ce3ade03d5a34667caeb861fc;hb=932921b5c247f5de09f0e20208534f354f9c0fef;hp=4008ac20ffea76bce8c9a1d15078b87c895965e4;hpb=701cc384c283206a29b21e4e7302e5cf5f2d9433;p=elogind.git diff --git a/service.c b/service.c index 4008ac20f..298cc27ed 100644 --- a/service.c +++ b/service.c @@ -661,6 +661,7 @@ static int service_load_sysv_path(Service *s, const char *path) { /* Special setting for all SysV services */ s->valid_no_process = true; + s->kill_mode = KILL_PROCESS_GROUP; /* Don't timeout special services during boot (like fsck) */ if (s->sysv_runlevels && !chars_intersect("12345", s->sysv_runlevels)) @@ -875,7 +876,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) { if (!s->exec_command[c]) continue; - fprintf(f, "%s→ %s:\n", + fprintf(f, "%s-> %s:\n", prefix, service_exec_command_to_string(c)); exec_command_dump_list(s->exec_command[c], f, prefix2); @@ -1069,7 +1070,7 @@ static void service_set_state(Service *s, ServiceState state) { service_close_socket_fd(s); if (old_state != state) - log_debug("%s changed %s → %s", UNIT(s)->meta.id, service_state_to_string(old_state), service_state_to_string(state)); + log_debug("%s changed %s -> %s", UNIT(s)->meta.id, service_state_to_string(old_state), service_state_to_string(state)); unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state]); } @@ -1093,13 +1094,17 @@ static int service_coldplug(Unit *u) { s->deserialized_state == SERVICE_STOP_POST || s->deserialized_state == SERVICE_FINAL_SIGTERM || s->deserialized_state == SERVICE_FINAL_SIGKILL || - s->deserialized_state == SERVICE_AUTO_RESTART) - if ((r = unit_watch_timer(UNIT(s), - s->deserialized_state == SERVICE_AUTO_RESTART ? - s->restart_usec : - s->timeout_usec, - &s->timer_watch)) < 0) - return r; + s->deserialized_state == SERVICE_AUTO_RESTART) { + + if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_usec > 0) { + usec_t k; + + k = s->deserialized_state == SERVICE_AUTO_RESTART ? s->restart_usec : s->timeout_usec; + + if ((r = unit_watch_timer(UNIT(s), k, &s->timer_watch)) < 0) + return r; + } + } if ((s->deserialized_state == SERVICE_START && (s->type == SERVICE_FORKING || @@ -1222,7 +1227,7 @@ static int service_spawn( goto fail; } - if (timeout) { + if (timeout && s->timeout_usec) { if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) goto fail; } else @@ -1314,6 +1319,7 @@ static void service_enter_dead(Service *s, bool success, bool allow_restart) { s->failure = true; if (allow_restart && + s->allow_restart && (s->restart == SERVICE_RESTART_ALWAYS || (s->restart == SERVICE_RESTART_ON_SUCCESS && !s->failure))) { @@ -1408,9 +1414,10 @@ static void service_enter_signal(Service *s, ServiceState state, bool success) { } } - if (sent) { - if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) - goto fail; + if (sent && (s->main_pid > 0 || s->control_pid > 0)) { + if (s->timeout_usec > 0) + if ((r = unit_watch_timer(UNIT(s), s->timeout_usec, &s->timer_watch)) < 0) + goto fail; service_set_state(s, state); } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL) @@ -1716,6 +1723,7 @@ static int service_start(Unit *u) { s->failure = false; s->main_pid_known = false; + s->allow_restart = true; service_enter_start_pre(s); return 0; @@ -1749,6 +1757,10 @@ static int service_stop(Unit *u) { assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED); + /* This is a user request, so don't do restarts on this + * shutdown. */ + s->allow_restart = false; + service_enter_stop(s, true); return 0; } @@ -1794,7 +1806,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) { * commands attached here, we will start from the first one * again */ if (s->control_command_id >= 0) - unit_serialize_item(u, f, "control-command", mount_exec_command_to_string(s->control_command_id)); + unit_serialize_item(u, f, "control-command", service_exec_command_to_string(s->control_command_id)); if (s->socket_fd >= 0) { int copy; @@ -2197,7 +2209,7 @@ static int service_enumerate(Manager *m) { } while ((de = readdir(d))) { - Unit *runlevel, *service; + Unit *service; if (ignore_file(de->d_name)) continue; @@ -2233,31 +2245,42 @@ static int service_enumerate(Manager *m) { if ((r = manager_load_unit(m, name, NULL, &service)) < 0) goto finish; - if ((r = manager_load_unit(m, rcnd_table[i+1], NULL, &runlevel)) < 0) - goto finish; - if (de->d_name[0] == 'S') { - if ((r = unit_add_dependency(runlevel, UNIT_WANTS, service, true)) < 0) + Unit *runlevel_target; + + if ((r = manager_load_unit(m, rcnd_table[i+1], NULL, &runlevel_target)) < 0) goto finish; - if ((r = unit_add_dependency(runlevel, UNIT_AFTER, service, true)) < 0) + if ((r = unit_add_dependency(runlevel_target, UNIT_WANTS, service, true)) < 0) + goto finish; + + if ((r = unit_add_dependency(service, UNIT_BEFORE, runlevel_target, true)) < 0) goto finish; } else if (de->d_name[0] == 'K' && (streq(rcnd_table[i+1], SPECIAL_RUNLEVEL0_TARGET) || streq(rcnd_table[i+1], SPECIAL_RUNLEVEL6_TARGET))) { + Unit *shutdown_target; + /* We honour K links only for * halt/reboot. For the normal * runlevels we assume the * stop jobs will be * implicitly added by the - * core logic. */ + * core logic. Also, we don't + * really distuingish here + * between the runlevels 0 and + * 6 and just add them to the + * special shutdown target. */ + + if ((r = manager_load_unit(m, SPECIAL_SHUTDOWN_TARGET, NULL, &shutdown_target)) < 0) + goto finish; - if ((r = unit_add_dependency(runlevel, UNIT_CONFLICTS, service, true)) < 0) + if ((r = unit_add_dependency(service, UNIT_CONFLICTS, shutdown_target, true)) < 0) goto finish; - if ((r = unit_add_dependency(runlevel, UNIT_BEFORE, service, true)) < 0) + if ((r = unit_add_dependency(service, UNIT_BEFORE, shutdown_target, true)) < 0) goto finish; } }