From: Lennart Poettering Date: Thu, 7 Apr 2011 02:11:31 +0000 (+0200) Subject: unit: introduce OnFailureIsolate= X-Git-Tag: v25~84 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=222ae6a8d7e27dd36552cb9574e63cbdfdf2d264;p=systemd unit: introduce OnFailureIsolate= --- diff --git a/TODO b/TODO index e8c1388e..af264d3a 100644 --- a/TODO +++ b/TODO @@ -12,9 +12,11 @@ F15: * ntpd should pull in time-sync.target. (PENDING) +* bluetooth should be possible to disable (PENDING) + * add fstab fields to add wait timeouts, change Wants to Requires by local-fs.target -* hook emergency.target into local-fs.target in some way as OnFailure with isolate +* hook emergency.target into local-fs.target in some way as OnFailure with isolate, add warning log message * bind mounts are ignored https://bugzilla.redhat.com/show_bug.cgi?id=682662 @@ -22,12 +24,10 @@ F15: * 0595f9a1c182a84581749823ef47c5f292e545f9 is borked, freezes shutdown (path: after installing inotify watches, recheck file again to fix race) -* bluetooth should be possible to disable +Features: * fix alsa mixer restore to not print error when no config is stored -Features: - * don't trim empty cgroups https://bugzilla.redhat.com/show_bug.cgi?id=678555 @@ -49,7 +49,7 @@ Features: * introduce /usr/lib/binfmt.d/, /usr/lib/tmpfiles.d/ -* in pam_systemd: don't rely on /proc/self/loginuid in a container +* in pam_systemd: don't rely on /proc/self/loginuid in a container (check if audit caps are there) * take BSD file lock on tty devices when using them? diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 5460ebeb..0fc2fbe7 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -444,6 +444,22 @@ state. + + OnFailureIsolate= + + Takes a boolean + argument. If the + unit listed in + OnFailure= will be + enqueued in isolation mode, i.e. all + units that are not its dependency will + be stopped. If this is set only a + single unit may be listed in + OnFailure=. Defaults + to + . + + StopWhenUnneeded= diff --git a/src/dbus-unit.h b/src/dbus-unit.h index efb61797..dfbc82c0 100644 --- a/src/dbus-unit.h +++ b/src/dbus-unit.h @@ -148,6 +148,7 @@ { "org.freedesktop.systemd1.Unit", "RefuseManualStop", bus_property_append_bool, "b", &u->meta.refuse_manual_stop }, \ { "org.freedesktop.systemd1.Unit", "AllowIsolate", bus_property_append_bool, "b", &u->meta.allow_isolate }, \ { "org.freedesktop.systemd1.Unit", "DefaultDependencies", bus_property_append_bool, "b", &u->meta.default_dependencies }, \ + { "org.freedesktop.systemd1.Unit", "OnFailureIsolate", bus_property_append_bool, "b", &u->meta.on_failure_isolate }, \ { "org.freedesktop.systemd1.Unit", "DefaultControlGroup", bus_unit_append_default_cgroup, "s", u }, \ { "org.freedesktop.systemd1.Unit", "ControlGroup", bus_unit_append_cgroups, "as", u }, \ { "org.freedesktop.systemd1.Unit", "NeedDaemonReload", bus_unit_append_need_daemon_reload, "b", u }, \ diff --git a/src/job.c b/src/job.c index a3be7bec..dcfa323b 100644 --- a/src/job.c +++ b/src/job.c @@ -563,8 +563,14 @@ int job_finish_and_invalidate(Job *j, JobResult result) { * the unit itself. We don't tread JOB_CANCELED as failure in * this context. And JOB_FAILURE is already handled by the * unit itself. */ - if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) + if (result == JOB_TIMEOUT || result == JOB_DEPENDENCY) { + log_notice("Job %s/%s failed with result '%s'.", + u->meta.id, + job_type_to_string(t), + job_result_to_string(result)); + unit_trigger_on_failure(u); + } /* Try to start the next jobs that can be started */ SET_FOREACH(other, u->meta.dependencies[UNIT_AFTER], i) diff --git a/src/load-fragment.c b/src/load-fragment.c index 8635bdb2..c27c9d84 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -1851,6 +1851,7 @@ static int load_from_path(Unit *u, const char *path) { { "RefuseManualStop", config_parse_bool, 0, &u->meta.refuse_manual_stop, "Unit" }, { "AllowIsolate", config_parse_bool, 0, &u->meta.allow_isolate, "Unit" }, { "DefaultDependencies", config_parse_bool, 0, &u->meta.default_dependencies, "Unit" }, + { "OnFailureIsolate", config_parse_bool, 0, &u->meta.on_failure_isolate, "Unit" }, { "JobTimeoutSec", config_parse_usec, 0, &u->meta.job_timeout, "Unit" }, { "ConditionPathExists", config_parse_condition_path, CONDITION_PATH_EXISTS, u, "Unit" }, { "ConditionPathIsDirectory", config_parse_condition_path, CONDITION_PATH_IS_DIRECTORY, u, "Unit" }, diff --git a/src/unit.c b/src/unit.c index e4345aef..90773e89 100644 --- a/src/unit.c +++ b/src/unit.c @@ -666,11 +666,13 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) { "%s\tStopWhenUnneeded: %s\n" "%s\tRefuseManualStart: %s\n" "%s\tRefuseManualStop: %s\n" - "%s\tDefaultDependencies: %s\n", + "%s\tDefaultDependencies: %s\n" + "%s\rOnFailureIsolate: %s\n", prefix, yes_no(u->meta.stop_when_unneeded), prefix, yes_no(u->meta.refuse_manual_start), prefix, yes_no(u->meta.refuse_manual_stop), - prefix, yes_no(u->meta.default_dependencies)); + prefix, yes_no(u->meta.default_dependencies), + prefix, yes_no(u->meta.on_failure_isolate)); LIST_FOREACH(by_unit, b, u->meta.cgroup_bondings) fprintf(f, "%s\tControlGroup: %s:%s\n", @@ -1096,8 +1098,17 @@ void unit_trigger_on_failure(Unit *u) { assert(u); - SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i) - manager_add_job(u->meta.manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL); + if (set_size(u->meta.dependencies[UNIT_ON_FAILURE]) <= 0) + return; + + log_info("Triggering OnFailure= dependencies of %s.", u->meta.id); + + SET_FOREACH(other, u->meta.dependencies[UNIT_ON_FAILURE], i) { + int r; + + if ((r = manager_add_job(u->meta.manager, JOB_START, other, u->meta.on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0) + log_error("Failed to enqueue OnFailure= job: %s", strerror(-r)); + } } void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_success) { diff --git a/src/unit.h b/src/unit.h index 4245f3cf..2c5cacd9 100644 --- a/src/unit.h +++ b/src/unit.h @@ -207,6 +207,9 @@ struct Meta { /* Allow isolation requests */ bool allow_isolate; + /* Isolate OnFailure unit */ + bool on_failure_isolate; + /* Did the last condition check suceed? */ bool condition_result;