]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/manager.c
tree-wide: use TAKE_PTR() and TAKE_FD() macros
[thirdparty/systemd.git] / src / core / manager.c
index 6140d06a7f7f77130bfa67a4f57d3301a3655227..ff6761e1616baa0dbd69c23cf69a96b155329ad0 100644 (file)
@@ -426,6 +426,8 @@ static int enable_special_signals(Manager *m) {
         return 0;
 }
 
+#define RTSIG_IF_AVAILABLE(signum) (signum <= SIGRTMAX ? signum : -1)
+
 static int manager_setup_signals(Manager *m) {
         struct sigaction sa = {
                 .sa_handler = SIG_DFL,
@@ -479,22 +481,22 @@ static int manager_setup_signals(Manager *m) {
 
                         /* .. one free signal here ... */
 
-#if !defined(__hppa64__) && !defined(__hppa__)
-                        /* Apparently Linux on hppa has fewer RT
-                         * signals (SIGRTMAX is SIGRTMIN+25 there),
-                         * hence let's not try to make use of them
-                         * here. Since these commands are accessible
-                         * by different means and only really a safety
-                         * net, the missing functionality on hppa
-                         * shouldn't matter. */
-
-                        SIGRTMIN+26, /* systemd: set log target to journal-or-kmsg */
-                        SIGRTMIN+27, /* systemd: set log target to console */
-                        SIGRTMIN+28, /* systemd: set log target to kmsg */
-                        SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg (obsolete) */
+                        /* Apparently Linux on hppa had fewer RT signals until v3.18,
+                         * SIGRTMAX was SIGRTMIN+25, and then SIGRTMIN was lowered,
+                         * see commit v3.17-7614-g1f25df2eff.
+                         *
+                         * We cannot unconditionally make use of those signals here,
+                         * so let's use a runtime check. Since these commands are
+                         * accessible by different means and only really a safety
+                         * net, the missing functionality on hppa shouldn't matter.
+                         */
+
+                        RTSIG_IF_AVAILABLE(SIGRTMIN+26), /* systemd: set log target to journal-or-kmsg */
+                        RTSIG_IF_AVAILABLE(SIGRTMIN+27), /* systemd: set log target to console */
+                        RTSIG_IF_AVAILABLE(SIGRTMIN+28), /* systemd: set log target to kmsg */
+                        RTSIG_IF_AVAILABLE(SIGRTMIN+29), /* systemd: set log target to syslog-or-kmsg (obsolete) */
 
                         /* ... one free signal here SIGRTMIN+30 ... */
-#endif
                         -1);
         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
@@ -798,8 +800,8 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) {
         /* Note that we do not set up the notify fd here. We do that after deserialization,
          * since they might have gotten serialized across the reexec. */
 
-        *_m = m;
-        m = NULL;
+        *_m = TAKE_PTR(m);
+
         return 0;
 }
 
@@ -842,8 +844,7 @@ static int manager_setup_notify(Manager *m) {
                 if (r < 0)
                         return log_error_errno(errno, "SO_PASSCRED failed: %m");
 
-                m->notify_fd = fd;
-                fd = -1;
+                m->notify_fd = TAKE_FD(fd);
 
                 log_debug("Using notification socket %s", m->notify_socket);
         }
@@ -1669,6 +1670,42 @@ Unit *manager_get_unit(Manager *m, const char *name) {
         return hashmap_get(m->units, name);
 }
 
+static int manager_dispatch_target_deps_queue(Manager *m) {
+        Unit *u;
+        unsigned k;
+        int r = 0;
+
+        static const UnitDependency deps[] = {
+                UNIT_REQUIRED_BY,
+                UNIT_REQUISITE_OF,
+                UNIT_WANTED_BY,
+                UNIT_BOUND_BY
+        };
+
+        assert(m);
+
+        while ((u = m->target_deps_queue)) {
+                assert(u->in_target_deps_queue);
+
+                LIST_REMOVE(target_deps_queue, u->manager->target_deps_queue, u);
+                u->in_target_deps_queue = false;
+
+                for (k = 0; k < ELEMENTSOF(deps); k++) {
+                        Unit *target;
+                        Iterator i;
+                        void *v;
+
+                        HASHMAP_FOREACH_KEY(v, target, u->dependencies[deps[k]], i) {
+                                r = unit_add_default_target_dependency(u, target);
+                                if (r < 0)
+                                        return r;
+                        }
+                }
+        }
+
+        return r;
+}
+
 unsigned manager_dispatch_load_queue(Manager *m) {
         Unit *u;
         unsigned n = 0;
@@ -1692,6 +1729,11 @@ unsigned manager_dispatch_load_queue(Manager *m) {
         }
 
         m->dispatching_load_queue = false;
+
+        /* Dispatch the units waiting for their target dependencies to be added now, as all targets that we know about
+         * should be loaded and have aliases resolved */
+        (void) manager_dispatch_target_deps_queue(m);
+
         return n;
 }
 
@@ -1852,8 +1894,7 @@ int manager_get_dump_string(Manager *m, char **ret) {
 
         f = safe_fclose(f);
 
-        *ret = dump;
-        dump = NULL;
+        *ret = TAKE_PTR(dump);
 
         return 0;
 }
@@ -2334,8 +2375,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
 
         case SIGTERM:
                 if (MANAGER_IS_SYSTEM(m)) {
-                        /* This is for compatibility with the
-                         * original sysvinit */
+                        /* This is for compatibility with the original sysvinit */
                         r = verify_run_space_and_log("Refusing to reexecute");
                         if (r >= 0)
                                 m->exit_code = MANAGER_REEXECUTE;
@@ -2352,21 +2392,20 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
                 break;
 
         case SIGWINCH:
+                /* This is a nop on non-init */
                 if (MANAGER_IS_SYSTEM(m))
                         manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE);
 
-                /* This is a nop on non-init */
                 break;
 
         case SIGPWR:
+                /* This is a nop on non-init */
                 if (MANAGER_IS_SYSTEM(m))
                         manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE);
 
