[systemd-devel] Fwd: [systemd-208][PATCH] Force machined to dispatch messages

solganik solganik at gmail.com
Wed Apr 29 00:06:40 PDT 2015


From: Alexander Solganik <solganik at gmail.com>

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.
---
 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..79e0319 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);

--
1.8.3.1


More information about the systemd-devel mailing list