]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/unit: search shared namespace in transitive relation of JoinsNamespaceOf=
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 25 May 2023 09:08:37 +0000 (18:08 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 26 May 2023 06:23:57 +0000 (15:23 +0900)
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.

src/core/unit.c
src/core/unit.h
test/testsuite-23.units/testsuite-23-joins-namespace-of-7.service
test/testsuite-23.units/testsuite-23-joins-namespace-of-8.service
test/testsuite-23.units/testsuite-23-joins-namespace-of-9.service

index be57bdbd1da8319febd0c7f51e18e9ccee7cd5d0..35f41531c42b0409e562c6417fb3d944841d77d9 100644 (file)
@@ -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,
index 09af8915dc35e33df5e33fca1938aabe6fc7ba45..f2d4fd6a4b2c2b0845b01a5cb25ea20a2049a7e1 100644 (file)
@@ -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));
index 6c7bbdb097d06ba8de118e0e48872fe9edaae1a4..60c083a3f4316857be0a96c19aca57d7eb731b7c 100644 (file)
@@ -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
index 42053b99f8c1727d204572a72fb8f45bd8ecae58..dac1cea7bdf30a766a4aeef6aa9afd65f505c57f 100644 (file)
@@ -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'
index a50a7fcdc29157dfd2ca08330b7eacaa00bdfda7..6c64873b24151f3a3a5b2f6a0e03cf637dfb7537 100644 (file)
@@ -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