anitazha / rpms / systemd

Forked from rpms/systemd 3 years ago
Clone
923a60
From 33ca0f1f0d4b9a91588c84067d2fb30968e41235 Mon Sep 17 00:00:00 2001
923a60
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= <lnykryn@redhat.com>
923a60
Date: Tue, 14 Jun 2016 14:20:56 +0200
923a60
Subject: [PATCH] manager: reduce complexity of unit_gc_sweep (#3507)
923a60
923a60
When unit is marked as UNSURE, we are trying to find if it state was
923a60
changed over and over again. So lets not go through the UNSURE states
923a60
again. Also when we find a GOOD unit lets propagate the GOOD state to
923a60
all units that this unit reference.
923a60
923a60
This is a problem on machines with a lot of initscripts with different
923a60
starting priority, since those units will reference each other and the
923a60
original algorithm might get to n! complexity.
923a60
923a60
Thanks HATAYAMA Daisuke for the expand_good_state code.
923a60
Cherry-picked from: 4892084f096c19da0e83f28f250ca187b58c22b2
923a60
Resolves: #1344556
923a60
---
923a60
 src/core/manager.c | 16 +++++++++++++++-
923a60
 1 file changed, 15 insertions(+), 1 deletion(-)
923a60
923a60
diff --git a/src/core/manager.c b/src/core/manager.c
923a60
index 370c8cbbed..e5226a8a6f 100644
923a60
--- a/src/core/manager.c
923a60
+++ b/src/core/manager.c
923a60
@@ -838,6 +838,19 @@ enum {
923a60
         _GC_OFFSET_MAX
923a60
 };
923a60
 
923a60
+static void unit_gc_mark_good(Unit *u, unsigned gc_marker)
923a60
+{
923a60
+        Iterator i;
923a60
+        Unit *other;
923a60
+
923a60
+        u->gc_marker = gc_marker + GC_OFFSET_GOOD;
923a60
+
923a60
+        /* Recursively mark referenced units as GOOD as well */
923a60
+        SET_FOREACH(other, u->dependencies[UNIT_REFERENCES], i)
923a60
+                if (other->gc_marker == gc_marker + GC_OFFSET_UNSURE)
923a60
+                        unit_gc_mark_good(other, gc_marker);
923a60
+}
923a60
+
923a60
 static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
923a60
         Iterator i;
923a60
         Unit *other;
923a60
@@ -847,6 +860,7 @@ static void unit_gc_sweep(Unit *u, unsigned gc_marker) {
923a60
 
923a60
         if (u->gc_marker == gc_marker + GC_OFFSET_GOOD ||
923a60
             u->gc_marker == gc_marker + GC_OFFSET_BAD ||
923a60
+            u->gc_marker == gc_marker + GC_OFFSET_UNSURE ||
923a60
             u->gc_marker == gc_marker + GC_OFFSET_IN_PATH)
923a60
                 return;
923a60
 
923a60
@@ -887,7 +901,7 @@ bad:
923a60
         return;
923a60
 
923a60
 good:
923a60
-        u->gc_marker = gc_marker + GC_OFFSET_GOOD;
923a60
+        unit_gc_mark_good(u, gc_marker);
923a60
 }
923a60
 
923a60
 static unsigned manager_dispatch_gc_queue(Manager *m) {