diff --git a/src/core/manager.c b/src/core/manager.c index f90cc12910..04e0c6fe3b 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -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); diff --git a/src/core/mount.c b/src/core/mount.c index 64115dc21b..dcc44657b2 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -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, diff --git a/src/core/scope.c b/src/core/scope.c index 5db3296044..27ff545313 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -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, }; diff --git a/src/core/slice.c b/src/core/slice.c index 71614e4b89..e8a7c9a585 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -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 = { diff --git a/src/core/unit.h b/src/core/unit.h index 9d9d94dd4e..cff3825ddc 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -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. */