[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