]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/service.c
service: make restart logic a bit easier to understand
[thirdparty/systemd.git] / src / core / service.c
index 26b9b56371afff8f638fbab89edbbef9a9efb893..3a614b1c7a6465d07b043b2b7403d03bc4c1a08a 100644 (file)
@@ -21,7 +21,6 @@
 
 #include <errno.h>
 #include <signal.h>
-#include <dirent.h>
 #include <unistd.h>
 
 #include "async.h"
@@ -46,6 +45,8 @@
 #include "bus-error.h"
 #include "bus-util.h"
 #include "bus-kernel.h"
+#include "formats-util.h"
+#include "process-util.h"
 
 static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
         [SERVICE_DEAD] = UNIT_INACTIVE,
@@ -495,8 +496,7 @@ static int service_add_default_dependencies(Service *s) {
                 return r;
 
         /* Second, activate normal shutdown */
-        r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
-        return r;
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
 }
 
 static void service_fix_output(Service *s) {
@@ -517,6 +517,69 @@ static void service_fix_output(Service *s) {
                 s->exec_context.std_output = UNIT(s)->manager->default_std_output;
 }
 
+static int service_add_extras(Service *s) {
+        int r;
+
+        assert(s);
+
+        if (s->type == _SERVICE_TYPE_INVALID) {
+                /* Figure out a type automatically */
+                if (s->bus_name)
+                        s->type = SERVICE_DBUS;
+                else if (s->exec_command[SERVICE_EXEC_START])
+                        s->type = SERVICE_SIMPLE;
+                else
+                        s->type = SERVICE_ONESHOT;
+        }
+
+        /* Oneshot services have disabled start timeout by default */
+        if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined)
+                s->timeout_start_usec = 0;
+
+        service_fix_output(s);
+
+        r = unit_patch_contexts(UNIT(s));
+        if (r < 0)
+                return r;
+
+        r = unit_add_exec_dependencies(UNIT(s), &s->exec_context);
+        if (r < 0)
+                return r;
+
+        r = unit_add_default_slice(UNIT(s), &s->cgroup_context);
+        if (r < 0)
+                return r;
+
+        if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE)
+                s->notify_access = NOTIFY_MAIN;
+
+        if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
+                s->notify_access = NOTIFY_MAIN;
+
+        if (s->bus_name) {
+#ifdef ENABLE_KDBUS
+                const char *n;
+
+                n = strjoina(s->bus_name, ".busname");
+                r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
+                if (r < 0)
+                        return r;
+#endif
+
+                r = unit_watch_bus_name(UNIT(s), s->bus_name);
+                if (r < 0)
+                        return r;
+        }
+
+        if (UNIT(s)->default_dependencies) {
+                r = service_add_default_dependencies(s);
+                if (r < 0)
+                        return r;
+        }
+
+        return 0;
+}
+
 static int service_load(Unit *u) {
         Service *s = SERVICE(u);
         int r;
@@ -541,52 +604,11 @@ static int service_load(Unit *u) {
                 if (r < 0)
                         return r;
 
-                if (s->type == _SERVICE_TYPE_INVALID) {
-                        /* Figure out a type automatically */
-                        if (s->bus_name)
-                                s->type = SERVICE_DBUS;
-                        else if (s->exec_command[SERVICE_EXEC_START])
-                                s->type = SERVICE_SIMPLE;
-                        else
-                                s->type = SERVICE_ONESHOT;
-                }
-
-                /* Oneshot services have disabled start timeout by default */
-                if (s->type == SERVICE_ONESHOT && !s->start_timeout_defined)
-                        s->timeout_start_usec = 0;
-
-                service_fix_output(s);
-
-                r = unit_patch_contexts(u);
-                if (r < 0)
-                        return r;
-
-                r = unit_add_exec_dependencies(u, &s->exec_context);
+                /* This is a new unit? Then let's add in some
+                 * extras */
+                r = service_add_extras(s);
                 if (r < 0)
                         return r;
-
-                r = unit_add_default_slice(u, &s->cgroup_context);
-                if (r < 0)
-                        return r;
-
-                if (s->type == SERVICE_NOTIFY && s->notify_access == NOTIFY_NONE)
-                        s->notify_access = NOTIFY_MAIN;
-
-                if (s->watchdog_usec > 0 && s->notify_access == NOTIFY_NONE)
-                        s->notify_access = NOTIFY_MAIN;
-
-                if (s->bus_name) {
-                        r = unit_watch_bus_name(u, s->bus_name);
-                        if (r < 0)
-                                return r;
-                }
-
-                if (u->default_dependencies) {
-                        r = service_add_default_dependencies(s);
-                        if (r < 0)
-
-                                return r;
-                }
         }
 
         return service_verify(s);
@@ -600,7 +622,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
         assert(s);
 
         prefix = strempty(prefix);
-        prefix2 = strappenda(prefix, "\t");
+        prefix2 = strjoina(prefix, "\t");
 
         fprintf(f,
                 "%sService State: %s\n"
@@ -785,8 +807,7 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
-                    SERVICE_STOP_SIGABRT, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,
                     SERVICE_AUTO_RESTART))
                 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
