From: Harald Hoyer <har...@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 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel