]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
core/unit: drop dependency to the unit being merged
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 15 Nov 2022 18:08:22 +0000 (03:08 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 6 Dec 2022 08:49:31 +0000 (17:49 +0900)
Fixes a bug in 15ed3c3a188cf7fa5a60ae508fc7a3ed048d2220.

Fixes #24990. Also, hopefully fixes #24577.

src/core/unit.c

index 36e3afd7fbf10e5c92fb18598608dc14a7170591..1a580157afa4938264e9bcc4b4b95e75f3ebd2d4 100644 (file)
@@ -1044,10 +1044,10 @@ static int unit_add_dependency_hashmap(
         return unit_per_dependency_type_hashmap_update(per_type, other, origin_mask, destination_mask);
 }
 
-static void unit_merge_dependencies(
-                Unit *u,
-                Unit *other) {
-
+static void unit_merge_dependencies(Unit *u, Unit *other) {
+        Hashmap *deps;
+        void *dt; /* Actually of type UnitDependency, except that we don't bother casting it here,
+                   * since the hashmaps all want it as void pointer. */
         int r;
 
         assert(u);
@@ -1056,12 +1056,19 @@ static void unit_merge_dependencies(
         if (u == other)
                 return;
 
+        /* First, remove dependency to other. */
+        HASHMAP_FOREACH_KEY(deps, dt, u->dependencies) {
+                if (hashmap_remove(deps, other))
+                        unit_maybe_warn_about_dependency(u, other->id, UNIT_DEPENDENCY_FROM_PTR(dt));
+
+                if (hashmap_isempty(deps))
+                        hashmap_free(hashmap_remove(u->dependencies, dt));
+        }
+
         for (;;) {
                 _cleanup_(hashmap_freep) Hashmap *other_deps = NULL;
                 UnitDependencyInfo di_back;
                 Unit *back;
-                void *dt; /* Actually of type UnitDependency, except that we don't bother casting it here,
-                           * since the hashmaps all want it as void pointer. */
 
                 /* Let's focus on one dependency type at a time, that 'other' has defined. */
                 other_deps = hashmap_steal_first_key_and_value(other->dependencies, &dt);
@@ -1103,8 +1110,6 @@ static void unit_merge_dependencies(
                  * them per type wholesale. */
                 r = hashmap_put(u->dependencies, dt, other_deps);
                 if (r == -EEXIST) {
-                        Hashmap *deps;
-
                         /* The target unit already has dependencies of this type, let's then merge this individually. */
 
                         assert_se(deps = hashmap_get(u->dependencies, dt));