diff --git a/src/manager.c b/src/manager.c index ae2960236ec..14f18eb9216 100644 --- a/src/manager.c +++ b/src/manager.c @@ -2490,14 +2490,8 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) { assert(f); assert(fds); - fprintf(f, "startup-timestamp=%llu %llu\n", - (unsigned long long) m->startup_timestamp.realtime, - (unsigned long long) m->startup_timestamp.monotonic); - - if (dual_timestamp_is_set(&m->finish_timestamp)) - fprintf(f, "finish-timestamp=%llu %llu\n", - (unsigned long long) m->finish_timestamp.realtime, - (unsigned long long) m->finish_timestamp.monotonic); + dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp); + dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp); fputc('\n', f); @@ -2550,25 +2544,11 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { if (l[0] == 0) break; - if (startswith(l, "startup-timestamp=")) { - unsigned long long a, b; - - if (sscanf(l+18, "%lli %llu", &a, &b) != 2) - log_debug("Failed to parse startup timestamp value %s", l+18); - else { - m->startup_timestamp.realtime = a; - m->startup_timestamp.monotonic = b; - } - } else if (startswith(l, "finish-timestamp=")) { - unsigned long long a, b; - - if (sscanf(l+17, "%lli %llu", &a, &b) != 2) - log_debug("Failed to parse finish timestamp value %s", l+17); - else { - m->finish_timestamp.realtime = a; - m->finish_timestamp.monotonic = b; - } - } else + if (startswith(l, "startup-timestamp=")) + dual_timestamp_deserialize(f, l+18, &m->startup_timestamp); + else if (startswith(l, "finish-timestamp=")) + dual_timestamp_deserialize(f, l+17, &m->finish_timestamp); + else log_debug("Unknown serialization item '%s'", l); } diff --git a/src/timer.c b/src/timer.c index 0dcaad50918..b01944ccdbd 100644 --- a/src/timer.c +++ b/src/timer.c @@ -197,9 +197,9 @@ static void timer_enter_waiting(Timer *t, bool initial) { switch (v->base) { case TIMER_ACTIVE: - if (state_translation_table[t->state] == UNIT_ACTIVE) { + if (state_translation_table[t->state] == UNIT_ACTIVE) base = t->meta.inactive_exit_timestamp.monotonic; - } else + else base = n; break; diff --git a/src/unit.c b/src/unit.c index d2f60801a9a..0e9325dfa49 100644 --- a/src/unit.c +++ b/src/unit.c @@ -2006,6 +2006,11 @@ int unit_serialize(Unit *u, FILE *f, FDSet *fds) { if (u->meta.job) unit_serialize_item(u, f, "job", job_type_to_string(u->meta.job->type)); + dual_timestamp_serialize(f, "inactive-exit-timestamp", &u->meta.inactive_exit_timestamp); + dual_timestamp_serialize(f, "active-enter-timestamp", &u->meta.active_enter_timestamp); + dual_timestamp_serialize(f, "active-exit-timestamp", &u->meta.active_exit_timestamp); + dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->meta.inactive_enter_timestamp); + /* End marker */ fputc('\n', f); return 0; @@ -2082,7 +2087,14 @@ int unit_deserialize(Unit *u, FILE *f, FDSet *fds) { u->meta.deserialized_job = type; continue; - } + } else if (streq(l, "inactive-exit-timestamp")) + dual_timestamp_deserialize(f, v, &u->meta.inactive_exit_timestamp); + else if (streq(l, "active-enter-timestamp")) + dual_timestamp_deserialize(f, v, &u->meta.active_enter_timestamp); + else if (streq(l, "active-exit-timestamp")) + dual_timestamp_deserialize(f, v, &u->meta.active_exit_timestamp); + else if (streq(l, "inactive-enter-timestamp")) + dual_timestamp_deserialize(f, v, &u->meta.inactive_enter_timestamp); if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0) return r; diff --git a/src/util.c b/src/util.c index f5ee29897f5..d653d6b549b 100644 --- a/src/util.c +++ b/src/util.c @@ -3528,6 +3528,36 @@ finish: return r; } +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t) { + + assert(f); + assert(name); + assert(t); + + if (!dual_timestamp_is_set(t)) + return; + + fprintf(f, "%s=%llu %llu\n", + name, + (unsigned long long) t->realtime, + (unsigned long long) t->monotonic); +} + +void dual_timestamp_deserialize(FILE *f, const char *value, dual_timestamp *t) { + unsigned long long a, b; + + assert(f); + assert(value); + assert(t); + + if (sscanf(value, "%lli %llu", &a, &b) != 2) + log_debug("Failed to parse finish timestamp value %s", value); + else { + t->realtime = a; + t->monotonic = b; + } +} + static const char *const ioprio_class_table[] = { [IOPRIO_CLASS_NONE] = "none", [IOPRIO_CLASS_RT] = "realtime", diff --git a/src/util.h b/src/util.h index 6a252abbb15..71889f14257 100644 --- a/src/util.h +++ b/src/util.h @@ -366,6 +366,9 @@ DIR *xopendirat(int dirfd, const char *name); int ask_password_tty(const char *message, usec_t until, const char *flag_file, char **_passphrase); +void dual_timestamp_serialize(FILE *f, const char *name, dual_timestamp *t); +void dual_timestamp_deserialize(FILE *f, const char *line, dual_timestamp *t); + #define NULSTR_FOREACH(i, l) \ for ((i) = (l); (i) && *(i); (i) = strchr((i), 0)+1)