chiark / gitweb /
core: send out "Reloading" signal before and after doing a full reload/reexec of...
authorLennart Poettering <lennart@poettering.net>
Wed, 10 Jul 2013 19:10:53 +0000 (21:10 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 10 Jul 2013 21:41:03 +0000 (23:41 +0200)
Since we'll unload all units/job during a reload, and then readd them it
is really useful for clients to be aware of this phase hence sent a
signal out before and after. This signal is called "Reloading" (despite
the fact that it is also sent out during reexecution, which we consider
a special case in this context) and has one boolean parameter which is
true for the signal sent before the reload, and false for the signal
after the reload. The UnitRemoved/JobRremoved and UnitNew/JobNew due to
the reloading are guranteed to be between the pair of Reloading
messages.

src/core/dbus-manager.c
src/core/dbus.c
src/core/dbus.h
src/core/main.c
src/core/manager.c
src/core/manager.h

index 742f6bb..d7604b1 100644 (file)
         "   <arg name=\"userspace\" type=\"t\"/>\n"                     \
         "   <arg name=\"total\" type=\"t\"/>\n"                         \
         "  </signal>"                                                   \
-        "  <signal name=\"UnitFilesChanged\"/>\n"
+        "  <signal name=\"UnitFilesChanged\"/>\n"                       \
+        "  <signal name=\"Reloading\">\n"                               \
+        "   <arg name=\"active\" type=\"b\"/>\n"                        \
+        "  </signal>"
 
 #define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL                        \
         "  <property name=\"Version\" type=\"s\" access=\"read\"/>\n"   \
index c1bf25c..aa3d93b 100644 (file)
@@ -1451,7 +1451,7 @@ void bus_broadcast_finished(
                 usec_t userspace_usec,
                 usec_t total_usec) {
 
-        DBusMessage *message;
+        _cleanup_dbus_message_unref_ DBusMessage *message = NULL;
 
         assert(m);
 
@@ -1471,18 +1471,42 @@ void bus_broadcast_finished(
                                       DBUS_TYPE_UINT64, &total_usec,
                                       DBUS_TYPE_INVALID)) {
                 log_oom();
-                goto finish;
+                return;
         }
 
 
         if (bus_broadcast(m, message) < 0) {
                 log_oom();
-                goto finish;
+                return;
         }
+}
 
-finish:
-        if (message)
-                dbus_message_unref(message);
+void bus_broadcast_reloading(Manager *m, bool active) {
+
+        _cleanup_dbus_message_unref_ DBusMessage *message = NULL;
+        dbus_bool_t b = active;
+
+        assert(m);
+
+        message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "Reloading");
+        if (!message) {
+                log_oom();
+                return;
+        }
+
+        assert_cc(sizeof(usec_t) == sizeof(uint64_t));
+        if (!dbus_message_append_args(message,
+                                      DBUS_TYPE_BOOLEAN, &b,
+                                      DBUS_TYPE_INVALID)) {
+                log_oom();
+                return;
+        }
+
+
+        if (bus_broadcast(m, message) < 0) {
+                log_oom();
+                return;
+        }
 }
 
 Set *bus_acquire_subscribed(Manager *m, DBusConnection *c) {
index b5c28c6..6500cd7 100644 (file)
@@ -43,6 +43,7 @@ bool bus_connection_has_subscriber(Manager *m, DBusConnection *c);
 int bus_fdset_add_all(Manager *m, FDSet *fds);
 
 void bus_broadcast_finished(Manager *m, usec_t firmware_usec, usec_t loader_usec, usec_t kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
+void bus_broadcast_reloading(Manager *m, bool active);
 
 Set *bus_acquire_subscribed(Manager *m, DBusConnection *c);
 
index 1d188e0..efc5791 100644 (file)
@@ -1055,15 +1055,16 @@ static int prepare_reexecute(Manager *m, FILE **_f, FDSet **_fds, bool switching
         assert(_f);
         assert(_fds);
 
-        /* Make sure nothing is really destructed when we shut down */
-        m->n_reloading ++;
-
         r = manager_open_serialization(m, &f);
         if (r < 0) {
                 log_error("Failed to create serialization file: %s", strerror(-r));
                 goto fail;
         }
 
+        /* Make sure nothing is really destructed when we shut down */
+        m->n_reloading ++;
+        bus_broadcast_reloading(m, true);
+
         fds = fdset_new();
         if (!fds) {
                 r = -ENOMEM;
index 51f03de..2e98181 100644 (file)
@@ -864,6 +864,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
         if (serialization) {
                 assert(m->n_reloading > 0);
                 m->n_reloading --;
+
+                /* Let's wait for the UnitNew/JobNew messages being
+                 * sent, before we notify that the reload is
+                 * finished */
+                m->send_reloading_done = true;
         }
 
         return r;
@@ -1163,6 +1168,13 @@ unsigned manager_dispatch_dbus_queue(Manager *m) {
         }
 
         m->dispatching_dbus_queue = false;
+
+        if (m->send_reloading_done) {
+                m->send_reloading_done = false;
+
+                bus_broadcast_reloading(m, false);
+        }
+
         return n;
 }
 
@@ -2238,6 +2250,7 @@ int manager_reload(Manager *m) {
                 return r;
 
         m->n_reloading ++;
+        bus_broadcast_reloading(m, true);
 
         fds = fdset_new();
         if (!fds) {
@@ -2297,6 +2310,8 @@ int manager_reload(Manager *m) {
         assert(m->n_reloading > 0);
         m->n_reloading--;
 
+        m->send_reloading_done = true;
+
 finish:
         if (f)
                 fclose(f);
index 31da04e..6d52414 100644 (file)
@@ -195,6 +195,8 @@ struct Manager {
         int32_t conn_data_slot;
         int32_t subscribed_data_slot;
 
+        bool send_reloading_done;
+
         uint32_t current_job_id;
         uint32_t default_unit_job_id;