X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fsystemctl%2Fsystemctl.c;h=653a3247b414634480659e5c92a9ac6898b5025b;hb=b3ae710c251d0ce5cf2cef63208e325497b5e323;hp=8ef3c08db02ec370e25067edcf175472e7abc6d8;hpb=90c3f79dc74229134818e78cb97d315e28ee93b5;p=elogind.git diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8ef3c08db..653a3247b 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -947,9 +947,39 @@ static int get_next_elapse( return 0; } +static int get_last_trigger( + sd_bus *bus, + const char *path, + usec_t *last) { + + _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; + int r; + + assert(bus); + assert(path); + assert(last); + + r = sd_bus_get_property_trivial( + bus, + "org.freedesktop.systemd1", + path, + "org.freedesktop.systemd1.Timer", + "LastTriggerUSec", + &error, + 't', + last); + if (r < 0) { + log_error("Failed to get last trigger time: %s", bus_error_message(&error, r)); + return r; + } + + return 0; +} + struct timer_info { const char* id; usec_t next_elapse; + usec_t last_trigger; char** triggered; }; @@ -970,6 +1000,8 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) { unsigned nextlen = strlen("NEXT"), leftlen = strlen("LEFT"), + lastlen = strlen("LAST"), + passedlen = strlen("PASSED"), unitlen = strlen("UNIT"), activatelen = strlen("ACTIVATES"); @@ -991,30 +1023,47 @@ static int output_timers_list(struct timer_info *timer_infos, unsigned n) { leftlen = MAX(leftlen, strlen(trel)); } + if (t->last_trigger > 0) { + char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = ""; + + format_timestamp(tstamp, sizeof(tstamp), t->last_trigger); + lastlen = MAX(lastlen, strlen(tstamp) + 1); + + format_timestamp_relative(trel, sizeof(trel), t->last_trigger); + passedlen = MAX(passedlen, strlen(trel)); + } + unitlen = MAX(unitlen, strlen(t->id)); STRV_FOREACH(a, t->triggered) ul += strlen(*a) + 2*(a != t->triggered); + activatelen = MAX(activatelen, ul); } if (n > 0) { if (!arg_no_legend) - printf("%-*s %-*s %-*s %s\n", - nextlen, "NEXT", - leftlen, "LEFT", - unitlen, "UNIT", - "ACTIVATES"); + printf("%-*s %-*s %-*s %-*s %-*s %s\n", + nextlen, "NEXT", + leftlen, "LEFT", + lastlen, "LAST", + passedlen, "PASSED", + unitlen, "UNIT", + "ACTIVATES"); for (t = timer_infos; t < timer_infos + n; t++) { - char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a"; + char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a"; + char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a"; char **a; - format_timestamp(tstamp, sizeof(tstamp), t->next_elapse); - format_timestamp_relative(trel, sizeof(trel), t->next_elapse); + format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse); + format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse); - printf("%-*s %-*s %-*s", - nextlen, tstamp, leftlen, trel, unitlen, t->id); + format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger); + format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger); + + printf("%-*s %-*s %-*s %-*s %-*s", + nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, t->id); STRV_FOREACH(a, t->triggered) printf("%s %s", @@ -1088,7 +1137,7 @@ static int list_timers(sd_bus *bus, char **args) { for (u = unit_infos; u < unit_infos + n; u++) { _cleanup_strv_free_ char **triggered = NULL; dual_timestamp next = {}; - usec_t m; + usec_t m, last = 0; if (!endswith(u->id, ".timer")) continue; @@ -1101,6 +1150,8 @@ static int list_timers(sd_bus *bus, char **args) { if (r < 0) goto cleanup; + get_last_trigger(bus, u->unit_path, &last); + if (!GREEDY_REALLOC(timer_infos, size, c+1)) { r = log_oom(); goto cleanup; @@ -1111,6 +1162,7 @@ static int list_timers(sd_bus *bus, char **args) { timer_infos[c++] = (struct timer_info) { .id = u->id, .next_elapse = m, + .last_trigger = last, .triggered = triggered, }; @@ -1582,7 +1634,7 @@ static int compare_machine_info(const void *a, const void *b) { const struct machine_info *u = a, *v = b; if (u->is_host != v->is_host) - return u->is_host > v->is_host ? 1 : -1; + return u->is_host > v->is_host ? -1 : 1; return strcasecmp(u->name, v->name); } @@ -1903,7 +1955,7 @@ static int set_default(sd_bus *bus, char **args) { if (r < 0) return r; - /* Try to reload if enabeld */ + /* Try to reload if enabled */ if (!arg_no_reload) r = daemon_reload(bus, args); else @@ -5190,7 +5242,7 @@ static int enable_unit(sd_bus *bus, char **args) { if (r < 0) return r; - /* Try to reload if enabeld */ + /* Try to reload if enabled */ if (!arg_no_reload) r = daemon_reload(bus, args); else @@ -5351,15 +5403,15 @@ static int systemctl_help(void) { " otherwise restart if active\n" " isolate NAME Start one unit and stop all others\n" " kill NAME... Send signal to processes of a unit\n" - " is-active NAME... Check whether units are active\n" - " is-failed NAME... Check whether units are failed\n" - " status [NAME...|PID...] Show runtime status of one or more units\n" - " show [NAME...|JOB...] Show properties of one or more\n" + " is-active PATTERN... Check whether units are active\n" + " is-failed PATTERN... Check whether units are failed\n" + " status [PATTERN...|PID...] Show runtime status of one or more units\n" + " show [PATTERN...|JOB...] Show properties of one or more\n" " units/jobs or the manager\n" - " cat NAME... Show files and drop-ins of one or more units\n" + " cat PATTERN... Show files and drop-ins of one or more units\n" " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n" - " help NAME...|PID... Show manual for one or more units\n" - " reset-failed [NAME...] Reset failed state for all, one, or more\n" + " help PATTERN...|PID... Show manual for one or more units\n" + " reset-failed [PATTERN...] Reset failed state for all, one, or more\n" " units\n" " list-dependencies [NAME] Recursively show units which are required\n" " or wanted by this unit or by which this\n"