summaryrefslogtreecommitdiff
path: root/src/systemctl
diff options
context:
space:
mode:
authorWaLyong Cho <walyong.cho@samsung.com>2016-07-07 22:45:05 +0900
committerWaLyong Cho <walyong.cho@samsung.com>2016-07-11 10:19:55 +0900
commitd5db7fe66a349574a000f47c4bb5623064d47d86 (patch)
treeeeb700b02a4b678a29a3fae95971ecfbed31a192 /src/systemctl
parentd6cdc4cd4b58cfff4b44e1201e54f05b4a38d2d4 (diff)
systemctl: show failed condition list
When unit has multiple condition list, systemctl is not showing which conditions were failed. When user want to know which conditions were failed, user has to check for each conditions. So, show failed condition list also.
Diffstat (limited to 'src/systemctl')
-rw-r--r--src/systemctl/systemctl.c85
1 files changed, 69 insertions, 16 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index b575437bcb..84278e9bdb 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -3455,6 +3455,24 @@ static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
return 1;
}
+typedef struct UnitCondition {
+ char *name;
+ bool trigger;
+ bool negate;
+ char *param;
+ int tristate;
+
+ LIST_FIELDS(struct UnitCondition, condition);
+} 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;
@@ -3501,10 +3519,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, condition);
usec_t assert_timestamp;
bool assert_result;
@@ -3664,19 +3679,32 @@ 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(condition, c, i->condition) {
+ if (c->tristate < 0)
+ n++;
+ }
+
+ LIST_FOREACH(condition, c, i->condition) {
+ if (c->tristate >= 0)
+ continue;
+
+ 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) {
@@ -4169,13 +4197,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, &param, &state)) > 0) {
+ UnitCondition *c;
+
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;
+
+ 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(condition, i->condition, c);
}
if (r < 0)
return bus_log_parse_error(r);
@@ -4583,6 +4630,7 @@ static int show_one(
.tasks_max = (uint64_t) -1,
};
ExecStatusInfo *p;
+ UnitCondition *c;
int r;
assert(path);
@@ -4701,6 +4749,11 @@ static int show_one(
strv_free(info.dropin_paths);
strv_free(info.listen);
+ while ((c = info.condition)) {
+ LIST_REMOVE(condition, info.condition, c);
+ unit_condition_free(c);
+ }
+
while ((p = info.exec)) {
LIST_REMOVE(exec, info.exec, p);
exec_status_info_free(p);