]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/service.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / core / service.c
index 601ca2eb20e2a2b6f851997d57fb2a58765808d2..a68e5c9f3df75fb498f80dfa04ae0bddede6320b 100644 (file)
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
 /***
   This file is part of systemd.
 
@@ -21,6 +22,8 @@
 #include <signal.h>
 #include <unistd.h>
 
+#include "sd-messages.h"
+
 #include "alloc-util.h"
 #include "async.h"
 #include "bus-error.h"
@@ -157,7 +160,7 @@ static int service_set_main_pid(Service *s, pid_t pid) {
         if (pid <= 1)
                 return -EINVAL;
 
-        if (pid == getpid())
+        if (pid == getpid_cached())
                 return -EINVAL;
 
         if (s->main_pid == pid && s->main_pid_known)
@@ -171,7 +174,7 @@ static int service_set_main_pid(Service *s, pid_t pid) {
         s->main_pid = pid;
         s->main_pid_known = true;
 
-        if (get_process_ppid(pid, &ppid) >= 0 && ppid != getpid()) {
+        if (get_process_ppid(pid, &ppid) >= 0 && ppid != getpid_cached()) {
                 log_unit_warning(UNIT(s), "Supervising process "PID_FMT" which is not our child. We'll most likely not notice when it exits.", pid);
                 s->main_pid_alien = true;
         } else
@@ -216,7 +219,7 @@ static void service_start_watchdog(Service *s) {
         assert(s);
 
         watchdog_usec = service_get_watchdog_usec(s);
-        if (watchdog_usec == 0 || watchdog_usec == USEC_INFINITY)
+        if (IN_SET(watchdog_usec, 0, USEC_INFINITY))
                 return;
 
         if (s->watchdog_event_source) {
@@ -292,6 +295,9 @@ static void service_fd_store_unlink(ServiceFDStore *fs) {
 static void service_release_fd_store(Service *s) {
         assert(s);
 
+        if (s->n_keep_fd_store > 0)
+                return;
+
         log_unit_debug(UNIT(s), "Releasing all stored fds");
         while (s->fd_store)
                 service_fd_store_unlink(s->fd_store);
@@ -299,7 +305,7 @@ static void service_release_fd_store(Service *s) {
         assert(s->n_fd_store == 0);
 }
 
-static void service_release_resources(Unit *u, bool inactive) {
+static void service_release_resources(Unit *u) {
         Service *s = SERVICE(u);
 
         assert(s);
@@ -313,8 +319,7 @@ static void service_release_resources(Unit *u, bool inactive) {
         s->stdout_fd = safe_close(s->stdout_fd);
         s->stderr_fd = safe_close(s->stderr_fd);
 
-        if (inactive)
-                service_release_fd_store(s);
+        service_release_fd_store(s);
 }
 
 static void service_done(Unit *u) {
@@ -358,7 +363,7 @@ static void service_done(Unit *u) {
 
         s->timer_event_source = sd_event_source_unref(s->timer_event_source);
 
-        service_release_resources(u, true);
+        service_release_resources(u);
 }
 
 static int on_fd_store_io(sd_event_source *e, int fd, uint32_t revents, void *userdata) {
@@ -527,7 +532,7 @@ static int service_verify(Service *s) {
         if (s->bus_name && s->type != SERVICE_DBUS)
                 log_unit_warning(UNIT(s), "Service has a D-Bus service name specified, but is not of type dbus. Ignoring.");
 
-        if (s->exec_context.pam_name && !(s->kill_context.kill_mode == KILL_CONTROL_GROUP || s->kill_context.kill_mode == KILL_MIXED)) {
+        if (s->exec_context.pam_name && !IN_SET(s->kill_context.kill_mode, KILL_CONTROL_GROUP, KILL_MIXED)) {
                 log_unit_error(UNIT(s), "Service has PAM enabled. Kill mode must be set to 'control-group' or 'mixed'. Refusing.");
                 return -EINVAL;
         }
@@ -560,7 +565,7 @@ static int service_add_default_dependencies(Service *s) {
                  * require it, so that we fail if we can't acquire
                  * it. */
 
-                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
+                r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                 if (r < 0)
                         return r;
         } else {
@@ -568,7 +573,7 @@ static int service_add_default_dependencies(Service *s) {
                 /* In the --user instance there's no sysinit.target,
                  * in that case require basic.target instead. */
 
-                r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true);
+                r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_BASIC_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
                 if (r < 0)
                         return r;
         }
