From: Lennart Poettering Date: Mon, 20 Nov 2017 20:01:13 +0000 (+0100) Subject: manager: rework the timestamps logic, so that they are an enum-index array X-Git-Tag: v236~148^2~5 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=9f9f034271cf719ba7d6b763130ad7013844207c;p=thirdparty%2Fsystemd.git manager: rework the timestamps logic, so that they are an enum-index array This makes things quite a bit more systematic I think, as we can systematically operate on all timestamps, for example for the purpose of serialization/deserialization. This rework doesn't necessarily make things shorter in the individual lines, but it does reduce the line count a bit. (This is useful particularly when we want to add additional timestamps, for example to solve #7023) --- diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 3c043ba91a6..b98351e84ef 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -323,7 +323,7 @@ static int property_get_progress( assert(reply); assert(m); - if (dual_timestamp_is_set(&m->finish_timestamp)) + if (dual_timestamp_is_set(m->timestamps + MANAGER_TIMESTAMP_FINISH)) d = 1.0; else d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs); @@ -2413,18 +2413,18 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("Virtualization", "s", property_get_virtualization, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Architecture", "s", property_get_architecture, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("Tainted", "s", property_get_tainted, 0, SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, firmware_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, loader_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, kernel_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, initrd_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, userspace_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, security_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, security_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, generators_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, generators_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, units_load_start_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), - BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, units_load_finish_timestamp), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("FirmwareTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FIRMWARE]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("LoaderTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_LOADER]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("KernelTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_KERNEL]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("InitRDTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_INITRD]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("UserspaceTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_USERSPACE]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("FinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("SecurityStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_START]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("SecurityFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_SECURITY_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_START]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("GeneratorsFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_GENERATORS_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadStartTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_START]), SD_BUS_VTABLE_PROPERTY_CONST), + BUS_PROPERTY_DUAL_TIMESTAMP("UnitsLoadFinishTimestamp", offsetof(Manager, timestamps[MANAGER_TIMESTAMP_UNITS_LOAD_FINISH]), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_WRITABLE_PROPERTY("LogLevel", "s", property_get_log_level, property_set_log_level, 0, 0), SD_BUS_WRITABLE_PROPERTY("LogTarget", "s", property_get_log_target, property_set_log_target, 0, 0), SD_BUS_PROPERTY("NNames", "u", property_get_n_names, 0, 0), diff --git a/src/core/main.c b/src/core/main.c index ee9594a00fc..6a9a297e5f3 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1995,11 +1995,11 @@ int main(int argc, char *argv[]) { goto finish; } - m->userspace_timestamp = userspace_timestamp; - m->kernel_timestamp = kernel_timestamp; - m->initrd_timestamp = initrd_timestamp; - m->security_start_timestamp = security_start_timestamp; - m->security_finish_timestamp = security_finish_timestamp; + m->timestamps[MANAGER_TIMESTAMP_KERNEL] = kernel_timestamp; + m->timestamps[MANAGER_TIMESTAMP_INITRD] = initrd_timestamp; + m->timestamps[MANAGER_TIMESTAMP_USERSPACE] = userspace_timestamp; + m->timestamps[MANAGER_TIMESTAMP_SECURITY_START] = security_start_timestamp; + m->timestamps[MANAGER_TIMESTAMP_SECURITY_FINISH] = security_finish_timestamp; set_manager_defaults(m); set_manager_settings(m); diff --git a/src/core/manager.c b/src/core/manager.c index 67fe3d21202..059482ff1d5 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -624,7 +624,9 @@ int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **_m) { #if ENABLE_EFI if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) - boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); + boot_timestamps(m->timestamps + MANAGER_TIMESTAMP_USERSPACE, + m->timestamps + MANAGER_TIMESTAMP_FIRMWARE, + m->timestamps + MANAGER_TIMESTAMP_LOADER); #endif /* Prepare log fields we can use for structured logging */ @@ -1340,9 +1342,9 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { return log_error_errno(r, "Failed to create transient generator directory \"%s\": %m", m->lookup_paths.transient); - dual_timestamp_get(&m->generators_start_timestamp); + dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_GENERATORS_START); r = manager_run_generators(m); - dual_timestamp_get(&m->generators_finish_timestamp); + dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_GENERATORS_FINISH); if (r < 0) return r; @@ -1369,9 +1371,9 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { m->n_reloading++; /* First, enumerate what we can from all config files */ - dual_timestamp_get(&m->units_load_start_timestamp); + dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_START); manager_enumerate(m); - dual_timestamp_get(&m->units_load_finish_timestamp); + dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_UNITS_LOAD_FINISH); /* Second, deserialize if there is something to deserialize */ if (serialization) { @@ -2577,9 +2579,10 @@ int manager_open_serialization(Manager *m, FILE **_f) { } int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { + ManagerTimestamp q; + const char *t; Iterator i; Unit *u; - const char *t; int r; assert(m); @@ -2594,20 +2597,17 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds, bool switching_root) { fprintf(f, "taint-usr=%s\n", yes_no(m->taint_usr)); fprintf(f, "ready-sent=%s\n", yes_no(m->ready_sent)); - dual_timestamp_serialize(f, "firmware-timestamp", &m->firmware_timestamp); - dual_timestamp_serialize(f, "loader-timestamp", &m->loader_timestamp); - dual_timestamp_serialize(f, "kernel-timestamp", &m->kernel_timestamp); - dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp); + for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) { + /* The userspace and finish timestamps only apply to the host system, hence only serialize them there */ + if (in_initrd() && IN_SET(q, MANAGER_TIMESTAMP_USERSPACE, MANAGER_TIMESTAMP_FINISH)) + continue; - if (!in_initrd()) { - dual_timestamp_serialize(f, "userspace-timestamp", &m->userspace_timestamp); - dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp); - dual_timestamp_serialize(f, "security-start-timestamp", &m->security_start_timestamp); - dual_timestamp_serialize(f, "security-finish-timestamp", &m->security_finish_timestamp); - dual_timestamp_serialize(f, "generators-start-timestamp", &m->generators_start_timestamp); - dual_timestamp_serialize(f, "generators-finish-timestamp", &m->generators_finish_timestamp); - dual_timestamp_serialize(f, "units-load-start-timestamp", &m->units_load_start_timestamp); - dual_timestamp_serialize(f, "units-load-finish-timestamp", &m->units_load_finish_timestamp); + t = manager_timestamp_to_string(q); + { + char field[strlen(t) + strlen("-timestamp") + 1]; + strcpy(stpcpy(field, t), "-timestamp"); + dual_timestamp_serialize(f, field, m->timestamps + q); + } } if (!switching_root) @@ -2758,31 +2758,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { else m->ready_sent = m->ready_sent || b; - } else if ((val = startswith(l, "firmware-timestamp="))) - dual_timestamp_deserialize(val, &m->firmware_timestamp); - else if ((val = startswith(l, "loader-timestamp="))) - dual_timestamp_deserialize(val, &m->loader_timestamp); - else if ((val = startswith(l, "kernel-timestamp="))) - dual_timestamp_deserialize(val, &m->kernel_timestamp); - else if ((val = startswith(l, "initrd-timestamp="))) - dual_timestamp_deserialize(val, &m->initrd_timestamp); - else if ((val = startswith(l, "userspace-timestamp="))) - dual_timestamp_deserialize(val, &m->userspace_timestamp); - else if ((val = startswith(l, "finish-timestamp="))) - dual_timestamp_deserialize(val, &m->finish_timestamp); - else if ((val = startswith(l, "security-start-timestamp="))) - dual_timestamp_deserialize(val, &m->security_start_timestamp); - else if ((val = startswith(l, "security-finish-timestamp="))) - dual_timestamp_deserialize(val, &m->security_finish_timestamp); - else if ((val = startswith(l, "generators-start-timestamp="))) - dual_timestamp_deserialize(val, &m->generators_start_timestamp); - else if ((val = startswith(l, "generators-finish-timestamp="))) - dual_timestamp_deserialize(val, &m->generators_finish_timestamp); - else if ((val = startswith(l, "units-load-start-timestamp="))) - dual_timestamp_deserialize(val, &m->units_load_start_timestamp); - else if ((val = startswith(l, "units-load-finish-timestamp="))) - dual_timestamp_deserialize(val, &m->units_load_finish_timestamp); - else if (startswith(l, "env=")) { + } else if (startswith(l, "env=")) { r = deserialize_environment(&m->environment, l); if (r == -ENOMEM) goto finish; @@ -2845,9 +2821,24 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { if (strv_extend(&m->deserialized_subscribed, val) < 0) log_oom(); + } else { + ManagerTimestamp q; + + for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) { + val = startswith(l, manager_timestamp_to_string(q)); + if (!val) + continue; - } else if (!startswith(l, "kdbus-fd=")) /* ignore this one */ - log_notice("Unknown serialization item '%s'", l); + val = startswith(val, "-timestamp="); + if (val) + break; + } + + if (q < _MANAGER_TIMESTAMP_MAX) /* found it */ + dual_timestamp_deserialize(val, m->timestamps + q); + else if (!startswith(l, "kdbus-fd=")) /* ignore kdbus */ + log_notice("Unknown serialization item '%s'", l); + } } for (;;) { @@ -3033,20 +3024,20 @@ static void manager_notify_finished(Manager *m) { if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) { - /* Note that m->kernel_usec.monotonic is always at 0, - * and m->firmware_usec.monotonic and - * m->loader_usec.monotonic should be considered + /* Note that MANAGER_TIMESTAMP_KERNEL's monotonic value is always at 0, and + * MANAGER_TIMESTAMP_FIRMWARE's and MANAGER_TIMESTAMP_LOADER's monotonic value should be considered * negative values. */ - firmware_usec = m->firmware_timestamp.monotonic - m->loader_timestamp.monotonic; - loader_usec = m->loader_timestamp.monotonic - m->kernel_timestamp.monotonic; - userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic; - total_usec = m->firmware_timestamp.monotonic + m->finish_timestamp.monotonic; + firmware_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic - m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic; + loader_usec = m->timestamps[MANAGER_TIMESTAMP_LOADER].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic; + userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic; + total_usec = m->timestamps[MANAGER_TIMESTAMP_FIRMWARE].monotonic + m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic; - if (dual_timestamp_is_set(&m->initrd_timestamp)) { + if (dual_timestamp_is_set(&m->timestamps[MANAGER_TIMESTAMP_INITRD])) { - kernel_usec = m->initrd_timestamp.monotonic - m->kernel_timestamp.monotonic; - initrd_usec = m->userspace_timestamp.monotonic - m->initrd_timestamp.monotonic; + /* The initrd case on bare-metal*/ + kernel_usec = m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic; + initrd_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_INITRD].monotonic; log_struct(LOG_INFO, "MESSAGE_ID=" SD_MESSAGE_STARTUP_FINISHED_STR, @@ -3060,7 +3051,9 @@ static void manager_notify_finished(Manager *m) { format_timespan(sum, sizeof(sum), total_usec, USEC_PER_MSEC)), NULL); } else { - kernel_usec = m->userspace_timestamp.monotonic - m->kernel_timestamp.monotonic; + /* The initrd-less case on bare-metal*/ + + kernel_usec = m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic - m->timestamps[MANAGER_TIMESTAMP_KERNEL].monotonic; initrd_usec = 0; log_struct(LOG_INFO, @@ -3074,8 +3067,9 @@ static void manager_notify_finished(Manager *m) { NULL); } } else { + /* The container case */ firmware_usec = loader_usec = initrd_usec = kernel_usec = 0; - total_usec = userspace_usec = m->finish_timestamp.monotonic - m->userspace_timestamp.monotonic; + total_usec = userspace_usec = m->timestamps[MANAGER_TIMESTAMP_FINISH].monotonic - m->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic; log_struct(LOG_INFO, "MESSAGE_ID=" SD_MESSAGE_USER_STARTUP_FINISHED_STR, @@ -3142,10 +3136,10 @@ void manager_check_finished(Manager *m) { /* This is no longer the first boot */ manager_set_first_boot(m, false); - if (dual_timestamp_is_set(&m->finish_timestamp)) + if (dual_timestamp_is_set(m->timestamps + MANAGER_TIMESTAMP_FINISH)) return; - dual_timestamp_get(&m->finish_timestamp); + dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH); manager_notify_finished(m); @@ -3500,7 +3494,7 @@ ManagerState manager_state(Manager *m) { assert(m); /* Did we ever finish booting? If not then we are still starting up */ - if (!dual_timestamp_is_set(&m->finish_timestamp)) { + if (!dual_timestamp_is_set(m->timestamps + MANAGER_TIMESTAMP_FINISH)) { u = manager_get_unit(m, SPECIAL_BASIC_TARGET); if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u))) @@ -3836,3 +3830,20 @@ static const char *const manager_state_table[_MANAGER_STATE_MAX] = { }; DEFINE_STRING_TABLE_LOOKUP(manager_state, ManagerState); + +static const char *const manager_timestamp_table[_MANAGER_TIMESTAMP_MAX] = { + [MANAGER_TIMESTAMP_FIRMWARE] = "firmware", + [MANAGER_TIMESTAMP_LOADER] = "loader", + [MANAGER_TIMESTAMP_KERNEL] = "kernel", + [MANAGER_TIMESTAMP_INITRD] = "initrd", + [MANAGER_TIMESTAMP_USERSPACE] = "userspace", + [MANAGER_TIMESTAMP_FINISH] = "finish", + [MANAGER_TIMESTAMP_SECURITY_START] = "security-start", + [MANAGER_TIMESTAMP_SECURITY_FINISH] = "security-finish", + [MANAGER_TIMESTAMP_GENERATORS_START] = "generators-start", + [MANAGER_TIMESTAMP_GENERATORS_FINISH] = "generators-finish", + [MANAGER_TIMESTAMP_UNITS_LOAD_START] = "units-load-start", + [MANAGER_TIMESTAMP_UNITS_LOAD_FINISH] = "units-load-finish", +}; + +DEFINE_STRING_TABLE_LOOKUP(manager_timestamp, ManagerTimestamp); diff --git a/src/core/manager.h b/src/core/manager.h index 8f1357d37ea..1812eb37ea6 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -70,6 +70,24 @@ typedef enum StatusType { STATUS_TYPE_EMERGENCY, } StatusType; +typedef enum ManagerTimestamp { + MANAGER_TIMESTAMP_FIRMWARE, + MANAGER_TIMESTAMP_LOADER, + MANAGER_TIMESTAMP_KERNEL, + MANAGER_TIMESTAMP_INITRD, + MANAGER_TIMESTAMP_USERSPACE, + MANAGER_TIMESTAMP_FINISH, + + MANAGER_TIMESTAMP_SECURITY_START, + MANAGER_TIMESTAMP_SECURITY_FINISH, + MANAGER_TIMESTAMP_GENERATORS_START, + MANAGER_TIMESTAMP_GENERATORS_FINISH, + MANAGER_TIMESTAMP_UNITS_LOAD_START, + MANAGER_TIMESTAMP_UNITS_LOAD_FINISH, + _MANAGER_TIMESTAMP_MAX, + _MANAGER_TIMESTAMP_INVALID = -1, +} ManagerTimestamp; + #include "execute.h" #include "job.h" #include "path-lookup.h" @@ -171,19 +189,7 @@ struct Manager { usec_t runtime_watchdog; usec_t shutdown_watchdog; - dual_timestamp firmware_timestamp; - dual_timestamp loader_timestamp; - dual_timestamp kernel_timestamp; - dual_timestamp initrd_timestamp; - dual_timestamp userspace_timestamp; - dual_timestamp finish_timestamp; - - dual_timestamp security_start_timestamp; - dual_timestamp security_finish_timestamp; - dual_timestamp generators_start_timestamp; - dual_timestamp generators_finish_timestamp; - dual_timestamp units_load_start_timestamp; - dual_timestamp units_load_finish_timestamp; + dual_timestamp timestamps[_MANAGER_TIMESTAMP_MAX]; struct udev* udev; @@ -431,3 +437,6 @@ ManagerState manager_state_from_string(const char *s) _pure_; const char *manager_get_confirm_spawn(Manager *m); bool manager_is_confirm_spawn_disabled(Manager *m); void manager_disable_confirm_spawn(void); + +const char *manager_timestamp_to_string(ManagerTimestamp m) _const_; +ManagerTimestamp manager_timestamp_from_string(const char *s) _pure_; diff --git a/src/core/timer.c b/src/core/timer.c index 27f4f74b49e..55197faa593 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -419,7 +419,7 @@ static void timer_enter_waiting(Timer *t, bool initial) { * our own startup. */ /* fall through */ case TIMER_STARTUP: - base = UNIT(t)->manager->userspace_timestamp.monotonic; + base = UNIT(t)->manager->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic; break; case TIMER_UNIT_ACTIVE: