]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
manager: reduce complexity of unit_gc_sweep (#3507)
authorLukáš Nykrýn <lnykryn@redhat.com>
Tue, 14 Jun 2016 12:20:56 +0000 (14:20 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 14 Jun 2016 12:20:56 +0000 (14:20 +0200)
When unit is marked as UNSURE, we are trying to find if it state was
changed over and over again. So lets not go through the UNSURE states
again. Also when we find a GOOD unit lets propagate the GOOD state to
all units that this unit reference.

This is a problem on machines with a lot of initscripts with different
starting priority, since those units will reference each other and the
original algorithm might get to n! complexity.

Thanks HATAYAMA Daisuke for the expand_good_state code.

src/core/manager.c

index ec8acdff5bc00656e44ec624fabd21f221e6fe3f..5c0fee935df7cb4e48997a07bc3b2528edb15ac8 100644 (file)
@@ -877,6 +877,19 @@ enum {
         _GC_OFFSET_MAX
 };
 
+static void unit_gc_mark_good(Unit *u, unsigned gc_marker)
+{
+        Iterator i;
+        Unit *other;
+
+        u->gc_marker = gc_marker + GC_OFFSET_GOOD;
+
+        /* Recursively mark referenced units as GOOD as well */
+        SET_FOREACH(other, u->dependencies[UNIT_REFERENCES], i)
+                if (other->gc_marker == gc_marker + GC_OFFSET_UNSURE)
+                        unit_gc_mark_good(other, gc_marker);
+}
+
 static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
         Iterator i;
         Unit *other;
@@ -886,6 +899,7 @@ static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
 
         if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
             u->gc_marker == gc_marker + GC_OFFSET_BAD ||
+            u->gc_marker == gc_marker + GC_OFFSET_UNSURE ||
             u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
                 return;
 
@@ -926,7 +940,7 @@ bad:
         return;
 
 good:
-        u->gc_marker = gc_marker + GC_OFFSET_GOOD;
+        unit_gc_mark_good(u, gc_marker);
 }
 
 static unsigned manager_dispatch_gc_queue(Manager *m) {