From: Yu Watanabe Date: Tue, 15 Nov 2022 18:08:22 +0000 (+0900) Subject: core/unit: drop dependency to the unit being merged X-Git-Tag: v253-rc1~252^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c8b3b524134539846917269ddd644ee93a35623f;p=thirdparty%2Fsystemd.git core/unit: drop dependency to the unit being merged Fixes a bug in 15ed3c3a188cf7fa5a60ae508fc7a3ed048d2220. Fixes #24990. Also, hopefully fixes #24577. --- diff --git a/src/core/unit.c b/src/core/unit.c index 36e3afd7fbf..1a580157afa 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -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));