]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/unit.c
core: add RootImage= setting for using a specific image file as root directory for...
[thirdparty/systemd.git] / src / core / unit.c
index da9bb58a5210e78dde6f5ddb59e14e3c0b38371c..90d7eea95629d27e59cc80e339c89627da9f391a 100644 (file)
@@ -389,10 +389,8 @@ void unit_add_to_gc_queue(Unit *u) {
         if (unit_check_gc(u))
                 return;
 
-        LIST_PREPEND(gc_queue, u->manager->gc_queue, u);
+        LIST_PREPEND(gc_queue, u->manager->gc_unit_queue, u);
         u->in_gc_queue = true;
-
-        u->manager->n_in_gc_queue++;
 }
 
 void unit_add_to_dbus_queue(Unit *u) {
@@ -518,7 +516,8 @@ void unit_free(Unit *u) {
         Iterator i;
         char *t;
 
-        assert(u);
+        if (!u)
+                return;
 
         if (u->transient_file)
                 fclose(u->transient_file);
@@ -570,10 +569,8 @@ void unit_free(Unit *u) {
         if (u->in_cleanup_queue)
                 LIST_REMOVE(cleanup_queue, u->manager->cleanup_queue, u);
 
-        if (u->in_gc_queue) {
-                LIST_REMOVE(gc_queue, u->manager->gc_queue, u);
-                u->manager->n_in_gc_queue--;
-        }
+        if (u->in_gc_queue)
+                LIST_REMOVE(gc_queue, u->manager->gc_unit_queue, u);
 
         if (u->in_cgroup_queue)
                 LIST_REMOVE(cgroup_queue, u->manager->cgroup_queue, u);
@@ -865,15 +862,25 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) {
                         return r;
         }
 
+        if (c->root_image) {
+                r = unit_require_mounts_for(u, c->root_image);
+                if (r < 0)
+                        return r;
+        }
+
         if (!MANAGER_IS_SYSTEM(u->manager))
                 return 0;
 
         if (c->private_tmp) {
-                r = unit_require_mounts_for(u, "/tmp");
-                if (r < 0)
-                        return r;
+                const char *p;
+
+                FOREACH_STRING(p, "/tmp", "/var/tmp") {
+                        r = unit_require_mounts_for(u, p);
+                        if (r < 0)
+                                return r;
+                }
 
-                r = unit_require_mounts_for(u, "/var/tmp");
+                r = unit_add_dependency_by_name(u, UNIT_AFTER, SPECIAL_TMPFILES_SETUP_SERVICE, NULL, true);
                 if (r < 0)
                         return r;
         }
@@ -1082,6 +1089,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
 
 /* Common implementation for multiple backends */
 int unit_load_fragment_and_dropin(Unit *u) {
+        Unit *t;
         int r;
 
         assert(u);
@@ -1094,16 +1102,18 @@ int unit_load_fragment_and_dropin(Unit *u) {
         if (u->load_state == UNIT_STUB)
                 return -ENOENT;
 
-        /* Load drop-in directory data */
-        r = unit_load_dropin(unit_follow_merge(u));
-        if (r < 0)
-                return r;
+        /* If the unit is an alias and the final unit has already been
+         * loaded, there's no point in reloading the dropins one more time. */
+        t = unit_follow_merge(u);
+        if (t != u && t->load_state != UNIT_STUB)
+                return 0;
 
-        return 0;
+        return unit_load_dropin(t);
 }
 
 /* Common implementation for multiple backends */
 int unit_load_fragment_and_dropin_optional(Unit *u) {
+        Unit *t;
         int r;
 
         assert(u);
@@ -1119,12 +1129,13 @@ int unit_load_fragment_and_dropin_optional(Unit *u) {
         if (u->load_state == UNIT_STUB)
                 u->load_state = UNIT_LOADED;
 
-        /* Load drop-in directory data */
-        r = unit_load_dropin(unit_follow_merge(u));
-        if (r < 0)
-                return r;
+        /* If the unit is an alias and the final unit has already been
+         * loaded, there's no point in reloading the dropins one more time. */
+        t = unit_follow_merge(u);
+        if (t != u && t->load_state != UNIT_STUB)
+                return 0;
 
-        return 0;
+        return unit_load_dropin(t);
 }
 
 int unit_add_default_target_dependency(Unit *u, Unit *target) {
@@ -1515,6 +1526,17 @@ int unit_start_limit_test(Unit *u) {
         return emergency_action(u->manager, u->start_limit_action, u->reboot_arg, "unit failed");
 }
 
+bool unit_shall_confirm_spawn(Unit *u) {
+
+        if (manager_is_confirm_spawn_disabled(u->manager))
+                return false;
+
+        /* For some reasons units remaining in the same process group
+         * as PID 1 fail to acquire the console even if it's not used
+         * by any process. So skip the confirmation question for them. */
+        return !unit_get_exec_context(u)->same_pgrp;
+}
+
 /* Errors:
  *         -EBADR:      This unit type does not support starting.
  *         -EALREADY:   Unit is already started.
@@ -3040,6 +3062,9 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep
         if (r < 0)
                 return r;
 
+        if (dep == UNIT_REQUIRES && device_shall_be_bound_by(device, u))
+                dep = UNIT_BINDS_TO;
+
         r = unit_add_two_dependencies(u, UNIT_AFTER,
                                       MANAGER_IS_SYSTEM(u->manager) ? dep : UNIT_WANTS,
                                       device, true);
@@ -3747,14 +3772,14 @@ int unit_kill_context(
                 bool main_pid_alien) {
 
         bool wait_for_exit = false, send_sighup;
-        cg_kill_log_func_t log_func;
+        cg_kill_log_func_t log_func = NULL;
         int sig, r;
 
         assert(u);
         assert(c);
 
-        /* Kill the processes belonging to this unit, in preparation for shutting the unit down. Returns > 0 if we
-         * killed something worth waiting for, 0 otherwise. */
+        /* Kill the processes belonging to this unit, in preparation for shutting the unit down.
+         * Returns > 0 if we killed something worth waiting for, 0 otherwise. */
 
         if (c->kill_mode == KILL_NONE)
                 return 0;
@@ -3766,9 +3791,8 @@ int unit_kill_context(
                 IN_SET(k, KILL_TERMINATE, KILL_TERMINATE_AND_LOG) &&
                 sig != SIGHUP;
 
-        log_func =
-                k != KILL_TERMINATE ||
-                IN_SET(sig, SIGKILL, SIGABRT) ? log_kill : NULL;
+        if (k != KILL_TERMINATE || IN_SET(sig, SIGKILL, SIGABRT))
+                log_func = log_kill;
 
         if (main_pid > 0) {
                 if (log_func)