]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/systemctl/systemctl-is-system-running.c
license: LGPL-2.1+ -> LGPL-2.1-or-later
[thirdparty/systemd.git] / src / systemctl / systemctl-is-system-running.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include "sd-event.h"
4 #include "sd-daemon.h"
5
6 #include "systemctl-util.h"
7 #include "systemctl-is-system-running.h"
8 #include "virt.h"
9 #include "systemctl.h"
10 #include "bus-util.h"
11 #include "bus-locator.h"
12 #include "bus-error.h"
13
14 static int match_startup_finished(sd_bus_message *m, void *userdata, sd_bus_error *error) {
15 char **state = userdata;
16 int r;
17
18 assert(state);
19
20 r = bus_get_property_string(sd_bus_message_get_bus(m), bus_systemd_mgr, "SystemState", NULL, state);
21
22 sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), r);
23 return 0;
24 }
25
26 int is_system_running(int argc, char *argv[], void *userdata) {
27 _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
28 _cleanup_(sd_bus_slot_unrefp) sd_bus_slot *slot_startup_finished = NULL;
29 _cleanup_(sd_event_unrefp) sd_event* event = NULL;
30 _cleanup_free_ char *state = NULL;
31 sd_bus *bus;
32 int r;
33
34 if (running_in_chroot() > 0 || (arg_transport == BUS_TRANSPORT_LOCAL && !sd_booted())) {
35 if (!arg_quiet)
36 puts("offline");
37 return EXIT_FAILURE;
38 }
39
40 r = acquire_bus(BUS_MANAGER, &bus);
41 if (r < 0)
42 return r;
43
44 if (arg_wait) {
45 r = sd_event_default(&event);
46 if (r >= 0)
47 r = sd_bus_attach_event(bus, event, 0);
48 if (r >= 0)
49 r = bus_match_signal_async(
50 bus,
51 &slot_startup_finished,
52 bus_systemd_mgr,
53 "StartupFinished",
54 match_startup_finished, NULL, &state);
55 if (r < 0) {
56 log_warning_errno(r, "Failed to request match for StartupFinished: %m");
57 arg_wait = false;
58 }
59 }
60
61 r = bus_get_property_string(bus, bus_systemd_mgr, "SystemState", &error, &state);
62 if (r < 0) {
63 log_warning_errno(r, "Failed to query system state: %s", bus_error_message(&error, r));
64
65 if (!arg_quiet)
66 puts("unknown");
67 return EXIT_FAILURE;
68 }
69
70 if (arg_wait && STR_IN_SET(state, "initializing", "starting")) {
71 r = sd_event_loop(event);
72 if (r < 0) {
73 log_warning_errno(r, "Failed to get property from event loop: %m");
74 if (!arg_quiet)
75 puts("unknown");
76 return EXIT_FAILURE;
77 }
78 }
79
80 if (!arg_quiet)
81 puts(state);
82
83 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
84 }