X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fservice.c;h=08b929e4fe7af4b5ff4763c7177b9e13ef9f0460;hb=dc99a9764418a1974c46c55efa73b034f530a5a5;hp=6f18cbf759bb98eb1571dd0f5820bd4cfa9103c7;hpb=c2756a68401102786be343712c0c35acbd73d28d;p=elogind.git diff --git a/src/core/service.c b/src/core/service.c index 6f18cbf75..08b929e4f 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -191,6 +191,8 @@ static int service_set_main_pid(Service *s, pid_t pid) { if (pid == getpid()) return -EINVAL; + service_unwatch_main_pid(s); + s->main_pid = pid; s->main_pid_known = true; @@ -1111,6 +1113,12 @@ static int service_verify(Service *s) { return -EINVAL; } + if (s->type == SERVICE_ONESHOT && s->restart != SERVICE_RESTART_NO) { + log_error_unit(UNIT(s)->id, + "%s has Restart setting other than no, which isn't allowed for Type=oneshot services. Refusing.", UNIT(s)->id); + return -EINVAL; + } + if (s->type == SERVICE_DBUS && !s->bus_name) { log_error_unit(UNIT(s)->id, "%s is of type D-Bus but no D-Bus service name has been specified. Refusing.", UNIT(s)->id); @@ -1617,6 +1625,7 @@ static int service_coldplug(Unit *u) { s->deserialized_state == SERVICE_FINAL_SIGTERM || s->deserialized_state == SERVICE_FINAL_SIGKILL || s->deserialized_state == SERVICE_AUTO_RESTART) { + if (s->deserialized_state == SERVICE_AUTO_RESTART || s->timeout_start_usec > 0) { usec_t k; @@ -1928,6 +1937,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) (s->restart == SERVICE_RESTART_ALWAYS || (s->restart == SERVICE_RESTART_ON_SUCCESS && s->result == SERVICE_SUCCESS) || (s->restart == SERVICE_RESTART_ON_FAILURE && s->result != SERVICE_SUCCESS) || + (s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) || (s->restart == SERVICE_RESTART_ON_ABORT && (s->result == SERVICE_FAILURE_SIGNAL || s->result == SERVICE_FAILURE_CORE_DUMP))) && (s->result != SERVICE_FAILURE_EXIT_CODE || @@ -1948,6 +1958,12 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) /* we want fresh tmpdirs in case service is started again immediately */ exec_context_tmp_dirs_done(&s->exec_context); + /* Try to delete the pid file. At this point it will be + * out-of-date, and some software might be confused by it, so + * let's remove it. */ + if (s->pid_file) + unlink_noerrno(s->pid_file); + return; fail: @@ -1986,7 +2002,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) { service_set_state(s, SERVICE_STOP_POST); } else - service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_SUCCESS); + service_enter_dead(s, SERVICE_SUCCESS, true); return; @@ -2144,7 +2160,6 @@ static void service_kill_control_processes(Service *s) { return; p = strappenda(UNIT(s)->cgroup_path, "/control"); - cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, p, SIGKILL, true, true, true, NULL); } @@ -2158,10 +2173,8 @@ static void service_enter_start(Service *s) { assert(s->exec_command[SERVICE_EXEC_START]); assert(!s->exec_command[SERVICE_EXEC_START]->command_next || s->type == SERVICE_ONESHOT); - if (s->type == SERVICE_FORKING) - service_unwatch_control_pid(s); - else - service_unwatch_main_pid(s); + service_unwatch_control_pid(s); + service_unwatch_main_pid(s); /* We want to ensure that nobody leaks processes from * START_PRE here, so let's go on a killing spree, People @@ -3322,8 +3335,7 @@ static void service_notify_cgroup_empty_event(Unit *u) { assert(u); - log_debug_unit(u->id, - "%s: cgroup is empty", u->id); + log_debug_unit(u->id, "%s: cgroup is empty", u->id); switch (s->state) { @@ -3752,6 +3764,7 @@ static void service_reset_failed(Unit *u) { static int service_kill(Unit *u, KillWho who, int signo, DBusError *error) { Service *s = SERVICE(u); + return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error); } @@ -3779,6 +3792,7 @@ static const char* const service_restart_table[_SERVICE_RESTART_MAX] = { [SERVICE_RESTART_NO] = "no", [SERVICE_RESTART_ON_SUCCESS] = "on-success", [SERVICE_RESTART_ON_FAILURE] = "on-failure", + [SERVICE_RESTART_ON_WATCHDOG] = "on-watchdog", [SERVICE_RESTART_ON_ABORT] = "on-abort", [SERVICE_RESTART_ALWAYS] = "always" };