summaryrefslogtreecommitdiffstats
path: root/src/systemctl/systemctl-is-system-running.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/systemctl/systemctl-is-system-running.c')
-rw-r--r--src/systemctl/systemctl-is-system-running.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/src/systemctl/systemctl-is-system-running.c b/src/systemctl/systemctl-is-system-running.c
new file mode 100644
index 0000000..59be6a7
--- /dev/null
+++ b/src/systemctl/systemctl-is-system-running.c
@@ -0,0 +1,82 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-event.h"
+#include "sd-daemon.h"
+
+#include "systemctl-util.h"
+#include "systemctl-is-system-running.h"
+#include "virt.h"
+#include "systemctl.h"
+#include "bus-util.h"
+#include "bus-locator.h"
+#include "bus-error.h"
+
+static int match_startup_finished(sd_bus_message *m, void *userdata, sd_bus_error *error) {
+ char **state = ASSERT_PTR(userdata);
+ int r;
+
+ r = bus_get_property_string(sd_bus_message_get_bus(m), bus_systemd_mgr, "SystemState", NULL, state);
+
+ sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), r);
+ return 0;
+}
+
+int verb_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 (!isempty(arg_root) || running_in_chroot() > 0 || (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted())) {
+ if (!arg_quiet)
+ puts("offline");
+ return EXIT_FAILURE;
+ }
+
+ r = acquire_bus(BUS_MANAGER, &bus);
+ 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 = bus_match_signal_async(
+ bus,
+ &slot_startup_finished,
+ bus_systemd_mgr,
+ "StartupFinished",
+ match_startup_finished, NULL, &state);
+ if (r < 0) {
+ log_warning_errno(r, "Failed to request match for StartupFinished: %m");
+ arg_wait = false;
+ }
+ }
+
+ r = bus_get_property_string(bus, bus_systemd_mgr, "SystemState", &error, &state);
+ if (r < 0) {
+ 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);
+
+ return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
+}