@@ -576,12 +581,12 @@ static int service_add_default_dependencies(Service *s) {
         /* Second, if the rest of the base system is in the same
          * transaction, order us after it, but do not pull it in or
          * even require it. */
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_BASIC_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
         if (r < 0)
                 return r;
 
         /* Third, add us in for normal shutdown. */
-        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
+        return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true, UNIT_DEPENDENCY_DEFAULT);
 }
 
 static void service_fix_output(Service *s) {
@@ -610,12 +615,12 @@ static int service_setup_bus_name(Service *s) {
         if (!s->bus_name)
                 return 0;
 
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true, UNIT_DEPENDENCY_FILE);
         if (r < 0)
                 return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
 
-        /* Regardless if kdbus is used or not, we always want to be ordered against dbus.socket if both are in the transaction. */
-        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true);
+        /* We always want to be ordered against dbus.socket if both are in the transaction. */
+        r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true, UNIT_DEPENDENCY_FILE);
         if (r < 0)
                 return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
 
@@ -801,6 +806,8 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
                         "%sFile Descriptor Store Current: %u\n",
                         prefix, s->n_fd_store_max,
                         prefix, s->n_fd_store);
+
+        cgroup_context_dump(&s->cgroup_context, f, prefix);
 }
 
 static int service_load_pid_file(Service *s, bool may_warn) {
@@ -1099,11 +1106,12 @@ static int service_collect_fds(Service *s,
                 rn_socket_fds = 1;
         } else {
                 Iterator i;
+                void *v;
                 Unit *u;
 
                 /* Pass all our configured sockets for singleton services */
 
-                SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) {
+                HASHMAP_FOREACH_KEY(v, u, UNIT(s)->dependencies[UNIT_TRIGGERED_BY], i) {
                         _cleanup_free_ int *cfds = NULL;
                         Socket *sock;
                         int cn_fds;
@@ -1216,7 +1224,6 @@ static int service_spawn(
         _cleanup_strv_free_ char **final_env = NULL, **our_env = NULL, **fd_names = NULL;
         _cleanup_free_ int *fds = NULL;
         unsigned n_storage_fds = 0, n_socket_fds = 0, n_env = 0;
-        const char *path;
         pid_t pid;
 
         ExecParameters exec_params = {
@@ -1235,17 +1242,20 @@ static int service_spawn(
         if (flags & EXEC_IS_CONTROL) {
                 /* If this is a control process, mask the permissions/chroot application if this is requested. */
                 if (s->permissions_start_only)
-                        exec_params.flags &= ~EXEC_APPLY_PERMISSIONS;
+                        exec_params.flags &= ~EXEC_APPLY_SANDBOXING;
                 if (s->root_directory_start_only)
                         exec_params.flags &= ~EXEC_APPLY_CHROOT;
         }
 
         (void) unit_realize_cgroup(UNIT(s));
-        if (s->reset_cpu_usage) {
-                (void) unit_reset_cpu_usage(UNIT(s));
-                s->reset_cpu_usage = false;
+        if (s->reset_accounting) {
+                (void) unit_reset_cpu_accounting(UNIT(s));
+                (void) unit_reset_ip_accounting(UNIT(s));
+                s->reset_accounting = false;
         }
 
+        unit_export_state_files(UNIT(s));
+
         r = unit_setup_exec_runtime(UNIT(s));
         if (r < 0)
                 return r;
@@ -1283,24 +1293,21 @@ static int service_spawn(
                         return -ENOMEM;
 
         if (MANAGER_IS_USER(UNIT(s)->manager))
-                if (asprintf(our_env + n_env++, "MANAGERPID="PID_FMT, getpid()) < 0)
+                if (asprintf(our_env + n_env++, "MANAGERPID="PID_FMT, getpid_cached()) < 0)
                         return -ENOMEM;
 
         if (s->socket_fd >= 0) {
                 union sockaddr_union sa;
                 socklen_t salen = sizeof(sa);
 
-                r = getpeername(s->socket_fd, &sa.sa, &salen);
-                if (r < 0) {
-                        r = -errno;
+                /* If this is a per-connection service instance, let's set $REMOTE_ADDR and $REMOTE_PORT to something
+                 * useful. Note that we do this only when we are still connected at this point in time, which we might
+                 * very well not be. Hence we ignore all errors when retrieving peer information (as that might result
+                 * in ENOTCONN), and just use whate we can use. */
 
-                        /* ENOTCONN is legitimate if the endpoint disappeared on shutdown.
-                         * This connection is over, but the socket unit lives on. */
-                        if (r != -ENOTCONN || !IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST))
-                                return r;
-                }
+                if (getpeername(s->socket_fd, &sa.sa, &salen) >= 0 &&
+                    IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
 
-                if (r == 0 && IN_SET(sa.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
                         _cleanup_free_ char *addr = NULL;
                         char *t;
                         unsigned port;
@@ -1342,28 +1349,31 @@ static int service_spawn(
                 }
         }
 
-        final_env = strv_env_merge(2, UNIT(s)->manager->environment, our_env, NULL);
+        manager_set_exec_params(UNIT(s)->manager, &exec_params);
+        unit_set_exec_params(UNIT(s), &exec_params);
+
+        final_env = strv_env_merge(2, exec_params.environment, our_env, NULL);
         if (!final_env)
                 return -ENOMEM;
 
         if ((flags & EXEC_IS_CONTROL) && UNIT(s)->cgroup_path) {
-                path = strjoina(UNIT(s)->cgroup_path, "/control");
-                (void) cg_create(SYSTEMD_CGROUP_CONTROLLER, path);
-        } else
-                path = UNIT(s)->cgroup_path;
+                exec_params.cgroup_path = strjoina(UNIT(s)->cgroup_path, "/control");
+                (void) cg_create(SYSTEMD_CGROUP_CONTROLLER, exec_params.cgroup_path);
+        }
+
+        /* System services should get a new keyring by default. */
+        SET_FLAG(exec_params.flags, EXEC_NEW_KEYRING, MANAGER_IS_SYSTEM(UNIT(s)->manager));
+
+        /* System D-Bus needs nss-systemd disabled, so that we don't deadlock */
+        SET_FLAG(exec_params.flags, EXEC_NSS_BYPASS_BUS,
+                 MANAGER_IS_SYSTEM(UNIT(s)->manager) && unit_has_name(UNIT(s), SPECIAL_DBUS_SERVICE));
 
-        exec_params.flags |= MANAGER_IS_SYSTEM(UNIT(s)->manager) ? EXEC_NEW_KEYRING : 0;
         exec_params.argv = c->argv;
         exec_params.environment = final_env;
         exec_params.fds = fds;
         exec_params.fd_names = fd_names;
         exec_params.n_storage_fds = n_storage_fds;
         exec_params.n_socket_fds = n_socket_fds;
-        exec_params.confirm_spawn = manager_get_confirm_spawn(UNIT(s)->manager);
-        exec_params.cgroup_supported = UNIT(s)->manager->cgroup_supported;
-        exec_params.cgroup_path = path;
-        exec_params.cgroup_delegate = s->cgroup_context.delegate;
-        exec_params.runtime_prefix = manager_get_runtime_prefix(UNIT(s)->manager);
         exec_params.watchdog_usec = s->watchdog_usec;
         exec_params.selinux_context_net = s->socket_fd_selinux_context_net;
         if (s->type == SERVICE_IDLE)
@@ -1394,8 +1404,7 @@ static int service_spawn(
 static int main_pid_good(Service *s) {
         assert(s);
 
-        /* Returns 0 if the pid is dead, 1 if it is good, -1 if we
-         * don't know */
+        /* Returns 0 if the pid is dead, > 0 if it is good, < 0 if we don't know */
 
         /* If we know the pid file, then let's just check if it is
          * still valid */
@@ -1416,9 +1425,13 @@ static int main_pid_good(Service *s) {
         return -EAGAIN;
 }
 
-_pure_ static int control_pid_good(Service *s) {
+static int control_pid_good(Service *s) {
         assert(s);
 
+        /* Returns 0 if the control PID is dead, > 0 if it is good. We never actually return < 0 here, but in order to
+         * make this function as similar as possible to main_pid_good() and cgroup_good(), we pretend that < 0 also
+         * means: we can't figure it out. */
+
         return s->control_pid > 0;
 }
 
@@ -1427,6 +1440,9 @@ static int cgroup_good(Service *s) {
 
         assert(s);
 
+        /* Returns 0 if the cgroup is empty or doesn't exist, > 0 if it is exists and is populated, < 0 if we can't
+         * figure it out */
+
         if (!UNIT(s)->cgroup_path)
                 return 0;
 
@@ -1434,7 +1450,7 @@ static int cgroup_good(Service *s) {
         if (r < 0)
                 return r;
 
-        return !r;
+        return r == 0;
 }
 
 static bool service_shall_restart(Service *s) {
@@ -1494,26 +1510,47 @@ static bool service_will_restart(Service *s) {
 
 static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart) {
         int r;
+
         assert(s);
 
+        /* If there's a stop job queued before we enter the DEAD state, we shouldn't act on Restart=, in order to not
+         * undo what has already been enqueued. */
+        if (unit_stop_pending(UNIT(s)))
+                allow_restart = false;
+
         if (s->result == SERVICE_SUCCESS)
                 s->result = f;
 
+        if (s->result != SERVICE_SUCCESS)
+                log_unit_warning(UNIT(s), "Failed with result '%s'.", service_result_to_string(s->result));
+
+        /* Make sure service_release_resources() doesn't destroy our FD store, while we are changing through
+         * SERVICE_FAILED/SERVICE_DEAD before entering into SERVICE_AUTO_RESTART. */
+        s->n_keep_fd_store ++;
+
         service_set_state(s, s->result != SERVICE_SUCCESS ? SERVICE_FAILED : SERVICE_DEAD);
 
-        if (s->result != SERVICE_SUCCESS) {
-                log_unit_warning(UNIT(s), "Failed with result '%s'.", service_result_to_string(s->result));
+        if (s->result != SERVICE_SUCCESS)
                 emergency_action(UNIT(s)->manager, s->emergency_action, UNIT(s)->reboot_arg, "service failed");
-        }
 
         if (allow_restart && service_shall_restart(s)) {
 
                 r = service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->restart_usec));
-                if (r < 0)
+                if (r < 0) {
+                        s->n_keep_fd_store--;
                         goto fail;
+                }
 
                 service_set_state(s, SERVICE_AUTO_RESTART);
-        }
+        } else
+                /* If we shan't restart, then flush out the restart counter. But don't do that immediately, so that the
+                 * user can still introspect the counter. Do so on the next start. */
+                s->flush_n_restarts = true;
+
+        /* The new state is in effect, let's decrease the fd store ref counter again. Let's also readd us to the GC
+         * queue, so that the fd store is possibly gc'ed again */
+        s->n_keep_fd_store--;
+        unit_add_to_gc_queue(UNIT(s));
 
         /* The next restart might not be a manual stop, hence reset the flag indicating manual stops */
         s->forbid_restart = false;
@@ -1525,7 +1562,7 @@ static void service_enter_dead(Service *s, ServiceResult f, bool allow_restart)
         if (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_NO ||
             (s->exec_context.runtime_directory_preserve_mode == EXEC_PRESERVE_RESTART && !service_will_restart(s)))
                 /* Also, remove the runtime directory */
-                exec_context_destroy_runtime_directory(&s->exec_context, manager_get_runtime_prefix(UNIT(s)->manager));
+                exec_context_destroy_runtime_directory(&s->exec_context, UNIT(s)->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
 
         /* Get rid of the IPC bits of the user */
         unit_unref_uid_gid(UNIT(s), true);
@@ -1563,7 +1600,7 @@ static void service_enter_stop_post(Service *s, ServiceResult f) {
                 r = service_spawn(s,
                                   s->control_command,
                                   s->timeout_stop_usec,
-                                  EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT,
+                                  EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_IS_CONTROL|EXEC_SETENV_RESULT,
                                   &s->control_pid);
                 if (r < 0)
                         goto fail;
@@ -1615,7 +1652,6 @@ static void service_enter_signal(Service *s, ServiceState state, ServiceResult f
                         s->main_pid,
                         s->control_pid,
                         s->main_pid_alien);
-
         if (r < 0)
                 goto fail;
 
@@ -1674,7 +1710,7 @@ static void service_enter_stop(Service *s, ServiceResult f) {
                 r = service_spawn(s,
                                   s->control_command,
                                   s->timeout_stop_usec,
-                                  EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT,
+                                  EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_SETENV_RESULT,
                                   &s->control_pid);
                 if (r < 0)
                         goto fail;
@@ -1753,7 +1789,7 @@ static void service_enter_start_post(Service *s) {
                 r = service_spawn(s,
                                   s->control_command,
                                   s->timeout_start_usec,
-                                  EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL,
+                                  EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL,
                                   &s->control_pid);
                 if (r < 0)
                         goto fail;
@@ -1770,13 +1806,39 @@ fail:
 }
 
 static void service_kill_control_processes(Service *s) {
-        char *p;
+        int r;
 
-        if (!UNIT(s)->cgroup_path)
-                return;
+        assert(s);
 
-        p = strjoina(UNIT(s)->cgroup_path, "/control");
-        cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, p, SIGKILL, CGROUP_SIGCONT|CGROUP_IGNORE_SELF|CGROUP_REMOVE, NULL, NULL, NULL);
+        if (s->control_pid > 0) {
+                r = kill_and_sigcont(s->control_pid, SIGKILL);
+                if (r < 0) {
+                        _cleanup_free_ char *comm = NULL;
+
+                        (void) get_process_comm(s->control_pid, &comm);
+
+                        log_unit_debug_errno(UNIT(s), r, "Failed to kill control process " PID_FMT " (%s), ignoring: %m",
+                                             s->control_pid, strna(comm));
+                }
+        }
+
+        if (UNIT(s)->cgroup_path) {
+                _cleanup_set_free_ Set *pid_set = NULL;
+                char *p;
+
+                if (s->control_pid > 0) {
+                        r = set_make(&pid_set, PID_TO_PTR(s->control_pid), NULL);
+                        if (r < 0) {
+                                log_oom();
+                                return;
+                        }
+                }
+
+                p = strjoina(UNIT(s)->cgroup_path, "/control");
+                r = cg_kill_recursive(SYSTEMD_CGROUP_CONTROLLER, p, SIGKILL, CGROUP_SIGCONT|CGROUP_IGNORE_SELF|CGROUP_REMOVE, pid_set, NULL, NULL);
+                if (r < 0)
+                        log_unit_debug_errno(UNIT(s), r, "Failed to send SIGKILL to processes of control group %s: %m", p);
+        }
 }
 
 static void service_enter_start(Service *s) {
@@ -1831,7 +1893,7 @@ static void service_enter_start(Service *s) {
         r = service_spawn(s,
                           c,
                           timeout,
-                          EXEC_PASS_FDS|EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_SET_WATCHDOG,
+                          EXEC_PASS_FDS|EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_SET_WATCHDOG,
                           &pid);
         if (r < 0)
                 goto fail;
@@ -1890,7 +1952,7 @@ static void service_enter_start_pre(Service *s) {
                 r = service_spawn(s,
                                   s->control_command,
                                   s->timeout_start_usec,
-                                  EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_APPLY_TTY_STDIN,
+                                  EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|EXEC_APPLY_TTY_STDIN,
                                   &s->control_pid);
                 if (r < 0)
                         goto fail;
@@ -1931,11 +1993,27 @@ static void service_enter_restart(Service *s) {
         if (r < 0)
                 goto fail;
 
+        /* Count the jobs we enqueue for restarting. This counter is maintained as long as the unit isn't fully
+         * stopped, i.e. as long as it remains up or remains in auto-start states. The use can reset the counter
+         * explicitly however via the usual "systemctl reset-failure" logic. */
+        s->n_restarts ++;
+        s->flush_n_restarts = false;
+
+        log_struct(LOG_INFO,
+                   "MESSAGE_ID=" SD_MESSAGE_UNIT_RESTART_SCHEDULED_STR,
+                   LOG_UNIT_ID(UNIT(s)),
+                   LOG_UNIT_INVOCATION_ID(UNIT(s)),
+                   LOG_UNIT_MESSAGE(UNIT(s), "Scheduled restart job, restart counter is at %u.", s->n_restarts),
+                   "N_RESTARTS=%u", s->n_restarts,
+                   NULL);
+
+        /* Notify clients about changed restart counter */
+        unit_add_to_dbus_queue(UNIT(s));
+
         /* Note that we stay in the SERVICE_AUTO_RESTART state here,
          * it will be canceled as part of the service_stop() call that
          * is executed as part of JOB_RESTART. */
 
-        log_unit_debug(UNIT(s), "Scheduled restart job.");
         return;
 
 fail:
@@ -1944,10 +2022,18 @@ fail:
 }
 
 static void service_enter_reload_by_notify(Service *s) {
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
+
         assert(s);
 
         service_arm_timer(s, usec_add(now(CLOCK_MONOTONIC), s->timeout_start_usec));
         service_set_state(s, SERVICE_RELOAD);
+
+        /* service_enter_reload_by_notify is never called during a reload, thus no loops are possible. */
+        r = manager_propagate_reload(UNIT(s)->manager, UNIT(s), JOB_FAIL, &error);
+        if (r < 0)
+                log_unit_warning(UNIT(s), "Failed to schedule propagation of reload: %s", bus_error_message(&error, -r));
 }
 
 static void service_enter_reload(Service *s) {
@@ -1965,7 +2051,7 @@ static void service_enter_reload(Service *s) {
                 r = service_spawn(s,
                                   s->control_command,
                                   s->timeout_start_usec,
-                                  EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL,
+                                  EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL,
                                   &s->control_pid);
                 if (r < 0)
                         goto fail;
@@ -2003,7 +2089,7 @@ static void service_run_next_control(Service *s) {
         r = service_spawn(s,
                           s->control_command,
                           timeout,
-                          EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|
+                          EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_IS_CONTROL|
                           (IN_SET(s->control_command_id, SERVICE_EXEC_START_PRE, SERVICE_EXEC_STOP_POST) ? EXEC_APPLY_TTY_STDIN : 0)|
                           (IN_SET(s->control_command_id, SERVICE_EXEC_STOP, SERVICE_EXEC_STOP_POST) ? EXEC_SETENV_RESULT : 0),
                           &s->control_pid);
@@ -2015,7 +2101,7 @@ static void service_run_next_control(Service *s) {
 fail:
         log_unit_warning_errno(UNIT(s), r, "Failed to run next control task: %m");
 
-        if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_STOP))
+        if (IN_SET(s->state, SERVICE_START_PRE, SERVICE_START_POST, SERVICE_STOP))
                 service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_RESOURCES);
         else if (s->state == SERVICE_STOP_POST)
                 service_enter_dead(s, SERVICE_FAILURE_RESOURCES, true);
@@ -2041,7 +2127,7 @@ static void service_run_next_main(Service *s) {
         r = service_spawn(s,
                           s->main_command,
                           s->timeout_start_usec,
-                          EXEC_PASS_FDS|EXEC_APPLY_PERMISSIONS|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_SET_WATCHDOG,
+                          EXEC_PASS_FDS|EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN|EXEC_SET_WATCHDOG,
                           &pid);
         if (r < 0)
                 goto fail;
@@ -2100,7 +2186,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;
+        s->reset_accounting = true;
 
         s->status_text = mfree(s->status_text);
         s->status_errno = 0;
@@ -2110,6 +2196,12 @@ static int service_start(Unit *u) {
         s->watchdog_override_enable = false;
         s->watchdog_override_usec = 0;
 
+        /* This is not an automatic restart? Flush the restart counter then */
+        if (s->flush_n_restarts) {
+                s->n_restarts = 0;
+                s->flush_n_restarts = false;
+        }
+
         service_enter_start_pre(s);
         return 1;
 }
@@ -2152,7 +2244,7 @@ static int service_reload(Unit *u) {
 
         assert(s);
 
-        assert(s->state == SERVICE_RUNNING || s->state == SERVICE_EXITED);
+        assert(IN_SET(s->state, SERVICE_RUNNING, SERVICE_EXITED));
 
         service_enter_reload(s);
         return 1;
@@ -2262,6 +2354,9 @@ static int service_serialize(Unit *u, FILE *f, FDSet *fds) {
         unit_serialize_item(u, f, "bus-name-good", yes_no(s->bus_name_good));
         unit_serialize_item(u, f, "bus-name-owner", s->bus_name_owner);
 
+        unit_serialize_item_format(u, f, "n-restarts", "%u", s->n_restarts);
+        unit_serialize_item(u, f, "flush-n-restarts", yes_no(s->flush_n_restarts));
+
         r = unit_serialize_item_escaped(u, f, "status-text", s->status_text);
         if (r < 0)
                 return r;
@@ -2627,6 +2722,18 @@ static int service_deserialize_item(Unit *u, const char *key, const char *value,
                 r = service_deserialize_exec_command(u, key, value);
                 if (r < 0)
                         log_unit_debug_errno(u, r, "Failed to parse serialized command \"%s\": %m", value);
+
+        } else if (streq(key, "n-restarts")) {
+                r = safe_atou(value, &s->n_restarts);
+                if (r < 0)
+                        log_unit_debug_errno(u, r, "Failed to parse serialized restart counter '%s': %m", value);
+
+        } else if (streq(key, "flush-n-restarts")) {
+                r = parse_boolean(value);
+                if (r < 0)
+                        log_unit_debug_errno(u, r, "Failed to parse serialized flush restart counter setting '%s': %m", value);
+                else
+                        s->flush_n_restarts = r;
         } else
                 log_unit_debug(u, "Unknown serialization key: %s", key);
 
@@ -2668,7 +2775,7 @@ static int service_retry_pid_file(Service *s) {
         int r;
 
         assert(s->pid_file);
-        assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
+        assert(IN_SET(s->state, SERVICE_START, SERVICE_START_POST));
 
         r = service_load_pid_file(s, false);
         if (r < 0)
@@ -2739,7 +2846,7 @@ static int service_dispatch_io(sd_event_source *source, int fd, uint32_t events,
 
         assert(s);
         assert(fd >= 0);
-        assert(s->state == SERVICE_START || s->state == SERVICE_START_POST);
+        assert(IN_SET(s->state, SERVICE_START, SERVICE_START_POST));
         assert(s->pid_file_pathspec);
         assert(path_spec_owns_inotify_fd(s->pid_file_pathspec, fd));
 
@@ -2778,7 +2885,9 @@ static void service_notify_cgroup_empty_event(Unit *u) {
                  * SIGCHLD for. */
 
         case SERVICE_START:
-                if (s->type == SERVICE_NOTIFY) {
+                if (s->type == SERVICE_NOTIFY &&
+                    main_pid_good(s) == 0 &&
+                    control_pid_good(s) == 0) {
                         /* No chance of getting a ready notification anymore */
                         service_enter_stop_post(s, SERVICE_FAILURE_PROTOCOL);
                         break;
@@ -2787,7 +2896,10 @@ static void service_notify_cgroup_empty_event(Unit *u) {
                 /* Fall through */
 
         case SERVICE_START_POST:
-                if (s->pid_file_pathspec) {
+                if (s->pid_file_pathspec &&
+                    main_pid_good(s) == 0 &&
+                    control_pid_good(s) == 0) {
+
                         /* Give up hoping for the daemon to write its PID file */
                         log_unit_warning(u, "Daemon never wrote its PID file. Failing.");
 
@@ -2808,7 +2920,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
         case SERVICE_STOP_SIGTERM:
         case SERVICE_STOP_SIGKILL:
 
-                if (main_pid_good(s) <= 0 && !control_pid_good(s))
+                if (main_pid_good(s) <= 0 && control_pid_good(s) <= 0)
                         service_enter_stop_post(s, SERVICE_SUCCESS);
 
                 break;
@@ -2816,7 +2928,7 @@ static void service_notify_cgroup_empty_event(Unit *u) {
         case SERVICE_STOP_POST:
         case SERVICE_FINAL_SIGTERM:
         case SERVICE_FINAL_SIGKILL:
-                if (main_pid_good(s) <= 0 && !control_pid_good(s))
+                if (main_pid_good(s) <= 0 && control_pid_good(s) <= 0)
                         service_enter_dead(s, SERVICE_SUCCESS, true);
 
                 break;
@@ -2863,7 +2975,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 
                         s->main_command->exec_status = s->main_exec_status;
 
-                        if (s->main_command->ignore)
+                        if (s->main_command->flags & EXEC_COMMAND_IGNORE_FAILURE)
                                 f = SERVICE_SUCCESS;
                 } else if (s->exec_command[SERVICE_EXEC_START]) {
 
@@ -2871,7 +2983,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                          * ignore the return value if this was
                          * configured for the starter process */
 
-                        if (s->exec_command[SERVICE_EXEC_START]->ignore)
+                        if (s->exec_command[SERVICE_EXEC_START]->flags & EXEC_COMMAND_IGNORE_FAILURE)
                                 f = SERVICE_SUCCESS;
                 }
 
@@ -2891,6 +3003,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                            "EXIT_CODE=%s", sigchld_code_to_string(code),
                            "EXIT_STATUS=%i", status,
                            LOG_UNIT_ID(u),
+                           LOG_UNIT_INVOCATION_ID(u),
                            NULL);
 
                 if (s->result == SERVICE_SUCCESS)
@@ -2898,6 +3011,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
 
                 if (s->main_command &&
                     s->main_command->command_next &&
+                    s->type == SERVICE_ONESHOT &&
                     f == SERVICE_SUCCESS) {
 
                         /* There is another command to *
@@ -2935,8 +3049,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                          * has been received */
                                         if (f != SERVICE_SUCCESS)
                                                 service_enter_signal(s, SERVICE_STOP_SIGTERM, f);
-                                        else if (!s->remain_after_exit)
-                                                /* The service has never been active */
+                                        else if (!s->remain_after_exit || s->notify_access == NOTIFY_MAIN)
+                                                /* The service has never been and will never be active */
                                                 service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL);
                                         break;
                                 }
@@ -2951,7 +3065,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                         case SERVICE_STOP_SIGTERM:
                         case SERVICE_STOP_SIGKILL:
 
-                                if (!control_pid_good(s))
+                                if (control_pid_good(s) <= 0)
                                         service_enter_stop_post(s, f);
 
                                 /* If there is still a control process, wait for that first */
@@ -2961,7 +3075,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                         case SERVICE_FINAL_SIGTERM:
                         case SERVICE_FINAL_SIGKILL:
 
-                                if (!control_pid_good(s))
+                                if (control_pid_good(s) <= 0)
                                         service_enter_dead(s, f, true);
                                 break;
 
@@ -2976,7 +3090,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                 if (s->control_command) {
                         exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
 
-                        if (s->control_command->ignore)
+                        if (s->control_command->flags & EXEC_COMMAND_IGNORE_FAILURE)
                                 f = SERVICE_SUCCESS;
                 }
 
@@ -3042,7 +3156,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                         r = service_load_pid_file(s, !has_start_post);
                                         if (!has_start_post && r < 0) {
                                                 r = service_demand_pid_file(s);
-                                                if (r < 0 || !cgroup_good(s))
+                                                if (r < 0 || cgroup_good(s) == 0)
                                                         service_enter_signal(s, SERVICE_STOP_SIGTERM, SERVICE_FAILURE_PROTOCOL);
                                                 break;
                                         }
@@ -3064,7 +3178,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                         r = service_load_pid_file(s, true);
                                         if (r < 0) {
                                                 r = service_demand_pid_file(s);
-                                                if (r < 0 || !cgroup_good(s))
+                                                if (r < 0 || cgroup_good(s) == 0)
                                                         service_enter_stop(s, SERVICE_FAILURE_PROTOCOL);
                                                 break;
                                         }
@@ -3125,7 +3239,7 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         /* If the PID set is empty now, then let's finish this off
            (On unified we use proper notifications) */
         if (cg_unified_controller(SYSTEMD_CGROUP_CONTROLLER) == 0 && set_isempty(u->pids))
-                service_notify_cgroup_empty_event(u);
+                unit_add_to_cgroup_empty_queue(u);
 }
 
 static int service_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
@@ -3283,7 +3397,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
                         log_unit_warning(u, "Failed to parse MAINPID= field in notification message: %s", e);
                 else if (pid == s->control_pid)
                         log_unit_warning(u, "A control process cannot also be the main process");
-                else if (pid == getpid() || pid == 1)
+                else if (pid == getpid_cached() || pid == 1)
                         log_unit_warning(u, "Service manager can't be main process, ignoring sd_notify() MAINPID= field");
                 else {
                         service_set_main_pid(s, pid);
@@ -3348,9 +3462,7 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags, FDSet *fds)
                 }
 
                 if (!streq_ptr(s->status_text, t)) {
-
                         free_and_replace(s->status_text, t);
-
                         notify_dbus = true;
                 }
         }
@@ -3460,10 +3572,11 @@ static void service_bus_name_owner_change(
 
         } else if (new_owner &&
                    s->main_pid <= 0 &&
-                   (s->state == SERVICE_START ||
-                    s->state == SERVICE_START_POST ||
-                    s->state == SERVICE_RUNNING ||
-                    s->state == SERVICE_RELOAD)) {
+                   IN_SET(s->state,
+                          SERVICE_START,
+                          SERVICE_START_POST,
+                          SERVICE_RUNNING,
+                          SERVICE_RELOAD)) {
 
                 _cleanup_(sd_bus_creds_unrefp) sd_bus_creds *creds = NULL;
                 pid_t pid;
@@ -3518,7 +3631,7 @@ int service_set_socket_fd(Service *s, int fd, Socket *sock, bool selinux_context
                         return r;
         }
 
-        r = unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false);
+        r = unit_add_two_dependencies(UNIT(sock), UNIT_BEFORE, UNIT_TRIGGERS, UNIT(s), false, UNIT_DEPENDENCY_IMPLICIT);
         if (r < 0)
                 return r;
 
@@ -3539,11 +3652,15 @@ static void service_reset_failed(Unit *u) {
 
         s->result = SERVICE_SUCCESS;
         s->reload_result = SERVICE_SUCCESS;
+        s->n_restarts = 0;
+        s->flush_n_restarts = false;
 }
 
 static int service_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
         Service *s = SERVICE(u);
 
+        assert(s);
+
         return unit_kill_common(u, who, signo, s->main_pid, s->control_pid, error);
 }