summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO2
-rw-r--r--src/dbus-manager.c6
-rw-r--r--src/dbus.c39
-rw-r--r--src/dbus.h2
-rw-r--r--src/logind.h2
-rw-r--r--src/manager.c45
6 files changed, 75 insertions, 21 deletions
diff --git a/TODO b/TODO
index d7c92e13b2..2700c7a25b 100644
--- 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
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index cc2b4d0157..b4e2f86aba 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -151,6 +151,12 @@
" <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 \
diff --git a/src/dbus.c b/src/dbus.c
index 93a19a45cd..764c65cc0d 100644
--- a/src/dbus.c
+++ b/src/dbus.c
@@ -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);
+}
diff --git a/src/dbus.h b/src/dbus.h
index c47e782692..bd539d0e72 100644
--- a/src/dbus.h
+++ b/src/dbus.h
@@ -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)
diff --git a/src/logind.h b/src/logind.h
index d512c3ee2f..be8bb1d389 100644
--- a/src/logind.h
+++ b/src/logind.h
@@ -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
diff --git a/src/manager.c b/src/manager.c
index 19172a2018..0830e8020e 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -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) {