summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.unit.xml40
-rw-r--r--src/core/dbus-unit.c3
-rw-r--r--src/core/job.h3
-rw-r--r--src/core/load-fragment-gperf.gperf.m43
-rw-r--r--src/core/load-fragment.c31
-rw-r--r--src/core/load-fragment.h2
-rw-r--r--src/core/unit.c11
-rw-r--r--src/core/unit.h4
-rw-r--r--units/initrd-cleanup.service.in1
-rw-r--r--units/initrd-fs.target2
-rw-r--r--units/initrd-parse-etc.service.in1
-rw-r--r--units/initrd-root-fs.target2
-rw-r--r--units/initrd-switch-root.service.in1
-rw-r--r--units/initrd.target2
-rw-r--r--units/local-fs.target2
15 files changed, 82 insertions, 26 deletions
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index baf44ad2e..b43fa1369 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -669,19 +669,37 @@
</varlistentry>
<varlistentry>
- <term><varname>OnFailureIsolate=</varname></term>
-
- <listitem><para>Takes a boolean
- argument. If <option>true</option>, the
- unit listed in
+ <term><varname>OnFailureJobMode=</varname></term>
+
+ <listitem><para>Takes a value of
+ <literal>fail</literal>,
+ <literal>replace</literal>,
+ <literal>replace-irreversibly</literal>
+ or
+ <literal>isolate</literal>. Defaults
+ to
+ <literal>replace</literal>. Specifies
+ how the units listed in
<varname>OnFailure=</varname> will be
- enqueued in isolation mode, i.e. all
- units that are not its dependency will
- be stopped. If this is set, only a
+ enqueued. If set to
+ <literal>fail</literal> and
+ contradicting jobs are already queued,
+ cause the activation to fail. If set
+ to <literal>replace</literal> and
+ contradicting jobs area already
+ queued, replace
+ those. <literal>replace-irreversibly</literal>
+ is similar to
+ <literal>replace</literal>, however,
+ creates jobs that cannot be reversed
+ unless they finished or are explicitly
+ canceled. <literal>isolate</literal>
+ may be used to terminate all other
+ units but the specified one. If
+ this is set to
+ <literal>isolate</literal>, only a
single unit may be listed in
- <varname>OnFailure=</varname>. Defaults
- to
- <option>false</option>.</para></listitem>
+ <varname>OnFailure=</varname>..</para></listitem>
</varlistentry>
<varlistentry>
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 666c97c98..f33e8db83 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -32,6 +32,7 @@
#include "dbus-client-track.h"
static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_load_state, unit_load_state, UnitLoadState);
+static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_job_mode, job_mode, JobMode);
static int property_get_names(
sd_bus *bus,
@@ -545,7 +546,7 @@ const sd_bus_vtable bus_unit_vtable[] = {
SD_BUS_PROPERTY("RefuseManualStop", "b", bus_property_get_bool, offsetof(Unit, refuse_manual_stop), 0),
SD_BUS_PROPERTY("AllowIsolate", "b", bus_property_get_bool, offsetof(Unit, allow_isolate), 0),
SD_BUS_PROPERTY("DefaultDependencies", "b", bus_property_get_bool, offsetof(Unit, default_dependencies), 0),
- SD_BUS_PROPERTY("OnFailureIsolate", "b", bus_property_get_bool, offsetof(Unit, on_failure_isolate), 0),
+ SD_BUS_PROPERTY("OnFailureJobMode", "s", property_get_job_mode, offsetof(Unit, on_failure_job_mode), 0),
SD_BUS_PROPERTY("IgnoreOnIsolate", "b", bus_property_get_bool, offsetof(Unit, ignore_on_isolate), 0),
SD_BUS_PROPERTY("IgnoreOnSnapshot", "b", bus_property_get_bool, offsetof(Unit, ignore_on_snapshot), 0),
SD_BUS_PROPERTY("NeedDaemonReload", "b", property_get_need_daemon_reload, 0, 0),
diff --git a/src/core/job.h b/src/core/job.h
index 60bb87d75..3f6357a05 100644
--- a/src/core/job.h
+++ b/src/core/job.h
@@ -82,7 +82,7 @@ enum JobState {
enum JobMode {
JOB_FAIL, /* Fail if a conflicting job is already queued */
JOB_REPLACE, /* Replace an existing conflicting job */
- JOB_REPLACE_IRREVERSIBLY, /* Like JOB_REPLACE + produce irreversible jobs */
+ JOB_REPLACE_IRREVERSIBLY,/* Like JOB_REPLACE + produce irreversible jobs */
JOB_ISOLATE, /* Start a unit, and stop all others */
JOB_IGNORE_DEPENDENCIES, /* Ignore both requirement and ordering dependencies */
JOB_IGNORE_REQUIREMENTS, /* Ignore requirement dependencies */
@@ -155,7 +155,6 @@ struct Job {
bool in_dbus_queue:1;
bool sent_dbus_new_signal:1;
bool ignore_order:1;
- bool forgot_bus_clients:1;
bool irreversible:1;
};
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index fbf8381bc..c06255041 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -122,7 +122,8 @@ Unit.RefuseManualStart, config_parse_bool, 0,
Unit.RefuseManualStop, config_parse_bool, 0, offsetof(Unit, refuse_manual_stop)
Unit.AllowIsolate, config_parse_bool, 0, offsetof(Unit, allow_isolate)
Unit.DefaultDependencies, config_parse_bool, 0, offsetof(Unit, default_dependencies)
-Unit.OnFailureIsolate, config_parse_bool, 0, offsetof(Unit, on_failure_isolate)
+Unit.OnFailureJobMode, config_parse_job_mode, 0, offsetof(Unit, on_failure_job_mode)
+Unit.OnFailureIsolate, config_parse_job_mode_isolate, 0, offsetof(Unit, on_failure_job_mode)
Unit.IgnoreOnIsolate, config_parse_bool, 0, offsetof(Unit, ignore_on_isolate)
Unit.IgnoreOnSnapshot, config_parse_bool, 0, offsetof(Unit, ignore_on_snapshot)
Unit.JobTimeoutSec, config_parse_sec, 0, offsetof(Unit, job_timeout)
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index e9bfbd396..d9dd6faae 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2326,6 +2326,37 @@ int config_parse_blockio_bandwidth(
return 0;
}
+DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode");
+
+int config_parse_job_mode_isolate(
+ const char *unit,
+ const char *filename,
+ unsigned line,
+ const char *section,
+ unsigned section_line,
+ const char *lvalue,
+ int ltype,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ JobMode *m = data;
+ int r;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+
+ r = parse_boolean(rvalue);
+ if (r < 0) {
+ log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Failed to parse boolean, ignoring: %s", rvalue);
+ return 0;
+ }
+
+ *m = r ? JOB_ISOLATE : JOB_REPLACE;
+ return 0;
+}
+
#define FOLLOW_MAX 8
static int open_follow(char **filename, FILE **_f, Set *names, char **_final) {
diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h
index 99b8e03aa..31e30e367 100644
--- a/src/core/load-fragment.h
+++ b/src/core/load-fragment.h
@@ -82,6 +82,8 @@ int config_parse_device_allow(const char *unit, const char *filename, unsigned l
int config_parse_blockio_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_blockio_device_weight(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_blockio_bandwidth(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_job_mode(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
+int config_parse_job_mode_isolate(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
/* gperf prototypes */
const struct ConfigPerfItem* load_fragment_gperf_lookup(const char *key, unsigned length);
diff --git a/src/core/unit.c b/src/core/unit.c
index 57f0a86c0..f4d60bcf3 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -86,6 +86,7 @@ Unit *unit_new(Manager *m, size_t size) {
u->deserialized_job = _JOB_TYPE_INVALID;
u->default_dependencies = true;
u->unit_file_state = _UNIT_FILE_STATE_INVALID;
+ u->on_failure_job_mode = JOB_REPLACE;
return u;
}
@@ -826,14 +827,14 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
"%s\tRefuseManualStart: %s\n"
"%s\tRefuseManualStop: %s\n"
"%s\tDefaultDependencies: %s\n"
- "%s\tOnFailureIsolate: %s\n"
+ "%s\tOnFailureJobMode: %s\n"
"%s\tIgnoreOnIsolate: %s\n"
"%s\tIgnoreOnSnapshot: %s\n",
prefix, yes_no(u->stop_when_unneeded),
prefix, yes_no(u->refuse_manual_start),
prefix, yes_no(u->refuse_manual_stop),
prefix, yes_no(u->default_dependencies),
- prefix, yes_no(u->on_failure_isolate),
+ prefix, job_mode_to_string(u->on_failure_job_mode),
prefix, yes_no(u->ignore_on_isolate),
prefix, yes_no(u->ignore_on_snapshot));
@@ -1044,11 +1045,11 @@ int unit_load(Unit *u) {
if (r < 0)
goto fail;
- if (u->on_failure_isolate &&
+ if (u->on_failure_job_mode == JOB_ISOLATE &&
set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
log_error_unit(u->id,
- "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id);
+ "More than one OnFailure= dependencies specified for %s but OnFailureJobMode=isolate set. Refusing.", u->id);
r = -EINVAL;
goto fail;
@@ -1454,7 +1455,7 @@ void unit_start_on_failure(Unit *u) {
SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
int r;
- r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
+ r = manager_add_job(u->manager, JOB_START, other, u->on_failure_job_mode, true, NULL, NULL);
if (r < 0)
log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
}
diff --git a/src/core/unit.h b/src/core/unit.h
index fe49b5740..a6dbe8ddb 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -230,8 +230,8 @@ struct Unit {
/* Allow isolation requests */
bool allow_isolate;
- /* Isolate OnFailure unit */
- bool on_failure_isolate;
+ /* How to start OnFailure units */
+ JobMode on_failure_job_mode;
/* Ignore this unit when isolating */
bool ignore_on_isolate;
diff --git a/units/initrd-cleanup.service.in b/units/initrd-cleanup.service.in
index 218ec807f..b1dda16b5 100644
--- a/units/initrd-cleanup.service.in
+++ b/units/initrd-cleanup.service.in
@@ -10,6 +10,7 @@ Description=Cleaning Up and Shutting Down Daemons
DefaultDependencies=no
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
After=initrd-root-fs.target initrd-fs.target initrd.target
[Service]
diff --git a/units/initrd-fs.target b/units/initrd-fs.target
index 866f0d025..7ec838a68 100644
--- a/units/initrd-fs.target
+++ b/units/initrd-fs.target
@@ -9,7 +9,7 @@
Description=Initrd File Systems
Documentation=man:systemd.special(7)
OnFailure=emergency.target
-OnFailureIsolate=yes
+OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release
After=initrd-parse-etc.service
DefaultDependencies=no
diff --git a/units/initrd-parse-etc.service.in b/units/initrd-parse-etc.service.in
index 07728e200..c0b25430b 100644
--- a/units/initrd-parse-etc.service.in
+++ b/units/initrd-parse-etc.service.in
@@ -11,6 +11,7 @@ DefaultDependencies=no
Requires=initrd-root-fs.target
After=initrd-root-fs.target
OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release
[Service]
diff --git a/units/initrd-root-fs.target b/units/initrd-root-fs.target
index d0b986300..64f0a9291 100644
--- a/units/initrd-root-fs.target
+++ b/units/initrd-root-fs.target
@@ -10,6 +10,6 @@ Description=Initrd Root File System
Documentation=man:systemd.special(7)
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
-OnFailureIsolate=yes
+OnFailureJobMode=replace-irreversibly
DefaultDependencies=no
Conflicts=shutdown.target
diff --git a/units/initrd-switch-root.service.in b/units/initrd-switch-root.service.in
index 674026414..82893dafb 100644
--- a/units/initrd-switch-root.service.in
+++ b/units/initrd-switch-root.service.in
@@ -10,6 +10,7 @@ Description=Switch Root
DefaultDependencies=no
ConditionPathExists=/etc/initrd-release
OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
AllowIsolate=yes
[Service]
diff --git a/units/initrd.target b/units/initrd.target
index bb9054fb8..eae7c703c 100644
--- a/units/initrd.target
+++ b/units/initrd.target
@@ -9,7 +9,7 @@
Description=Initrd Default Target
Documentation=man:systemd.special(7)
OnFailure=emergency.target
-OnFailureIsolate=yes
+OnFailureJobMode=replace-irreversibly
ConditionPathExists=/etc/initrd-release
Requires=basic.target
Wants=initrd-root-fs.target initrd-fs.target initrd-parse-etc.service
diff --git a/units/local-fs.target b/units/local-fs.target
index 8f06ed6ca..ae3cedcb6 100644
--- a/units/local-fs.target
+++ b/units/local-fs.target
@@ -12,4 +12,4 @@ After=local-fs-pre.target
DefaultDependencies=no
Conflicts=shutdown.target
OnFailure=emergency.target
-OnFailureIsolate=no
+OnFailureJobMode=replace-irreversibly