@@ -794,8 +815,7 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START, SERVICE_START_POST,
                     SERVICE_RUNNING, SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
-                    SERVICE_STOP_SIGABRT, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                 service_unwatch_main_pid(s);
                 s->main_command = NULL;
@@ -804,8 +824,7 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
-                    SERVICE_STOP_SIGABRT, SERVICE_STOP_POST,
+                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                     SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                 service_unwatch_control_pid(s);
                 s->control_command = NULL;
@@ -818,8 +837,8 @@ static void service_set_state(Service *s, ServiceState state) {
         if (!IN_SET(state,
                     SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                     SERVICE_RUNNING, SERVICE_RELOAD,
-                    SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
-                    SERVICE_STOP_SIGABRT, SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
+                    SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                    SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL) &&
             !(state == SERVICE_DEAD && UNIT(s)->job)) {
                 service_close_socket_fd(s);
                 service_connection_unref(s);
@@ -872,8 +891,7 @@ static int service_coldplug(Unit *u) {
                 if (IN_SET(s->deserialized_state,
                            SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                            SERVICE_RELOAD,
-                           SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
-                           SERVICE_STOP_SIGABRT, SERVICE_STOP_POST,
+                           SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                            SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
 
                         usec_t k;
@@ -901,8 +919,7 @@ static int service_coldplug(Unit *u) {
                      IN_SET(s->deserialized_state,
                             SERVICE_START, SERVICE_START_POST,
                             SERVICE_RUNNING, SERVICE_RELOAD,
-                            SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
-                            SERVICE_STOP_SIGABRT, SERVICE_STOP_POST,
+                            SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                             SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))) {
                         r = unit_watch_pid(UNIT(s), s->main_pid);
                         if (r < 0)
@@ -913,8 +930,7 @@ static int service_coldplug(Unit *u) {
                     IN_SET(s->deserialized_state,
                            SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST,
                            SERVICE_RELOAD,
-                           SERVICE_STOP, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL,
-                           SERVICE_STOP_SIGABRT, SERVICE_STOP_POST,
+                           SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
                            SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL)) {
                         r = unit_watch_pid(UNIT(s), s->control_pid);
                         if (r < 0)
@@ -1039,7 +1055,11 @@ static int service_spawn(
         assert(c);
         assert(_pid);
 
-        unit_realize_cgroup(UNIT(s));
+        (void) unit_realize_cgroup(UNIT(s));
+        if (s->reset_cpu_usage) {
+                (void) unit_reset_cpu_usage(UNIT(s));
+                s->reset_cpu_usage = false;
+        }
 
         r = unit_setup_exec_runtime(UNIT(s));
         if (r < 0)
@@ -1073,7 +1093,7 @@ static int service_spawn(
         if (r < 0)
                 goto fail;
 
-        our_env = new0(char*, 4);
+        our_env = new0(char*, 6);
         if (!our_env) {
                 r = -ENOMEM;
                 goto fail;
@@ -1097,6 +1117,46 @@ static int service_spawn(
                         goto fail;
                 }
 
+        if (UNIT_DEREF(s->accept_socket)) {
+                union sockaddr_union sa;
+                socklen_t salen = sizeof(sa);
+
+                r = getpeername(s->socket_fd, &sa.sa, &salen);
+                if (r < 0) {
+                        r = -errno;
+                        goto fail;
+                }
+
+                if (IN_SET(sa.sa.sa_family, AF_INET, AF_INET6)) {
+                        _cleanup_free_ char *addr = NULL;
+                        char *t;
+                        int port;
+
+                        r = sockaddr_pretty(&sa.sa, salen, true, false, &addr);
+                        if (r < 0)
+                                goto fail;
+
+                        t = strappend("REMOTE_ADDR=", addr);
+                        if (!t) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+                        our_env[n_env++] = t;
+
+                        port = sockaddr_port(&sa.sa);
+                        if (port < 0) {
+                                r = port;
+                                goto fail;
+                        }
+
+                        if (asprintf(&t, "REMOTE_PORT=%u", port) < 0) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+                        our_env[n_env++] = t;
+                }
+        }
+
         final_env = strv_env_merge(2, UNIT(s)->manager->environment, our_env, NULL);
         if (!final_env) {
                 r = -ENOMEM;
@@ -1104,7 +1164,7 @@ static int service_spawn(
         }
 
         if (is_control && UNIT(s)->cgroup_path) {
-                path = strappenda(UNIT(s)->cgroup_path, "/control");
+                path = strjoina(UNIT(s)->cgroup_path, "/control");
                 cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
         } else
                 path = UNIT(s)->cgroup_path;
@@ -1208,6 +1268,49 @@ static int cgroup_good(Service *s) {
         return !r;
 }
 
+static bool service_shall_restart(Service *s) {
+        assert(s);
+
+        /* Don't restart after manual stops */
+        if (s->forbid_restart)
+                return false;
+
+        /* Never restart if this is configured as special exception */
+        if (exit_status_set_test(&s->restart_prevent_status, s->main_exec_status.code, s->main_exec_status.status))
+                return false;
+
+        /* Restart if the exit code/status are configured as restart triggers */
+        if (exit_status_set_test(&s->restart_force_status,  s->main_exec_status.code, s->main_exec_status.status))
+                return true;
+
+        switch (s->restart) {
+
+        case SERVICE_RESTART_NO:
+                return false;
+
+        case SERVICE_RESTART_ALWAYS:
+                return true;
+
+        case SERVICE_RESTART_ON_SUCCESS:
+                return s->result == SERVICE_SUCCESS;
+
+        case SERVICE_RESTART_ON_FAILURE:
+                return s->result != SERVICE_SUCCESS;
+
+        case SERVICE_RESTART_ON_ABNORMAL:
+                return !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE);
+
+        case SERVICE_RESTART_ON_WATCHDOG:
+                return s->result == SERVICE_FAILURE_WATCHDOG;
+
+        case SERVICE_RESTART_ON_ABORT:
+                return IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP);
+
+        default:
+                assert_not_reached("unknown restart setting");
+        }
+}
+
 static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
         int r;
         assert(s);
@@ -1222,18 +1325,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
                 failure_action(UNIT(s)->manager, s->failure_action, s->reboot_arg);
         }
 
-        if (allow_restart &&
-            !s->forbid_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_ABNORMAL && !IN_SET(s->result, SERVICE_SUCCESS, SERVICE_FAILURE_EXIT_CODE)) ||
-             (s->restart == SERVICE_RESTART_ON_WATCHDOG && s->result == SERVICE_FAILURE_WATCHDOG) ||
-             (s->restart == SERVICE_RESTART_ON_ABORT && IN_SET(s->result, SERVICE_FAILURE_SIGNAL, SERVICE_FAILURE_CORE_DUMP)) ||
-             (s->main_exec_status.code == CLD_EXITED && set_contains(s->restart_force_status.status, INT_TO_PTR(s->main_exec_status.status))) ||
-             (IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) && set_contains(s->restart_force_status.signal, INT_TO_PTR(s->main_exec_status.status)))) &&
-            (s->main_exec_status.code != CLD_EXITED || !set_contains(s->restart_prevent_status.status, INT_TO_PTR(s->main_exec_status.status))) &&
-            (!IN_SET(s->main_exec_status.code, CLD_KILLED, CLD_DUMPED) || !set_contains(s->restart_prevent_status.signal, INT_TO_PTR(s->main_exec_status.status)))) {
+        if (allow_restart && service_shall_restart(s)) {
 
                 r = service_arm_timer(s, s->restart_usec);
                 if (r < 0)
@@ -1301,6 +1393,25 @@ fail:
         service_enter_signal(s, SERVICE_FINAL_SIGTERM, SERVICE_FAILURE_RESOURCES);
 }
 
+static int state_to_kill_operation(ServiceState state) {
+        switch (state) {
+
+        case SERVICE_STOP_SIGABRT:
+                return KILL_ABORT;
+
+        case SERVICE_STOP_SIGTERM:
+        case SERVICE_FINAL_SIGTERM:
+                return KILL_TERMINATE;
+
+        case SERVICE_STOP_SIGKILL:
+        case SERVICE_FINAL_SIGKILL:
+                return KILL_KILL;
+
+        default:
+                return _KILL_OPERATION_INVALID;
+        }
+}
+
 static void service_enter_signal(Service *s, ServiceState state, ServiceResult f) {
         int r;
 
@@ -1314,8 +1425,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
         r = unit_kill_context(
                         UNIT(s),
                         &s->kill_context,
-                        (state != SERVICE_STOP_SIGTERM && state != SERVICE_FINAL_SIGTERM && state != SERVICE_STOP_SIGABRT) ?
-                        KILL_KILL : (state == SERVICE_STOP_SIGABRT ? KILL_ABORT : KILL_TERMINATE),
+                        state_to_kill_operation(state),
                         s->main_pid,
                         s->control_pid,
                         s->main_pid_alien);
@@ -1331,11 +1441,11 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
                 }
 
                 service_set_state(s, state);
-        } else if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGABRT)
+        } else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM) && s->kill_context.send_sigkill)
                 service_enter_signal(s, SERVICE_STOP_SIGKILL, SERVICE_SUCCESS);
