diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-07-25 11:27:14 -0400 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-07-25 11:27:14 -0400 |
commit | 3d391fa84f0b0f5708246848c713f2d52eaf92fe (patch) | |
tree | 3c57040a57d57d6f3cee1bb8837da09310597554 /src/systemctl/systemctl.c | |
parent | 26598be814ae4f64de812898e4012fb329559326 (diff) | |
parent | b1ed76ae19bbbe9b836f3dae700cf610ce5dd869 (diff) |
Merge pull request #3681 from walyong/systemctl_condition
Diffstat (limited to 'src/systemctl/systemctl.c')
-rw-r--r-- | src/systemctl/systemctl.c | 83 |
1 files changed, 66 insertions, 17 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index bfd770e4df..7df2fa5421 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -3458,6 +3458,24 @@ static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) { return 1; } +typedef struct UnitCondition { + char *name; + char *param; + bool trigger; + bool negate; + int tristate; + + LIST_FIELDS(struct UnitCondition, conditions); +} UnitCondition; + +static void unit_condition_free(UnitCondition *c) { + assert(c); + + free(c->name); + free(c->param); + free(c); +} + typedef struct UnitStatusInfo { const char *id; const char *load_state; @@ -3504,10 +3522,7 @@ typedef struct UnitStatusInfo { usec_t condition_timestamp; bool condition_result; - bool failed_condition_trigger; - bool failed_condition_negate; - const char *failed_condition; - const char *failed_condition_parameter; + LIST_HEAD(UnitCondition, conditions); usec_t assert_timestamp; bool assert_result; @@ -3667,19 +3682,28 @@ static void print_status_info( printf("\n"); if (!i->condition_result && i->condition_timestamp > 0) { + UnitCondition *c; + int n = 0; + s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp); s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); printf("Condition: start %scondition failed%s at %s%s%s\n", ansi_highlight_yellow(), ansi_normal(), s2, s1 ? "; " : "", strempty(s1)); - if (i->failed_condition_trigger) - printf(" none of the trigger conditions were met\n"); - else if (i->failed_condition) - printf(" %s=%s%s was not met\n", - i->failed_condition, - i->failed_condition_negate ? "!" : "", - i->failed_condition_parameter); + + LIST_FOREACH(conditions, c, i->conditions) + if (c->tristate < 0) + n++; + + LIST_FOREACH(conditions, c, i->conditions) + if (c->tristate < 0) + printf(" %s %s=%s%s%s was not met\n", + --n ? special_glyph(TREE_BRANCH) : special_glyph(TREE_RIGHT), + c->name, + c->trigger ? "|" : "", + c->negate ? "!" : "", + c->param); } if (!i->assert_result && i->assert_timestamp > 0) { @@ -4174,13 +4198,32 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo * return bus_log_parse_error(r); while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) { - log_debug("%s %d %d %s %d", cond, trigger, negate, param, state); - if (state < 0 && (!trigger || !i->failed_condition)) { - i->failed_condition = cond; - i->failed_condition_trigger = trigger; - i->failed_condition_negate = negate; - i->failed_condition_parameter = param; + UnitCondition *c; + + log_debug("%s trigger=%d negate=%d %s →%d", cond, trigger, negate, param, state); + + c = new0(UnitCondition, 1); + if (!c) + return log_oom(); + + c->name = strdup(cond); + if (!c->name) { + free(c); + return log_oom(); } + + c->param = strdup(param); + if (!c->param) { + free(c->name); + free(c); + return log_oom(); + } + + c->trigger = trigger; + c->negate = negate; + c->tristate = state; + + LIST_PREPEND(conditions, i->conditions, c); } if (r < 0) return bus_log_parse_error(r); @@ -4588,6 +4631,7 @@ static int show_one( .tasks_max = (uint64_t) -1, }; ExecStatusInfo *p; + UnitCondition *c; int r; assert(path); @@ -4706,6 +4750,11 @@ static int show_one( strv_free(info.dropin_paths); strv_free(info.listen); + while ((c = info.conditions)) { + LIST_REMOVE(conditions, info.conditions, c); + unit_condition_free(c); + } + while ((p = info.exec)) { LIST_REMOVE(exec, info.exec, p); exec_status_info_free(p); |