diff options
author | Lennart Poettering <lennart@poettering.net> | 2010-07-17 00:58:47 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2010-07-17 00:58:47 +0200 |
commit | 5de9682cd647f07f043254fde70e62e1aa837476 (patch) | |
tree | be788640f3b80c89da3a39f75884b3bf8469878d /src | |
parent | 45fb0699c45d2e042e04a53e3ea00501e3f65f59 (diff) |
unit: introduce OnFailure dependencies to activate units on failure of other units, as a way to implement an automatic rescue shell
Diffstat (limited to 'src')
-rw-r--r-- | src/dbus-unit.h | 2 | ||||
-rw-r--r-- | src/unit.c | 34 | ||||
-rw-r--r-- | src/unit.h | 3 |
3 files changed, 28 insertions, 11 deletions
diff --git a/src/dbus-unit.h b/src/dbus-unit.h index d4af5a8b23..e93d65892a 100644 --- a/src/dbus-unit.h +++ b/src/dbus-unit.h @@ -70,6 +70,7 @@ " <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" \ @@ -105,6 +106,7 @@ { "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 }, \ diff --git a/src/unit.c b/src/unit.c index e46182adad..44dc811630 100644 --- a/src/unit.c +++ b/src/unit.c @@ -987,9 +987,6 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { 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); @@ -1072,6 +1069,16 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns) { 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)) { @@ -1294,6 +1301,7 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen [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 }; @@ -1301,7 +1309,6 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen 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 @@ -1317,10 +1324,13 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen 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) @@ -1329,10 +1339,11 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen 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) { @@ -2097,7 +2108,8 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = { [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); diff --git a/src/unit.h b/src/unit.h index d3a00797f9..55fe0fa60e 100644 --- a/src/unit.h +++ b/src/unit.h @@ -114,6 +114,9 @@ enum UnitDependency { UNIT_BEFORE, /* inverse of 'before' is 'after' and vice versa */ UNIT_AFTER, + /* On Failure */ + UNIT_ON_FAILURE, + /* Reference information for GC logic */ UNIT_REFERENCES, /* Inverse of 'references' is 'referenced_by' */ UNIT_REFERENCED_BY, |