chiark / gitweb /
dbus: send our finished signal when we are finished booting
authorLennart Poettering <lennart@poettering.net>
Mon, 27 Jun 2011 11:47:03 +0000 (13:47 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 27 Jun 2011 11:47:03 +0000 (13:47 +0200)
TODO
src/dbus-manager.c
src/dbus.c
src/dbus.h
src/logind.h
src/manager.c

diff --git a/TODO b/TODO
index d7c92e13b2351dde10461e5c09d6474918786a14..2700c7a25b2d5a827041ae18930b663dd2e5211c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -56,8 +56,6 @@ Features:
 
 * add prefix match to sysctl, tmpfiles, ...
 
-* send out "finished" signal when we are finished booting
-
 * drop /.readahead on bigger upgrades with yum
 
 * add inode stat() check to readahead to suppress preloading changed files
index cc2b4d01573e0e6b8707746e4b3434feccf514c8..b4e2f86aba51d4fee14c30ac231e65c402041a23 100644 (file)
         "   <arg name=\"id\" type=\"u\"/>\n"                            \
         "   <arg name=\"job\" type=\"o\"/>\n"                           \
         "   <arg name=\"result\" type=\"s\"/>\n"                        \
+        "  </signal>"                                                   \
+        "  <signal name=\"StartupFinished\">\n"                         \
+        "   <arg name=\"kernel\" type=\"t\"/>\n"                        \
+        "   <arg name=\"initrd\" type=\"t\"/>\n"                        \
+        "   <arg name=\"userspace\" type=\"t\"/>\n"                     \
+        "   <arg name=\"total\" type=\"t\"/>\n"                         \
         "  </signal>"
 
 #define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL                        \
index 93a19a45cd111321827a3d86d03674da60fa475d..764c65cc0d80b4c832fe5d351e7d41e11ee32e9c 100644 (file)
@@ -1274,3 +1274,42 @@ int bus_fdset_add_all(Manager *m, FDSet *fds) {
 
         return 0;
 }
+
+void bus_broadcast_finished(
+                Manager *m,
+                usec_t kernel_usec,
+                usec_t initrd_usec,
+                usec_t userspace_usec,
+                usec_t total_usec) {
+
+        DBusMessage *message;
+
+        assert(m);
+
+        message = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "StartupFinished");
+        if (!message) {
+                log_error("Out of memory.");
+                return;
+        }
+
+        assert_cc(sizeof(usec_t) == sizeof(uint64_t));
+        if (!dbus_message_append_args(message,
+                                      DBUS_TYPE_UINT64, &kernel_usec,
+                                      DBUS_TYPE_UINT64, &initrd_usec,
+                                      DBUS_TYPE_UINT64, &userspace_usec,
+                                      DBUS_TYPE_UINT64, &total_usec,
+                                      DBUS_TYPE_INVALID)) {
+                log_error("Out of memory.");
+                goto finish;
+        }
+
+
+        if (bus_broadcast(m, message) < 0) {
+                log_error("Out of memory.");
+                goto finish;
+        }
+
+finish:
+        if (m)
+                dbus_message_unref(message);
+}
index c47e782692f15a6175df01eb1fde688231ec0cfa..bd539d0e72998dc706f801d906a90ca1d5a572e8 100644 (file)
@@ -43,6 +43,8 @@ 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 kernel_usec, usec_t initrd_usec, usec_t userspace_usec, usec_t total_usec);
+
 #define BUS_CONNECTION_SUBSCRIBED(m, c) dbus_connection_get_data((c), (m)->subscribed_data_slot)
 #define BUS_PENDING_CALL_NAME(m, p) dbus_pending_call_get_data((p), (m)->name_data_slot)
 
index d512c3ee2ffd9c135facd240fd75e1aa812c171b..be8bb1d389a37b033f95cee088835856a5ba0b62 100644 (file)
@@ -37,7 +37,7 @@
  * recreate VTs when disallocated
  * spawn user systemd
  * direct client API
- * D-Bus method: AttachDevice(seat, device);
+ * D-Bus method: AttachDevices(seat, devices[]);
  * D-Bus method: SetLinger(user, bool b);
  *
  * non-local X11 server
index 19172a20181a1274435a9932d2acefbe59266b72..0830e8020efc8311cdfe4aa1217ad17ddabdefca 100644 (file)
@@ -2899,6 +2899,7 @@ bool manager_unit_pending_inactive(Manager *m, const char *name) {
 
 void manager_check_finished(Manager *m) {
         char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX];
+        usec_t kernel_usec = 0, initrd_usec = 0, userspace_usec = 0, total_usec = 0;
 
         assert(m);
 
@@ -2912,29 +2913,37 @@ void manager_check_finished(Manager *m) {
 
         if (m->running_as == MANAGER_SYSTEM && detect_container(NULL) <= 0) {
 
+                userspace_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
+                total_usec = m->finish_timestamp.monotonic;
+
                 if (dual_timestamp_is_set(&m->initrd_timestamp)) {
+
+                        kernel_usec = m->initrd_timestamp.monotonic;
+                        initrd_usec = m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic;
+
                         log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.",
-                                 format_timespan(kernel, sizeof(kernel),
-                                                 m->initrd_timestamp.monotonic),
-                                 format_timespan(initrd, sizeof(initrd),
-                                                 m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic),
-                                 format_timespan(userspace, sizeof(userspace),
-                                                 m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
-                                 format_timespan(sum, sizeof(sum),
-                                                 m->finish_timestamp.monotonic));
-                } else
+                                 format_timespan(kernel, sizeof(kernel), kernel_usec),
+                                 format_timespan(initrd, sizeof(initrd), initrd_usec),
+                                 format_timespan(userspace, sizeof(userspace), userspace_usec),
+                                 format_timespan(sum, sizeof(sum), total_usec));
+                } else {
+                        kernel_usec = m->startup_timestamp.monotonic;
+                        initrd_usec = 0;
+
                         log_info("Startup finished in %s (kernel) + %s (userspace) = %s.",
-                                 format_timespan(kernel, sizeof(kernel),
-                                                 m->startup_timestamp.monotonic),
-                                 format_timespan(userspace, sizeof(userspace),
-                                                 m->finish_timestamp.monotonic - m->startup_timestamp.monotonic),
-                                 format_timespan(sum, sizeof(sum),
-                                                 m->finish_timestamp.monotonic));
-        } else
+                                 format_timespan(kernel, sizeof(kernel), kernel_usec),
+                                 format_timespan(userspace, sizeof(userspace), userspace_usec),
+                                 format_timespan(sum, sizeof(sum), total_usec));
+                }
+        } else {
+                userspace_usec = initrd_usec = kernel_usec = 0;
+                total_usec = m->finish_timestamp.monotonic - m->startup_timestamp.monotonic;
+
                 log_debug("Startup finished in %s.",
-                          format_timespan(userspace, sizeof(userspace),
-                                          m->finish_timestamp.monotonic - m->startup_timestamp.monotonic));
+                          format_timespan(sum, sizeof(sum), total_usec));
+        }
 
+        bus_broadcast_finished(m, kernel_usec, initrd_usec, userspace_usec, total_usec);
 }
 
 void manager_run_generators(Manager *m) {