condition_dump_list(u->meta.conditions, f, prefix);
+ if (dual_timestamp_is_set(&u->meta.condition_timestamp))
+ fprintf(f,
+ "%s\tCondition Timestamp: %s\n"
+ "%s\tCondition Result: %s\n",
+ prefix, strna(format_timestamp(timestamp1, sizeof(timestamp1), u->meta.condition_timestamp.realtime)),
+ prefix, yes_no(u->meta.condition_result));
+
for (d = 0; d < _UNIT_DEPENDENCY_MAX; d++) {
Unit *other;
target->meta.load_state != UNIT_LOADED)
return 0;
+ /* If either side wants no automatic dependencies, then let's
+ * skip this */
+ if (!u->meta.default_dependencies ||
+ target->meta.default_dependencies)
+ return 0;
+
/* Don't create loops */
if (set_get(target->meta.dependencies[UNIT_BEFORE], u))
return 0;
}
static int unit_add_default_dependencies(Unit *u) {
+ static const UnitDependency deps[] = {
+ UNIT_REQUIRED_BY,
+ UNIT_REQUIRED_BY_OVERRIDABLE,
+ UNIT_WANTED_BY,
+ UNIT_BOUND_BY
+ };
+
Unit *target;
Iterator i;
int r;
+ unsigned k;
assert(u);
- SET_FOREACH(target, u->meta.dependencies[UNIT_REQUIRED_BY], i)
- if ((r = unit_add_default_target_dependency(u, target)) < 0)
- return r;
-
- SET_FOREACH(target, u->meta.dependencies[UNIT_REQUIRED_BY_OVERRIDABLE], i)
- if ((r = unit_add_default_target_dependency(u, target)) < 0)
- return r;
-
- SET_FOREACH(target, u->meta.dependencies[UNIT_WANTED_BY], i)
- if ((r = unit_add_default_target_dependency(u, target)) < 0)
- return r;
-
- SET_FOREACH(target, u->meta.dependencies[UNIT_BOUND_BY], i)
- if ((r = unit_add_default_target_dependency(u, target)) < 0)
- return r;
+ for (k = 0; k < ELEMENTSOF(deps); k++)
+ SET_FOREACH(target, u->meta.dependencies[deps[k]], i)
+ if ((r = unit_add_default_target_dependency(u, target)) < 0)
+ return r;
return 0;
}
return r;
}
+bool unit_condition_test(Unit *u) {
+ assert(u);
+
+ dual_timestamp_get(&u->meta.condition_timestamp);
+ u->meta.condition_result = condition_test_list(u->meta.conditions);
+
+ return u->meta.condition_result;
+}
+
/* Errors:
* -EBADR: This unit type does not support starting.
* -EALREADY: Unit is already started.
return -EALREADY;
/* If the conditions failed, don't do anything at all */
- if (!condition_test_list(u->meta.conditions)) {
+ if (!unit_condition_test(u)) {
log_debug("Starting of %s requested but condition failed. Ignoring.", u->meta.id);
return -EALREADY;
}
retroactively_stop_dependencies(u);
}
- if (ns != os && ns == UNIT_FAILED) {
+ if (ns != os && ns == UNIT_FAILED && u->meta.manager->n_deserializing <= 0) {
log_notice("Unit %s entered failed state.", u->meta.id);
unit_trigger_on_failure(u);
}
* yet connected. */
bus_init(u->meta.manager, true);
- if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE))
- /* The syslog daemon just might have become
- * available, hence try to connect to it, if
- * we aren't yet connected. */
- log_open();
-
if (u->meta.type == UNIT_SERVICE &&
!UNIT_IS_ACTIVE_OR_RELOADING(os)) {
/* Write audit record if we have just finished starting up */
} else {
- if (unit_has_name(u, SPECIAL_SYSLOG_SERVICE))
- /* The syslog daemon might just have
- * terminated, hence try to disconnect from
- * it. */
- log_close_syslog();
-
/* We don't care about D-Bus here, since we'll get an
* asynchronous notification for it anyway. */
unit_add_to_dbus_queue(u);
unit_add_to_gc_queue(u);
+
+ manager_recheck_syslog(u->meta.manager);
}
int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
dual_timestamp_serialize(f, "active-enter-timestamp", &u->meta.active_enter_timestamp);
dual_timestamp_serialize(f, "active-exit-timestamp", &u->meta.active_exit_timestamp);
dual_timestamp_serialize(f, "inactive-enter-timestamp", &u->meta.inactive_enter_timestamp);
+ dual_timestamp_serialize(f, "condition-timestamp", &u->meta.condition_timestamp);
+
+ if (dual_timestamp_is_set(&u->meta.condition_timestamp))
+ unit_serialize_item(u, f, "condition-result", yes_no(u->meta.condition_result));
/* End marker */
fputc('\n', f);
} else if (streq(l, "inactive-enter-timestamp")) {
dual_timestamp_deserialize(v, &u->meta.inactive_enter_timestamp);
continue;
+ } else if (streq(l, "condition-timestamp")) {
+ dual_timestamp_deserialize(v, &u->meta.condition_timestamp);
+ continue;
+ } else if (streq(l, "condition-result")) {
+ int b;
+
+ if ((b = parse_boolean(v)) < 0)
+ log_debug("Failed to parse condition result value %s", v);
+ else
+ u->meta.condition_result = b;
+
+ continue;
}
if ((r = UNIT_VTABLE(u)->deserialize_item(u, l, v, fds)) < 0)
return r;
if (u->meta.deserialized_job >= 0) {
- if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_FAIL, false, NULL, NULL)) < 0)
+ if ((r = manager_add_job(u->meta.manager, u->meta.deserialized_job, u, JOB_IGNORE_DEPENDENCIES, false, NULL, NULL)) < 0)
return r;
u->meta.deserialized_job = _JOB_TYPE_INVALID;