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));
/* 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);
return 1;
}
-static int synthesize_root_mount(Manager *m) {
+static void mount_enumerate_perpetual(Manager *m) {
Unit *u;
int r;
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;
unit_add_to_load_queue(u);
unit_add_to_dbus_queue(u);
-
- return 0;
}
static bool mount_is_mounted(Mount *m) {
assert(m);
- r = synthesize_root_mount(m);
- if (r < 0)
- goto fail;
-
mnt_init_debug(0);
if (!m->mount_monitor) {
.can_transient = true,
+ .enumerate_perpetual = mount_enumerate_perpetual,
.enumerate = mount_enumerate,
.shutdown = mount_shutdown,
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;
.bus_set_property = bus_scope_set_property,
.bus_commit_properties = bus_scope_commit_properties,
- .enumerate = scope_enumerate,
+ .enumerate_perpetual = scope_enumerate_perpetual,
};
return 0;
}
-static void slice_enumerate(Manager *m) {
+static void slice_enumerate_perpetual(Manager *m) {
Unit *u;
int r;
.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 = {
/* 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. */