" <property name=\"Conflicts\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"Before\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"After\" type=\"as\" access=\"read\"/>\n" \
+ " <property name=\"OnFailure\" type=\"as\" access=\"read\"/>\n" \
" <property name=\"Description\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"LoadState\" type=\"s\" access=\"read\"/>\n" \
" <property name=\"ActiveState\" type=\"s\" access=\"read\"/>\n" \
{ "org.freedesktop.systemd1.Unit", "Conflicts", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_CONFLICTS] }, \
{ "org.freedesktop.systemd1.Unit", "Before", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_BEFORE] }, \
{ "org.freedesktop.systemd1.Unit", "After", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_AFTER] }, \
+ { "org.freedesktop.systemd1.Unit", "OnFailure", bus_unit_append_dependencies, "as", u->meta.dependencies[UNIT_ON_FAILURE] }, \
{ "org.freedesktop.systemd1.Unit", "Description", bus_unit_append_description, "s", u }, \
{ "org.freedesktop.systemd1.Unit", "LoadState", bus_unit_append_load_state, "s", &u->meta.load_state }, \
{ "org.freedesktop.systemd1.Unit", "ActiveState", bus_unit_append_active_state, "s", u }, \
else if (UNIT_IS_ACTIVE_OR_RELOADING(os) && !UNIT_IS_ACTIVE_OR_RELOADING(ns))
u->meta.active_exit_timestamp = ts;
- if (ns != os && ns == UNIT_MAINTENANCE)
- log_notice("Unit %s entered maintenance state.", u->meta.id);
-
if (UNIT_IS_INACTIVE_OR_MAINTENANCE(ns))
cgroup_bonding_trim_list(u->meta.cgroup_bondings, true);
retroactively_stop_dependencies(u);
}
+ if (ns != os && ns == UNIT_MAINTENANCE) {
+ Iterator i;
+ Unit *other;
+
+ SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i)
+ manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
+
+ log_notice("Unit %s entered maintenance state.", u->meta.id);
+ }
+
/* Some names are special */
if (UNIT_IS_ACTIVE_OR_RELOADING(ns)) {
if (unit_has_name(u, SPECIAL_DBUS_SERVICE)) {
[UNIT_CONFLICTS] = UNIT_CONFLICTS,
[UNIT_BEFORE] = UNIT_AFTER,
[UNIT_AFTER] = UNIT_BEFORE,
+ [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
[UNIT_REFERENCES] = UNIT_REFERENCED_BY,
[UNIT_REFERENCED_BY] = UNIT_REFERENCES
};
assert(u);
assert(d >= 0 && d < _UNIT_DEPENDENCY_MAX);
- assert(inverse_table[d] != _UNIT_DEPENDENCY_INVALID);
assert(other);
/* We won't allow dependencies on ourselves. We will not
return -EINVAL;
}
- if ((r = set_ensure_allocated(&u->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0 ||
- (r = set_ensure_allocated(&other->meta.dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
+ if ((r = set_ensure_allocated(&u->meta.dependencies[d], trivial_hash_func, trivial_compare_func)) < 0)
return r;
+ if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
+ if ((r = set_ensure_allocated(&other->meta.dependencies[inverse_table[d]], trivial_hash_func, trivial_compare_func)) < 0)
+ return r;
+
if (add_reference)
if ((r = set_ensure_allocated(&u->meta.dependencies[UNIT_REFERENCES], trivial_hash_func, trivial_compare_func)) < 0 ||
(r = set_ensure_allocated(&other->meta.dependencies[UNIT_REFERENCED_BY], trivial_hash_func, trivial_compare_func)) < 0)
if ((q = set_put(u->meta.dependencies[d], other)) < 0)
return q;
- if ((v = set_put(other->meta.dependencies[inverse_table[d]], u)) < 0) {
- r = v;
- goto fail;
- }
+ if (inverse_table[d] != _UNIT_DEPENDENCY_INVALID)
+ if ((v = set_put(other->meta.dependencies[inverse_table[d]], u)) < 0) {
+ r = v;
+ goto fail;
+ }
if (add_reference) {
if ((w = set_put(u->meta.dependencies[UNIT_REFERENCES], other)) < 0) {
[UNIT_BEFORE] = "Before",
[UNIT_AFTER] = "After",
[UNIT_REFERENCES] = "References",
- [UNIT_REFERENCED_BY] = "ReferencedBy"
+ [UNIT_REFERENCED_BY] = "ReferencedBy",
+ [UNIT_ON_FAILURE] = "OnFailure"
};
DEFINE_STRING_TABLE_LOOKUP(unit_dependency, UnitDependency);