]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core: add new PropagateStopTo= dependency (and inverse)
authorLennart Poettering <lennart@poettering.net>
Tue, 13 Apr 2021 20:30:31 +0000 (22:30 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 25 May 2021 14:03:03 +0000 (16:03 +0200)
This takes inspiration from PropagatesReloadTo=, but propagates
stop jobs instead of restart jobs.

This is defined based on exactly two atoms: UNIT_ATOM_PROPAGATE_STOP +
UNIT_ATOM_RETROACTIVE_STOP_ON_STOP. The former ensures that when the
unit the dependency is originating from is stopped based on user
request, we'll propagate the stop job to the target unit, too. In
addition, when the originating unit suddenly stops from external causes
the stopping is propagated too. Note that this does *not* include the
UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT atom (which is used by BoundBy=),
i.e. this dependency is purely about propagating "edges" and not
"levels", i.e. it's about propagating specific events, instead of
continious states.

This is supposed to be useful for dependencies between .mount units and
their backing .device units. So far we either placed a BindsTo= or
Requires= dependency between them. The former gave a very clear binding
of the to units together, however was problematic if users establish
mounnts manually with different block device sources than our
configuration defines, as we there might come to the conclusion that the
backing device was absent and thus we need to umount again what the user
mounted. By combining Requires= with the new StopPropagatedFrom= (i.e.
the inverse PropagateStopTo=) we can get behaviour that matches BindsTo=
in every single atom but one: UNIT_ATOM_CANNOT_BE_ACTIVE_WITHOUT is
absent, and hence the level-triggered logic doesn't apply.

Replaces: #11340

man/org.freedesktop.systemd1.xml
man/systemd.unit.xml
src/basic/unit-def.c
src/basic/unit-def.h
src/core/dbus-unit.c
src/core/load-fragment-gperf.gperf.in
src/core/unit-dependency-atom.c
src/core/unit.c
test/fuzz/fuzz-unit-file/directives.service

index 36bd7173d4c110dd4f20042fbd6f823bc7995546..13322746fa52092a2f3e3f7171b887a9668484ea 100644 (file)
@@ -1640,6 +1640,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly as ReloadPropagatedFrom = ['...', ...];
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+      readonly as PropagatesStopTo = ['...', ...];
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+      readonly as StopPropagatedFrom = ['...', ...];
+      @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly as JoinsNamespaceOf = ['...', ...];
       @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
       readonly as SliceOf = ['...', ...];
@@ -1779,6 +1783,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <!--property ReloadPropagatedFrom is not documented!-->
 
+    <!--property PropagatesStopTo is not documented!-->
+
+    <!--property StopPropagatedFrom is not documented!-->
+
     <!--property JoinsNamespaceOf is not documented!-->
 
     <!--property SliceOf is not documented!-->
@@ -1919,6 +1927,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
 
     <variablelist class="dbus-property" generated="True" extra-ref="ReloadPropagatedFrom"/>
 
+    <variablelist class="dbus-property" generated="True" extra-ref="PropagatesStopTo"/>
+
+    <variablelist class="dbus-property" generated="True" extra-ref="StopPropagatedFrom"/>
+
     <variablelist class="dbus-property" generated="True" extra-ref="JoinsNamespaceOf"/>
 
     <variablelist class="dbus-property" generated="True" extra-ref="SliceOf"/>
index 913cad05b4f4b2e8def0585994dd7e21470cfa1d..07ea21a6e7fd002e01aa4d319a0cd7dd7b62aae6 100644 (file)
         <term><varname>PropagatesReloadTo=</varname></term>
         <term><varname>ReloadPropagatedFrom=</varname></term>
 
-        <listitem><para>A space-separated list of one or more units
-        where reload requests on this unit will be propagated to, or
-        reload requests on the other unit will be propagated to this
-        unit, respectively. Issuing a reload request on a unit will
-        automatically also enqueue a reload request on all units that
-        the reload request shall be propagated to via these two
-        settings.</para></listitem>
+        <listitem><para>A space-separated list of one or more units to which reload requests from this unit
+        shall be propagated to, or units from which reload requests shall be propagated to this unit,
+        respectively. Issuing a reload request on a unit will automatically also enqueue reload requests on
+        all units that are linked to it using these two settings.</para></listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>PropagatesStopTo=</varname></term>
+        <term><varname>StopPropagatedFrom=</varname></term>
+
+        <listitem><para>A space-separated list of one or more units to which stop requests from this unit
+        shall be propagated to, or units from which stop requests shall be propagated to this unit,
+        respectively. Issuing a stop request on a unit will automatically also enqueue stop requests on all
+        units that are linked to it using these two settings.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index fd7615de8814343492fb867734ea89f6d7d12830..32be5219fcedf91719f2996e1acb9ee8cf19d7d9 100644 (file)
@@ -280,6 +280,8 @@ static const char* const unit_dependency_table[_UNIT_DEPENDENCY_MAX] = {
         [UNIT_TRIGGERED_BY] = "TriggeredBy",
         [UNIT_PROPAGATES_RELOAD_TO] = "PropagatesReloadTo",
         [UNIT_RELOAD_PROPAGATED_FROM] = "ReloadPropagatedFrom",
+        [UNIT_PROPAGATES_STOP_TO] = "PropagatesStopTo",
+        [UNIT_STOP_PROPAGATED_FROM] = "StopPropagatedFrom",
         [UNIT_JOINS_NAMESPACE_OF] = "JoinsNamespaceOf",
         [UNIT_REFERENCES] = "References",
         [UNIT_REFERENCED_BY] = "ReferencedBy",
index ec40bab01f06302fb5f86679885069f38adf7735..dc5aa5555d70e410580a62881a30552c6a98b540 100644 (file)
@@ -239,6 +239,10 @@ typedef enum UnitDependency {
         UNIT_PROPAGATES_RELOAD_TO,
         UNIT_RELOAD_PROPAGATED_FROM,
 
+        /* Propagate stops */
+        UNIT_PROPAGATES_STOP_TO,
+        UNIT_STOP_PROPAGATED_FROM,
+
         /* Joins namespace of */
         UNIT_JOINS_NAMESPACE_OF,
 
index 6ca16262ab650b15c5a13b1b6786ca6a73da3ae0..5e5a0a33a1193dea9c6533d351058b0503845eaa 100644 (file)
@@ -870,6 +870,8 @@ const sd_bus_vtable bus_unit_vtable[] = {
         SD_BUS_PROPERTY("TriggeredBy", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("PropagatesReloadTo", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("ReloadPropagatedFrom", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("PropagatesStopTo", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
+        SD_BUS_PROPERTY("StopPropagatedFrom", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("JoinsNamespaceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("SliceOf", "as", property_get_dependencies, 0, SD_BUS_VTABLE_PROPERTY_CONST),
         SD_BUS_PROPERTY("RequiresMountsFor", "as", property_get_requires_mounts_for, offsetof(Unit, requires_mounts_for), SD_BUS_VTABLE_PROPERTY_CONST),
@@ -2302,6 +2304,8 @@ static int bus_unit_set_transient_property(
                             UNIT_ON_FAILURE,
                             UNIT_PROPAGATES_RELOAD_TO,
                             UNIT_RELOAD_PROPAGATED_FROM,
+                            UNIT_PROPAGATES_STOP_TO,
+                            UNIT_STOP_PROPAGATED_FROM,
                             UNIT_JOINS_NAMESPACE_OF))
                     return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Dependency type %s may not be created transiently.", unit_dependency_to_string(d));
 
index 98ece8054c01b01c877d3438bae01a10bd71a8ce..bb3c4453df2cf0ea87c6268c15e7953687594140 100644 (file)
@@ -269,6 +269,8 @@ Unit.PropagatesReloadTo,                 config_parse_unit_deps,
 Unit.PropagateReloadTo,                  config_parse_unit_deps,                      UNIT_PROPAGATES_RELOAD_TO,          0
 Unit.ReloadPropagatedFrom,               config_parse_unit_deps,                      UNIT_RELOAD_PROPAGATED_FROM,        0
 Unit.PropagateReloadFrom,                config_parse_unit_deps,                      UNIT_RELOAD_PROPAGATED_FROM,        0
+Unit.PropagatesStopTo,                   config_parse_unit_deps,                      UNIT_PROPAGATES_STOP_TO,            0
+Unit.StopPropagatedFrom,                 config_parse_unit_deps,                      UNIT_STOP_PROPAGATED_FROM,          0
 Unit.PartOf,                             config_parse_unit_deps,                      UNIT_PART_OF,                       0
 Unit.JoinsNamespaceOf,                   config_parse_unit_deps,                      UNIT_JOINS_NAMESPACE_OF,            0
 Unit.RequiresOverridable,                config_parse_obsolete_unit_deps,             UNIT_REQUIRES,                      0
index c4fbfee015cd6325e1a7886b6011ca146c250857..eaeb1d389e4384fc4d809146257faddbb094142d 100644 (file)
@@ -68,6 +68,9 @@ static const UnitDependencyAtom atom_map[_UNIT_DEPENDENCY_MAX] = {
                                         UNIT_ATOM_RETROACTIVE_STOP_ON_START |
                                         UNIT_ATOM_PROPAGATE_STOP_FAILURE,
 
+        [UNIT_PROPAGATES_STOP_TO]     = UNIT_ATOM_RETROACTIVE_STOP_ON_STOP |
+                                        UNIT_ATOM_PROPAGATE_STOP,
+
         /* These are simple dependency types: they consist of a single atom only */
         [UNIT_BEFORE]                 = UNIT_ATOM_BEFORE,
         [UNIT_AFTER]                  = UNIT_ATOM_AFTER,
@@ -86,6 +89,7 @@ static const UnitDependencyAtom atom_map[_UNIT_DEPENDENCY_MAX] = {
          * have no effect of their own, they all map to no atoms at all, i.e. the value 0. */
         [UNIT_RELOAD_PROPAGATED_FROM] = 0,
         [UNIT_ON_FAILURE_OF]          = 0,
+        [UNIT_STOP_PROPAGATED_FROM]   = 0,
 };
 
 UnitDependencyAtom unit_dependency_to_atom(UnitDependency d) {
@@ -149,7 +153,6 @@ UnitDependency unit_dependency_from_unique_atom(UnitDependencyAtom atom) {
                 UNIT_ATOM_PROPAGATE_START_FAILURE |
                 UNIT_ATOM_PINS_STOP_WHEN_UNNEEDED |
                 UNIT_ATOM_DEFAULT_TARGET_DEPENDENCIES:
-        case UNIT_ATOM_RETROACTIVE_STOP_ON_STOP:
                 return UNIT_BOUND_BY;
 
         case UNIT_ATOM_PULL_IN_STOP |
index 708c725b4980ed8d6fdc8b70637046c5156685ba..ed6f87d96096cfec5d3cb6ebc48845b922b33486 100644 (file)
@@ -2879,6 +2879,8 @@ int unit_add_dependency(
                 [UNIT_TRIGGERED_BY] = UNIT_TRIGGERS,
                 [UNIT_PROPAGATES_RELOAD_TO] = UNIT_RELOAD_PROPAGATED_FROM,
                 [UNIT_RELOAD_PROPAGATED_FROM] = UNIT_PROPAGATES_RELOAD_TO,
+                [UNIT_PROPAGATES_STOP_TO] = UNIT_STOP_PROPAGATED_FROM,
+                [UNIT_STOP_PROPAGATED_FROM] = UNIT_PROPAGATES_STOP_TO,
                 [UNIT_JOINS_NAMESPACE_OF] = UNIT_JOINS_NAMESPACE_OF, /* symmetric! ðŸ‘“ */
                 [UNIT_IN_SLICE] = UNIT_SLICE_OF,
                 [UNIT_SLICE_OF] = UNIT_IN_SLICE,
index 73e1707c5c03fe3cddd9f4030ecb8770b6fcf981..95ab9a1c32a116386f7955eb1a7276d5e975a6ff 100644 (file)
@@ -80,6 +80,7 @@ PartOf=
 PropagateReloadFrom=
 PropagateReloadTo=
 PropagatesReloadTo=
+PropagatesStopTo=
 RebootArgument=
 RefuseManualStart=
 RefuseManualStop=
@@ -97,6 +98,7 @@ StartLimitBurst=
 StartLimitInterval=
 StartLimitIntervalSec=
 StopWhenUnneeded=
+StopPropagatedFrom=
 SuccessAction=
 SuccessActionExitStatus=
 Wants=