Merge pull request #7406 from poettering/timestamp-rework

timestamping rework
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2017-11-22 11:55:04 +01:00 committed by GitHub
commit bfbcf21d75
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 175 additions and 123 deletions

View file

@ -1072,7 +1072,7 @@ PartOf=graphical-session.target
<citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd.slice</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry project='man-pages'><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>bootup</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>
</para>
</refsect1>

View file

@ -323,7 +323,7 @@ static int property_get_progress(
assert(reply);
assert(m);
if (dual_timestamp_is_set(&m->finish_timestamp))
if (MANAGER_IS_FINISHED(m))
d = 1.0;
else
d = 1.0 - ((double) hashmap_size(m->jobs) / (double) m->n_installed_jobs);
@ -1289,9 +1289,7 @@ static int method_unsubscribe(sd_bus_message *message, void *userdata, sd_bus_er
static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *error) {
_cleanup_free_ char *dump = NULL;
_cleanup_fclose_ FILE *f = NULL;
Manager *m = userdata;
size_t size;
int r;
assert(message);
@ -1303,14 +1301,7 @@ static int method_dump(sd_bus_message *message, void *userdata, sd_bus_error *er
if (r < 0)
return r;
f = open_memstream(&dump, &size);
if (!f)
return -ENOMEM;
manager_dump_units(m, f, NULL);
manager_dump_jobs(m, f, NULL);
r = fflush_and_check(f);
r = manager_get_dump_string(m, &dump);
if (r < 0)
return r;
@ -2413,18 +2404,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),

View file

@ -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);

View file

@ -22,6 +22,7 @@
#include <fcntl.h>
#include <linux/kd.h>
#include <signal.h>
#include <stdio_ext.h>
#include <string.h>
#include <sys/epoll.h>
#include <sys/inotify.h>
@ -624,7 +625,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 +1343,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 +1372,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) {
@ -1709,6 +1712,55 @@ void manager_dump_units(Manager *s, FILE *f, const char *prefix) {
unit_dump(u, f, prefix);
}
void manager_dump(Manager *m, FILE *f, const char *prefix) {
ManagerTimestamp q;
assert(m);
assert(f);
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
char buf[FORMAT_TIMESTAMP_MAX];
if (dual_timestamp_is_set(m->timestamps + q))
fprintf(f, "%sTimestamp %s: %s\n",
strempty(prefix),
manager_timestamp_to_string(q),
format_timestamp(buf, sizeof(buf), m->timestamps[q].realtime));
}
manager_dump_units(m, f, prefix);
manager_dump_jobs(m, f, prefix);
}
int manager_get_dump_string(Manager *m, char **ret) {
_cleanup_free_ char *dump = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t size;
int r;
assert(m);
assert(ret);
f = open_memstream(&dump, &size);
if (!f)
return -errno;
__fsetlocking(f, FSETLOCKING_BYCALLER);
manager_dump(m, f, NULL);
r = fflush_and_check(f);
if (r < 0)
return r;
f = safe_fclose(f);
*ret = dump;
dump = NULL;
return 0;
}
void manager_clear_jobs(Manager *m) {
Job *j;
@ -2156,21 +2208,10 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t
case SIGUSR2: {
_cleanup_free_ char *dump = NULL;
_cleanup_fclose_ FILE *f = NULL;
size_t size;
f = open_memstream(&dump, &size);
if (!f) {
log_warning_errno(errno, "Failed to allocate memory stream: %m");
break;
}
manager_dump_units(m, f, "\t");
manager_dump_jobs(m, f, "\t");
r = fflush_and_check(f);
r = manager_get_dump_string(m, &dump);
if (r < 0) {
log_warning_errno(r, "Failed to write status stream: %m");
log_warning_errno(errno, "Failed to acquire manager dump: %m");
break;
}
@ -2576,9 +2617,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);
@ -2593,20 +2635,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)
@ -2757,31 +2796,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;
@ -2844,9 +2859,24 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
if (strv_extend(&m->deserialized_subscribed, val) < 0)
log_oom();
} else {
ManagerTimestamp q;
} else if (!startswith(l, "kdbus-fd=")) /* ignore this one */
log_notice("Unknown serialization item '%s'", l);
for (q = 0; q < _MANAGER_TIMESTAMP_MAX; q++) {
val = startswith(l, manager_timestamp_to_string(q));
if (!val)
continue;
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 (;;) {
@ -3032,20 +3062,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,
@ -3059,7 +3089,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,
@ -3073,8 +3105,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,
@ -3141,10 +3174,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 (MANAGER_IS_FINISHED(m))
return;
dual_timestamp_get(&m->finish_timestamp);
dual_timestamp_get(m->timestamps + MANAGER_TIMESTAMP_FINISH);
manager_notify_finished(m);
@ -3499,7 +3532,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 (!MANAGER_IS_FINISHED(m)) {
u = manager_get_unit(m, SPECIAL_BASIC_TARGET);
if (!u || !UNIT_IS_ACTIVE_OR_RELOADING(unit_active_state(u)))
@ -3508,20 +3541,18 @@ ManagerState manager_state(Manager *m) {
return MANAGER_STARTING;
}
/* Is the special shutdown target queued? If so, we are in shutdown state */
/* Is the special shutdown target active or queued? If so, we are in shutdown state */
u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET);
if (u && u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_RELOAD_OR_START))
if (unit_active_or_pending(u))
return MANAGER_STOPPING;
/* Are the rescue or emergency targets active or queued? If so we are in maintenance state */
u = manager_get_unit(m, SPECIAL_RESCUE_TARGET);
if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
(u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_RELOAD_OR_START))))
if (unit_active_or_pending(u))
return MANAGER_MAINTENANCE;
u = manager_get_unit(m, SPECIAL_EMERGENCY_TARGET);
if (u && (UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(u)) ||
(u->job && IN_SET(u->job->type, JOB_START, JOB_RESTART, JOB_RELOAD_OR_START))))
if (unit_active_or_pending(u))
return MANAGER_MAINTENANCE;
/* Are there any failed units? If so, we are in degraded mode */
@ -3835,3 +3866,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);

View file

@ -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;
@ -346,6 +352,8 @@ struct Manager {
#define MANAGER_IS_RELOADING(m) ((m)->n_reloading > 0)
#define MANAGER_IS_FINISHED(m) (dual_timestamp_is_set((m)->timestamps + MANAGER_TIMESTAMP_FINISH))
int manager_new(UnitFileScope scope, unsigned test_run_flags, Manager **m);
Manager* manager_free(Manager *m);
@ -368,6 +376,8 @@ int manager_propagate_reload(Manager *m, Unit *unit, JobMode mode, sd_bus_error
void manager_dump_units(Manager *s, FILE *f, const char *prefix);
void manager_dump_jobs(Manager *s, FILE *f, const char *prefix);
void manager_dump(Manager *s, FILE *f, const char *prefix);
int manager_get_dump_string(Manager *m, char **ret);
void manager_clear_jobs(Manager *m);
@ -431,3 +441,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_;

View file

@ -419,7 +419,7 @@ static void timer_enter_waiting(Timer *t, bool initial) {
* our own startup. */
_fallthrough_;
case TIMER_STARTUP:
base = UNIT(t)->manager->userspace_timestamp.monotonic;
base = UNIT(t)->manager->timestamps[MANAGER_TIMESTAMP_USERSPACE].monotonic;
break;
case TIMER_UNIT_ACTIVE: