From: Yu Watanabe Date: Thu, 25 May 2023 09:08:37 +0000 (+0900) Subject: core/unit: search shared namespace in transitive relation of JoinsNamespaceOf= X-Git-Tag: v254-rc1~369^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83123a44989c095f9b7a89841db9917417fc451a;p=thirdparty%2Fsystemd.git core/unit: search shared namespace in transitive relation of JoinsNamespaceOf= Previously, dependency chain of JoinsNamespaceOf= did not work, e.g. - a.service has JoinsNamespaceOf=b.service - b.service has JoinsNamespaceOf=c.service if, first c.service, next a.service, finally b.service is started, then a.service is not joined to the namespace of c.service. And, as mentioned in the document, the namespace used by b.service is not deterministic. This makes when searching exsiting namespace to be joined, all units in the transitive dependency of JoinsNamespaceOf= are checked. --- diff --git a/src/core/unit.c b/src/core/unit.c index be57bdbd1da..35f41531c42 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 09af8915dc3..f2d4fd6a4b2 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 6c7bbdb097d..60c083a3f43 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 42053b99f8c..dac1cea7bdf 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 a50a7fcdc29..6c64873b241 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