[systemd-devel] [PATCH 6/6] Add OnStopRestoreConflicts rule.

Oleksii Shevchuk alxchk at gmail.com
Sat Nov 3 12:52:04 PDT 2012


If checked, the unit with this rule should start all
conflicted units, that were successfuly stopped on starting
---
 man/systemd.unit.xml                  | 12 ++++++++++
 src/core/dbus-unit.c                  |  2 ++
 src/core/dbus-unit.h                  |  1 +
 src/core/load-fragment-gperf.gperf.m4 |  1 +
 src/core/transaction.c                |  6 +++++
 src/core/unit.c                       | 44 +++++++++++++++++++++++++++++------
 src/core/unit.h                       |  5 ++++
 7 files changed, 64 insertions(+), 7 deletions(-)

diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index c5e84d7..623b225 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -644,6 +644,18 @@
                         </varlistentry>
 
                         <varlistentry>
+                                <term><varname>OnStopRestoreConflicts=</varname></term>
+
+                                <listitem><para>Takes a boolean
+                                argument. If <option>true</option> all
+                                jobs stopped as conflicted by this unit
+                                will be started on successfull stop of this
+                                unit.
+                                Defaults to
+                                <option>false</option>.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
                                 <term><varname>IgnoreOnIsolate=</varname></term>
 
                                 <listitem><para>Takes a boolean
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 347263a..05f4039 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -841,6 +841,7 @@ const BusProperty bus_unit_properties[] = {
         { "After",                bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_AFTER]),                   true },
         { "OnFailure",            bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_ON_FAILURE]),              true },
         { "OnStop",               bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_ON_STOP]),                 true },
+        { "OnStopRestoreConflicts",bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_ON_STOP_RESTORE_CONFLICTS]), true },
         { "Triggers",             bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_TRIGGERS]),                true },
         { "TriggeredBy",          bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_TRIGGERED_BY]),            true },
         { "PropagatesReloadTo",   bus_unit_append_dependencies,      "as", offsetof(Unit, dependencies[UNIT_PROPAGATES_RELOAD_TO]),    true },
@@ -873,6 +874,7 @@ const BusProperty bus_unit_properties[] = {
         { "AllowIsolate",         bus_property_append_bool,           "b", offsetof(Unit, allow_isolate)                      },
         { "DefaultDependencies",  bus_property_append_bool,           "b", offsetof(Unit, default_dependencies)               },
         { "OnFailureIsolate",     bus_property_append_bool,           "b", offsetof(Unit, on_failure_isolate)                 },
+        { "OnStopRestoreConflicts",bus_property_append_bool,           "b", offsetof(Unit, on_stop_restore_conflicts)         },
         { "IgnoreOnIsolate",      bus_property_append_bool,           "b", offsetof(Unit, ignore_on_isolate)                  },
         { "IgnoreOnSnapshot",     bus_property_append_bool,           "b", offsetof(Unit, ignore_on_snapshot)                 },
         { "DefaultControlGroup",  bus_unit_append_default_cgroup,     "s", 0 },
diff --git a/src/core/dbus-unit.h b/src/core/dbus-unit.h
index b614bb1..6e8bcf8 100644
--- a/src/core/dbus-unit.h
+++ b/src/core/dbus-unit.h
@@ -112,6 +112,7 @@
         "  <property name=\"AllowIsolate\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"DefaultDependencies\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"OnFailureIsolate\" type=\"b\" access=\"read\"/>\n" \
+        "  <property name=\"OnStopRestoreConflicts\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"IgnoreOnIsolate\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"IgnoreOnSnapshot\" type=\"b\" access=\"read\"/>\n" \
         "  <property name=\"DefaultControlGroup\" type=\"s\" access=\"read\"/>\n" \
diff --git a/src/core/load-fragment-gperf.gperf.m4 b/src/core/load-fragment-gperf.gperf.m4
index d93d13f..eb5b583 100644
--- a/src/core/load-fragment-gperf.gperf.m4
+++ b/src/core/load-fragment-gperf.gperf.m4
@@ -121,6 +121,7 @@ Unit.RefuseManualStop,           config_parse_bool,                  0,
 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.OnStopRestoreConflicts,     config_parse_bool,                  0,                             offsetof(Unit, on_stop_restore_conflicts)
 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_usec,                  0,                             offsetof(Unit, job_timeout)
diff --git a/src/core/transaction.c b/src/core/transaction.c
index 4bce942..702a94f 100644
--- a/src/core/transaction.c
+++ b/src/core/transaction.c
@@ -956,6 +956,9 @@ int transaction_add_job_and_dependencies(
 
                                         if (e)
                                                 dbus_error_free(e);
+                                } else if (ret->unit->on_stop_restore_conflicts) {
+                                        log_notice("Add %s to %s OnStopReferencedBy queue\n", ret->unit->id, dep->id);
+                                        unit_add_dependency(dep, UNIT_ON_STOP_RESTORE_CONFLICTS_BY, ret->unit, false);
                                 }
                         }
 
@@ -966,6 +969,9 @@ int transaction_add_job_and_dependencies(
 
                                         if (e)
                                                 dbus_error_free(e);
+                                } else if (ret->unit->on_stop_restore_conflicts) {
+                                        log_notice("Add %s to %s OnStopReferencedBy queue (CB)\n", ret->unit->id, dep->id);
+                                        unit_add_dependency(dep, UNIT_ON_STOP_RESTORE_CONFLICTS_BY, ret->unit, false);
                                 }
                         }
 
