1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
50 #include "utmp-wtmp.h"
53 #include "path-util.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "socket-util.h"
73 #include "bus-message.h"
74 #include "bus-error.h"
75 #include "bus-errors.h"
77 static char **arg_types = NULL;
78 static char **arg_states = NULL;
79 static char **arg_properties = NULL;
80 static bool arg_all = false;
81 static enum dependency {
87 } arg_dependency = DEPENDENCY_FORWARD;
88 static const char *arg_job_mode = "replace";
89 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
90 static bool arg_no_block = false;
91 static bool arg_no_legend = false;
92 static bool arg_no_pager = false;
93 static bool arg_no_wtmp = false;
94 static bool arg_no_wall = false;
95 static bool arg_no_reload = false;
96 static bool arg_show_types = false;
97 static bool arg_ignore_inhibitors = false;
98 static bool arg_dry = false;
99 static bool arg_quiet = false;
100 static bool arg_full = false;
101 static bool arg_recursive = false;
102 static int arg_force = 0;
103 static bool arg_ask_password = true;
104 static bool arg_runtime = false;
105 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
106 static char **arg_wall = NULL;
107 static const char *arg_kill_who = NULL;
108 static int arg_signal = SIGTERM;
109 static const char *arg_root = NULL;
110 static usec_t arg_when = 0;
132 ACTION_CANCEL_SHUTDOWN,
134 } arg_action = ACTION_SYSTEMCTL;
135 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
136 static char *arg_host = NULL;
137 static unsigned arg_lines = 10;
138 static OutputMode arg_output = OUTPUT_SHORT;
139 static bool arg_plain = false;
141 static bool original_stdout_is_tty;
143 static int daemon_reload(sd_bus *bus, char **args);
144 static int halt_now(enum action a);
145 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
147 static char** strv_skip_first(char **strv) {
148 if (strv_length(strv) > 0)
153 static void pager_open_if_enabled(void) {
161 static void ask_password_agent_open_if_enabled(void) {
163 /* Open the password agent as a child process if necessary */
165 if (!arg_ask_password)
168 if (arg_scope != UNIT_FILE_SYSTEM)
171 if (arg_transport != BUS_TRANSPORT_LOCAL)
174 ask_password_agent_open();
178 static void polkit_agent_open_if_enabled(void) {
180 /* Open the polkit agent as a child process if necessary */
182 if (!arg_ask_password)
185 if (arg_scope != UNIT_FILE_SYSTEM)
188 if (arg_transport != BUS_TRANSPORT_LOCAL)
195 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
198 if (!sd_bus_error_is_set(error))
201 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
202 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
203 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
204 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
205 return EXIT_NOPERMISSION;
207 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
208 return EXIT_NOTINSTALLED;
210 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
211 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
212 return EXIT_NOTIMPLEMENTED;
214 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
215 return EXIT_NOTCONFIGURED;
223 static void warn_wall(enum action a) {
224 static const char *table[_ACTION_MAX] = {
225 [ACTION_HALT] = "The system is going down for system halt NOW!",
226 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
227 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
228 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
229 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
230 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
231 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
238 _cleanup_free_ char *p;
240 p = strv_join(arg_wall, " ");
247 utmp_wall(p, NULL, NULL);
255 utmp_wall(table[a], NULL, NULL);
258 static bool avoid_bus(void) {
260 if (running_in_chroot() > 0)
263 if (sd_booted() <= 0)
266 if (!isempty(arg_root))
269 if (arg_scope == UNIT_FILE_GLOBAL)
275 static int compare_unit_info(const void *a, const void *b) {
276 const UnitInfo *u = a, *v = b;
280 /* First, order by machine */
281 if (!u->machine && v->machine)
283 if (u->machine && !v->machine)
285 if (u->machine && v->machine) {
286 r = strcasecmp(u->machine, v->machine);
291 /* Second, order by unit type */
292 d1 = strrchr(u->id, '.');
293 d2 = strrchr(v->id, '.');
295 r = strcasecmp(d1, d2);
300 /* Third, order by name */
301 return strcasecmp(u->id, v->id);
304 static bool output_show_unit(const UnitInfo *u, char **patterns) {
305 if (!strv_isempty(patterns)) {
308 STRV_FOREACH(pattern, patterns)
309 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
318 dot = strrchr(u->id, '.');
322 if (!strv_find(arg_types, dot+1))
332 if (streq(u->active_state, "inactive") || u->following[0])
338 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
339 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
341 unsigned n_shown = 0;
344 max_id_len = strlen("UNIT");
345 load_len = strlen("LOAD");
346 active_len = strlen("ACTIVE");
347 sub_len = strlen("SUB");
348 job_len = strlen("JOB");
351 for (u = unit_infos; u < unit_infos + c; u++) {
352 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
353 load_len = MAX(load_len, strlen(u->load_state));
354 active_len = MAX(active_len, strlen(u->active_state));
355 sub_len = MAX(sub_len, strlen(u->sub_state));
357 if (u->job_id != 0) {
358 job_len = MAX(job_len, strlen(u->job_type));
362 if (!arg_no_legend &&
363 (streq(u->active_state, "failed") ||
364 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
368 if (!arg_full && original_stdout_is_tty) {
371 id_len = MIN(max_id_len, 25u);
372 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
375 basic_len += job_len + 1;
377 if (basic_len < (unsigned) columns()) {
378 unsigned extra_len, incr;
379 extra_len = columns() - basic_len;
381 /* Either UNIT already got 25, or is fully satisfied.
382 * Grant up to 25 to DESC now. */
383 incr = MIN(extra_len, 25u);
387 /* split the remaining space between UNIT and DESC,
388 * but do not give UNIT more than it needs. */
390 incr = MIN(extra_len / 2, max_id_len - id_len);
392 desc_len += extra_len - incr;
398 for (u = unit_infos; u < unit_infos + c; u++) {
399 _cleanup_free_ char *e = NULL, *j = NULL;
400 const char *on_loaded = "", *off_loaded = "";
401 const char *on_active = "", *off_active = "";
402 const char *on_circle = "", *off_circle = "";
406 if (!n_shown && !arg_no_legend) {
411 printf("%-*s %-*s %-*s %-*s ",
414 active_len, "ACTIVE",
418 printf("%-*s ", job_len, "JOB");
420 if (!arg_full && arg_no_pager)
421 printf("%.*s\n", desc_len, "DESCRIPTION");
423 printf("%s\n", "DESCRIPTION");
428 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
429 on_loaded = ansi_highlight_red();
430 on_circle = ansi_highlight_yellow();
431 off_loaded = off_circle = ansi_highlight_off();
435 if (streq(u->active_state, "failed")) {
436 on_circle = on_active = ansi_highlight_red();
437 off_circle = off_active = ansi_highlight_off();
442 j = strjoin(u->machine, ":", u->id, NULL);
451 e = ellipsize(id, id_len, 33);
459 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
461 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
462 on_active, id_len, id, off_active,
463 on_loaded, load_len, u->load_state, off_loaded,
464 on_active, active_len, u->active_state,
465 sub_len, u->sub_state, off_active,
466 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
469 printf("%.*s\n", desc_len, u->description);
471 printf("%s\n", u->description);
474 if (!arg_no_legend) {
475 const char *on, *off;
479 "LOAD = Reflects whether the unit definition was properly loaded.\n"
480 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
481 "SUB = The low-level unit activation state, values depend on unit type.");
482 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
483 on = ansi_highlight();
484 off = ansi_highlight_off();
486 on = ansi_highlight_red();
487 off = ansi_highlight_off();
491 printf("%s%u loaded units listed.%s\n"
492 "To show all installed unit files use 'systemctl list-unit-files'.\n",
495 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
496 "To show all installed unit files use 'systemctl list-unit-files'.\n",
503 static int get_unit_list(
507 UnitInfo **unit_infos,
509 sd_bus_message **_reply) {
511 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
512 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
513 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
522 r = sd_bus_message_new_method_call(
525 "org.freedesktop.systemd1",
526 "/org/freedesktop/systemd1",
527 "org.freedesktop.systemd1.Manager",
528 "ListUnitsFiltered");
531 return bus_log_create_error(r);
533 r = sd_bus_message_append_strv(m, arg_states);
535 return bus_log_create_error(r);
537 r = sd_bus_call(bus, m, 0, &error, &reply);
539 log_error("Failed to list units: %s", bus_error_message(&error, r));
543 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
545 return bus_log_parse_error(r);
547 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
550 if (!output_show_unit(&u, patterns))
553 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
556 (*unit_infos)[c++] = u;
559 return bus_log_parse_error(r);
561 r = sd_bus_message_exit_container(reply);
563 return bus_log_parse_error(r);
571 static void message_set_freep(Set **set) {
574 while ((m = set_steal_first(*set)))
575 sd_bus_message_unref(m);
580 static int get_unit_list_recursive(
583 UnitInfo **_unit_infos,
587 _cleanup_free_ UnitInfo *unit_infos = NULL;
588 _cleanup_(message_set_freep) Set *replies;
589 sd_bus_message *reply;
597 replies = set_new(NULL);
601 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
605 r = set_put(replies, reply);
607 sd_bus_message_unref(reply);
612 _cleanup_strv_free_ char **machines = NULL;
615 r = sd_get_machine_names(&machines);
619 STRV_FOREACH(i, machines) {
620 _cleanup_bus_close_unref_ sd_bus *container = NULL;
623 r = sd_bus_open_system_container(&container, *i);
625 log_error_errno(r, "Failed to connect to container %s: %m", *i);
629 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
635 r = set_put(replies, reply);
637 sd_bus_message_unref(reply);
642 *_machines = machines;
647 *_unit_infos = unit_infos;
656 static int list_units(sd_bus *bus, char **args) {
657 _cleanup_free_ UnitInfo *unit_infos = NULL;
658 _cleanup_(message_set_freep) Set *replies = NULL;
659 _cleanup_strv_free_ char **machines = NULL;
662 pager_open_if_enabled();
664 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
668 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
669 return output_units_list(unit_infos, r);
672 static int get_triggered_units(
677 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
680 r = sd_bus_get_property_strv(
682 "org.freedesktop.systemd1",
684 "org.freedesktop.systemd1.Unit",
690 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
695 static int get_listening(
697 const char* unit_path,
700 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
701 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
702 const char *type, *path;
705 r = sd_bus_get_property(
707 "org.freedesktop.systemd1",
709 "org.freedesktop.systemd1.Socket",
715 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
719 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
721 return bus_log_parse_error(r);
723 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
725 r = strv_extend(listening, type);
729 r = strv_extend(listening, path);
736 return bus_log_parse_error(r);
738 r = sd_bus_message_exit_container(reply);
740 return bus_log_parse_error(r);
752 /* Note: triggered is a list here, although it almost certainly
753 * will always be one unit. Nevertheless, dbus API allows for multiple
754 * values, so let's follow that.*/
757 /* The strv above is shared. free is set only in the first one. */
761 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
767 if (!a->machine && b->machine)
769 if (a->machine && !b->machine)
771 if (a->machine && b->machine) {
772 o = strcasecmp(a->machine, b->machine);
777 o = strcmp(a->path, b->path);
779 o = strcmp(a->type, b->type);
784 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
785 struct socket_info *s;
786 unsigned pathlen = strlen("LISTEN"),
787 typelen = strlen("TYPE") * arg_show_types,
788 socklen = strlen("UNIT"),
789 servlen = strlen("ACTIVATES");
790 const char *on, *off;
792 for (s = socket_infos; s < socket_infos + cs; s++) {
796 socklen = MAX(socklen, strlen(s->id));
798 typelen = MAX(typelen, strlen(s->type));
799 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
801 STRV_FOREACH(a, s->triggered)
802 tmp += strlen(*a) + 2*(a != s->triggered);
803 servlen = MAX(servlen, tmp);
808 printf("%-*s %-*.*s%-*s %s\n",
810 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
814 for (s = socket_infos; s < socket_infos + cs; s++) {
815 _cleanup_free_ char *j = NULL;
820 j = strjoin(s->machine, ":", s->path, NULL);
828 printf("%-*s %-*s %-*s",
829 pathlen, path, typelen, s->type, socklen, s->id);
832 pathlen, path, socklen, s->id);
833 STRV_FOREACH(a, s->triggered)
835 a == s->triggered ? "" : ",", *a);
839 on = ansi_highlight();
840 off = ansi_highlight_off();
844 on = ansi_highlight_red();
845 off = ansi_highlight_off();
848 if (!arg_no_legend) {
849 printf("%s%u sockets listed.%s\n", on, cs, off);
851 printf("Pass --all to see loaded but inactive sockets, too.\n");
857 static int list_sockets(sd_bus *bus, char **args) {
858 _cleanup_(message_set_freep) Set *replies = NULL;
859 _cleanup_strv_free_ char **machines = NULL;
860 _cleanup_free_ UnitInfo *unit_infos = NULL;
861 _cleanup_free_ struct socket_info *socket_infos = NULL;
863 struct socket_info *s;
868 pager_open_if_enabled();
870 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
874 for (u = unit_infos; u < unit_infos + n; u++) {
875 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
878 if (!endswith(u->id, ".socket"))
881 r = get_triggered_units(bus, u->unit_path, &triggered);
885 c = get_listening(bus, u->unit_path, &listening);
891 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
896 for (i = 0; i < c; i++)
897 socket_infos[cs + i] = (struct socket_info) {
898 .machine = u->machine,
900 .type = listening[i*2],
901 .path = listening[i*2 + 1],
902 .triggered = triggered,
903 .own_triggered = i==0,
906 /* from this point on we will cleanup those socket_infos */
909 listening = triggered = NULL; /* avoid cleanup */
912 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
913 (__compar_fn_t) socket_info_compare);
915 output_sockets_list(socket_infos, cs);
918 assert(cs == 0 || socket_infos);
919 for (s = socket_infos; s < socket_infos + cs; s++) {
922 if (s->own_triggered)
923 strv_free(s->triggered);
929 static int get_next_elapse(
932 dual_timestamp *next) {
934 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
942 r = sd_bus_get_property_trivial(
944 "org.freedesktop.systemd1",
946 "org.freedesktop.systemd1.Timer",
947 "NextElapseUSecMonotonic",
952 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
956 r = sd_bus_get_property_trivial(
958 "org.freedesktop.systemd1",
960 "org.freedesktop.systemd1.Timer",
961 "NextElapseUSecRealtime",
966 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
974 static int get_last_trigger(
979 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
986 r = sd_bus_get_property_trivial(
988 "org.freedesktop.systemd1",
990 "org.freedesktop.systemd1.Timer",
996 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1004 const char* machine;
1007 usec_t last_trigger;
1011 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1017 if (!a->machine && b->machine)
1019 if (a->machine && !b->machine)
1021 if (a->machine && b->machine) {
1022 o = strcasecmp(a->machine, b->machine);
1027 if (a->next_elapse < b->next_elapse)
1029 if (a->next_elapse > b->next_elapse)
1032 return strcmp(a->id, b->id);
1035 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1036 struct timer_info *t;
1038 nextlen = strlen("NEXT"),
1039 leftlen = strlen("LEFT"),
1040 lastlen = strlen("LAST"),
1041 passedlen = strlen("PASSED"),
1042 unitlen = strlen("UNIT"),
1043 activatelen = strlen("ACTIVATES");
1045 const char *on, *off;
1047 assert(timer_infos || n == 0);
1049 for (t = timer_infos; t < timer_infos + n; t++) {
1053 if (t->next_elapse > 0) {
1054 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1056 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1057 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1059 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1060 leftlen = MAX(leftlen, strlen(trel));
1063 if (t->last_trigger > 0) {
1064 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1066 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1067 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1069 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1070 passedlen = MAX(passedlen, strlen(trel));
1073 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1075 STRV_FOREACH(a, t->triggered)
1076 ul += strlen(*a) + 2*(a != t->triggered);
1078 activatelen = MAX(activatelen, ul);
1083 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1087 passedlen, "PASSED",
1091 for (t = timer_infos; t < timer_infos + n; t++) {
1092 _cleanup_free_ char *j = NULL;
1094 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1095 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1098 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1099 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1101 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1102 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1105 j = strjoin(t->machine, ":", t->id, NULL);
1112 printf("%-*s %-*s %-*s %-*s %-*s",
1113 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1115 STRV_FOREACH(a, t->triggered)
1117 a == t->triggered ? "" : ",", *a);
1121 on = ansi_highlight();
1122 off = ansi_highlight_off();
1126 on = ansi_highlight_red();
1127 off = ansi_highlight_off();
1130 if (!arg_no_legend) {
1131 printf("%s%u timers listed.%s\n", on, n, off);
1133 printf("Pass --all to see loaded but inactive timers, too.\n");
1139 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1145 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1148 if (next->monotonic > nw->monotonic)
1149 converted = nw->realtime + (next->monotonic - nw->monotonic);
1151 converted = nw->realtime - (nw->monotonic - next->monotonic);
1153 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1154 next_elapse = MIN(converted, next->realtime);
1156 next_elapse = converted;
1159 next_elapse = next->realtime;
1164 static int list_timers(sd_bus *bus, char **args) {
1165 _cleanup_(message_set_freep) Set *replies = NULL;
1166 _cleanup_strv_free_ char **machines = NULL;
1167 _cleanup_free_ struct timer_info *timer_infos = NULL;
1168 _cleanup_free_ UnitInfo *unit_infos = NULL;
1169 struct timer_info *t;
1176 pager_open_if_enabled();
1178 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1182 dual_timestamp_get(&nw);
1184 for (u = unit_infos; u < unit_infos + n; u++) {
1185 _cleanup_strv_free_ char **triggered = NULL;
1186 dual_timestamp next = {};
1189 if (!endswith(u->id, ".timer"))
1192 r = get_triggered_units(bus, u->unit_path, &triggered);
1196 r = get_next_elapse(bus, u->unit_path, &next);
1200 get_last_trigger(bus, u->unit_path, &last);
1202 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1207 m = calc_next_elapse(&nw, &next);
1209 timer_infos[c++] = (struct timer_info) {
1210 .machine = u->machine,
1213 .last_trigger = last,
1214 .triggered = triggered,
1217 triggered = NULL; /* avoid cleanup */
1220 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1221 (__compar_fn_t) timer_info_compare);
1223 output_timers_list(timer_infos, c);
1226 for (t = timer_infos; t < timer_infos + c; t++)
1227 strv_free(t->triggered);
1232 static int compare_unit_file_list(const void *a, const void *b) {
1233 const char *d1, *d2;
1234 const UnitFileList *u = a, *v = b;
1236 d1 = strrchr(u->path, '.');
1237 d2 = strrchr(v->path, '.');
1242 r = strcasecmp(d1, d2);
1247 return strcasecmp(basename(u->path), basename(v->path));
1250 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1251 if (!strv_isempty(patterns)) {
1254 STRV_FOREACH(pattern, patterns)
1255 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1261 if (!strv_isempty(arg_types)) {
1264 dot = strrchr(u->path, '.');
1268 if (!strv_find(arg_types, dot+1))
1272 if (!strv_isempty(arg_states)) {
1273 if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
1280 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1281 unsigned max_id_len, id_cols, state_cols;
1282 const UnitFileList *u;
1284 max_id_len = strlen("UNIT FILE");
1285 state_cols = strlen("STATE");
1287 for (u = units; u < units + c; u++) {
1288 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1289 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1293 unsigned basic_cols;
1295 id_cols = MIN(max_id_len, 25u);
1296 basic_cols = 1 + id_cols + state_cols;
1297 if (basic_cols < (unsigned) columns())
1298 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1300 id_cols = max_id_len;
1303 printf("%-*s %-*s\n",
1304 id_cols, "UNIT FILE",
1305 state_cols, "STATE");
1307 for (u = units; u < units + c; u++) {
1308 _cleanup_free_ char *e = NULL;
1309 const char *on, *off;
1312 if (u->state == UNIT_FILE_MASKED ||
1313 u->state == UNIT_FILE_MASKED_RUNTIME ||
1314 u->state == UNIT_FILE_DISABLED ||
1315 u->state == UNIT_FILE_INVALID) {
1316 on = ansi_highlight_red();
1317 off = ansi_highlight_off();
1318 } else if (u->state == UNIT_FILE_ENABLED) {
1319 on = ansi_highlight_green();
1320 off = ansi_highlight_off();
1324 id = basename(u->path);
1326 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1328 printf("%-*s %s%-*s%s\n",
1329 id_cols, e ? e : id,
1330 on, state_cols, unit_file_state_to_string(u->state), off);
1334 printf("\n%u unit files listed.\n", c);
1337 static int list_unit_files(sd_bus *bus, char **args) {
1338 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1339 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1340 _cleanup_free_ UnitFileList *units = NULL;
1348 pager_open_if_enabled();
1356 h = hashmap_new(&string_hash_ops);
1360 r = unit_file_get_list(arg_scope, arg_root, h);
1362 unit_file_list_free(h);
1363 log_error_errno(r, "Failed to get unit file list: %m");
1367 n_units = hashmap_size(h);
1369 units = new(UnitFileList, n_units);
1370 if (!units && n_units > 0) {
1371 unit_file_list_free(h);
1375 HASHMAP_FOREACH(u, h, i) {
1376 if (!output_show_unit_file(u, strv_skip_first(args)))
1383 assert(c <= n_units);
1386 r = sd_bus_call_method(
1388 "org.freedesktop.systemd1",
1389 "/org/freedesktop/systemd1",
1390 "org.freedesktop.systemd1.Manager",
1396 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1400 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1402 return bus_log_parse_error(r);
1404 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1406 if (!GREEDY_REALLOC(units, size, c + 1))
1409 units[c] = (struct UnitFileList) {
1411 unit_file_state_from_string(state)
1414 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1419 return bus_log_parse_error(r);
1421 r = sd_bus_message_exit_container(reply);
1423 return bus_log_parse_error(r);
1426 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1427 output_unit_file_list(units, c);
1430 for (unit = units; unit < units + c; unit++)
1437 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1438 _cleanup_free_ char *n = NULL;
1439 size_t max_len = MAX(columns(),20u);
1445 for (i = level - 1; i >= 0; i--) {
1447 if (len > max_len - 3 && !arg_full) {
1448 printf("%s...\n",max_len % 2 ? "" : " ");
1451 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1455 if (len > max_len - 3 && !arg_full) {
1456 printf("%s...\n",max_len % 2 ? "" : " ");
1460 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1464 printf("%s\n", name);
1468 n = ellipsize(name, max_len-len, 100);
1476 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1478 static const char *dependencies[_DEPENDENCY_MAX] = {
1479 [DEPENDENCY_FORWARD] = "Requires\0"
1480 "RequiresOverridable\0"
1482 "RequisiteOverridable\0"
1485 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1486 "RequiredByOverridable\0"
1490 [DEPENDENCY_AFTER] = "After\0",
1491 [DEPENDENCY_BEFORE] = "Before\0",
1494 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1495 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1496 _cleanup_strv_free_ char **ret = NULL;
1497 _cleanup_free_ char *path = NULL;
1503 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1505 path = unit_dbus_path_from_name(name);
1509 r = sd_bus_call_method(
1511 "org.freedesktop.systemd1",
1513 "org.freedesktop.DBus.Properties",
1517 "s", "org.freedesktop.systemd1.Unit");
1519 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1523 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1525 return bus_log_parse_error(r);
1527 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1530 r = sd_bus_message_read(reply, "s", &prop);
1532 return bus_log_parse_error(r);
1534 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1535 r = sd_bus_message_skip(reply, "v");
1537 return bus_log_parse_error(r);
1540 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1542 return bus_log_parse_error(r);
1544 r = bus_message_read_strv_extend(reply, &ret);
1546 return bus_log_parse_error(r);
1548 r = sd_bus_message_exit_container(reply);
1550 return bus_log_parse_error(r);
1553 r = sd_bus_message_exit_container(reply);
1555 return bus_log_parse_error(r);
1559 return bus_log_parse_error(r);
1561 r = sd_bus_message_exit_container(reply);
1563 return bus_log_parse_error(r);
1571 static int list_dependencies_compare(const void *_a, const void *_b) {
1572 const char **a = (const char**) _a, **b = (const char**) _b;
1574 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1576 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1579 return strcasecmp(*a, *b);
1582 static int list_dependencies_one(
1587 unsigned int branches) {
1589 _cleanup_strv_free_ char **deps = NULL;
1597 r = strv_extend(units, name);
1601 r = list_dependencies_get_dependencies(bus, name, &deps);
1605 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1607 STRV_FOREACH(c, deps) {
1610 if (strv_contains(*units, *c)) {
1612 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1619 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1621 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1623 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1625 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1629 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1630 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1637 strv_remove(*units, name);
1642 static int list_dependencies(sd_bus *bus, char **args) {
1643 _cleanup_strv_free_ char **units = NULL;
1644 _cleanup_free_ char *unit = NULL;
1650 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1655 u = SPECIAL_DEFAULT_TARGET;
1657 pager_open_if_enabled();
1661 return list_dependencies_one(bus, u, 0, &units, 0);
1664 struct machine_info {
1668 char *control_group;
1669 uint32_t n_failed_units;
1674 static const struct bus_properties_map machine_info_property_map[] = {
1675 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1676 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1677 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1678 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1679 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1683 static void free_machines_list(struct machine_info *machine_infos, int n) {
1689 for (i = 0; i < n; i++) {
1690 free(machine_infos[i].name);
1691 free(machine_infos[i].state);
1692 free(machine_infos[i].control_group);
1695 free(machine_infos);
1698 static int compare_machine_info(const void *a, const void *b) {
1699 const struct machine_info *u = a, *v = b;
1701 if (u->is_host != v->is_host)
1702 return u->is_host > v->is_host ? -1 : 1;
1704 return strcasecmp(u->name, v->name);
1707 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1708 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1714 r = sd_bus_open_system_container(&container, mi->name);
1721 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1728 static bool output_show_machine(const char *name, char **patterns) {
1733 if (strv_isempty(patterns))
1736 STRV_FOREACH(i, patterns)
1737 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1743 static int get_machine_list(
1745 struct machine_info **_machine_infos,
1748 struct machine_info *machine_infos = NULL;
1749 _cleanup_strv_free_ char **m = NULL;
1750 _cleanup_free_ char *hn = NULL;
1755 hn = gethostname_malloc();
1759 if (output_show_machine(hn, patterns)) {
1760 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1763 machine_infos[c].is_host = true;
1764 machine_infos[c].name = hn;
1767 get_machine_properties(bus, &machine_infos[c]);
1771 sd_get_machine_names(&m);
1772 STRV_FOREACH(i, m) {
1773 _cleanup_free_ char *class = NULL;
1775 if (!output_show_machine(*i, patterns))
1778 sd_machine_get_class(*i, &class);
1779 if (!streq_ptr(class, "container"))
1782 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1783 free_machines_list(machine_infos, c);
1787 machine_infos[c].is_host = false;
1788 machine_infos[c].name = strdup(*i);
1789 if (!machine_infos[c].name) {
1790 free_machines_list(machine_infos, c);
1794 get_machine_properties(NULL, &machine_infos[c]);
1798 *_machine_infos = machine_infos;
1802 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1803 struct machine_info *m;
1806 namelen = sizeof("NAME") - 1,
1807 statelen = sizeof("STATE") - 1,
1808 failedlen = sizeof("FAILED") - 1,
1809 jobslen = sizeof("JOBS") - 1;
1811 assert(machine_infos || n == 0);
1813 for (m = machine_infos; m < machine_infos + n; m++) {
1814 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1815 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1816 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1817 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1819 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1823 if (!arg_no_legend) {
1827 printf("%-*s %-*s %-*s %-*s\n",
1830 failedlen, "FAILED",
1834 for (m = machine_infos; m < machine_infos + n; m++) {
1835 const char *on_state = "", *off_state = "";
1836 const char *on_failed = "", *off_failed = "";
1837 bool circle = false;
1839 if (streq_ptr(m->state, "degraded")) {
1840 on_state = ansi_highlight_red();
1841 off_state = ansi_highlight_off();
1843 } else if (!streq_ptr(m->state, "running")) {
1844 on_state = ansi_highlight_yellow();
1845 off_state = ansi_highlight_off();
1849 if (m->n_failed_units > 0) {
1850 on_failed = ansi_highlight_red();
1851 off_failed = ansi_highlight_off();
1853 on_failed = off_failed = "";
1856 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1859 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1860 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1861 on_state, statelen, strna(m->state), off_state,
1862 on_failed, failedlen, m->n_failed_units, off_failed,
1863 jobslen, m->n_jobs);
1865 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1866 namelen, strna(m->name),
1867 on_state, statelen, strna(m->state), off_state,
1868 on_failed, failedlen, m->n_failed_units, off_failed,
1869 jobslen, m->n_jobs);
1873 printf("\n%u machines listed.\n", n);
1876 static int list_machines(sd_bus *bus, char **args) {
1877 struct machine_info *machine_infos = NULL;
1882 if (geteuid() != 0) {
1883 log_error("Must be root.");
1887 pager_open_if_enabled();
1889 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1893 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1894 output_machines_list(machine_infos, r);
1895 free_machines_list(machine_infos, r);
1900 static int get_default(sd_bus *bus, char **args) {
1901 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1902 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1903 _cleanup_free_ char *_path = NULL;
1907 if (!bus || avoid_bus()) {
1908 r = unit_file_get_default(arg_scope, arg_root, &_path);
1910 log_error_errno(r, "Failed to get default target: %m");
1916 r = sd_bus_call_method(
1918 "org.freedesktop.systemd1",
1919 "/org/freedesktop/systemd1",
1920 "org.freedesktop.systemd1.Manager",
1926 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1930 r = sd_bus_message_read(reply, "s", &path);
1932 return bus_log_parse_error(r);
1936 printf("%s\n", path);
1941 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1944 assert(changes || n_changes == 0);
1946 for (i = 0; i < n_changes; i++) {
1947 if (changes[i].type == UNIT_FILE_SYMLINK)
1948 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1950 log_info("Removed symlink %s.", changes[i].path);
1954 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1955 const char *type, *path, *source;
1958 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1960 return bus_log_parse_error(r);
1962 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1964 if (streq(type, "symlink"))
1965 log_info("Created symlink from %s to %s.", path, source);
1967 log_info("Removed symlink %s.", path);
1971 return bus_log_parse_error(r);
1973 r = sd_bus_message_exit_container(m);
1975 return bus_log_parse_error(r);
1980 static int set_default(sd_bus *bus, char **args) {
1981 _cleanup_free_ char *unit = NULL;
1982 UnitFileChange *changes = NULL;
1983 unsigned n_changes = 0;
1986 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1990 if (!bus || avoid_bus()) {
1991 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1993 log_error_errno(r, "Failed to set default target: %m");
1998 dump_unit_file_changes(changes, n_changes);
2002 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
2003 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2005 r = sd_bus_message_new_method_call(
2008 "org.freedesktop.systemd1",
2009 "/org/freedesktop/systemd1",
2010 "org.freedesktop.systemd1.Manager",
2011 "SetDefaultTarget");
2013 return bus_log_create_error(r);
2015 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2017 return bus_log_create_error(r);
2019 r = sd_bus_message_append(m, "sb", unit, 1);
2021 return bus_log_create_error(r);
2023 r = sd_bus_call(bus, m, 0, &error, &reply);
2025 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2029 r = deserialize_and_dump_unit_file_changes(reply);
2033 /* Try to reload if enabled */
2035 r = daemon_reload(bus, args);
2040 unit_file_changes_free(changes, n_changes);
2047 const char *name, *type, *state;
2050 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2051 unsigned id_len, unit_len, type_len, state_len;
2052 const struct job_info *j;
2053 const char *on, *off;
2054 bool shorten = false;
2056 assert(n == 0 || jobs);
2059 on = ansi_highlight_green();
2060 off = ansi_highlight_off();
2062 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2066 pager_open_if_enabled();
2068 id_len = strlen("JOB");
2069 unit_len = strlen("UNIT");
2070 type_len = strlen("TYPE");
2071 state_len = strlen("STATE");
2073 for (j = jobs; j < jobs + n; j++) {
2074 uint32_t id = j->id;
2075 assert(j->name && j->type && j->state);
2077 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2078 unit_len = MAX(unit_len, strlen(j->name));
2079 type_len = MAX(type_len, strlen(j->type));
2080 state_len = MAX(state_len, strlen(j->state));
2083 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2084 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2089 printf("%*s %-*s %-*s %-*s\n",
2093 state_len, "STATE");
2095 for (j = jobs; j < jobs + n; j++) {
2096 _cleanup_free_ char *e = NULL;
2098 if (streq(j->state, "running")) {
2099 on = ansi_highlight();
2100 off = ansi_highlight_off();
2104 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2105 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2107 on, unit_len, e ? e : j->name, off,
2109 on, state_len, j->state, off);
2112 if (!arg_no_legend) {
2113 on = ansi_highlight();
2114 off = ansi_highlight_off();
2116 printf("\n%s%u jobs listed%s.\n", on, n, off);
2120 static bool output_show_job(struct job_info *job, char **patterns) {
2125 if (strv_isempty(patterns))
2128 STRV_FOREACH(pattern, patterns)
2129 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2134 static int list_jobs(sd_bus *bus, char **args) {
2135 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2136 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2137 const char *name, *type, *state, *job_path, *unit_path;
2138 _cleanup_free_ struct job_info *jobs = NULL;
2143 bool skipped = false;
2145 r = sd_bus_call_method(
2147 "org.freedesktop.systemd1",
2148 "/org/freedesktop/systemd1",
2149 "org.freedesktop.systemd1.Manager",
2155 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2159 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2161 return bus_log_parse_error(r);
2163 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2164 struct job_info job = { id, name, type, state };
2166 if (!output_show_job(&job, strv_skip_first(args))) {
2171 if (!GREEDY_REALLOC(jobs, size, c + 1))
2177 return bus_log_parse_error(r);
2179 r = sd_bus_message_exit_container(reply);
2181 return bus_log_parse_error(r);
2183 output_jobs_list(jobs, c, skipped);
2187 static int cancel_job(sd_bus *bus, char **args) {
2188 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2194 if (strv_length(args) <= 1)
2195 return daemon_reload(bus, args);
2197 STRV_FOREACH(name, args+1) {
2198 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2202 q = safe_atou32(*name, &id);
2204 log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2208 q = sd_bus_message_new_method_call(
2211 "org.freedesktop.systemd1",
2212 "/org/freedesktop/systemd1",
2213 "org.freedesktop.systemd1.Manager",
2216 return bus_log_create_error(q);
2218 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2220 return bus_log_create_error(1);
2222 q = sd_bus_message_append(m, "u", id);
2224 return bus_log_create_error(q);
2226 q = sd_bus_call(bus, m, 0, &error, NULL);
2228 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2237 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2238 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2242 /* We ignore all errors here, since this is used to show a
2245 /* We don't use unit_dbus_path_from_name() directly since we
2246 * don't want to load the unit if it isn't loaded. */
2248 r = sd_bus_call_method(
2250 "org.freedesktop.systemd1",
2251 "/org/freedesktop/systemd1",
2252 "org.freedesktop.systemd1.Manager",
2260 r = sd_bus_message_read(reply, "o", &path);
2264 r = sd_bus_get_property_trivial(
2266 "org.freedesktop.systemd1",
2268 "org.freedesktop.systemd1.Unit",
2278 typedef struct WaitData {
2285 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2292 log_debug("Got D-Bus request: %s.%s() on %s",
2293 sd_bus_message_get_interface(m),
2294 sd_bus_message_get_member(m),
2295 sd_bus_message_get_path(m));
2297 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2298 log_error("Warning! D-Bus connection terminated.");
2300 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2302 const char *path, *result, *unit;
2306 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2308 ret = set_remove(d->set, (char*) path);
2314 if (!isempty(result))
2315 d->result = strdup(result);
2318 d->name = strdup(unit);
2323 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2325 ret = set_remove(d->set, (char*) path);
2332 d->result = strdup(result);
2338 bus_log_parse_error(r);
2344 static int enable_wait_for_jobs(sd_bus *bus) {
2349 r = sd_bus_add_match(
2353 "sender='org.freedesktop.systemd1',"
2354 "interface='org.freedesktop.systemd1.Manager',"
2355 "member='JobRemoved',"
2356 "path='/org/freedesktop/systemd1'",
2359 log_error("Failed to add match");
2363 /* This is slightly dirty, since we don't undo the match registrations. */
2367 static int bus_process_wait(sd_bus *bus) {
2371 r = sd_bus_process(bus, NULL);
2376 r = sd_bus_wait(bus, (uint64_t) -1);
2382 static int check_wait_response(WaitData *d) {
2388 if (streq(d->result, "timeout"))
2389 log_error("Job for %s timed out.", strna(d->name));
2390 else if (streq(d->result, "canceled"))
2391 log_error("Job for %s canceled.", strna(d->name));
2392 else if (streq(d->result, "dependency"))
2393 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
2394 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
2398 quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
2400 log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
2402 quotes ? "'" : "", d->name, quotes ? "'" : "");
2404 log_error("Job failed. See \"journalctl -xe\" for details.");
2408 if (streq(d->result, "timeout"))
2410 else if (streq(d->result, "canceled"))
2412 else if (streq(d->result, "dependency"))
2414 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2420 static int wait_for_jobs(sd_bus *bus, Set *s) {
2421 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2422 WaitData d = { .set = s };
2428 q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2432 while (!set_isempty(s)) {
2433 q = bus_process_wait(bus);
2435 log_error_errno(q, "Failed to wait for response: %m");
2440 q = check_wait_response(&d);
2441 /* Return the first error as it is most likely to be
2443 if (q < 0 && r == 0)
2445 log_debug("Got result %s/%s for job %s",
2446 strna(d.result), strerror(-q), strna(d.name));
2459 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2460 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2461 _cleanup_free_ char *n = NULL, *state = NULL;
2467 n = unit_name_mangle(name, MANGLE_NOGLOB);
2471 /* We don't use unit_dbus_path_from_name() directly since we
2472 * don't want to load the unit if it isn't loaded. */
2474 r = sd_bus_call_method(
2476 "org.freedesktop.systemd1",
2477 "/org/freedesktop/systemd1",
2478 "org.freedesktop.systemd1.Manager",
2489 r = sd_bus_message_read(reply, "o", &path);
2491 return bus_log_parse_error(r);
2493 r = sd_bus_get_property_string(
2495 "org.freedesktop.systemd1",
2497 "org.freedesktop.systemd1.Unit",
2510 return nulstr_contains(good_states, state);
2513 static int check_triggering_units(
2517 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2518 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2519 _cleanup_strv_free_ char **triggered_by = NULL;
2520 bool print_warning_label = true;
2524 n = unit_name_mangle(name, MANGLE_NOGLOB);
2528 path = unit_dbus_path_from_name(n);
2532 r = sd_bus_get_property_string(
2534 "org.freedesktop.systemd1",
2536 "org.freedesktop.systemd1.Unit",
2541 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2545 if (streq(state, "masked"))
2548 r = sd_bus_get_property_strv(
2550 "org.freedesktop.systemd1",
2552 "org.freedesktop.systemd1.Unit",
2557 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2561 STRV_FOREACH(i, triggered_by) {
2562 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2564 log_error_errno(r, "Failed to check unit: %m");
2571 if (print_warning_label) {
2572 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2573 print_warning_label = false;
2576 log_warning(" %s", *i);
2582 static const struct {
2585 } unit_actions[] = {
2586 { "start", "StartUnit" },
2587 { "stop", "StopUnit" },
2588 { "condstop", "StopUnit" },
2589 { "reload", "ReloadUnit" },
2590 { "restart", "RestartUnit" },
2591 { "try-restart", "TryRestartUnit" },
2592 { "condrestart", "TryRestartUnit" },
2593 { "reload-or-restart", "ReloadOrRestartUnit" },
2594 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2595 { "condreload", "ReloadOrTryRestartUnit" },
2596 { "force-reload", "ReloadOrTryRestartUnit" }
2599 static const char *verb_to_method(const char *verb) {
2602 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2603 if (streq_ptr(unit_actions[i].verb, verb))
2604 return unit_actions[i].method;
2609 static const char *method_to_verb(const char *method) {
2612 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2613 if (streq_ptr(unit_actions[i].method, method))
2614 return unit_actions[i].verb;
2619 static int start_unit_one(
2624 sd_bus_error *error,
2627 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2636 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2638 r = sd_bus_message_new_method_call(
2641 "org.freedesktop.systemd1",
2642 "/org/freedesktop/systemd1",
2643 "org.freedesktop.systemd1.Manager",
2646 return bus_log_create_error(r);
2648 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2650 return bus_log_create_error(r);
2652 r = sd_bus_message_append(m, "ss", name, mode);
2654 return bus_log_create_error(r);
2656 r = sd_bus_call(bus, m, 0, error, &reply);
2660 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2661 /* There's always a fallback possible for
2662 * legacy actions. */
2663 return -EADDRNOTAVAIL;
2665 verb = method_to_verb(method);
2667 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2671 r = sd_bus_message_read(reply, "o", &path);
2673 return bus_log_parse_error(r);
2675 if (need_daemon_reload(bus, name) > 0)
2676 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2677 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2686 log_debug("Adding %s to the set", p);
2687 r = set_consume(s, p);
2695 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2697 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2701 STRV_FOREACH(name, names) {
2704 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2708 if (string_is_glob(t))
2709 r = strv_consume(&globs, t);
2711 r = strv_consume(&mangled, t);
2716 /* Query the manager only if any of the names are a glob, since
2717 * this is fairly expensive */
2718 if (!strv_isempty(globs)) {
2719 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2720 _cleanup_free_ UnitInfo *unit_infos = NULL;
2722 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2726 for (i = 0; i < r; i++)
2727 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2732 mangled = NULL; /* do not free */
2737 static const struct {
2741 } action_table[_ACTION_MAX] = {
2742 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2743 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2744 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2745 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2746 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2747 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2748 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2749 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2750 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2751 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2752 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2753 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2754 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2755 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2756 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2759 static enum action verb_to_action(const char *verb) {
2762 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2763 if (streq_ptr(action_table[i].verb, verb))
2766 return _ACTION_INVALID;
2769 static int start_unit(sd_bus *bus, char **args) {
2770 _cleanup_set_free_free_ Set *s = NULL;
2771 _cleanup_strv_free_ char **names = NULL;
2772 const char *method, *mode, *one_name, *suffix = NULL;
2778 ask_password_agent_open_if_enabled();
2780 if (arg_action == ACTION_SYSTEMCTL) {
2782 method = verb_to_method(args[0]);
2783 action = verb_to_action(args[0]);
2785 if (streq(args[0], "isolate")) {
2789 mode = action_table[action].mode ?: arg_job_mode;
2791 one_name = action_table[action].target;
2793 assert(arg_action < ELEMENTSOF(action_table));
2794 assert(action_table[arg_action].target);
2796 method = "StartUnit";
2798 mode = action_table[arg_action].mode;
2799 one_name = action_table[arg_action].target;
2803 names = strv_new(one_name, NULL);
2805 r = expand_names(bus, args + 1, suffix, &names);
2807 log_error_errno(r, "Failed to expand names: %m");
2810 if (!arg_no_block) {
2811 r = enable_wait_for_jobs(bus);
2813 log_error_errno(r, "Could not watch jobs: %m");
2817 s = set_new(&string_hash_ops);
2822 STRV_FOREACH(name, names) {
2823 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2826 q = start_unit_one(bus, method, *name, mode, &error, s);
2827 if (r >= 0 && q < 0)
2828 r = translate_bus_error_to_exit_status(q, &error);
2831 if (!arg_no_block) {
2834 q = wait_for_jobs(bus, s);
2838 /* When stopping units, warn if they can still be triggered by
2839 * another active unit (socket, path, timer) */
2840 if (!arg_quiet && streq(method, "StopUnit"))
2841 STRV_FOREACH(name, names)
2842 check_triggering_units(bus, *name);
2848 /* Ask systemd-logind, which might grant access to unprivileged users
2849 * through PolicyKit */
2850 static int reboot_with_logind(sd_bus *bus, enum action a) {
2852 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2859 polkit_agent_open_if_enabled();
2867 case ACTION_POWEROFF:
2868 method = "PowerOff";
2871 case ACTION_SUSPEND:
2875 case ACTION_HIBERNATE:
2876 method = "Hibernate";
2879 case ACTION_HYBRID_SLEEP:
2880 method = "HybridSleep";
2887 r = sd_bus_call_method(
2889 "org.freedesktop.login1",
2890 "/org/freedesktop/login1",
2891 "org.freedesktop.login1.Manager",
2895 "b", arg_ask_password);
2897 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2905 static int check_inhibitors(sd_bus *bus, enum action a) {
2907 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2908 _cleanup_strv_free_ char **sessions = NULL;
2909 const char *what, *who, *why, *mode;
2918 if (arg_ignore_inhibitors || arg_force > 0)
2930 r = sd_bus_call_method(
2932 "org.freedesktop.login1",
2933 "/org/freedesktop/login1",
2934 "org.freedesktop.login1.Manager",
2940 /* If logind is not around, then there are no inhibitors... */
2943 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2945 return bus_log_parse_error(r);
2947 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2948 _cleanup_free_ char *comm = NULL, *user = NULL;
2949 _cleanup_strv_free_ char **sv = NULL;
2951 if (!streq(mode, "block"))
2954 sv = strv_split(what, ":");
2958 if (!strv_contains(sv,
2960 a == ACTION_POWEROFF ||
2961 a == ACTION_REBOOT ||
2962 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2965 get_process_comm(pid, &comm);
2966 user = uid_to_name(uid);
2968 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2969 who, pid, strna(comm), strna(user), why);
2974 return bus_log_parse_error(r);
2976 r = sd_bus_message_exit_container(reply);
2978 return bus_log_parse_error(r);
2980 /* Check for current sessions */
2981 sd_get_sessions(&sessions);
2982 STRV_FOREACH(s, sessions) {
2983 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2985 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2988 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2991 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2994 sd_session_get_tty(*s, &tty);
2995 sd_session_get_seat(*s, &seat);
2996 sd_session_get_service(*s, &service);
2997 user = uid_to_name(uid);
2999 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
3006 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3007 action_table[a].verb);
3015 static int start_special(sd_bus *bus, char **args) {
3021 a = verb_to_action(args[0]);
3023 r = check_inhibitors(bus, a);
3027 if (arg_force >= 2 && geteuid() != 0) {
3028 log_error("Must be root.");
3032 if (arg_force >= 2 &&
3033 (a == ACTION_HALT ||
3034 a == ACTION_POWEROFF ||
3035 a == ACTION_REBOOT))
3038 if (arg_force >= 1 &&
3039 (a == ACTION_HALT ||
3040 a == ACTION_POWEROFF ||
3041 a == ACTION_REBOOT ||
3042 a == ACTION_KEXEC ||
3044 return daemon_reload(bus, args);
3046 /* first try logind, to allow authentication with polkit */
3047 if (geteuid() != 0 &&
3048 (a == ACTION_POWEROFF ||
3049 a == ACTION_REBOOT ||
3050 a == ACTION_SUSPEND ||
3051 a == ACTION_HIBERNATE ||
3052 a == ACTION_HYBRID_SLEEP)) {
3053 r = reboot_with_logind(bus, a);
3058 r = start_unit(bus, args);
3059 if (r == EXIT_SUCCESS)
3065 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3066 _cleanup_strv_free_ char **names = NULL;
3073 r = expand_names(bus, args, NULL, &names);
3075 log_error_errno(r, "Failed to expand names: %m");
3079 STRV_FOREACH(name, names) {
3082 state = check_one_unit(bus, *name, good_states, arg_quiet);
3092 static int check_unit_active(sd_bus *bus, char **args) {
3093 /* According to LSB: 3, "program is not running" */
3094 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3097 static int check_unit_failed(sd_bus *bus, char **args) {
3098 return check_unit_generic(bus, 1, "failed\0", args + 1);
3101 static int kill_unit(sd_bus *bus, char **args) {
3102 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3103 _cleanup_strv_free_ char **names = NULL;
3111 arg_kill_who = "all";
3113 r = expand_names(bus, args + 1, NULL, &names);
3115 log_error_errno(r, "Failed to expand names: %m");
3117 STRV_FOREACH(name, names) {
3118 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3120 q = sd_bus_message_new_method_call(
3123 "org.freedesktop.systemd1",
3124 "/org/freedesktop/systemd1",
3125 "org.freedesktop.systemd1.Manager",
3128 return bus_log_create_error(q);
3130 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3132 return bus_log_create_error(q);
3134 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3136 return bus_log_create_error(q);
3138 q = sd_bus_call(bus, m, 0, &error, NULL);
3140 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3149 typedef struct ExecStatusInfo {
3157 usec_t start_timestamp;
3158 usec_t exit_timestamp;
3163 LIST_FIELDS(struct ExecStatusInfo, exec);
3166 static void exec_status_info_free(ExecStatusInfo *i) {
3175 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3176 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3179 int32_t code, status;
3185 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3187 return bus_log_parse_error(r);
3191 r = sd_bus_message_read(m, "s", &path);
3193 return bus_log_parse_error(r);
3195 i->path = strdup(path);
3199 r = sd_bus_message_read_strv(m, &i->argv);
3201 return bus_log_parse_error(r);
3203 r = sd_bus_message_read(m,
3206 &start_timestamp, &start_timestamp_monotonic,
3207 &exit_timestamp, &exit_timestamp_monotonic,
3211 return bus_log_parse_error(r);
3214 i->start_timestamp = (usec_t) start_timestamp;
3215 i->exit_timestamp = (usec_t) exit_timestamp;
3216 i->pid = (pid_t) pid;
3220 r = sd_bus_message_exit_container(m);
3222 return bus_log_parse_error(r);
3227 typedef struct UnitStatusInfo {
3229 const char *load_state;
3230 const char *active_state;
3231 const char *sub_state;
3232 const char *unit_file_state;
3234 const char *description;
3235 const char *following;
3237 char **documentation;
3239 const char *fragment_path;
3240 const char *source_path;
3241 const char *control_group;
3243 char **dropin_paths;
3245 const char *load_error;
3248 usec_t inactive_exit_timestamp;
3249 usec_t inactive_exit_timestamp_monotonic;
3250 usec_t active_enter_timestamp;
3251 usec_t active_exit_timestamp;
3252 usec_t inactive_enter_timestamp;
3254 bool need_daemon_reload;
3259 const char *status_text;
3260 const char *pid_file;
3264 usec_t start_timestamp;
3265 usec_t exit_timestamp;
3267 int exit_code, exit_status;
3269 usec_t condition_timestamp;
3270 bool condition_result;
3271 bool failed_condition_trigger;
3272 bool failed_condition_negate;
3273 const char *failed_condition;
3274 const char *failed_condition_parameter;
3276 usec_t assert_timestamp;
3278 bool failed_assert_trigger;
3279 bool failed_assert_negate;
3280 const char *failed_assert;
3281 const char *failed_assert_parameter;
3284 unsigned n_accepted;
3285 unsigned n_connections;
3288 /* Pairs of type, path */
3292 const char *sysfs_path;
3294 /* Mount, Automount */
3300 LIST_HEAD(ExecStatusInfo, exec);
3303 static void print_status_info(
3308 const char *active_on, *active_off, *on, *off, *ss;
3310 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3311 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3314 arg_all * OUTPUT_SHOW_ALL |
3315 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3316 on_tty() * OUTPUT_COLOR |
3317 !arg_quiet * OUTPUT_WARN_CUTOFF |
3318 arg_full * OUTPUT_FULL_WIDTH;
3323 /* This shows pretty information about a unit. See
3324 * print_property() for a low-level property printer */
3326 if (streq_ptr(i->active_state, "failed")) {
3327 active_on = ansi_highlight_red();
3328 active_off = ansi_highlight_off();
3329 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3330 active_on = ansi_highlight_green();
3331 active_off = ansi_highlight_off();
3333 active_on = active_off = "";
3335 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3337 if (i->description && !streq_ptr(i->id, i->description))
3338 printf(" - %s", i->description);
3343 printf(" Follow: unit currently follows state of %s\n", i->following);
3345 if (streq_ptr(i->load_state, "error")) {
3346 on = ansi_highlight_red();
3347 off = ansi_highlight_off();
3351 path = i->source_path ? i->source_path : i->fragment_path;
3354 printf(" Loaded: %s%s%s (Reason: %s)\n",
3355 on, strna(i->load_state), off, i->load_error);
3356 else if (path && i->unit_file_state)
3357 printf(" Loaded: %s%s%s (%s; %s)\n",
3358 on, strna(i->load_state), off, path, i->unit_file_state);
3360 printf(" Loaded: %s%s%s (%s)\n",
3361 on, strna(i->load_state), off, path);
3363 printf(" Loaded: %s%s%s\n",
3364 on, strna(i->load_state), off);
3366 if (!strv_isempty(i->dropin_paths)) {
3367 _cleanup_free_ char *dir = NULL;
3371 STRV_FOREACH(dropin, i->dropin_paths) {
3372 if (! dir || last) {
3373 printf(dir ? " " : " Drop-In: ");
3378 if (path_get_parent(*dropin, &dir) < 0) {
3383 printf("%s\n %s", dir,
3384 draw_special_char(DRAW_TREE_RIGHT));
3387 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3389 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3393 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3395 printf(" Active: %s%s (%s)%s",
3396 active_on, strna(i->active_state), ss, active_off);
3398 printf(" Active: %s%s%s",
3399 active_on, strna(i->active_state), active_off);
3401 if (!isempty(i->result) && !streq(i->result, "success"))
3402 printf(" (Result: %s)", i->result);
3404 timestamp = (streq_ptr(i->active_state, "active") ||
3405 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3406 (streq_ptr(i->active_state, "inactive") ||
3407 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3408 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3409 i->active_exit_timestamp;
3411 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3412 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3415 printf(" since %s; %s\n", s2, s1);
3417 printf(" since %s\n", s2);
3421 if (!i->condition_result && i->condition_timestamp > 0) {
3422 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3423 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3425 printf("Condition: start %scondition failed%s at %s%s%s\n",
3426 ansi_highlight_yellow(), ansi_highlight_off(),
3427 s2, s1 ? "; " : "", s1 ? s1 : "");
3428 if (i->failed_condition_trigger)
3429 printf(" none of the trigger conditions were met\n");
3430 else if (i->failed_condition)
3431 printf(" %s=%s%s was not met\n",
3432 i->failed_condition,
3433 i->failed_condition_negate ? "!" : "",
3434 i->failed_condition_parameter);
3437 if (!i->assert_result && i->assert_timestamp > 0) {
3438 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3439 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3441 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3442 ansi_highlight_red(), ansi_highlight_off(),
3443 s2, s1 ? "; " : "", s1 ? s1 : "");
3444 if (i->failed_assert_trigger)
3445 printf(" none of the trigger assertions were met\n");
3446 else if (i->failed_assert)
3447 printf(" %s=%s%s was not met\n",
3449 i->failed_assert_negate ? "!" : "",
3450 i->failed_assert_parameter);
3454 printf(" Device: %s\n", i->sysfs_path);
3456 printf(" Where: %s\n", i->where);
3458 printf(" What: %s\n", i->what);
3460 STRV_FOREACH(t, i->documentation)
3461 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3463 STRV_FOREACH_PAIR(t, t2, i->listen)
3464 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3467 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3469 LIST_FOREACH(exec, p, i->exec) {
3470 _cleanup_free_ char *argv = NULL;
3473 /* Only show exited processes here */
3477 argv = strv_join(p->argv, " ");
3478 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3480 good = is_clean_exit_lsb(p->code, p->status, NULL);
3482 on = ansi_highlight_red();
3483 off = ansi_highlight_off();
3487 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3489 if (p->code == CLD_EXITED) {
3492 printf("status=%i", p->status);
3494 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3499 printf("signal=%s", signal_to_string(p->status));
3501 printf(")%s\n", off);
3503 if (i->main_pid == p->pid &&
3504 i->start_timestamp == p->start_timestamp &&
3505 i->exit_timestamp == p->start_timestamp)
3506 /* Let's not show this twice */
3509 if (p->pid == i->control_pid)
3513 if (i->main_pid > 0 || i->control_pid > 0) {
3514 if (i->main_pid > 0) {
3515 printf(" Main PID: "PID_FMT, i->main_pid);
3518 _cleanup_free_ char *comm = NULL;
3519 get_process_comm(i->main_pid, &comm);
3521 printf(" (%s)", comm);
3522 } else if (i->exit_code > 0) {
3523 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3525 if (i->exit_code == CLD_EXITED) {
3528 printf("status=%i", i->exit_status);
3530 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3535 printf("signal=%s", signal_to_string(i->exit_status));
3539 if (i->control_pid > 0)
3543 if (i->control_pid > 0) {
3544 _cleanup_free_ char *c = NULL;
3546 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3548 get_process_comm(i->control_pid, &c);
3557 printf(" Status: \"%s\"\n", i->status_text);
3558 if (i->status_errno > 0)
3559 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3561 if (i->control_group &&
3562 (i->main_pid > 0 || i->control_pid > 0 ||
3563 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3566 printf(" CGroup: %s\n", i->control_group);
3568 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3571 static const char prefix[] = " ";
3574 if (c > sizeof(prefix) - 1)
3575 c -= sizeof(prefix) - 1;
3579 if (i->main_pid > 0)
3580 extra[k++] = i->main_pid;
3582 if (i->control_pid > 0)
3583 extra[k++] = i->control_pid;
3585 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3589 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3590 show_journal_by_unit(stdout,
3594 i->inactive_exit_timestamp_monotonic,
3597 flags | OUTPUT_BEGIN_NEWLINE,
3598 arg_scope == UNIT_FILE_SYSTEM,
3602 if (i->need_daemon_reload)
3603 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3604 ansi_highlight_red(),
3605 ansi_highlight_off(),
3606 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3609 static void show_unit_help(UnitStatusInfo *i) {
3614 if (!i->documentation) {
3615 log_info("Documentation for %s not known.", i->id);
3619 STRV_FOREACH(p, i->documentation)
3620 if (startswith(*p, "man:"))
3621 show_man_page(*p + 4, false);
3623 log_info("Can't show: %s", *p);
3626 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3633 switch (contents[0]) {
3635 case SD_BUS_TYPE_STRING: {
3638 r = sd_bus_message_read(m, "s", &s);
3640 return bus_log_parse_error(r);
3643 if (streq(name, "Id"))
3645 else if (streq(name, "LoadState"))
3647 else if (streq(name, "ActiveState"))
3648 i->active_state = s;
3649 else if (streq(name, "SubState"))
3651 else if (streq(name, "Description"))
3653 else if (streq(name, "FragmentPath"))
3654 i->fragment_path = s;
3655 else if (streq(name, "SourcePath"))
3658 else if (streq(name, "DefaultControlGroup")) {
3660 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3662 i->control_group = e;
3665 else if (streq(name, "ControlGroup"))
3666 i->control_group = s;
3667 else if (streq(name, "StatusText"))
3669 else if (streq(name, "PIDFile"))
3671 else if (streq(name, "SysFSPath"))
3673 else if (streq(name, "Where"))
3675 else if (streq(name, "What"))
3677 else if (streq(name, "Following"))
3679 else if (streq(name, "UnitFileState"))
3680 i->unit_file_state = s;
3681 else if (streq(name, "Result"))
3688 case SD_BUS_TYPE_BOOLEAN: {
3691 r = sd_bus_message_read(m, "b", &b);
3693 return bus_log_parse_error(r);
3695 if (streq(name, "Accept"))
3697 else if (streq(name, "NeedDaemonReload"))
3698 i->need_daemon_reload = b;
3699 else if (streq(name, "ConditionResult"))
3700 i->condition_result = b;
3701 else if (streq(name, "AssertResult"))
3702 i->assert_result = b;
3707 case SD_BUS_TYPE_UINT32: {
3710 r = sd_bus_message_read(m, "u", &u);
3712 return bus_log_parse_error(r);
3714 if (streq(name, "MainPID")) {
3716 i->main_pid = (pid_t) u;
3719 } else if (streq(name, "ControlPID"))
3720 i->control_pid = (pid_t) u;
3721 else if (streq(name, "ExecMainPID")) {
3723 i->main_pid = (pid_t) u;
3724 } else if (streq(name, "NAccepted"))
3726 else if (streq(name, "NConnections"))
3727 i->n_connections = u;
3732 case SD_BUS_TYPE_INT32: {
3735 r = sd_bus_message_read(m, "i", &j);
3737 return bus_log_parse_error(r);
3739 if (streq(name, "ExecMainCode"))
3740 i->exit_code = (int) j;
3741 else if (streq(name, "ExecMainStatus"))
3742 i->exit_status = (int) j;
3743 else if (streq(name, "StatusErrno"))
3744 i->status_errno = (int) j;
3749 case SD_BUS_TYPE_UINT64: {
3752 r = sd_bus_message_read(m, "t", &u);
3754 return bus_log_parse_error(r);
3756 if (streq(name, "ExecMainStartTimestamp"))
3757 i->start_timestamp = (usec_t) u;
3758 else if (streq(name, "ExecMainExitTimestamp"))
3759 i->exit_timestamp = (usec_t) u;
3760 else if (streq(name, "ActiveEnterTimestamp"))
3761 i->active_enter_timestamp = (usec_t) u;
3762 else if (streq(name, "InactiveEnterTimestamp"))
3763 i->inactive_enter_timestamp = (usec_t) u;
3764 else if (streq(name, "InactiveExitTimestamp"))
3765 i->inactive_exit_timestamp = (usec_t) u;
3766 else if (streq(name, "InactiveExitTimestampMonotonic"))
3767 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3768 else if (streq(name, "ActiveExitTimestamp"))
3769 i->active_exit_timestamp = (usec_t) u;
3770 else if (streq(name, "ConditionTimestamp"))
3771 i->condition_timestamp = (usec_t) u;
3772 else if (streq(name, "AssertTimestamp"))
3773 i->assert_timestamp = (usec_t) u;
3778 case SD_BUS_TYPE_ARRAY:
3780 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3781 _cleanup_free_ ExecStatusInfo *info = NULL;
3783 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3785 return bus_log_parse_error(r);
3787 info = new0(ExecStatusInfo, 1);
3791 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3793 info->name = strdup(name);
3797 LIST_PREPEND(exec, i->exec, info);
3799 info = new0(ExecStatusInfo, 1);
3805 return bus_log_parse_error(r);
3807 r = sd_bus_message_exit_container(m);
3809 return bus_log_parse_error(r);
3813 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3814 const char *type, *path;
3816 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3818 return bus_log_parse_error(r);
3820 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3822 r = strv_extend(&i->listen, type);
3826 r = strv_extend(&i->listen, path);
3831 return bus_log_parse_error(r);
3833 r = sd_bus_message_exit_container(m);
3835 return bus_log_parse_error(r);
3839 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3841 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3843 return bus_log_parse_error(r);
3845 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3847 r = sd_bus_message_read_strv(m, &i->documentation);
3849 return bus_log_parse_error(r);
3851 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3852 const char *cond, *param;
3853 int trigger, negate;
3856 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3858 return bus_log_parse_error(r);
3860 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3861 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3862 if (state < 0 && (!trigger || !i->failed_condition)) {
3863 i->failed_condition = cond;
3864 i->failed_condition_trigger = trigger;
3865 i->failed_condition_negate = negate;
3866 i->failed_condition_parameter = param;
3870 return bus_log_parse_error(r);
3872 r = sd_bus_message_exit_container(m);
3874 return bus_log_parse_error(r);
3876 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3877 const char *cond, *param;
3878 int trigger, negate;
3881 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3883 return bus_log_parse_error(r);
3885 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3886 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3887 if (state < 0 && (!trigger || !i->failed_assert)) {
3888 i->failed_assert = cond;
3889 i->failed_assert_trigger = trigger;
3890 i->failed_assert_negate = negate;
3891 i->failed_assert_parameter = param;
3895 return bus_log_parse_error(r);
3897 r = sd_bus_message_exit_container(m);
3899 return bus_log_parse_error(r);
3906 case SD_BUS_TYPE_STRUCT_BEGIN:
3908 if (streq(name, "LoadError")) {
3909 const char *n, *message;
3911 r = sd_bus_message_read(m, "(ss)", &n, &message);
3913 return bus_log_parse_error(r);
3915 if (!isempty(message))
3916 i->load_error = message;
3929 r = sd_bus_message_skip(m, contents);
3931 return bus_log_parse_error(r);
3936 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3942 /* This is a low-level property printer, see
3943 * print_status_info() for the nicer output */
3945 if (arg_properties && !strv_find(arg_properties, name)) {
3946 /* skip what we didn't read */
3947 r = sd_bus_message_skip(m, contents);
3951 switch (contents[0]) {
3953 case SD_BUS_TYPE_STRUCT_BEGIN:
3955 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3958 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3960 return bus_log_parse_error(r);
3963 printf("%s=%"PRIu32"\n", name, u);
3965 printf("%s=\n", name);
3969 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3972 r = sd_bus_message_read(m, "(so)", &s, NULL);
3974 return bus_log_parse_error(r);
3976 if (arg_all || !isempty(s))
3977 printf("%s=%s\n", name, s);
3981 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3982 const char *a = NULL, *b = NULL;
3984 r = sd_bus_message_read(m, "(ss)", &a, &b);
3986 return bus_log_parse_error(r);
3988 if (arg_all || !isempty(a) || !isempty(b))
3989 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3992 } else if (streq_ptr(name, "SystemCallFilter")) {
3993 _cleanup_strv_free_ char **l = NULL;
3996 r = sd_bus_message_enter_container(m, 'r', "bas");
3998 return bus_log_parse_error(r);
4000 r = sd_bus_message_read(m, "b", &whitelist);
4002 return bus_log_parse_error(r);
4004 r = sd_bus_message_read_strv(m, &l);
4006 return bus_log_parse_error(r);
4008 r = sd_bus_message_exit_container(m);
4010 return bus_log_parse_error(r);
4012 if (arg_all || whitelist || !strv_isempty(l)) {
4016 fputs(name, stdout);
4022 STRV_FOREACH(i, l) {
4030 fputc('\n', stdout);
4038 case SD_BUS_TYPE_ARRAY:
4040 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4044 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4046 return bus_log_parse_error(r);
4048 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4049 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4052 return bus_log_parse_error(r);
4054 r = sd_bus_message_exit_container(m);
4056 return bus_log_parse_error(r);
4060 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4061 const char *type, *path;
4063 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4065 return bus_log_parse_error(r);
4067 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4068 printf("%s=%s\n", type, path);
4070 return bus_log_parse_error(r);
4072 r = sd_bus_message_exit_container(m);
4074 return bus_log_parse_error(r);
4078 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4079 const char *type, *path;
4081 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4083 return bus_log_parse_error(r);
4085 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4086 printf("Listen%s=%s\n", type, path);
4088 return bus_log_parse_error(r);
4090 r = sd_bus_message_exit_container(m);
4092 return bus_log_parse_error(r);
4096 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4098 uint64_t value, next_elapse;
4100 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4102 return bus_log_parse_error(r);
4104 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4105 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4107 printf("%s={ value=%s ; next_elapse=%s }\n",
4109 format_timespan(timespan1, sizeof(timespan1), value, 0),
4110 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4113 return bus_log_parse_error(r);
4115 r = sd_bus_message_exit_container(m);
4117 return bus_log_parse_error(r);
4121 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4122 ExecStatusInfo info = {};
4124 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4126 return bus_log_parse_error(r);
4128 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4129 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4130 _cleanup_free_ char *tt;
4132 tt = strv_join(info.argv, " ");
4134 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4138 yes_no(info.ignore),
4139 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4140 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4142 sigchld_code_to_string(info.code),
4144 info.code == CLD_EXITED ? "" : "/",
4145 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4148 strv_free(info.argv);
4152 r = sd_bus_message_exit_container(m);
4154 return bus_log_parse_error(r);
4158 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4159 const char *path, *rwm;
4161 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4163 return bus_log_parse_error(r);
4165 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4166 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4168 return bus_log_parse_error(r);
4170 r = sd_bus_message_exit_container(m);
4172 return bus_log_parse_error(r);
4176 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4180 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4182 return bus_log_parse_error(r);
4184 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4185 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4187 return bus_log_parse_error(r);
4189 r = sd_bus_message_exit_container(m);
4191 return bus_log_parse_error(r);
4195 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4199 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4201 return bus_log_parse_error(r);
4203 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4204 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4206 return bus_log_parse_error(r);
4208 r = sd_bus_message_exit_container(m);
4210 return bus_log_parse_error(r);
4218 r = bus_print_property(name, m, arg_all);
4220 return bus_log_parse_error(r);
4223 r = sd_bus_message_skip(m, contents);
4225 return bus_log_parse_error(r);
4228 printf("%s=[unprintable]\n", name);
4234 static int show_one(
4238 bool show_properties,
4242 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4243 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4244 UnitStatusInfo info = {};
4251 log_debug("Showing one %s", path);
4253 r = sd_bus_call_method(
4255 "org.freedesktop.systemd1",
4257 "org.freedesktop.DBus.Properties",
4263 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4267 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4269 return bus_log_parse_error(r);
4276 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4277 const char *name, *contents;
4279 r = sd_bus_message_read(reply, "s", &name);
4281 return bus_log_parse_error(r);
4283 r = sd_bus_message_peek_type(reply, NULL, &contents);
4285 return bus_log_parse_error(r);
4287 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4289 return bus_log_parse_error(r);
4291 if (show_properties)
4292 r = print_property(name, reply, contents);
4294 r = status_property(name, reply, &info, contents);
4298 r = sd_bus_message_exit_container(reply);
4300 return bus_log_parse_error(r);
4302 r = sd_bus_message_exit_container(reply);
4304 return bus_log_parse_error(r);
4307 return bus_log_parse_error(r);
4309 r = sd_bus_message_exit_container(reply);
4311 return bus_log_parse_error(r);
4315 if (!show_properties) {
4316 if (streq(verb, "help"))
4317 show_unit_help(&info);
4319 print_status_info(&info, ellipsized);
4322 strv_free(info.documentation);
4323 strv_free(info.dropin_paths);
4324 strv_free(info.listen);
4326 if (!streq_ptr(info.active_state, "active") &&
4327 !streq_ptr(info.active_state, "reloading") &&
4328 streq(verb, "status")) {
4329 /* According to LSB: "program not running" */
4330 /* 0: program is running or service is OK
4331 * 1: program is dead and /run PID file exists
4332 * 2: program is dead and /run/lock lock file exists
4333 * 3: program is not running
4334 * 4: program or service status is unknown
4336 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4342 while ((p = info.exec)) {
4343 LIST_REMOVE(exec, info.exec, p);
4344 exec_status_info_free(p);
4350 static int get_unit_dbus_path_by_pid(
4355 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4356 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4360 r = sd_bus_call_method(
4362 "org.freedesktop.systemd1",
4363 "/org/freedesktop/systemd1",
4364 "org.freedesktop.systemd1.Manager",
4370 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4374 r = sd_bus_message_read(reply, "o", &u);
4376 return bus_log_parse_error(r);
4386 static int show_all(
4389 bool show_properties,
4393 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4394 _cleanup_free_ UnitInfo *unit_infos = NULL;
4399 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4403 pager_open_if_enabled();
4407 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4409 for (u = unit_infos; u < unit_infos + c; u++) {
4410 _cleanup_free_ char *p = NULL;
4412 p = unit_dbus_path_from_name(u->id);
4416 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4419 else if (r > 0 && ret == 0)
4426 static int show_system_status(sd_bus *bus) {
4427 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4428 _cleanup_free_ char *hn = NULL;
4429 struct machine_info mi = {};
4430 const char *on, *off;
4433 hn = gethostname_malloc();
4437 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4439 log_error_errno(r, "Failed to read server status: %m");
4443 if (streq_ptr(mi.state, "degraded")) {
4444 on = ansi_highlight_red();
4445 off = ansi_highlight_off();
4446 } else if (!streq_ptr(mi.state, "running")) {
4447 on = ansi_highlight_yellow();
4448 off = ansi_highlight_off();
4452 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4454 printf(" State: %s%s%s\n",
4455 on, strna(mi.state), off);
4457 printf(" Jobs: %u queued\n", mi.n_jobs);
4458 printf(" Failed: %u units\n", mi.n_failed_units);
4460 printf(" Since: %s; %s\n",
4461 format_timestamp(since2, sizeof(since2), mi.timestamp),
4462 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4464 printf(" CGroup: %s\n", mi.control_group ?: "/");
4465 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4467 arg_all * OUTPUT_SHOW_ALL |
4468 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4469 on_tty() * OUTPUT_COLOR |
4470 !arg_quiet * OUTPUT_WARN_CUTOFF |
4471 arg_full * OUTPUT_FULL_WIDTH;
4473 static const char prefix[] = " ";
4477 if (c > sizeof(prefix) - 1)
4478 c -= sizeof(prefix) - 1;
4482 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4486 free(mi.control_group);
4491 static int show(sd_bus *bus, char **args) {
4492 bool show_properties, show_status, new_line = false;
4493 bool ellipsized = false;
4499 show_properties = streq(args[0], "show");
4500 show_status = streq(args[0], "status");
4502 if (show_properties)
4503 pager_open_if_enabled();
4505 /* If no argument is specified inspect the manager itself */
4507 if (show_properties && strv_length(args) <= 1)
4508 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4510 if (show_status && strv_length(args) <= 1) {
4512 pager_open_if_enabled();
4513 show_system_status(bus);
4517 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4519 _cleanup_free_ char **patterns = NULL;
4522 STRV_FOREACH(name, args + 1) {
4523 _cleanup_free_ char *unit = NULL;
4526 if (safe_atou32(*name, &id) < 0) {
4527 if (strv_push(&patterns, *name) < 0)
4531 } else if (show_properties) {
4532 /* Interpret as job id */
4533 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4537 /* Interpret as PID */
4538 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4545 r = show_one(args[0], bus, unit, show_properties,
4546 &new_line, &ellipsized);
4549 else if (r > 0 && ret == 0)
4553 if (!strv_isempty(patterns)) {
4554 _cleanup_strv_free_ char **names = NULL;
4556 r = expand_names(bus, patterns, NULL, &names);
4558 log_error_errno(r, "Failed to expand names: %m");
4560 STRV_FOREACH(name, names) {
4561 _cleanup_free_ char *unit;
4563 unit = unit_dbus_path_from_name(*name);
4567 r = show_one(args[0], bus, unit, show_properties,
4568 &new_line, &ellipsized);
4571 else if (r > 0 && ret == 0)
4577 if (ellipsized && !arg_quiet)
4578 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4583 static int cat(sd_bus *bus, char **args) {
4584 _cleanup_strv_free_ char **names = NULL;
4592 r = expand_names(bus, args + 1, NULL, &names);
4594 log_error_errno(r, "Failed to expand names: %m");
4596 pager_open_if_enabled();
4598 STRV_FOREACH(name, names) {
4599 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4600 _cleanup_strv_free_ char **dropin_paths = NULL;
4601 _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
4604 unit = unit_dbus_path_from_name(*name);
4608 if (need_daemon_reload(bus, *name) > 0)
4609 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4610 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4612 r = sd_bus_get_property_string(
4614 "org.freedesktop.systemd1",
4616 "org.freedesktop.systemd1.Unit",
4621 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4625 r = sd_bus_get_property_strv(
4627 "org.freedesktop.systemd1",
4629 "org.freedesktop.systemd1.Unit",
4634 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4643 if (!isempty(fragment_path)) {
4644 printf("%s# %s%s\n",
4645 ansi_highlight_blue(),
4647 ansi_highlight_off());
4650 r = copy_file_fd(fragment_path, STDOUT_FILENO);
4652 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4657 STRV_FOREACH(path, dropin_paths) {
4658 printf("%s%s# %s%s\n",
4659 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4660 ansi_highlight_blue(),
4662 ansi_highlight_off());
4665 r = copy_file_fd(*path, STDOUT_FILENO);
4667 log_warning_errno(r, "Failed to cat %s: %m", *path);
4673 return r < 0 ? r : 0;
4676 static int set_property(sd_bus *bus, char **args) {
4677 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4678 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4679 _cleanup_free_ char *n = NULL;
4683 r = sd_bus_message_new_method_call(
4686 "org.freedesktop.systemd1",
4687 "/org/freedesktop/systemd1",
4688 "org.freedesktop.systemd1.Manager",
4689 "SetUnitProperties");
4691 return bus_log_create_error(r);
4693 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4695 return bus_log_create_error(r);
4697 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4701 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4703 return bus_log_create_error(r);
4705 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4707 return bus_log_create_error(r);
4709 STRV_FOREACH(i, args + 2) {
4710 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4712 return bus_log_create_error(r);
4714 r = bus_append_unit_property_assignment(m, *i);
4718 r = sd_bus_message_close_container(m);
4720 return bus_log_create_error(r);
4723 r = sd_bus_message_close_container(m);
4725 return bus_log_create_error(r);
4727 r = sd_bus_call(bus, m, 0, &error, NULL);
4729 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4736 static int snapshot(sd_bus *bus, char **args) {
4737 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4738 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4739 _cleanup_free_ char *n = NULL, *id = NULL;
4743 if (strv_length(args) > 1)
4744 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4750 r = sd_bus_message_new_method_call(
4753 "org.freedesktop.systemd1",
4754 "/org/freedesktop/systemd1",
4755 "org.freedesktop.systemd1.Manager",
4758 return bus_log_create_error(r);
4760 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4762 return bus_log_create_error(r);
4764 r = sd_bus_message_append(m, "sb", n, false);
4766 return bus_log_create_error(r);
4768 r = sd_bus_call(bus, m, 0, &error, &reply);
4770 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4774 r = sd_bus_message_read(reply, "o", &path);
4776 return bus_log_parse_error(r);
4778 r = sd_bus_get_property_string(
4780 "org.freedesktop.systemd1",
4782 "org.freedesktop.systemd1.Unit",
4787 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4797 static int delete_snapshot(sd_bus *bus, char **args) {
4798 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4799 _cleanup_strv_free_ char **names = NULL;
4805 r = expand_names(bus, args + 1, ".snapshot", &names);
4807 log_error_errno(r, "Failed to expand names: %m");
4809 STRV_FOREACH(name, names) {
4810 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4813 q = sd_bus_message_new_method_call(
4816 "org.freedesktop.systemd1",
4817 "/org/freedesktop/systemd1",
4818 "org.freedesktop.systemd1.Manager",
4821 return bus_log_create_error(q);
4823 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4825 return bus_log_create_error(q);
4827 q = sd_bus_message_append(m, "s", *name);
4829 return bus_log_create_error(q);
4831 q = sd_bus_call(bus, m, 0, &error, NULL);
4833 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4842 static int daemon_reload(sd_bus *bus, char **args) {
4843 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4844 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4848 if (arg_action == ACTION_RELOAD)
4850 else if (arg_action == ACTION_REEXEC)
4851 method = "Reexecute";
4853 assert(arg_action == ACTION_SYSTEMCTL);
4856 streq(args[0], "clear-jobs") ||
4857 streq(args[0], "cancel") ? "ClearJobs" :
4858 streq(args[0], "daemon-reexec") ? "Reexecute" :
4859 streq(args[0], "reset-failed") ? "ResetFailed" :
4860 streq(args[0], "halt") ? "Halt" :
4861 streq(args[0], "poweroff") ? "PowerOff" :
4862 streq(args[0], "reboot") ? "Reboot" :
4863 streq(args[0], "kexec") ? "KExec" :
4864 streq(args[0], "exit") ? "Exit" :
4865 /* "daemon-reload" */ "Reload";
4868 r = sd_bus_message_new_method_call(
4871 "org.freedesktop.systemd1",
4872 "/org/freedesktop/systemd1",
4873 "org.freedesktop.systemd1.Manager",
4876 return bus_log_create_error(r);
4878 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4880 return bus_log_create_error(r);
4882 r = sd_bus_call(bus, m, 0, &error, NULL);
4883 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4884 /* There's always a fallback possible for
4885 * legacy actions. */
4887 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4888 /* On reexecution, we expect a disconnect, not a
4892 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4894 return r < 0 ? r : 0;
4897 static int reset_failed(sd_bus *bus, char **args) {
4898 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4899 _cleanup_strv_free_ char **names = NULL;
4903 if (strv_length(args) <= 1)
4904 return daemon_reload(bus, args);
4906 r = expand_names(bus, args + 1, NULL, &names);
4908 log_error_errno(r, "Failed to expand names: %m");
4910 STRV_FOREACH(name, names) {
4911 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4913 q = sd_bus_message_new_method_call(
4916 "org.freedesktop.systemd1",
4917 "/org/freedesktop/systemd1",
4918 "org.freedesktop.systemd1.Manager",
4921 return bus_log_create_error(q);
4923 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4925 return bus_log_create_error(q);
4927 q = sd_bus_message_append(m, "s", *name);
4929 return bus_log_create_error(q);
4931 q = sd_bus_call(bus, m, 0, &error, NULL);
4933 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4942 static int show_environment(sd_bus *bus, char **args) {
4943 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4944 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4948 pager_open_if_enabled();
4950 r = sd_bus_get_property(
4952 "org.freedesktop.systemd1",
4953 "/org/freedesktop/systemd1",
4954 "org.freedesktop.systemd1.Manager",
4960 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4964 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4966 return bus_log_parse_error(r);
4968 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4971 return bus_log_parse_error(r);
4973 r = sd_bus_message_exit_container(reply);
4975 return bus_log_parse_error(r);
4980 static int switch_root(sd_bus *bus, char **args) {
4981 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4982 _cleanup_free_ char *cmdline_init = NULL;
4983 const char *root, *init;
4987 l = strv_length(args);
4988 if (l < 2 || l > 3) {
4989 log_error("Wrong number of arguments.");
4998 r = parse_env_file("/proc/cmdline", WHITESPACE,
4999 "init", &cmdline_init,
5002 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5004 init = cmdline_init;
5011 const char *root_systemd_path = NULL, *root_init_path = NULL;
5013 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
5014 root_init_path = strappenda(root, "/", init);
5016 /* If the passed init is actually the same as the
5017 * systemd binary, then let's suppress it. */
5018 if (files_same(root_init_path, root_systemd_path) > 0)
5022 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5024 r = sd_bus_call_method(
5026 "org.freedesktop.systemd1",
5027 "/org/freedesktop/systemd1",
5028 "org.freedesktop.systemd1.Manager",
5034 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5041 static int set_environment(sd_bus *bus, char **args) {
5042 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5043 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5050 method = streq(args[0], "set-environment")
5052 : "UnsetEnvironment";
5054 r = sd_bus_message_new_method_call(
5057 "org.freedesktop.systemd1",
5058 "/org/freedesktop/systemd1",
5059 "org.freedesktop.systemd1.Manager",
5062 return bus_log_create_error(r);
5064 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5066 return bus_log_create_error(r);
5068 r = sd_bus_message_append_strv(m, args + 1);
5070 return bus_log_create_error(r);
5072 r = sd_bus_call(bus, m, 0, &error, NULL);
5074 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5081 static int import_environment(sd_bus *bus, char **args) {
5082 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5083 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5089 r = sd_bus_message_new_method_call(
5092 "org.freedesktop.systemd1",
5093 "/org/freedesktop/systemd1",
5094 "org.freedesktop.systemd1.Manager",
5097 return bus_log_create_error(r);
5099 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5101 return bus_log_create_error(r);
5103 if (strv_isempty(args + 1))
5104 r = sd_bus_message_append_strv(m, environ);
5108 r = sd_bus_message_open_container(m, 'a', "s");
5110 return bus_log_create_error(r);
5112 STRV_FOREACH(a, args + 1) {
5114 if (!env_name_is_valid(*a)) {
5115 log_error("Not a valid environment variable name: %s", *a);
5119 STRV_FOREACH(b, environ) {
5122 eq = startswith(*b, *a);
5123 if (eq && *eq == '=') {
5125 r = sd_bus_message_append(m, "s", *b);
5127 return bus_log_create_error(r);
5134 r = sd_bus_message_close_container(m);
5137 return bus_log_create_error(r);
5139 r = sd_bus_call(bus, m, 0, &error, NULL);
5141 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5148 static int enable_sysv_units(const char *verb, char **args) {
5151 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5152 unsigned f = 1, t = 1;
5153 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5155 if (arg_scope != UNIT_FILE_SYSTEM)
5158 if (!streq(verb, "enable") &&
5159 !streq(verb, "disable") &&
5160 !streq(verb, "is-enabled"))
5163 /* Processes all SysV units, and reshuffles the array so that
5164 * afterwards only the native units remain */
5166 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5171 for (f = 0; args[f]; f++) {
5173 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5174 bool found_native = false, found_sysv;
5176 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5184 if (!endswith(name, ".service"))
5187 if (path_is_absolute(name))
5190 STRV_FOREACH(k, paths.unit_path) {
5191 _cleanup_free_ char *path = NULL;
5193 path = path_join(arg_root, *k, name);
5197 found_native = access(path, F_OK) >= 0;
5205 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5209 p[strlen(p) - strlen(".service")] = 0;
5210 found_sysv = access(p, F_OK) >= 0;
5214 /* Mark this entry, so that we don't try enabling it as native unit */
5215 args[f] = (char*) "";
5217 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5219 if (!isempty(arg_root))
5220 argv[c++] = q = strappend("--root=", arg_root);
5222 argv[c++] = basename(p);
5224 streq(verb, "enable") ? "on" :
5225 streq(verb, "disable") ? "off" : "--level=5";
5228 l = strv_join((char**)argv, " ");
5232 log_info("Executing %s", l);
5236 log_error("Failed to fork: %m");
5238 } else if (pid == 0) {
5241 execv(argv[0], (char**) argv);
5242 _exit(EXIT_FAILURE);
5245 j = wait_for_terminate(pid, &status);
5247 log_error_errno(r, "Failed to wait for child: %m");
5251 if (status.si_code == CLD_EXITED) {
5252 if (streq(verb, "is-enabled")) {
5253 if (status.si_status == 0) {
5262 } else if (status.si_status != 0)
5268 /* Drop all SysV units */
5269 for (f = 0, t = 0; args[f]; f++) {
5271 if (isempty(args[f]))
5274 args[t++] = args[f];
5283 static int mangle_names(char **original_names, char ***mangled_names) {
5284 char **i, **l, **name;
5286 l = new(char*, strv_length(original_names) + 1);
5291 STRV_FOREACH(name, original_names) {
5293 /* When enabling units qualified path names are OK,
5294 * too, hence allow them explicitly. */
5299 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5315 static int enable_unit(sd_bus *bus, char **args) {
5316 _cleanup_strv_free_ char **names = NULL;
5317 const char *verb = args[0];
5318 UnitFileChange *changes = NULL;
5319 unsigned n_changes = 0;
5320 int carries_install_info = -1;
5326 r = mangle_names(args+1, &names);
5330 r = enable_sysv_units(verb, names);
5334 /* If the operation was fully executed by the SysV compat,
5335 * let's finish early */
5336 if (strv_isempty(names))
5339 if (!bus || avoid_bus()) {
5340 if (streq(verb, "enable")) {
5341 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5342 carries_install_info = r;
5343 } else if (streq(verb, "disable"))
5344 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5345 else if (streq(verb, "reenable")) {
5346 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5347 carries_install_info = r;
5348 } else if (streq(verb, "link"))
5349 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5350 else if (streq(verb, "preset")) {
5351 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5352 carries_install_info = r;
5353 } else if (streq(verb, "mask"))
5354 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5355 else if (streq(verb, "unmask"))
5356 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5358 assert_not_reached("Unknown verb");
5361 log_error_errno(r, "Operation failed: %m");
5366 dump_unit_file_changes(changes, n_changes);
5370 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5371 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5372 int expect_carries_install_info = false;
5373 bool send_force = true, send_preset_mode = false;
5376 if (streq(verb, "enable")) {
5377 method = "EnableUnitFiles";
5378 expect_carries_install_info = true;
5379 } else if (streq(verb, "disable")) {
5380 method = "DisableUnitFiles";
5382 } else if (streq(verb, "reenable")) {
5383 method = "ReenableUnitFiles";
5384 expect_carries_install_info = true;
5385 } else if (streq(verb, "link"))
5386 method = "LinkUnitFiles";
5387 else if (streq(verb, "preset")) {
5389 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5390 method = "PresetUnitFilesWithMode";
5391 send_preset_mode = true;
5393 method = "PresetUnitFiles";
5395 expect_carries_install_info = true;
5396 } else if (streq(verb, "mask"))
5397 method = "MaskUnitFiles";
5398 else if (streq(verb, "unmask")) {
5399 method = "UnmaskUnitFiles";
5402 assert_not_reached("Unknown verb");
5404 r = sd_bus_message_new_method_call(
5407 "org.freedesktop.systemd1",
5408 "/org/freedesktop/systemd1",
5409 "org.freedesktop.systemd1.Manager",
5412 return bus_log_create_error(r);
5414 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5416 return bus_log_create_error(r);
5418 r = sd_bus_message_append_strv(m, names);
5420 return bus_log_create_error(r);
5422 if (send_preset_mode) {
5423 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5425 return bus_log_create_error(r);
5428 r = sd_bus_message_append(m, "b", arg_runtime);
5430 return bus_log_create_error(r);
5433 r = sd_bus_message_append(m, "b", arg_force);
5435 return bus_log_create_error(r);
5438 r = sd_bus_call(bus, m, 0, &error, &reply);
5440 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5444 if (expect_carries_install_info) {
5445 r = sd_bus_message_read(reply, "b", &carries_install_info);
5447 return bus_log_parse_error(r);
5450 r = deserialize_and_dump_unit_file_changes(reply);
5454 /* Try to reload if enabled */
5456 r = daemon_reload(bus, args);
5461 if (carries_install_info == 0)
5462 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5463 "using systemctl.\n"
5464 "Possible reasons for having this kind of units are:\n"
5465 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5466 " .wants/ or .requires/ directory.\n"
5467 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5468 " a requirement dependency on it.\n"
5469 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5470 " D-Bus, udev, scripted systemctl call, ...).\n");
5473 unit_file_changes_free(changes, n_changes);
5478 static int add_dependency(sd_bus *bus, char **args) {
5479 _cleanup_strv_free_ char **names = NULL;
5480 _cleanup_free_ char *target = NULL;
5481 const char *verb = args[0];
5488 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5492 r = mangle_names(args+2, &names);
5496 if (streq(verb, "add-wants"))
5498 else if (streq(verb, "add-requires"))
5499 dep = UNIT_REQUIRES;
5501 assert_not_reached("Unknown verb");
5503 if (!bus || avoid_bus()) {
5504 UnitFileChange *changes = NULL;
5505 unsigned n_changes = 0;
5507 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5510 log_error_errno(r, "Can't add dependency: %m");
5515 dump_unit_file_changes(changes, n_changes);
5517 unit_file_changes_free(changes, n_changes);
5520 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5521 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5523 r = sd_bus_message_new_method_call(
5526 "org.freedesktop.systemd1",
5527 "/org/freedesktop/systemd1",
5528 "org.freedesktop.systemd1.Manager",
5529 "AddDependencyUnitFiles");
5531 return bus_log_create_error(r);
5533 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5535 return bus_log_create_error(r);
5537 r = sd_bus_message_append_strv(m, names);
5539 return bus_log_create_error(r);
5541 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5543 return bus_log_create_error(r);
5545 r = sd_bus_call(bus, m, 0, &error, &reply);
5547 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5551 r = deserialize_and_dump_unit_file_changes(reply);
5556 r = daemon_reload(bus, args);
5564 static int preset_all(sd_bus *bus, char **args) {
5565 UnitFileChange *changes = NULL;
5566 unsigned n_changes = 0;
5569 if (!bus || avoid_bus()) {
5571 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5573 log_error_errno(r, "Operation failed: %m");
5578 dump_unit_file_changes(changes, n_changes);
5583 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5584 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5586 r = sd_bus_message_new_method_call(
5589 "org.freedesktop.systemd1",
5590 "/org/freedesktop/systemd1",
5591 "org.freedesktop.systemd1.Manager",
5592 "PresetAllUnitFiles");
5594 return bus_log_create_error(r);
5596 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5598 return bus_log_create_error(r);
5600 r = sd_bus_message_append(
5603 unit_file_preset_mode_to_string(arg_preset_mode),
5607 return bus_log_create_error(r);
5609 r = sd_bus_call(bus, m, 0, &error, &reply);
5611 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5615 r = deserialize_and_dump_unit_file_changes(reply);
5620 r = daemon_reload(bus, args);
5626 unit_file_changes_free(changes, n_changes);
5631 static int unit_is_enabled(sd_bus *bus, char **args) {
5633 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5634 _cleanup_strv_free_ char **names = NULL;
5639 r = mangle_names(args+1, &names);
5643 r = enable_sysv_units(args[0], names);
5649 if (!bus || avoid_bus()) {
5651 STRV_FOREACH(name, names) {
5652 UnitFileState state;
5654 state = unit_file_get_state(arg_scope, arg_root, *name);
5656 log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5660 if (state == UNIT_FILE_ENABLED ||
5661 state == UNIT_FILE_ENABLED_RUNTIME ||
5662 state == UNIT_FILE_STATIC ||
5663 state == UNIT_FILE_INDIRECT)
5667 puts(unit_file_state_to_string(state));
5671 STRV_FOREACH(name, names) {
5672 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5675 r = sd_bus_call_method(
5677 "org.freedesktop.systemd1",
5678 "/org/freedesktop/systemd1",
5679 "org.freedesktop.systemd1.Manager",
5685 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5689 r = sd_bus_message_read(reply, "s", &s);
5691 return bus_log_parse_error(r);
5693 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5704 static int is_system_running(sd_bus *bus, char **args) {
5705 _cleanup_free_ char *state = NULL;
5708 r = sd_bus_get_property_string(
5710 "org.freedesktop.systemd1",
5711 "/org/freedesktop/systemd1",
5712 "org.freedesktop.systemd1.Manager",
5725 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5728 static void systemctl_help(void) {
5730 pager_open_if_enabled();
5732 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5733 "Query or send control commands to the systemd manager.\n\n"
5734 " -h --help Show this help\n"
5735 " --version Show package version\n"
5736 " --system Connect to system manager\n"
5737 " --user Connect to user service manager\n"
5738 " -H --host=[USER@]HOST\n"
5739 " Operate on remote host\n"
5740 " -M --machine=CONTAINER\n"
5741 " Operate on local container\n"
5742 " -t --type=TYPE List only units of a particular type\n"
5743 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5744 " -p --property=NAME Show only properties by this name\n"
5745 " -a --all Show all loaded units/properties, including dead/empty\n"
5746 " ones. To list all units installed on the system, use\n"
5747 " the 'list-unit-files' command instead.\n"
5748 " -l --full Don't ellipsize unit names on output\n"
5749 " -r --recursive Show unit list of host and local containers\n"
5750 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5751 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5752 " queueing a new job\n"
5753 " --show-types When showing sockets, explicitly show their type\n"
5754 " -i --ignore-inhibitors\n"
5755 " When shutting down or sleeping, ignore inhibitors\n"
5756 " --kill-who=WHO Who to send signal to\n"
5757 " -s --signal=SIGNAL Which signal to send\n"
5758 " -q --quiet Suppress output\n"
5759 " --no-block Do not wait until operation finished\n"
5760 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5761 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5763 " --no-legend Do not print a legend (column headers and hints)\n"
5764 " --no-pager Do not pipe output into a pager\n"
5765 " --no-ask-password\n"
5766 " Do not ask for system passwords\n"
5767 " --global Enable/disable unit files globally\n"
5768 " --runtime Enable unit files only temporarily until next reboot\n"
5769 " -f --force When enabling unit files, override existing symlinks\n"
5770 " When shutting down, execute action immediately\n"
5771 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
5772 " or only disable\n"
5773 " --root=PATH Enable unit files in the specified root directory\n"
5774 " -n --lines=INTEGER Number of journal entries to show\n"
5775 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5776 " verbose, export, json, json-pretty, json-sse, cat)\n"
5777 " --plain Print unit dependencies as a list instead of a tree\n\n"
5779 " list-units [PATTERN...] List loaded units\n"
5780 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5781 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5782 " start NAME... Start (activate) one or more units\n"
5783 " stop NAME... Stop (deactivate) one or more units\n"
5784 " reload NAME... Reload one or more units\n"
5785 " restart NAME... Start or restart one or more units\n"
5786 " try-restart NAME... Restart one or more units if active\n"
5787 " reload-or-restart NAME... Reload one or more units if possible,\n"
5788 " otherwise start or restart\n"
5789 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5790 " otherwise restart if active\n"
5791 " isolate NAME Start one unit and stop all others\n"
5792 " kill NAME... Send signal to processes of a unit\n"
5793 " is-active PATTERN... Check whether units are active\n"
5794 " is-failed PATTERN... Check whether units are failed\n"
5795 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5796 " show [PATTERN...|JOB...] Show properties of one or more\n"
5797 " units/jobs or the manager\n"
5798 " cat PATTERN... Show files and drop-ins of one or more units\n"
5799 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5800 " help PATTERN...|PID... Show manual for one or more units\n"
5801 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5803 " list-dependencies [NAME] Recursively show units which are required\n"
5804 " or wanted by this unit or by which this\n"
5805 " unit is required or wanted\n\n"
5806 "Unit File Commands:\n"
5807 " list-unit-files [PATTERN...] List installed unit files\n"
5808 " enable NAME... Enable one or more unit files\n"
5809 " disable NAME... Disable one or more unit files\n"
5810 " reenable NAME... Reenable one or more unit files\n"
5811 " preset NAME... Enable/disable one or more unit files\n"
5812 " based on preset configuration\n"
5813 " preset-all Enable/disable all unit files based on\n"
5814 " preset configuration\n"
5815 " is-enabled NAME... Check whether unit files are enabled\n\n"
5816 " mask NAME... Mask one or more units\n"
5817 " unmask NAME... Unmask one or more units\n"
5818 " link PATH... Link one or more units files into\n"
5819 " the search path\n"
5820 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
5821 " on specified one or more units\n"
5822 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
5823 " on specified one or more units\n"
5824 " get-default Get the name of the default target\n"
5825 " set-default NAME Set the default target\n\n"
5826 "Machine Commands:\n"
5827 " list-machines [PATTERN...] List local containers and host\n\n"
5829 " list-jobs [PATTERN...] List jobs\n"
5830 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5831 "Snapshot Commands:\n"
5832 " snapshot [NAME] Create a snapshot\n"
5833 " delete NAME... Remove one or more snapshots\n\n"
5834 "Environment Commands:\n"
5835 " show-environment Dump environment\n"
5836 " set-environment NAME=VALUE... Set one or more environment variables\n"
5837 " unset-environment NAME... Unset one or more environment variables\n"
5838 " import-environment NAME... Import all, one or more environment variables\n\n"
5839 "Manager Lifecycle Commands:\n"
5840 " daemon-reload Reload systemd manager configuration\n"
5841 " daemon-reexec Reexecute systemd manager\n\n"
5842 "System Commands:\n"
5843 " is-system-running Check whether system is fully running\n"
5844 " default Enter system default mode\n"
5845 " rescue Enter system rescue mode\n"
5846 " emergency Enter system emergency mode\n"
5847 " halt Shut down and halt the system\n"
5848 " poweroff Shut down and power-off the system\n"
5849 " reboot [ARG] Shut down and reboot the system\n"
5850 " kexec Shut down and reboot the system with kexec\n"
5851 " exit Request user instance exit\n"
5852 " switch-root ROOT [INIT] Change to a different root file system\n"
5853 " suspend Suspend the system\n"
5854 " hibernate Hibernate the system\n"
5855 " hybrid-sleep Hibernate and suspend the system\n",
5856 program_invocation_short_name);
5859 static void halt_help(void) {
5860 printf("%s [OPTIONS...]%s\n\n"
5861 "%s the system.\n\n"
5862 " --help Show this help\n"
5863 " --halt Halt the machine\n"
5864 " -p --poweroff Switch off the machine\n"
5865 " --reboot Reboot the machine\n"
5866 " -f --force Force immediate halt/power-off/reboot\n"
5867 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5868 " -d --no-wtmp Don't write wtmp record\n"
5869 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5870 program_invocation_short_name,
5871 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5872 arg_action == ACTION_REBOOT ? "Reboot" :
5873 arg_action == ACTION_POWEROFF ? "Power off" :
5877 static void shutdown_help(void) {
5878 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5879 "Shut down the system.\n\n"
5880 " --help Show this help\n"
5881 " -H --halt Halt the machine\n"
5882 " -P --poweroff Power-off the machine\n"
5883 " -r --reboot Reboot the machine\n"
5884 " -h Equivalent to --poweroff, overridden by --halt\n"
5885 " -k Don't halt/power-off/reboot, just send warnings\n"
5886 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5887 " -c Cancel a pending shutdown\n",
5888 program_invocation_short_name);
5891 static void telinit_help(void) {
5892 printf("%s [OPTIONS...] {COMMAND}\n\n"
5893 "Send control commands to the init daemon.\n\n"
5894 " --help Show this help\n"
5895 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5897 " 0 Power-off the machine\n"
5898 " 6 Reboot the machine\n"
5899 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5900 " 1, s, S Enter rescue mode\n"
5901 " q, Q Reload init daemon configuration\n"
5902 " u, U Reexecute init daemon\n",
5903 program_invocation_short_name);
5906 static void runlevel_help(void) {
5907 printf("%s [OPTIONS...]\n\n"
5908 "Prints the previous and current runlevel of the init system.\n\n"
5909 " --help Show this help\n",
5910 program_invocation_short_name);
5913 static void help_types(void) {
5918 puts("Available unit types:");
5919 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5920 t = unit_type_to_string(i);
5926 static int systemctl_parse_argv(int argc, char *argv[]) {
5935 ARG_IGNORE_DEPENDENCIES,
5947 ARG_NO_ASK_PASSWORD,
5957 static const struct option options[] = {
5958 { "help", no_argument, NULL, 'h' },
5959 { "version", no_argument, NULL, ARG_VERSION },
5960 { "type", required_argument, NULL, 't' },
5961 { "property", required_argument, NULL, 'p' },
5962 { "all", no_argument, NULL, 'a' },
5963 { "reverse", no_argument, NULL, ARG_REVERSE },
5964 { "after", no_argument, NULL, ARG_AFTER },
5965 { "before", no_argument, NULL, ARG_BEFORE },
5966 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5967 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5968 { "full", no_argument, NULL, 'l' },
5969 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5970 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5971 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5972 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5973 { "ignore-inhibitors", no_argument, NULL, 'i' },
5974 { "user", no_argument, NULL, ARG_USER },
5975 { "system", no_argument, NULL, ARG_SYSTEM },
5976 { "global", no_argument, NULL, ARG_GLOBAL },
5977 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5978 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5979 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5980 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5981 { "quiet", no_argument, NULL, 'q' },
5982 { "root", required_argument, NULL, ARG_ROOT },
5983 { "force", no_argument, NULL, ARG_FORCE },
5984 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5985 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5986 { "signal", required_argument, NULL, 's' },
5987 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5988 { "host", required_argument, NULL, 'H' },
5989 { "machine", required_argument, NULL, 'M' },
5990 { "runtime", no_argument, NULL, ARG_RUNTIME },
5991 { "lines", required_argument, NULL, 'n' },
5992 { "output", required_argument, NULL, 'o' },
5993 { "plain", no_argument, NULL, ARG_PLAIN },
5994 { "state", required_argument, NULL, ARG_STATE },
5995 { "recursive", no_argument, NULL, 'r' },
5996 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6005 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6014 puts(PACKAGE_STRING);
6015 puts(SYSTEMD_FEATURES);
6019 const char *word, *state;
6022 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6023 _cleanup_free_ char *type;
6025 type = strndup(word, size);
6029 if (streq(type, "help")) {
6034 if (unit_type_from_string(type) >= 0) {
6035 if (strv_push(&arg_types, type))
6041 /* It's much nicer to use --state= for
6042 * load states, but let's support this
6043 * in --types= too for compatibility
6044 * with old versions */
6045 if (unit_load_state_from_string(optarg) >= 0) {
6046 if (strv_push(&arg_states, type) < 0)
6052 log_error("Unknown unit type or load state '%s'.", type);
6053 log_info("Use -t help to see a list of allowed values.");
6061 /* Make sure that if the empty property list
6062 was specified, we won't show any properties. */
6063 if (isempty(optarg) && !arg_properties) {
6064 arg_properties = new0(char*, 1);
6065 if (!arg_properties)
6068 const char *word, *state;
6071 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6074 prop = strndup(word, size);
6078 if (strv_consume(&arg_properties, prop) < 0)
6083 /* If the user asked for a particular
6084 * property, show it to him, even if it is
6096 arg_dependency = DEPENDENCY_REVERSE;
6100 arg_dependency = DEPENDENCY_AFTER;
6104 arg_dependency = DEPENDENCY_BEFORE;
6107 case ARG_SHOW_TYPES:
6108 arg_show_types = true;
6112 arg_job_mode = optarg;
6116 arg_job_mode = "fail";
6119 case ARG_IRREVERSIBLE:
6120 arg_job_mode = "replace-irreversibly";
6123 case ARG_IGNORE_DEPENDENCIES:
6124 arg_job_mode = "ignore-dependencies";
6128 arg_scope = UNIT_FILE_USER;
6132 arg_scope = UNIT_FILE_SYSTEM;
6136 arg_scope = UNIT_FILE_GLOBAL;
6140 arg_no_block = true;
6144 arg_no_legend = true;
6148 arg_no_pager = true;
6164 if (strv_extend(&arg_states, "failed") < 0)
6182 arg_no_reload = true;
6186 arg_kill_who = optarg;
6190 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6191 log_error("Failed to parse signal string %s.", optarg);
6196 case ARG_NO_ASK_PASSWORD:
6197 arg_ask_password = false;
6201 arg_transport = BUS_TRANSPORT_REMOTE;
6206 arg_transport = BUS_TRANSPORT_CONTAINER;
6215 if (safe_atou(optarg, &arg_lines) < 0) {
6216 log_error("Failed to parse lines '%s'", optarg);
6222 arg_output = output_mode_from_string(optarg);
6223 if (arg_output < 0) {
6224 log_error("Unknown output '%s'.", optarg);
6230 arg_ignore_inhibitors = true;
6238 const char *word, *state;
6241 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6244 s = strndup(word, size);
6248 if (strv_consume(&arg_states, s) < 0)
6255 if (geteuid() != 0) {
6256 log_error("--recursive requires root privileges.");
6260 arg_recursive = true;
6263 case ARG_PRESET_MODE:
6265 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6266 if (arg_preset_mode < 0) {
6267 log_error("Failed to parse preset mode: %s.", optarg);
6277 assert_not_reached("Unhandled option");
6280 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6281 log_error("Cannot access user instance remotely.");
6288 static int halt_parse_argv(int argc, char *argv[]) {
6297 static const struct option options[] = {
6298 { "help", no_argument, NULL, ARG_HELP },
6299 { "halt", no_argument, NULL, ARG_HALT },
6300 { "poweroff", no_argument, NULL, 'p' },
6301 { "reboot", no_argument, NULL, ARG_REBOOT },
6302 { "force", no_argument, NULL, 'f' },
6303 { "wtmp-only", no_argument, NULL, 'w' },
6304 { "no-wtmp", no_argument, NULL, 'd' },
6305 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6314 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6315 if (runlevel == '0' || runlevel == '6')
6318 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6326 arg_action = ACTION_HALT;
6330 if (arg_action != ACTION_REBOOT)
6331 arg_action = ACTION_POWEROFF;
6335 arg_action = ACTION_REBOOT;
6357 /* Compatibility nops */
6364 assert_not_reached("Unhandled option");
6367 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6368 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6371 } else if (optind < argc) {
6372 log_error("Too many arguments.");
6379 static int parse_time_spec(const char *t, usec_t *_u) {
6383 if (streq(t, "now"))
6385 else if (!strchr(t, ':')) {
6388 if (safe_atou64(t, &u) < 0)
6391 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6400 hour = strtol(t, &e, 10);
6401 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6404 minute = strtol(e+1, &e, 10);
6405 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6408 n = now(CLOCK_REALTIME);
6409 s = (time_t) (n / USEC_PER_SEC);
6411 assert_se(localtime_r(&s, &tm));
6413 tm.tm_hour = (int) hour;
6414 tm.tm_min = (int) minute;
6417 assert_se(s = mktime(&tm));
6419 *_u = (usec_t) s * USEC_PER_SEC;
6422 *_u += USEC_PER_DAY;
6428 static int shutdown_parse_argv(int argc, char *argv[]) {
6435 static const struct option options[] = {
6436 { "help", no_argument, NULL, ARG_HELP },
6437 { "halt", no_argument, NULL, 'H' },
6438 { "poweroff", no_argument, NULL, 'P' },
6439 { "reboot", no_argument, NULL, 'r' },
6440 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6441 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6450 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6458 arg_action = ACTION_HALT;
6462 arg_action = ACTION_POWEROFF;
6467 arg_action = ACTION_KEXEC;
6469 arg_action = ACTION_REBOOT;
6473 arg_action = ACTION_KEXEC;
6477 if (arg_action != ACTION_HALT)
6478 arg_action = ACTION_POWEROFF;
6491 /* Compatibility nops */
6495 arg_action = ACTION_CANCEL_SHUTDOWN;
6502 assert_not_reached("Unhandled option");
6505 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6506 r = parse_time_spec(argv[optind], &arg_when);
6508 log_error("Failed to parse time specification: %s", argv[optind]);
6512 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6514 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6515 /* No time argument for shutdown cancel */
6516 arg_wall = argv + optind;
6517 else if (argc > optind + 1)
6518 /* We skip the time argument */
6519 arg_wall = argv + optind + 1;
6526 static int telinit_parse_argv(int argc, char *argv[]) {
6533 static const struct option options[] = {
6534 { "help", no_argument, NULL, ARG_HELP },
6535 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6539 static const struct {
6543 { '0', ACTION_POWEROFF },
6544 { '6', ACTION_REBOOT },
6545 { '1', ACTION_RESCUE },
6546 { '2', ACTION_RUNLEVEL2 },
6547 { '3', ACTION_RUNLEVEL3 },
6548 { '4', ACTION_RUNLEVEL4 },
6549 { '5', ACTION_RUNLEVEL5 },
6550 { 's', ACTION_RESCUE },
6551 { 'S', ACTION_RESCUE },
6552 { 'q', ACTION_RELOAD },
6553 { 'Q', ACTION_RELOAD },
6554 { 'u', ACTION_REEXEC },
6555 { 'U', ACTION_REEXEC }
6564 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6579 assert_not_reached("Unhandled option");
6582 if (optind >= argc) {
6583 log_error("%s: required argument missing.",
6584 program_invocation_short_name);
6588 if (optind + 1 < argc) {
6589 log_error("Too many arguments.");
6593 if (strlen(argv[optind]) != 1) {
6594 log_error("Expected single character argument.");
6598 for (i = 0; i < ELEMENTSOF(table); i++)
6599 if (table[i].from == argv[optind][0])
6602 if (i >= ELEMENTSOF(table)) {
6603 log_error("Unknown command '%s'.", argv[optind]);
6607 arg_action = table[i].to;
6614 static int runlevel_parse_argv(int argc, char *argv[]) {
6620 static const struct option options[] = {
6621 { "help", no_argument, NULL, ARG_HELP },
6630 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6641 assert_not_reached("Unhandled option");
6644 if (optind < argc) {
6645 log_error("Too many arguments.");
6652 static int parse_argv(int argc, char *argv[]) {
6656 if (program_invocation_short_name) {
6658 if (strstr(program_invocation_short_name, "halt")) {
6659 arg_action = ACTION_HALT;
6660 return halt_parse_argv(argc, argv);
6661 } else if (strstr(program_invocation_short_name, "poweroff")) {
6662 arg_action = ACTION_POWEROFF;
6663 return halt_parse_argv(argc, argv);
6664 } else if (strstr(program_invocation_short_name, "reboot")) {
6666 arg_action = ACTION_KEXEC;
6668 arg_action = ACTION_REBOOT;
6669 return halt_parse_argv(argc, argv);
6670 } else if (strstr(program_invocation_short_name, "shutdown")) {
6671 arg_action = ACTION_POWEROFF;
6672 return shutdown_parse_argv(argc, argv);
6673 } else if (strstr(program_invocation_short_name, "init")) {
6675 if (sd_booted() > 0) {
6676 arg_action = _ACTION_INVALID;
6677 return telinit_parse_argv(argc, argv);
6679 /* Hmm, so some other init system is
6680 * running, we need to forward this
6681 * request to it. For now we simply
6682 * guess that it is Upstart. */
6684 execv(TELINIT, argv);
6686 log_error("Couldn't find an alternative telinit implementation to spawn.");
6690 } else if (strstr(program_invocation_short_name, "runlevel")) {
6691 arg_action = ACTION_RUNLEVEL;
6692 return runlevel_parse_argv(argc, argv);
6696 arg_action = ACTION_SYSTEMCTL;
6697 return systemctl_parse_argv(argc, argv);
6700 _pure_ static int action_to_runlevel(void) {
6702 static const char table[_ACTION_MAX] = {
6703 [ACTION_HALT] = '0',
6704 [ACTION_POWEROFF] = '0',
6705 [ACTION_REBOOT] = '6',
6706 [ACTION_RUNLEVEL2] = '2',
6707 [ACTION_RUNLEVEL3] = '3',
6708 [ACTION_RUNLEVEL4] = '4',
6709 [ACTION_RUNLEVEL5] = '5',
6710 [ACTION_RESCUE] = '1'
6713 assert(arg_action < _ACTION_MAX);
6715 return table[arg_action];
6718 static int talk_initctl(void) {
6720 struct init_request request = {
6721 .magic = INIT_MAGIC,
6723 .cmd = INIT_CMD_RUNLVL
6726 _cleanup_close_ int fd = -1;
6730 rl = action_to_runlevel();
6734 request.runlevel = rl;
6736 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6738 if (errno == ENOENT)
6741 log_error("Failed to open "INIT_FIFO": %m");
6746 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6748 log_error("Failed to write to "INIT_FIFO": %m");
6749 return errno > 0 ? -errno : -EIO;
6755 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6757 static const struct {
6765 int (* const dispatch)(sd_bus *bus, char **args);
6771 { "list-units", MORE, 0, list_units },
6772 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6773 { "list-sockets", MORE, 1, list_sockets },
6774 { "list-timers", MORE, 1, list_timers },
6775 { "list-jobs", MORE, 1, list_jobs },
6776 { "list-machines", MORE, 1, list_machines },
6777 { "clear-jobs", EQUAL, 1, daemon_reload },
6778 { "cancel", MORE, 2, cancel_job },
6779 { "start", MORE, 2, start_unit },
6780 { "stop", MORE, 2, start_unit },
6781 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6782 { "reload", MORE, 2, start_unit },
6783 { "restart", MORE, 2, start_unit },
6784 { "try-restart", MORE, 2, start_unit },
6785 { "reload-or-restart", MORE, 2, start_unit },
6786 { "reload-or-try-restart", MORE, 2, start_unit },
6787 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6788 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6789 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6790 { "isolate", EQUAL, 2, start_unit },
6791 { "kill", MORE, 2, kill_unit },
6792 { "is-active", MORE, 2, check_unit_active },
6793 { "check", MORE, 2, check_unit_active },
6794 { "is-failed", MORE, 2, check_unit_failed },
6795 { "show", MORE, 1, show },
6796 { "cat", MORE, 2, cat },
6797 { "status", MORE, 1, show },
6798 { "help", MORE, 2, show },
6799 { "snapshot", LESS, 2, snapshot },
6800 { "delete", MORE, 2, delete_snapshot },
6801 { "daemon-reload", EQUAL, 1, daemon_reload },
6802 { "daemon-reexec", EQUAL, 1, daemon_reload },
6803 { "show-environment", EQUAL, 1, show_environment },
6804 { "set-environment", MORE, 2, set_environment },
6805 { "unset-environment", MORE, 2, set_environment },
6806 { "import-environment", MORE, 1, import_environment},
6807 { "halt", EQUAL, 1, start_special, FORCE },
6808 { "poweroff", EQUAL, 1, start_special, FORCE },
6809 { "reboot", EQUAL, 1, start_special, FORCE },
6810 { "kexec", EQUAL, 1, start_special },
6811 { "suspend", EQUAL, 1, start_special },
6812 { "hibernate", EQUAL, 1, start_special },
6813 { "hybrid-sleep", EQUAL, 1, start_special },
6814 { "default", EQUAL, 1, start_special },
6815 { "rescue", EQUAL, 1, start_special },
6816 { "emergency", EQUAL, 1, start_special },
6817 { "exit", EQUAL, 1, start_special },
6818 { "reset-failed", MORE, 1, reset_failed },
6819 { "enable", MORE, 2, enable_unit, NOBUS },
6820 { "disable", MORE, 2, enable_unit, NOBUS },
6821 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6822 { "reenable", MORE, 2, enable_unit, NOBUS },
6823 { "preset", MORE, 2, enable_unit, NOBUS },
6824 { "preset-all", EQUAL, 1, preset_all, NOBUS },
6825 { "mask", MORE, 2, enable_unit, NOBUS },
6826 { "unmask", MORE, 2, enable_unit, NOBUS },
6827 { "link", MORE, 2, enable_unit, NOBUS },
6828 { "switch-root", MORE, 2, switch_root },
6829 { "list-dependencies", LESS, 2, list_dependencies },
6830 { "set-default", EQUAL, 2, set_default, NOBUS },
6831 { "get-default", EQUAL, 1, get_default, NOBUS },
6832 { "set-property", MORE, 3, set_property },
6833 { "is-system-running", EQUAL, 1, is_system_running },
6834 { "add-wants", MORE, 3, add_dependency, NOBUS },
6835 { "add-requires", MORE, 3, add_dependency, NOBUS },
6844 left = argc - optind;
6846 /* Special rule: no arguments (left == 0) means "list-units" */
6848 if (streq(argv[optind], "help") && !argv[optind+1]) {
6849 log_error("This command expects one or more "
6850 "unit names. Did you mean --help?");
6854 for (; verb->verb; verb++)
6855 if (streq(argv[optind], verb->verb))
6858 log_error("Unknown operation '%s'.", argv[optind]);
6863 switch (verb->argc_cmp) {
6866 if (left != verb->argc) {
6867 log_error("Invalid number of arguments.");
6874 if (left < verb->argc) {
6875 log_error("Too few arguments.");
6882 if (left > verb->argc) {
6883 log_error("Too many arguments.");
6890 assert_not_reached("Unknown comparison operator.");
6893 /* Require a bus connection for all operations but
6895 if (verb->bus == NOBUS) {
6896 if (!bus && !avoid_bus()) {
6897 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
6902 if (running_in_chroot() > 0) {
6903 log_info("Running in chroot, ignoring request.");
6907 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6908 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
6913 return verb->dispatch(bus, argv + optind);
6916 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6918 struct sd_shutdown_command c = {
6925 union sockaddr_union sockaddr = {
6926 .un.sun_family = AF_UNIX,
6927 .un.sun_path = "/run/systemd/shutdownd",
6930 struct iovec iovec[2] = {{
6931 .iov_base = (char*) &c,
6932 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6935 struct msghdr msghdr = {
6936 .msg_name = &sockaddr,
6937 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6938 + strlen("/run/systemd/shutdownd"),
6943 _cleanup_close_ int fd;
6945 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6949 if (!isempty(message)) {
6950 iovec[1].iov_base = (char*) message;
6951 iovec[1].iov_len = strlen(message);
6952 msghdr.msg_iovlen++;
6955 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6961 static int reload_with_fallback(sd_bus *bus) {
6964 /* First, try systemd via D-Bus. */
6965 if (daemon_reload(bus, NULL) >= 0)
6969 /* Nothing else worked, so let's try signals */
6970 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6972 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6973 log_error("kill() failed: %m");
6980 static int start_with_fallback(sd_bus *bus) {
6983 /* First, try systemd via D-Bus. */
6984 if (start_unit(bus, NULL) >= 0)
6988 /* Nothing else worked, so let's try
6990 if (talk_initctl() > 0)
6993 log_error("Failed to talk to init daemon.");
6997 warn_wall(arg_action);
7001 static int halt_now(enum action a) {
7003 /* The kernel will automaticall flush ATA disks and suchlike
7004 * on reboot(), but the file systems need to be synce'd
7005 * explicitly in advance. */
7008 /* Make sure C-A-D is handled by the kernel from this point
7010 reboot(RB_ENABLE_CAD);
7015 log_info("Halting.");
7016 reboot(RB_HALT_SYSTEM);
7019 case ACTION_POWEROFF:
7020 log_info("Powering off.");
7021 reboot(RB_POWER_OFF);
7024 case ACTION_REBOOT: {
7025 _cleanup_free_ char *param = NULL;
7027 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7028 log_info("Rebooting with argument '%s'.", param);
7029 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7030 LINUX_REBOOT_CMD_RESTART2, param);
7033 log_info("Rebooting.");
7034 reboot(RB_AUTOBOOT);
7039 assert_not_reached("Unknown action.");
7043 static int halt_main(sd_bus *bus) {
7046 r = check_inhibitors(bus, arg_action);
7050 if (geteuid() != 0) {
7051 /* Try logind if we are a normal user and no special
7052 * mode applies. Maybe PolicyKit allows us to shutdown
7055 if (arg_when <= 0 &&
7058 (arg_action == ACTION_POWEROFF ||
7059 arg_action == ACTION_REBOOT)) {
7060 r = reboot_with_logind(bus, arg_action);
7065 log_error("Must be root.");
7070 _cleanup_free_ char *m;
7072 m = strv_join(arg_wall, " ");
7076 r = send_shutdownd(arg_when,
7077 arg_action == ACTION_HALT ? 'H' :
7078 arg_action == ACTION_POWEROFF ? 'P' :
7079 arg_action == ACTION_KEXEC ? 'K' :
7086 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7088 char date[FORMAT_TIMESTAMP_MAX];
7090 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7091 format_timestamp(date, sizeof(date), arg_when));
7096 if (!arg_dry && !arg_force)
7097 return start_with_fallback(bus);
7100 if (sd_booted() > 0)
7101 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7103 r = utmp_put_shutdown();
7105 log_warning_errno(r, "Failed to write utmp record: %m");
7112 r = halt_now(arg_action);
7113 log_error_errno(r, "Failed to reboot: %m");
7118 static int runlevel_main(void) {
7119 int r, runlevel, previous;
7121 r = utmp_get_runlevel(&runlevel, &previous);
7128 previous <= 0 ? 'N' : previous,
7129 runlevel <= 0 ? 'N' : runlevel);
7134 int main(int argc, char*argv[]) {
7135 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7138 setlocale(LC_ALL, "");
7139 log_parse_environment();
7142 /* Explicitly not on_tty() to avoid setting cached value.
7143 * This becomes relevant for piping output which might be
7145 original_stdout_is_tty = isatty(STDOUT_FILENO);
7147 r = parse_argv(argc, argv);
7151 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7152 * let's shortcut this */
7153 if (arg_action == ACTION_RUNLEVEL) {
7154 r = runlevel_main();
7158 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7159 log_info("Running in chroot, ignoring request.");
7165 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7167 /* systemctl_main() will print an error message for the bus
7168 * connection, but only if it needs to */
7170 switch (arg_action) {
7172 case ACTION_SYSTEMCTL:
7173 r = systemctl_main(bus, argc, argv, r);
7177 case ACTION_POWEROFF:
7183 case ACTION_RUNLEVEL2:
7184 case ACTION_RUNLEVEL3:
7185 case ACTION_RUNLEVEL4:
7186 case ACTION_RUNLEVEL5:
7188 case ACTION_EMERGENCY:
7189 case ACTION_DEFAULT:
7190 r = start_with_fallback(bus);
7195 r = reload_with_fallback(bus);
7198 case ACTION_CANCEL_SHUTDOWN: {
7199 _cleanup_free_ char *m = NULL;
7202 m = strv_join(arg_wall, " ");
7209 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7211 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7215 case ACTION_RUNLEVEL:
7216 case _ACTION_INVALID:
7218 assert_not_reached("Unknown action");
7223 ask_password_agent_close();
7224 polkit_agent_close();
7226 strv_free(arg_types);
7227 strv_free(arg_states);
7228 strv_free(arg_properties);
7230 return r < 0 ? EXIT_FAILURE : r;