-        else if (state == SERVICE_STOP_SIGKILL)
+        else if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
                 service_enter_stop_post(s, SERVICE_SUCCESS);
-        else if (state == SERVICE_FINAL_SIGTERM)
+        else if (state == SERVICE_FINAL_SIGTERM && s->kill_context.send_sigkill)
                 service_enter_signal(s, SERVICE_FINAL_SIGKILL, SERVICE_SUCCESS);
         else
                 service_enter_dead(s, SERVICE_SUCCESS, true);
@@ -1345,8 +1455,7 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
 fail:
         log_unit_warning_errno(UNIT(s)->id, r, "%s failed to kill processes: %m", UNIT(s)->id);
 
-        if (state == SERVICE_STOP_SIGTERM || state == SERVICE_STOP_SIGKILL ||
-            state == SERVICE_STOP_SIGABRT)
+        if (IN_SET(state, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL))
                 service_enter_stop_post(s, SERVICE_FAILURE_RESOURCES);
         else
                 service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@@ -1470,7 +1579,7 @@ static void service_kill_control_processes(Service *s) {
         if (!UNIT(s)->cgroup_path)
                 return;
 
-        p = strappenda(UNIT(s)->cgroup_path, "/control");
+        p = strjoina(UNIT(s)->cgroup_path, "/control");
         cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, p, SIGKILL, true, true, true, NULL);
 }
 
