[systemd-devel] [PATCH] core/manager.c: for switch-root wait for pending JOB_STOP

harald at redhat.com harald at redhat.com
Wed Jul 11 23:44:00 PDT 2012


From: Harald Hoyer <harald at redhat.com>

if we don't wait for the pending stopping jobs, the following can
happen:

** initramfs start **
Installed new job systemd-udevd.service/stop as 29
systemd-udevd.service changed running -> stop-sigterm
** switch-root to real root **
Reinstalled deserialized job systemd-udevd.service/stop as 29
systemd-udevd.service changed dead -> stop-sigterm
Job systemd-udevd.service/stop finished, result=canceled
Installed new job systemd-udevd.service/start as 62
Child 107 belongs to systemd-udevd.service
systemd-udevd.service: main process exited, code=exited, status=0
systemd-udevd.service changed stop-sigterm -> dead
systemd-udevd.service changed dead -> auto-restart
systemd-udevd.service automatic restart is pending, must be stopped before issuing start request.
Job systemd-udevd.service/start	finished, result=failed
systemd-udevd.service holdoff time over, scheduling restart.
Trying to enqueue job systemd-udevd.service/restart/fail
Installed new job systemd-udevd.service/restart as 92

With this patch the log looks like this:

 ** initramfs start **
Installed new job systemd-udevd.service/stop as 29
systemd-udevd.service changed running -> stop-sigterm
Child 107 belongs to systemd-udevd.service
systemd-udevd.service: main process exited, code=exited, status=0
systemd-udevd.service changed stop-sigterm -> dead
Job systemd-udevd.service/stop finished, result=done
** switch-root to real root **
Installed new job systemd-udevd.service/start as 63
systemd-udevd.service changed dead -> start
Got notification message for unit systemd-udevd.service
systemd-udevd.service: Got message
systemd-udevd.service: got READY=1
systemd-udevd.service changed start -> running
Job systemd-udevd.service/start finished, result=done
---
 src/core/manager.c |   24 +++++++++++++++++++++++-
 1 file changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/core/manager.c b/src/core/manager.c
index 7bd484b..0484868 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -1409,6 +1409,26 @@ static int process_event(Manager *m, struct epoll_event *ev) {
         return 0;
 }
 
+static bool manager_has_pending_terminating_units(Manager *m)
+{
+        Iterator i;
+        Unit *u;
+        const char *t;
+
+        HASHMAP_FOREACH_KEY(u, t, m->units, i) {
+                if (u->id != t)
+                        continue;
+
+                if (u->job == NULL)
+                        continue;
+
+                if (u->job->type == JOB_STOP)
+                        return true;
+        }
+        return false;
+}
+
+
 int manager_loop(Manager *m) {
         int r;
 
@@ -1429,7 +1449,9 @@ int manager_loop(Manager *m) {
         if (r < 0)
                 return r;
 
-        while (m->exit_code == MANAGER_RUNNING) {
+        while (m->exit_code == MANAGER_RUNNING
+               || (m->exit_code == MANAGER_SWITCH_ROOT && manager_has_pending_terminating_units(m))) {
+
                 struct epoll_event event;
                 int n;
                 int wait_msec = -1;
-- 
1.7.10.4



More information about the systemd-devel mailing list