diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index 36bd7173d4..13322746fa 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -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 {
+
+
+
+
@@ -1919,6 +1927,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
+
+
diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml
index 913cad05b4..07ea21a6e7 100644
--- a/man/systemd.unit.xml
+++ b/man/systemd.unit.xml
@@ -787,13 +787,20 @@
PropagatesReloadTo=
ReloadPropagatedFrom=
- 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.
+ 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.
+
+
+
+ PropagatesStopTo=
+ StopPropagatedFrom=
+
+ 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.
diff --git a/src/basic/unit-def.c b/src/basic/unit-def.c
index fd7615de88..32be5219fc 100644
--- a/src/basic/unit-def.c
+++ b/src/basic/unit-def.c
@@ -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",
diff --git a/src/basic/unit-def.h b/src/basic/unit-def.h
index ec40bab01f..dc5aa5555d 100644
--- a/src/basic/unit-def.h
+++ b/src/basic/unit-def.h
@@ -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,
diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c
index 6ca16262ab..5e5a0a33a1 100644
--- a/src/core/dbus-unit.c
+++ b/src/core/dbus-unit.c
@@ -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));
diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in
index 98ece8054c..bb3c4453df 100644
--- a/src/core/load-fragment-gperf.gperf.in
+++ b/src/core/load-fragment-gperf.gperf.in
@@ -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
diff --git a/src/core/unit-dependency-atom.c b/src/core/unit-dependency-atom.c
index c4fbfee015..eaeb1d389e 100644
--- a/src/core/unit-dependency-atom.c
+++ b/src/core/unit-dependency-atom.c
@@ -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 |
diff --git a/src/core/unit.c b/src/core/unit.c
index 708c725b49..ed6f87d960 100644
--- a/src/core/unit.c
+++ b/src/core/unit.c
@@ -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,
diff --git a/test/fuzz/fuzz-unit-file/directives.service b/test/fuzz/fuzz-unit-file/directives.service
index 73e1707c5c..95ab9a1c32 100644
--- a/test/fuzz/fuzz-unit-file/directives.service
+++ b/test/fuzz/fuzz-unit-file/directives.service
@@ -80,6 +80,7 @@ PartOf=
PropagateReloadFrom=
PropagateReloadTo=
PropagatesReloadTo=
+PropagatesStopTo=
RebootArgument=
RefuseManualStart=
RefuseManualStop=
@@ -97,6 +98,7 @@ StartLimitBurst=
StartLimitInterval=
StartLimitIntervalSec=
StopWhenUnneeded=
+StopPropagatedFrom=
SuccessAction=
SuccessActionExitStatus=
Wants=