diff --git a/src/core/unit.c b/src/core/unit.c
index 564e16c..da36cb2 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -729,6 +729,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                         "%s\tRefuseManualStop: %s\n"
                         "%s\tDefaultDependencies: %s\n"
                         "%s\tOnFailureIsolate: %s\n"
+                        "%s\tOnStopRestoreConflicts: %s\n"
                         "%s\tIgnoreOnIsolate: %s\n"
                         "%s\tIgnoreOnSnapshot: %s\n",
                         prefix, yes_no(u->stop_when_unneeded),
@@ -736,6 +737,7 @@ void unit_dump(Unit *u, FILE *f, const char *prefix) {
                         prefix, yes_no(u->refuse_manual_stop),
                         prefix, yes_no(u->default_dependencies),
                         prefix, yes_no(u->on_failure_isolate),
+                        prefix, yes_no(u->on_stop_restore_conflicts),
                         prefix, yes_no(u->ignore_on_isolate),
                         prefix, yes_no(u->ignore_on_snapshot));
 
@@ -1322,16 +1324,41 @@ void unit_trigger_on_stop(Unit *u) {
 
         assert(u);
 
-        if (set_size(u->dependencies[UNIT_ON_STOP]) <= 0)
-                return;
+        if (set_size(u->dependencies[UNIT_ON_STOP]) > 0)
+        {
+                log_info("Triggering OnStop= dependencies of %s.", u->id);
 
-        log_info("Triggering OnStop= dependencies of %s.", u->id);
+                SET_FOREACH(other, u->dependencies[UNIT_ON_STOP], i) {
+                        int r;
 
-        SET_FOREACH(other, u->dependencies[UNIT_ON_STOP], i) {
-                int r;
+                        if ((r = manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL)) < 0)
+                                log_error("Failed to enqueue OnStop= job: %s", strerror(-r));
+                }
+        }
+
+        if (set_size(u->dependencies[UNIT_ON_STOP_RESTORE_CONFLICTS_BY]) > 0)
+        {
+                log_notice("Setting up OnStopRestoreConflicts virtual deps for Conflicted units\n");
+                SET_FOREACH(other, u->dependencies[UNIT_ON_STOP_RESTORE_CONFLICTS_BY], i) {
+                        log_notice("Add %s to %s OnStop queue\n", u->id, other->id);
+                        unit_add_dependency(other, UNIT_ON_STOP_RESTORE_CONFLICTS, u, true);
+                }
+
+                set_clear(u->dependencies[UNIT_ON_STOP_RESTORE_CONFLICTS_BY]);
+        }
+
+        if (set_size(u->dependencies[UNIT_ON_STOP_RESTORE_CONFLICTS]) > 0)
+        {
+                log_info("Triggering OnStopRestoreConflicts= virtual dependencies of %s.", u->id);
+
+                SET_FOREACH(other, u->dependencies[UNIT_ON_STOP_RESTORE_CONFLICTS], i) {
+                        int r;
+
+                        if ((r = manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL)) < 0)
+                                log_error("Failed to enqueue OnStop= job: %s", strerror(-r));
+                }
 
-                if ((r = manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL)) < 0)
-                        log_error("Failed to enqueue OnStop= job: %s", strerror(-r));
+                set_clear(u->dependencies[UNIT_ON_STOP_RESTORE_CONFLICTS]);
         }
 }
 
@@ -1713,6 +1740,8 @@ int unit_add_dependency(Unit *u, UnitDependency d, Unit *other, bool add_referen
                 [UNIT_AFTER] = UNIT_BEFORE,
                 [UNIT_ON_FAILURE] = _UNIT_DEPENDENCY_INVALID,
                 [UNIT_ON_STOP] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_ON_STOP_RESTORE_CONFLICTS] = _UNIT_DEPENDENCY_INVALID,
+                [UNIT_ON_STOP_RESTORE_CONFLICTS_BY] = _UNIT_DEPENDENCY_INVALID,
                 [UNIT_REFERENCES] = UNIT_REFERENCED_BY,
                 [UNIT_REFERENCED_BY] = UNIT_REFERENCES,
                 [UNIT_TRIGGERS] = UNIT_TRIGGERED_BY,
@@ -2748,6 +2777,7 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
         [UNIT_AFTER] = "After",
         [UNIT_ON_FAILURE] = "OnFailure",
         [UNIT_ON_STOP] = "OnStop",
+        [UNIT_ON_STOP_RESTORE_CONFLICTS] = "OnStopRestoreConflicts",
         [UNIT_TRIGGERS] = "Triggers",
         [UNIT_TRIGGERED_BY] = "TriggeredBy",
         [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
diff --git a/src/core/unit.h b/src/core/unit.h
index 1ca0931..8be83f6 100644
--- a/src/core/unit.h
+++ b/src/core/unit.h
@@ -97,6 +97,8 @@ enum UnitDependency {
 
         /* On Stop */
         UNIT_ON_STOP,
+        UNIT_ON_STOP_RESTORE_CONFLICTS,
+        UNIT_ON_STOP_RESTORE_CONFLICTS_BY,
 
         /* Triggers (i.e. a socket triggers a service) */
         UNIT_TRIGGERS,
@@ -218,6 +220,9 @@ struct Unit {
         /* Isolate OnFailure unit */
         bool on_failure_isolate;
 
+        /* Enqueue conflits to OnStop  */
+        bool on_stop_restore_conflicts;
+
         /* Ignore this unit when isolating */
         bool ignore_on_isolate;
 
-- 
1.7.12.4



More information about the systemd-devel mailing list