diff --git a/src/core/unit.c b/src/core/unit.c index be57bdbd1d..35f41531c4 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -4888,6 +4888,7 @@ int unit_require_mounts_for(Unit *u, const char *path, UnitDependencyMask mask) int unit_setup_exec_runtime(Unit *u) { _cleanup_(exec_shared_runtime_unrefp) ExecSharedRuntime *esr = NULL; _cleanup_(dynamic_creds_unrefp) DynamicCreds *dcreds = NULL; + _cleanup_set_free_ Set *units = NULL; ExecRuntime **rt; ExecContext *ec; size_t offset; @@ -4905,8 +4906,12 @@ int unit_setup_exec_runtime(Unit *u) { ec = unit_get_exec_context(u); assert(ec); + r = unit_get_transitive_dependency_set(u, UNIT_ATOM_JOINS_NAMESPACE_OF, &units); + if (r < 0) + return r; + /* Try to get it from somebody else */ - UNIT_FOREACH_DEPENDENCY(other, u, UNIT_ATOM_JOINS_NAMESPACE_OF) { + SET_FOREACH(other, units) { r = exec_shared_runtime_acquire(u->manager, NULL, other->id, false, &esr); if (r < 0) return r; @@ -6111,6 +6116,33 @@ int unit_get_dependency_array(const Unit *u, UnitDependencyAtom atom, Unit ***re return (int) n; } +int unit_get_transitive_dependency_set(Unit *u, UnitDependencyAtom atom, Set **ret) { + _cleanup_set_free_ Set *units = NULL, *queue = NULL; + Unit *other; + int r; + + assert(u); + assert(ret); + + /* Similar to unit_get_dependency_array(), but also search the same dependency in other units. */ + + do { + UNIT_FOREACH_DEPENDENCY(other, u, atom) { + r = set_ensure_put(&units, NULL, other); + if (r < 0) + return r; + if (r == 0) + continue; + r = set_ensure_put(&queue, NULL, other); + if (r < 0) + return r; + } + } while ((u = set_steal_first(queue))); + + *ret = TAKE_PTR(units); + return 0; +} + const ActivationDetailsVTable * const activation_details_vtable[_UNIT_TYPE_MAX] = { [UNIT_PATH] = &activation_details_path_vtable, [UNIT_TIMER] = &activation_details_timer_vtable, diff --git a/src/core/unit.h b/src/core/unit.h index 09af8915dc..f2d4fd6a4b 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -810,6 +810,7 @@ static inline const UnitVTable* UNIT_VTABLE(const Unit *u) { Unit* unit_has_dependency(const Unit *u, UnitDependencyAtom atom, Unit *other); int unit_get_dependency_array(const Unit *u, UnitDependencyAtom atom, Unit ***ret_array); +int unit_get_transitive_dependency_set(Unit *u, UnitDependencyAtom atom, Set **ret); static inline Hashmap* unit_get_dependencies(Unit *u, UnitDependency d) { return hashmap_get(u->dependencies, UNIT_DEPENDENCY_TO_PTR(d)); diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service index 6c7bbdb097..60c083a3f4 100644 --- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service +++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service @@ -6,6 +6,6 @@ JoinsNamespaceOf=testsuite-23-joins-namespace-of-8.service Type=oneshot MountAPIVFS=yes PrivateTmp=yes -ExecStart=test ! -e /tmp/shared-private-file-x +ExecStart=test -e /tmp/shared-private-file-x ExecStart=test ! -e /tmp/shared-private-file-y ExecStart=touch /tmp/hoge diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service index 42053b99f8..dac1cea7bd 100644 --- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service +++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service @@ -5,5 +5,5 @@ NotifyAccess=all MountAPIVFS=yes PrivateTmp=yes ExecStartPre=test -e /tmp/shared-private-file-x -ExecStartPre=test ! -e /tmp/hoge +ExecStartPre=test -e /tmp/hoge ExecStart=/bin/bash -c 'touch /tmp/shared-private-file-y && systemd-notify --ready && sleep infinity' diff --git a/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service index a50a7fcdc2..6c64873b24 100644 --- a/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service +++ b/test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service @@ -6,6 +6,6 @@ JoinsNamespaceOf=testsuite-23-joins-namespace-of-8.service Type=oneshot MountAPIVFS=yes PrivateTmp=yes -ExecStart=test ! -e /tmp/shared-private-file-x -ExecStart=test ! -e /tmp/shared-private-file-y -ExecStart=test ! -e /tmp/hoge +ExecStart=test -e /tmp/shared-private-file-x +ExecStart=test -e /tmp/shared-private-file-y +ExecStart=test -e /tmp/hoge