From 1ed560ffff6753d79f2f1da81447e5f8d3628ec1 Mon Sep 17 00:00:00 2001 From: Alexander Solganik Date: Wed, 29 Apr 2015 10:06:40 +0300 Subject: [PATCH] machined: force machined to dispatch messages Fixes https://bugzilla.redhat.com/show_bug.cgi?format=multiple&id=1172387. Machined works in the follwing way : loop : 1) perform GC (Note at the end) 2) read messages from DBUS and dispatch one 3) if more messages pending goto (1) 3) perform GC (NOTE at the end) 4) poll on DBUS fd 5) goto step 1 This works fine, except that in step (3) and (1) there is a message send/reply receive of r = bus_method_call_with_reply( manager->bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StopUnit", &reply, error, DBUS_TYPE_STRING, &unit, DBUS_TYPE_STRING, &fail, DBUS_TYPE_INVALID); which causes network layer to read/write messages to DBUS fd. In case that any other message gets in during this send/receive cycle it wont be processed till next stage (2) which will occur only in case that more messages are received by machined. Cherry-picked from: rhel-only Resolves: #1243401 --- src/machine/machined.c | 8 ++++++-- src/machine/machined.h | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/machine/machined.c b/src/machine/machined.c index ad804a1..531e7ad 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -243,20 +243,23 @@ fail: return r; } -void manager_gc(Manager *m, bool drop_not_started) { +bool manager_gc(Manager *m, bool drop_not_started) { Machine *machine; + bool dbus_send_receive_performed = false; assert(m); while ((machine = m->machine_gc_queue)) { LIST_REMOVE(Machine, gc_queue, m->machine_gc_queue, machine); machine->in_gc_queue = false; + dbus_send_receive_performed = true; if (machine_check_gc(machine, drop_not_started) == 0) { machine_stop(machine); machine_free(machine); } } + return dbus_send_receive_performed; } int manager_startup(Manager *m) { @@ -301,7 +304,8 @@ int manager_run(Manager *m) { if (dbus_connection_dispatch(m->bus) != DBUS_DISPATCH_COMPLETE) continue; - manager_gc(m, true); + if (manager_gc(m, true)) + continue; n = epoll_wait(m->epoll_fd, &event, 1, -1); if (n < 0) { diff --git a/src/machine/machined.h b/src/machine/machined.h index 780f516..3245e05 100644 --- a/src/machine/machined.h +++ b/src/machine/machined.h @@ -59,7 +59,7 @@ int manager_enumerate_machines(Manager *m); int manager_startup(Manager *m); int manager_run(Manager *m); -void manager_gc(Manager *m, bool drop_not_started); +bool manager_gc(Manager *m, bool drop_not_started); int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine);