Compare commits

..

4 Commits

Author SHA1 Message Date
Zbigniew Jędrzejewski-Szmek 7fd7dab90f
Merge pull request #13554 from keur/systemctl_status_timer
systemctl: Add timer activation to status
2019-11-08 14:19:40 +01:00
Zbigniew Jędrzejewski-Szmek bc9aa96bbd systemctl: simplify printing of Triggers/TriggeredBy 2019-11-05 22:01:46 +01:00
Kevin Kuehler 0d588deae2 systemctl: Align all status outputs to TriggeredBy 2019-11-05 21:51:31 +01:00
Kevin Kuehler 965c5d1d5a systemctl: Add TriggeredBy and Triggers to status
For all units that aren't timers, if it is activated by another unit,
add the triggering unit under the  "TriggeredBy:" header. If a unit can
trigger other units, print the units it triggers other the "Triggers:"
header.
2019-11-05 21:51:31 +01:00
2 changed files with 77 additions and 43 deletions

1
TODO
View File

@ -1113,7 +1113,6 @@ External:
- <command> <verb> -<TAB> should complete options, but currently does not - <command> <verb> -<TAB> should complete options, but currently does not
- systemctl add-wants,add-requires - systemctl add-wants,add-requires
* systemctl status foo.service should say that it is trigger by foo.timer
* systemctl status should know about 'systemd-analyze calendar ... --iterations=' * systemctl status should know about 'systemd-analyze calendar ... --iterations='
* If timer has just OnInactiveSec=..., it should fire after a specified time * If timer has just OnInactiveSec=..., it should fire after a specified time
after being started. after being started.

View File

@ -4050,6 +4050,9 @@ typedef struct UnitStatusInfo {
char **dropin_paths; char **dropin_paths;
char **triggered_by;
char **triggers;
const char *load_error; const char *load_error;
const char *result; const char *result;
@ -4134,6 +4137,8 @@ static void unit_status_info_free(UnitStatusInfo *info) {
strv_free(info->documentation); strv_free(info->documentation);
strv_free(info->dropin_paths); strv_free(info->dropin_paths);
strv_free(info->triggered_by);
strv_free(info->triggers);
strv_free(info->listen); strv_free(info->listen);
while ((c = info->conditions)) { while ((c = info->conditions)) {
@ -4147,6 +4152,17 @@ static void unit_status_info_free(UnitStatusInfo *info) {
} }
} }
static void format_active_state(const char *active_state, const char **active_on, const char **active_off) {
if (streq_ptr(active_state, "failed")) {
*active_on = ansi_highlight_red();
*active_off = ansi_normal();
} else if (STRPTR_IN_SET(active_state, "active", "reloading")) {
*active_on = ansi_highlight_green();
*active_off = ansi_normal();
} else
*active_on = *active_off = "";
}
static void print_status_info( static void print_status_info(
sd_bus *bus, sd_bus *bus,
UnitStatusInfo *i, UnitStatusInfo *i,
@ -4166,14 +4182,7 @@ static void print_status_info(
/* This shows pretty information about a unit. See /* This shows pretty information about a unit. See
* print_property() for a low-level property printer */ * print_property() for a low-level property printer */
if (streq_ptr(i->active_state, "failed")) { format_active_state(i->active_state, &active_on, &active_off);
active_on = ansi_highlight_red();
active_off = ansi_normal();
} else if (STRPTR_IN_SET(i->active_state, "active", "reloading")) {
active_on = ansi_highlight_green();
active_off = ansi_normal();
} else
active_on = active_off = "";
printf("%s%s%s %s", active_on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), active_off, strna(i->id)); printf("%s%s%s %s", active_on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), active_off, strna(i->id));
@ -4278,6 +4287,18 @@ static void print_status_info(
else else
printf("\n"); printf("\n");
STRV_FOREACH(t, i->triggered_by) {
UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
(void) get_state_one_unit(bus, *t, &state);
format_active_state(unit_active_state_to_string(state), &on, &off);
printf("%s %s%s%s %s\n",
t == i->triggered_by ? "TriggeredBy:" : " ",
on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off,
*t);
}
if (endswith(i->id, ".timer")) { if (endswith(i->id, ".timer")) {
char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX], char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
tstamp2[FORMAT_TIMESTAMP_MAX]; tstamp2[FORMAT_TIMESTAMP_MAX];
@ -4299,6 +4320,18 @@ static void print_status_info(
printf("n/a\n"); printf("n/a\n");
} }
STRV_FOREACH(t, i->triggers) {
UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
(void) get_state_one_unit(bus, *t, &state);
format_active_state(unit_active_state_to_string(state), &on, &off);
printf("%s %s%s%s %s\n",
t == i->triggers ? " Triggers:" : " ",
on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off,
*t);
}
if (!i->condition_result && i->condition_timestamp > 0) { if (!i->condition_result && i->condition_timestamp > 0) {
UnitCondition *c; UnitCondition *c;
int n = 0; int n = 0;
@ -5510,6 +5543,8 @@ static int show_one(
{ "DropInPaths", "as", NULL, offsetof(UnitStatusInfo, dropin_paths) }, { "DropInPaths", "as", NULL, offsetof(UnitStatusInfo, dropin_paths) },
{ "LoadError", "(ss)", map_load_error, offsetof(UnitStatusInfo, load_error) }, { "LoadError", "(ss)", map_load_error, offsetof(UnitStatusInfo, load_error) },
{ "Result", "s", NULL, offsetof(UnitStatusInfo, result) }, { "Result", "s", NULL, offsetof(UnitStatusInfo, result) },
{ "TriggeredBy", "as", NULL, offsetof(UnitStatusInfo, triggered_by) },
{ "Triggers", "as", NULL, offsetof(UnitStatusInfo, triggers) },
{ "InactiveExitTimestamp", "t", NULL, offsetof(UnitStatusInfo, inactive_exit_timestamp) }, { "InactiveExitTimestamp", "t", NULL, offsetof(UnitStatusInfo, inactive_exit_timestamp) },
{ "InactiveExitTimestampMonotonic", "t", NULL, offsetof(UnitStatusInfo, inactive_exit_timestamp_monotonic) }, { "InactiveExitTimestampMonotonic", "t", NULL, offsetof(UnitStatusInfo, inactive_exit_timestamp_monotonic) },
{ "ActiveEnterTimestamp", "t", NULL, offsetof(UnitStatusInfo, active_enter_timestamp) }, { "ActiveEnterTimestamp", "t", NULL, offsetof(UnitStatusInfo, active_enter_timestamp) },