pid1: fix collection of cycles of units which reference one another

A .socket will reference a .service unit, by registering a UnitRef with the
.service unit. If this .service unit has the .socket unit listed in Wants or
Sockets or such, a cycle will be created. We would not free this cycle
properly, because we treated any unit with non-empty refs as uncollectable. To
solve this issue, treats refs with UnitRef in u->refs_by_target similarly to
the refs in u->dependencies, and check if the "other" unit is known to be
needed. If it is not needed, do not treat the reference from it as preventing
the unit we are looking at from being freed.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2018-02-15 13:32:53 +01:00
parent 7f7d01ed58
commit 2641f02e23
2 changed files with 19 additions and 4 deletions
+14
View File
@@ -1074,6 +1074,20 @@ static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
is_bad = false;
}
if (u->refs_by_target) {
const UnitRef *ref;
LIST_FOREACH(refs_by_target, ref, u->refs_by_target) {
unit_gc_sweep(ref->source, gc_marker);
if (ref->source->gc_marker == gc_marker + GC_OFFSET_GOOD)
goto good;
if (ref->source->gc_marker != gc_marker + GC_OFFSET_BAD)
is_bad = false;
}
}
if (is_bad)
goto bad;