diff --git a/src/core/manager.c b/src/core/manager.c index bf4d2333d9..0ccbaa61c5 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1670,11 +1670,36 @@ static unsigned manager_dispatch_stop_notify_queue(Manager *m) { return n; } +static void manager_clear_unit_dependencies(Manager *m) { + Unit *u; + const char *name; + + assert(m); + + HASHMAP_FOREACH_KEY(u, name, m->units) { + + /* ignore aliases */ + if (u->id != name) + continue; + + for (Hashmap *dependencies; (dependencies = hashmap_steal_first(u->dependencies));) + hashmap_free(dependencies); + + u->dependencies = hashmap_free(u->dependencies); + u->dependency_generation++; + } +} + static void manager_clear_jobs_and_units(Manager *m) { Unit *u; assert(m); + /* All units are going away, hence discard the full dependency graph in one pass. Otherwise + * unit_free() removes every edge from both endpoints separately, which becomes very costly with + * large numbers of synthesized mount units. */ + manager_clear_unit_dependencies(m); + while ((u = hashmap_first(m->units))) unit_free(u);