]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: enumerate perpetual units in a separate per-unit-type method
authorLennart Poettering <lennart@poettering.net>
Tue, 5 Jun 2018 16:26:45 +0000 (18:26 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 7 Jun 2018 13:29:17 +0000 (15:29 +0200)
Previously the enumerate() callback defined for each unit type would do
two things:

1. It would create perpetual units (i.e. -.slice, system.slice, -.mount and
   init.scope)

2. It would enumerate units from /proc/self/mountinfo, /proc/swaps and
   the udev database

With this change these two parts are split into two seperate methods:
enumerate() now only does #2, while enumerate_perpetual() is responsible
for #1. Why make this change? Well, perpetual units should have a
slightly different effect that those found through enumeration: as
perpetual units should be up unconditionally, perpetually and thus never
change state, they should also not pull in deps by their state changing,
not even when the state is first set to active. Thus, their state is
generally initialized through the per-device coldplug() method in
similar  fashion to the deserialized state from a previous run would be
put into place. OTOH units found through regular enumeration should
result in state changes (and thus pull in deps due to state changes),
hence their state should be put in effect in the catchup() method
instead. Hence, given this difference, let's also separate the
functions, so that the rule is:

1. What is created in enumerate_perpetual() should be started in
   coldplug()

2. What is created in enumerate() should be started in catchup().

src/core/manager.c
src/core/mount.c
src/core/scope.c
src/core/slice.c
src/core/unit.h

index f90cc129107db4e64ea1f389807499f04e2dc086..04e0c6fe3b0bae5cd25890f9075c7b72bb91271d 100644 (file)
@@ -1322,13 +1322,30 @@ Manager* manager_free(Manager *m) {
         return mfree(m);
 }
 
+static void manager_enumerate_perpetual(Manager *m) {
+        UnitType c;
+
+        assert(m);
+
+        /* Let's ask every type to load all units from disk/kernel that it might know */
+        for (c = 0; c < _UNIT_TYPE_MAX; c++) {
+                if (!unit_type_supported(c)) {
+                        log_debug("Unit type .%s is not supported on this system.", unit_type_to_string(c));
+                        continue;
+                }
+
+                if (unit_vtable[c]->enumerate_perpetual)
+                        unit_vtable[c]->enumerate_perpetual(m);
+        }
+}
+
+
 static void manager_enumerate(Manager *m) {
         UnitType c;
 
         assert(m);
 
-        /* Let's ask every type to load all units from disk/kernel
-         * that it might know */
+        /* Let's ask every type to load all units from disk/kernel that it might know */
         for (c = 0; c < _UNIT_TYPE_MAX; c++) {
                 if (!unit_type_supported(c)) {
                         log_debug("Unit type .%s is not supported on this system.", unit_type_to_string(c));
@@ -1562,6 +1579,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
 
         /* First, enumerate what we can from all config files */
         dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_START);
+        manager_enumerate_perpetual(m);
         manager_enumerate(m);
         dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_FINISH);
 
index 64115dc21bbceb594af67a57f03d923966f1bca6..dcc44657b22a7aee3e6241d1541fe21873d7d154 100644 (file)
@@ -1671,7 +1671,7 @@ static int mount_get_timeout(Unit *u, usec_t *timeout) {
         return 1;
 }
 
-static int synthesize_root_mount(Manager *m) {
+static void mount_enumerate_perpetual(Manager *m) {
         Unit *u;
         int r;
 
@@ -1683,8 +1683,10 @@ static int synthesize_root_mount(Manager *m) {
         u = manager_get_unit(m, SPECIAL_ROOT_MOUNT);
         if (!u) {
                 r = unit_new_for_name(m, sizeof(Mount), SPECIAL_ROOT_MOUNT, &u);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to allocate the special " SPECIAL_ROOT_MOUNT " unit: %m");
+                if (r < 0) {
+                        log_error_errno(r, "Failed to allocate the special " SPECIAL_ROOT_MOUNT " unit: %m");
+                        return;
+                }
         }
 
         u->perpetual = true;
@@ -1692,8 +1694,6 @@ static int synthesize_root_mount(Manager *m) {
 
         unit_add_to_load_queue(u);
         unit_add_to_dbus_queue(u);
-
-        return 0;
 }
 
 static bool mount_is_mounted(Mount *m) {
@@ -1707,10 +1707,6 @@ static void mount_enumerate(Manager *m) {
 
         assert(m);
 
-        r = synthesize_root_mount(m);
-        if (r < 0)
-                goto fail;
-
         mnt_init_debug(0);
 
         if (!m->mount_monitor) {
@@ -2001,6 +1997,7 @@ const UnitVTable mount_vtable = {
 
         .can_transient = true,
 
+        .enumerate_perpetual = mount_enumerate_perpetual,
         .enumerate = mount_enumerate,
         .shutdown = mount_shutdown,
 
index 5db329604414e006be42763ecbb15da3c54af67e..27ff545313449bd43e7fc76a33f0ca0151aeb17d 100644 (file)
@@ -540,7 +540,7 @@ _pure_ static const char *scope_sub_state_to_string(Unit *u) {
         return scope_state_to_string(SCOPE(u)->state);
 }
 
-static void scope_enumerate(Manager *m) {
+static void scope_enumerate_perpetual(Manager *m) {
         Unit *u;
         int r;
 
@@ -622,5 +622,5 @@ const UnitVTable scope_vtable = {
         .bus_set_property = bus_scope_set_property,
         .bus_commit_properties = bus_scope_commit_properties,
 
-        .enumerate = scope_enumerate,
+        .enumerate_perpetual = scope_enumerate_perpetual,
 };
index 71614e4b89a2026b9deab7174166e5d2f4b57046..e8a7c9a5851979b748d9b0bb47a84474c058fb93 100644 (file)
@@ -326,7 +326,7 @@ static int slice_make_perpetual(Manager *m, const char *name, Unit **ret) {
         return 0;
 }
 
-static void slice_enumerate(Manager *m) {
+static void slice_enumerate_perpetual(Manager *m) {
         Unit *u;
         int r;
 
@@ -383,7 +383,7 @@ const UnitVTable slice_vtable = {
         .bus_set_property = bus_slice_set_property,
         .bus_commit_properties = bus_slice_commit_properties,
 
-        .enumerate = slice_enumerate,
+        .enumerate_perpetual = slice_enumerate_perpetual,
 
         .status_message_formats = {
                 .finished_start_job = {
index 9d9d94dd4e74c3c26852206d15d6f323fdd65317..cff3825ddc3721225821720f57923e059a810f86 100644 (file)
@@ -535,9 +535,15 @@ typedef struct UnitVTable {
         /* Returns true if the unit currently needs access to the console */
         bool (*needs_console)(Unit *u);
 
+        /* Like the enumerate() callback further down, but only enumerates the perpetual units, i.e. all units that
+         * unconditionally exist and are always active. The main reason to keep both enumeration functions separate is
+         * philosophical: the state of perpetual units should be put in place by coldplug(), while the state of those
+         * discovered through regular enumeration should be put in place by catchup(), see below. */
+        void (*enumerate_perpetual)(Manager *m);
+
         /* This is called for each unit type and should be used to enumerate units already existing in the system
          * internally and load them. However, everything that is loaded here should still stay in inactive state. It is
-         * the job of the coldplug() call above to put the units into the initial state.  */
+         * the job of the catchup() call above to put the units into the discovered state. */
         void (*enumerate)(Manager *m);
 
         /* Type specific cleanups. */