Note that this will wait forever if any given unit never terminates
(by itself or by getting stopped explicitly); particularly services
which use <literal>RemainAfterExit=yes</literal>.</para>
+
+ <para>When used with <command>is-system-running</command>, wait
+ until the boot process is completed before returning.</para>
</listitem>
</varlistentry>
output, see the table below. Use <option>--quiet</option> to
suppress this output.</para>
+ <para>Use <option>--wait</option> to wait until the boot
+ process is completed before printing the current state and
+ returning the appropriate error status. If <option>--wait</option>
+ is in use, states <varname>initializing</varname> or
+ <varname>starting</varname> will not be reported, instead
+ the command will block until a later state (such as
+ <varname>running</varname> or <varname>degraded</varname>)
+ is reached.</para>
+
<table>
<title><command>is-system-running</command> output</title>
<tgroup cols='3'>
#include "sd-bus.h"
#include "sd-daemon.h"
+#include "sd-event.h"
#include "sd-login.h"
#include "alloc-util.h"
return enabled ? EXIT_SUCCESS : EXIT_FAILURE;
}
+static int match_startup_finished(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ char **state = userdata;
+ int r;
+
+ assert(state);
+
+ r = sd_bus_get_property_string(
+ sd_bus_message_get_bus(m),
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "SystemState",
+ NULL,
+ state);
+
+ sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), r);
+ return 0;
+}
+
static int is_system_running(int argc, char *argv[], void *userdata) {
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot_startup_finished = NULL;
+ _cleanup_(sd_event_unrefp) sd_event* event = NULL;
_cleanup_free_ char *state = NULL;
sd_bus *bus;
int r;
if (r < 0)
return r;
+ if (arg_wait) {
+ r = sd_event_default(&event);
+ if (r >= 0)
+ r = sd_bus_attach_event(bus, event, 0);
+ if (r >= 0)
+ r = sd_bus_match_signal_async(
+ bus,
+ &slot_startup_finished,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartupFinished",
+ match_startup_finished, NULL, &state);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to request match for StartupFinished: %m");
+ arg_wait = false;
+ }
+ }
+
r = sd_bus_get_property_string(
bus,
"org.freedesktop.systemd1",
&error,
&state);
if (r < 0) {
- log_debug_errno(r, "Failed to query system state: %s", bus_error_message(&error, r));
+ log_warning_errno(r, "Failed to query system state: %s", bus_error_message(&error, r));
if (!arg_quiet)
puts("unknown");
return EXIT_FAILURE;
}
+ if (arg_wait && STR_IN_SET(state, "initializing", "starting")) {
+ r = sd_event_loop(event);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to get property from event loop: %m");
+ if (!arg_quiet)
+ puts("unknown");
+ return EXIT_FAILURE;
+ }
+ }
+
if (!arg_quiet)
puts(state);
" --dry-run Only print what would be done\n"
" -q --quiet Suppress output\n"
" --wait For (re)start, wait until service stopped again\n"
+ " For is-system-running, wait until startup is completed\n"
" --no-block Do not wait until operation finished\n"
" --no-wall Don't send wall message before halt/power-off/reboot\n"
" --no-reload Don't reload daemon after en-/dis-abling unit files\n"