@@ -1771,19 +1880,13 @@ static int service_start(Unit *u) {
 
         /* We cannot fulfill this request right now, try again later
          * please! */
-        if (s->state == SERVICE_STOP ||
-            s->state == SERVICE_STOP_SIGABRT ||
-            s->state == SERVICE_STOP_SIGTERM ||
-            s->state == SERVICE_STOP_SIGKILL ||
-            s->state == SERVICE_STOP_POST ||
-            s->state == SERVICE_FINAL_SIGTERM ||
-            s->state == SERVICE_FINAL_SIGKILL)
+        if (IN_SET(s->state,
+                   SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                   SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
                 return -EAGAIN;
 
         /* Already on it! */
-        if (s->state == SERVICE_START_PRE ||
-            s->state == SERVICE_START ||
-            s->state == SERVICE_START_POST)
+        if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST))
                 return 0;
 
         /* A service that will be restarted must be stopped first to
@@ -1796,7 +1899,7 @@ static int service_start(Unit *u) {
         if (s->state == SERVICE_AUTO_RESTART)
                 return -EAGAIN;
 
-        assert(s->state == SERVICE_DEAD || s->state == SERVICE_FAILED);
+        assert(IN_SET(s->state, SERVICE_DEAD, SERVICE_FAILED));
 
         /* Make sure we don't enter a busy loop of some kind. */
         r = service_start_limit_test(s);
@@ -1810,6 +1913,7 @@ static int service_start(Unit *u) {
         s->main_pid_known = false;
         s->main_pid_alien = false;
         s->forbid_restart = false;
+        s->reset_cpu_usage = true;
 
         free(s->status_text);
         s->status_text = NULL;
@@ -1818,7 +1922,7 @@ static int service_start(Unit *u) {
         s->notify_state = NOTIFY_UNKNOWN;
 
         service_enter_start_pre(s);
-        return 0;
+        return 1;
 }
 
 static int service_stop(Unit *u) {
@@ -1826,17 +1930,13 @@ static int service_stop(Unit *u) {
 
         assert(s);
 
-        /* Don't create restart jobs from here. */
+        /* Don't create restart jobs from manual stops. */
         s->forbid_restart = true;
 
         /* Already on it */
-        if (s->state == SERVICE_STOP ||
-            s->state == SERVICE_STOP_SIGABRT ||
-            s->state == SERVICE_STOP_SIGTERM ||
-            s->state == SERVICE_STOP_SIGKILL ||
-            s->state == SERVICE_STOP_POST ||
-            s->state == SERVICE_FINAL_SIGTERM ||
-            s->state == SERVICE_FINAL_SIGKILL)
+        if (IN_SET(s->state,
+                   SERVICE_STOP, SERVICE_STOP_SIGABRT, SERVICE_STOP_SIGTERM, SERVICE_STOP_SIGKILL, SERVICE_STOP_POST,
+                   SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL))
                 return 0;
 
         /* A restart will be scheduled or is in progress. */
@@ -1847,19 +1947,15 @@ static int service_stop(Unit *u) {
 
         /* If there's already something running we go directly into
          * kill mode. */
-        if (s->state == SERVICE_START_PRE ||
-            s->state == SERVICE_START ||
-            s->state == SERVICE_START_POST ||
-            s->state == SERVICE_RELOAD) {
+        if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START, SERVICE_START_POST, SERVICE_RELOAD)) {
                 service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_SUCCESS);
                 return 0;
         }
 
-        assert(s->state == SERVICE_RUNNING ||
-               s->state == SERVICE_EXITED);
+        assert(IN_SET(s->state, SERVICE_RUNNING, SERVICE_EXITED));
 
         service_enter_stop(s, SERVICE_SUCCESS);
-        return 0;
+        return 1;
 }
 
 static int service_reload(Unit *u) {
@@ -1894,8 +1990,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
         unit_serialize_item(u, f, "reload-result", service_result_to_string(s->reload_result));
 
         if (s->control_pid > 0)
-                unit_serialize_item_format(u, f, "control-pid", PID_FMT,
-                                           s->control_pid);
+                unit_serialize_item_format(u, f, "control-pid", PID_FMT, s->control_pid);
 
         if (s->main_pid_known && s->main_pid > 0)
                 unit_serialize_item_format(u, f, "main-pid", PID_FMT, s->main_pid);
@@ -1909,8 +2004,7 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
          * multiple commands attached here, we will start from the
          * first one again */
         if (s->control_command_id >= 0)
-                unit_serialize_item(u, f, "control-command",
-                                    service_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;
@@ -1943,20 +2037,16 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
         }
 
         if (s->main_exec_status.pid > 0) {
-                unit_serialize_item_format(u, f, "main-exec-status-pid", PID_FMT,
-                                           s->main_exec_status.pid);
-                dual_timestamp_serialize(f, "main-exec-status-start",
-                                         &s->main_exec_status.start_timestamp);
-                dual_timestamp_serialize(f, "main-exec-status-exit",
-                                         &s->main_exec_status.exit_timestamp);
+                unit_serialize_item_format(u, f, "main-exec-status-pid", PID_FMT, s->main_exec_status.pid);
+                dual_timestamp_serialize(f, "main-exec-status-start", &s->main_exec_status.start_timestamp);
+                dual_timestamp_serialize(f, "main-exec-status-exit", &s->main_exec_status.exit_timestamp);
 
                 if (dual_timestamp_is_set(&s->main_exec_status.exit_timestamp)) {
-                        unit_serialize_item_format(u, f, "main-exec-status-code", "%i",
-                                                   s->main_exec_status.code);
-                        unit_serialize_item_format(u, f, "main-exec-status-status", "%i",
-                                                   s->main_exec_status.status);
+                        unit_serialize_item_format(u, f, "main-exec-status-code", "%i", s->main_exec_status.code);
+                        unit_serialize_item_format(u, f, "main-exec-status-status", "%i", s->main_exec_status.status);
                 }
         }
+
         if (dual_timestamp_is_set(&s->watchdog_timestamp))
                 dual_timestamp_serialize(f, "watchdog-timestamp", &s->watchdog_timestamp);
 
@@ -2630,9 +2720,8 @@ static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *us
                 break;
 
         case SERVICE_STOP_SIGABRT:
-                log_unit_warning(UNIT(s)->id,
-                                 "%s stop-sigabrt timed out. Terminating.", UNIT(s)->id);
-                service_enter_signal(s, SERVICE_STOP_SIGTERM, s->result);
+                log_unit_warning(UNIT(s)->id, "%s stop-sigabrt timed out. Terminating.", UNIT(s)->id);
+                service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_TIMEOUT);
                 break;
 
         case SERVICE_STOP_SIGTERM: