diff options
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | src/core/condition.c | 8 | ||||
-rw-r--r-- | src/core/condition.h | 6 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 177 | ||||
-rw-r--r-- | src/core/dbus-unit.h | 1 | ||||
-rw-r--r-- | src/core/unit.c | 3 | ||||
-rw-r--r-- | src/systemctl/systemctl.c | 62 |
7 files changed, 180 insertions, 79 deletions
@@ -532,8 +532,6 @@ Features: when done. That means clients don't get a successful method reply, but much rather a disconnect on success. -* remember which condition failed for services, not just the fact that something failed - * use opterr = 0 for all getopt tools * properly handle loop back mounts via fstab, especially regards to fsck/passno diff --git a/src/core/condition.c b/src/core/condition.c index 2fbc5ad0e6..6c387450af 100644 --- a/src/core/condition.c +++ b/src/core/condition.c @@ -250,7 +250,7 @@ static bool test_ac_power(const char *parameter) { return (on_ac_power() != 0) == !!r; } -bool condition_test(Condition *c) { +static bool condition_test(Condition *c) { assert(c); switch(c->type) { @@ -358,6 +358,7 @@ bool condition_test_list(const char *unit, Condition *first) { c->parameter, b ? "succeeded" : "failed", unit); + c->state = b ? 1 : -1; if (!c->trigger && !b) return false; @@ -377,12 +378,13 @@ void condition_dump(Condition *c, FILE *f, const char *prefix) { prefix = ""; fprintf(f, - "%s\t%s: %s%s%s\n", + "%s\t%s: %s%s%s %s\n", prefix, condition_type_to_string(c->type), c->trigger ? "|" : "", c->negate ? "!" : "", - c->parameter); + c->parameter, + c->state < 0 ? "failed" : c->state > 0 ? "succeeded" : "untested"); } void condition_dump_list(Condition *first, FILE *f, const char *prefix) { diff --git a/src/core/condition.h b/src/core/condition.h index 2ad77876e4..1813b735a5 100644 --- a/src/core/condition.h +++ b/src/core/condition.h @@ -48,11 +48,14 @@ typedef enum ConditionType { typedef struct Condition { ConditionType type; - char *parameter; bool trigger:1; bool negate:1; + char *parameter; + + int state; + LIST_FIELDS(struct Condition, conditions); } Condition; @@ -60,7 +63,6 @@ Condition* condition_new(ConditionType type, const char *parameter, bool trigger void condition_free(Condition *c); void condition_free_list(Condition *c); -bool condition_test(Condition *c); bool condition_test_list(const char *unit, Condition *c); void condition_dump(Condition *c, FILE *f, const char *prefix); diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index ba4d42652e..4cd3a13fd2 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -311,6 +311,58 @@ static int bus_unit_append_need_daemon_reload(DBusMessageIter *i, const char *pr return 0; } +static int bus_property_append_condition(DBusMessageIter *i, const char *property, void *data) { + Condition **cp = data; + Condition *c; + const char *name, *param; + dbus_bool_t trigger, negate; + dbus_int32_t state; + DBusMessageIter sub; + + assert(i); + assert(property); + assert(cp); + + c = *cp; + assert(c); + + name = condition_type_to_string(c->type); + param = c->parameter; + trigger = c->trigger; + negate = c->negate; + state = c->state; + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_STRUCT, NULL, &sub) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &name) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &trigger) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_BOOLEAN, &negate) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, ¶m) || + !dbus_message_iter_append_basic(&sub, DBUS_TYPE_INT32, &state) || + !dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + +static int bus_property_append_condition_list(DBusMessageIter *i, const char *property, void *data) { + Condition **first = data, *c; + DBusMessageIter sub; + + assert(i); + assert(data); + + if (!dbus_message_iter_open_container(i, DBUS_TYPE_ARRAY, "(sbbsi)", &sub)) + return -ENOMEM; + + LIST_FOREACH(conditions, c, *first) + bus_property_append_condition(&sub, property, &c); + + if (!dbus_message_iter_close_container(i, &sub)) + return -ENOMEM; + + return 0; +} + static int bus_unit_append_load_error(DBusMessageIter *i, const char *property, void *data) { Unit *u = data; const char *name, *message; @@ -975,68 +1027,69 @@ int bus_unit_set_properties( } const BusProperty bus_unit_properties[] = { - { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, - { "Names", bus_unit_append_names, "as", 0 }, - { "Following", bus_unit_append_following, "s", 0 }, - { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, - { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, - { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, - { "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true }, - { "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true }, - { "BindsTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]), true }, - { "PartOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PART_OF]), true }, - { "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true }, - { "RequiredByOverridable",bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true }, - { "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true }, - { "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true }, - { "ConsistsOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), true }, - { "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true }, - { "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true }, - { "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true }, - { "After", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_AFTER]), true }, - { "OnFailure", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]), true }, - { "Triggers", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]), true }, - { "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true }, - { "PropagatesReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), true }, - { "ReloadPropagatedFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), true }, - { "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true }, - { "Documentation", bus_property_append_strv, "as", offsetof(Unit, documentation), true }, - { "Description", bus_unit_append_description, "s", 0 }, - { "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) }, - { "ActiveState", bus_unit_append_active_state, "s", 0 }, - { "SubState", bus_unit_append_sub_state, "s", 0 }, - { "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true }, - { "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true }, - { "DropInPaths", bus_property_append_strv, "as", offsetof(Unit, dropin_paths), true }, - { "UnitFileState", bus_unit_append_file_state, "s", 0 }, - { "InactiveExitTimestamp",bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) }, - { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) }, - { "ActiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.realtime) }, - { "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.monotonic) }, - { "ActiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.realtime) }, - { "ActiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.monotonic) }, - { "InactiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.realtime) }, - { "InactiveEnterTimestampMonotonic",bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) }, - { "CanStart", bus_unit_append_can_start, "b", 0 }, - { "CanStop", bus_unit_append_can_stop, "b", 0 }, - { "CanReload", bus_unit_append_can_reload, "b", 0 }, - { "CanIsolate", bus_unit_append_can_isolate, "b", 0 }, - { "Job", bus_unit_append_job, "(uo)", 0 }, - { "StopWhenUnneeded", bus_property_append_bool, "b", offsetof(Unit, stop_when_unneeded) }, - { "RefuseManualStart", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_start) }, - { "RefuseManualStop", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_stop) }, - { "AllowIsolate", bus_property_append_bool, "b", offsetof(Unit, allow_isolate) }, - { "DefaultDependencies", bus_property_append_bool, "b", offsetof(Unit, default_dependencies) }, - { "OnFailureIsolate", bus_property_append_bool, "b", offsetof(Unit, on_failure_isolate) }, - { "IgnoreOnIsolate", bus_property_append_bool, "b", offsetof(Unit, ignore_on_isolate) }, - { "IgnoreOnSnapshot", bus_property_append_bool, "b", offsetof(Unit, ignore_on_snapshot) }, - { "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", 0 }, - { "JobTimeoutUSec", bus_property_append_usec, "t", offsetof(Unit, job_timeout) }, - { "ConditionTimestamp", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.realtime) }, - { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, - { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, - { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, - { "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) }, + { "Id", bus_property_append_string, "s", offsetof(Unit, id), true }, + { "Names", bus_unit_append_names, "as", 0 }, + { "Following", bus_unit_append_following, "s", 0 }, + { "Requires", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES]), true }, + { "RequiresOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRES_OVERRIDABLE]), true }, + { "Requisite", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE]), true }, + { "RequisiteOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUISITE_OVERRIDABLE]), true }, + { "Wants", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTS]), true }, + { "BindsTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BINDS_TO]), true }, + { "PartOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PART_OF]), true }, + { "RequiredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY]), true }, + { "RequiredByOverridable", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_REQUIRED_BY_OVERRIDABLE]), true }, + { "WantedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_WANTED_BY]), true }, + { "BoundBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BOUND_BY]), true }, + { "ConsistsOf", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONSISTS_OF]), true }, + { "Conflicts", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTS]), true }, + { "ConflictedBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_CONFLICTED_BY]), true }, + { "Before", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_BEFORE]), true }, + { "After", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_AFTER]), true }, + { "OnFailure", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]), true }, + { "Triggers", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]), true }, + { "TriggeredBy", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]), true }, + { "PropagatesReloadTo", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]), true }, + { "ReloadPropagatedFrom", bus_unit_append_dependencies, "as", offsetof(Unit, dependencies[UNIT_RELOAD_PROPAGATED_FROM]), true }, + { "RequiresMountsFor", bus_property_append_strv, "as", offsetof(Unit, requires_mounts_for), true }, + { "Documentation", bus_property_append_strv, "as", offsetof(Unit, documentation), true }, + { "Description", bus_unit_append_description, "s", 0 }, + { "LoadState", bus_unit_append_load_state, "s", offsetof(Unit, load_state) }, + { "ActiveState", bus_unit_append_active_state, "s", 0 }, + { "SubState", bus_unit_append_sub_state, "s", 0 }, + { "FragmentPath", bus_property_append_string, "s", offsetof(Unit, fragment_path), true }, + { "SourcePath", bus_property_append_string, "s", offsetof(Unit, source_path), true }, + { "DropInPaths", bus_property_append_strv, "as", offsetof(Unit, dropin_paths), true }, + { "UnitFileState", bus_unit_append_file_state, "s", 0 }, + { "InactiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.realtime) }, + { "InactiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_exit_timestamp.monotonic) }, + { "ActiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.realtime) }, + { "ActiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_enter_timestamp.monotonic) }, + { "ActiveExitTimestamp", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.realtime) }, + { "ActiveExitTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, active_exit_timestamp.monotonic) }, + { "InactiveEnterTimestamp", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.realtime) }, + { "InactiveEnterTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, inactive_enter_timestamp.monotonic) }, + { "CanStart", bus_unit_append_can_start, "b", 0 }, + { "CanStop", bus_unit_append_can_stop, "b", 0 }, + { "CanReload", bus_unit_append_can_reload, "b", 0 }, + { "CanIsolate", bus_unit_append_can_isolate, "b", 0 }, + { "Job", bus_unit_append_job, "(uo)", 0 }, + { "StopWhenUnneeded", bus_property_append_bool, "b", offsetof(Unit, stop_when_unneeded) }, + { "RefuseManualStart", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_start) }, + { "RefuseManualStop", bus_property_append_bool, "b", offsetof(Unit, refuse_manual_stop) }, + { "AllowIsolate", bus_property_append_bool, "b", offsetof(Unit, allow_isolate) }, + { "DefaultDependencies", bus_property_append_bool, "b", offsetof(Unit, default_dependencies) }, + { "OnFailureIsolate", bus_property_append_bool, "b", offsetof(Unit, on_failure_isolate) }, + { "IgnoreOnIsolate", bus_property_append_bool, "b", offsetof(Unit, ignore_on_isolate) }, + { "IgnoreOnSnapshot", bus_property_append_bool, "b", offsetof(Unit, ignore_on_snapshot) }, + { "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", 0 }, + { "JobTimeoutUSec", bus_property_append_usec, "t", offsetof(Unit, job_timeout) }, + { "ConditionTimestamp", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.realtime) }, + { "ConditionTimestampMonotonic", bus_property_append_usec, "t", offsetof(Unit, condition_timestamp.monotonic) }, + { "ConditionResult", bus_property_append_bool, "b", offsetof(Unit, condition_result) }, + { "Conditions", bus_property_append_condition_list, "a(sbbsi)", offsetof(Unit, conditions) }, + { "LoadError", bus_unit_append_load_error, "(ss)", 0 }, + { "Transient", bus_property_append_bool, "b", offsetof(Unit, transient) }, {} }; diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h index d3f7ec621e..3064cd552a 100644 --- a/src/core/dbus-unit.h +++ b/src/core/dbus-unit.h @@ -125,6 +125,7 @@ " <property name=\"ConditionTimestamp\" type=\"t\" access=\"read\"/>\n" \ " <property name=\"ConditionTimestampMonotonic\" type=\"t\" access=\"read\"/>\n" \ " <property name=\"ConditionResult\" type=\"b\" access=\"read\"/>\n" \ + " <property name=\"Conditions\" type=\"a(sbbsi)\" access=\"read\"/>\n" \ " <property name=\"LoadError\" type=\"(ss)\" access=\"read\"/>\n" \ " <property name=\"Transient\" type=\"b\" access=\"read\"/>\n" \ " </interface>\n" diff --git a/src/core/unit.c b/src/core/unit.c index a201fa4041..0e9329f8c9 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1125,7 +1125,8 @@ int unit_start(Unit *u) { } /* Forward to the main object, if we aren't it. */ - if ((following = unit_following(u))) { + following = unit_following(u); + if (following) { log_debug_unit(u->id, "Redirecting start request from %s to %s.", u->id, following->id); return unit_start(following); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 6fdbc417b6..b3b679e0af 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2534,6 +2534,10 @@ 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_param; /* Socket */ unsigned n_accepted; @@ -2676,10 +2680,15 @@ static void print_status_info(UnitStatusInfo *i) { s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp); s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp); - if (s1) - printf(" start condition failed at %s; %s\n", s2, s1); - else if (s2) - printf(" start condition failed at %s\n", s2); + printf(" start condition failed at %s%s%s\n", + s2, s1 ? "; " : "", s1 ? 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_param); } if (i->sysfs_path) @@ -3038,15 +3047,18 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn ExecStatusInfo *info; int r; - if (!(info = new0(ExecStatusInfo, 1))) + info = new0(ExecStatusInfo, 1); + if (!info) return -ENOMEM; - if (!(info->name = strdup(name))) { + info->name = strdup(name); + if (!info->name) { free(info); return -ENOMEM; } - if ((r = exec_status_info_deserialize(&sub, info)) < 0) { + r = exec_status_info_deserialize(&sub, info); + if (r < 0) { free(info); return r; } @@ -3056,7 +3068,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn dbus_message_iter_next(&sub); } - } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && streq(name, "Listen")) { + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && + streq(name, "Listen")) { DBusMessageIter sub, sub2; dbus_message_iter_recurse(iter, &sub); @@ -3082,7 +3095,8 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn return 0; - } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING && streq(name, "DropInPaths")) { + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRING && + streq(name, "DropInPaths")) { int r = bus_parse_strv_iter(iter, &i->dropin_paths); if (r < 0) return r; @@ -3105,6 +3119,36 @@ static int status_property(const char *name, DBusMessageIter *iter, UnitStatusIn dbus_message_iter_next(&sub); } + + } else if (dbus_message_iter_get_element_type(iter) == DBUS_TYPE_STRUCT && + streq(name, "Conditions")) { + DBusMessageIter sub, sub2; + + dbus_message_iter_recurse(iter, &sub); + while (dbus_message_iter_get_arg_type(&sub) == DBUS_TYPE_STRUCT) { + const char *cond, *param; + dbus_bool_t trigger, negate; + dbus_int32_t state; + + dbus_message_iter_recurse(&sub, &sub2); + log_debug("here"); + + if(bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, &cond, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &trigger, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_BOOLEAN, &negate, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_STRING, ¶m, true) >= 0 && + bus_iter_get_basic_and_next(&sub2, DBUS_TYPE_INT32, &state, false) >= 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_param = param; + } + } + + dbus_message_iter_next(&sub); + } } break; |