-                /* This is a nop on non-init */
                 break;
 
         case SIGUSR1:
-
                 if (manager_dbus_is_running(m, false)) {
                         log_info("Trying to reconnect to bus...");
 
@@ -3221,6 +3260,9 @@ int manager_reload(Manager *m) {
 
         exec_runtime_vacuum(m);
 
+        assert(m->n_reloading > 0);
+        m->n_reloading--;
+
         /* It might be safe to log to the journal now and connect to dbus */
         manager_recheck_journal(m);
         manager_recheck_dbus(m);
@@ -3230,9 +3272,6 @@ int manager_reload(Manager *m) {
         if (q < 0 && r >= 0)
                 r = q;
 
-        assert(m->n_reloading > 0);
-        m->n_reloading--;
-
         m->send_reloading_done = true;
 
         return r;
@@ -3596,6 +3635,9 @@ void manager_recheck_dbus(Manager *m) {
          * connection of the API bus). That's because the system bus after all runs as service of the system instance,
          * while in the user instance we can assume it's already there. */
 
+        if (MANAGER_IS_RELOADING(m))
+                return; /* don't check while we are reloading… */
+
         if (manager_dbus_is_running(m, false)) {
                 (void) bus_init_api(m);
 
@@ -3646,6 +3688,10 @@ void manager_recheck_journal(Manager *m) {
         if (getpid_cached() != 1)
                 return;
 
+        /* Don't check this while we are reloading, things might still change */
+        if (MANAGER_IS_RELOADING(m))
+                return;
+
         /* The journal is fully and entirely up? If so, let's permit logging to it, if that's configured. If the
          * journal is down, don't ever log to it, otherwise we might end up deadlocking ourselves as we might trigger
          * an activation ourselves we can't fulfill. */