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) {
2705 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2707 t = unit_name_mangle(*name, MANGLE_GLOB);
2711 if (string_is_glob(t))
2712 r = strv_consume(&globs, t);
2714 r = strv_consume(&mangled, t);
2719 /* Query the manager only if any of the names are a glob, since
2720 * this is fairly expensive */
2721 if (!strv_isempty(globs)) {
2722 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2723 _cleanup_free_ UnitInfo *unit_infos = NULL;
2725 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2729 for (i = 0; i < r; i++)
2730 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2735 mangled = NULL; /* do not free */
2740 static const struct {
2744 } action_table[_ACTION_MAX] = {
2745 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2746 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2747 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2748 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2749 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2750 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2751 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2752 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2753 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2754 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2755 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2756 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2757 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2758 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2759 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2762 static enum action verb_to_action(const char *verb) {
2765 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2766 if (streq_ptr(action_table[i].verb, verb))
2769 return _ACTION_INVALID;
2772 static int start_unit(sd_bus *bus, char **args) {
2773 _cleanup_set_free_free_ Set *s = NULL;
2774 _cleanup_strv_free_ char **names = NULL;
2775 const char *method, *mode, *one_name, *suffix = NULL;
2781 ask_password_agent_open_if_enabled();
2783 if (arg_action == ACTION_SYSTEMCTL) {
2785 method = verb_to_method(args[0]);
2786 action = verb_to_action(args[0]);
2788 if (streq(args[0], "isolate")) {
2792 mode = action_table[action].mode ?: arg_job_mode;
2794 one_name = action_table[action].target;
2796 assert(arg_action < ELEMENTSOF(action_table));
2797 assert(action_table[arg_action].target);
2799 method = "StartUnit";
2801 mode = action_table[arg_action].mode;
2802 one_name = action_table[arg_action].target;
2806 names = strv_new(one_name, NULL);
2808 r = expand_names(bus, args + 1, suffix, &names);
2810 log_error_errno(-r, "Failed to expand names: %m");
2813 if (!arg_no_block) {
2814 r = enable_wait_for_jobs(bus);
2816 log_error_errno(-r, "Could not watch jobs: %m");
2820 s = set_new(&string_hash_ops);
2825 STRV_FOREACH(name, names) {
2826 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2829 q = start_unit_one(bus, method, *name, mode, &error, s);
2830 if (r >= 0 && q < 0)
2831 r = translate_bus_error_to_exit_status(q, &error);
2834 if (!arg_no_block) {
2837 q = wait_for_jobs(bus, s);
2841 /* When stopping units, warn if they can still be triggered by
2842 * another active unit (socket, path, timer) */
2843 if (!arg_quiet && streq(method, "StopUnit"))
2844 STRV_FOREACH(name, names)
2845 check_triggering_units(bus, *name);
2851 /* Ask systemd-logind, which might grant access to unprivileged users
2852 * through PolicyKit */
2853 static int reboot_with_logind(sd_bus *bus, enum action a) {
2855 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2862 polkit_agent_open_if_enabled();
2870 case ACTION_POWEROFF:
2871 method = "PowerOff";
2874 case ACTION_SUSPEND:
2878 case ACTION_HIBERNATE:
2879 method = "Hibernate";
2882 case ACTION_HYBRID_SLEEP:
2883 method = "HybridSleep";
2890 r = sd_bus_call_method(
2892 "org.freedesktop.login1",
2893 "/org/freedesktop/login1",
2894 "org.freedesktop.login1.Manager",
2898 "b", arg_ask_password);
2900 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2908 static int check_inhibitors(sd_bus *bus, enum action a) {
2910 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2911 _cleanup_strv_free_ char **sessions = NULL;
2912 const char *what, *who, *why, *mode;
2921 if (arg_ignore_inhibitors || arg_force > 0)
2933 r = sd_bus_call_method(
2935 "org.freedesktop.login1",
2936 "/org/freedesktop/login1",
2937 "org.freedesktop.login1.Manager",
2943 /* If logind is not around, then there are no inhibitors... */
2946 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2948 return bus_log_parse_error(r);
2950 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2951 _cleanup_free_ char *comm = NULL, *user = NULL;
2952 _cleanup_strv_free_ char **sv = NULL;
2954 if (!streq(mode, "block"))
2957 sv = strv_split(what, ":");
2961 if (!strv_contains(sv,
2963 a == ACTION_POWEROFF ||
2964 a == ACTION_REBOOT ||
2965 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2968 get_process_comm(pid, &comm);
2969 user = uid_to_name(uid);
2971 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2972 who, pid, strna(comm), strna(user), why);
2977 return bus_log_parse_error(r);
2979 r = sd_bus_message_exit_container(reply);
2981 return bus_log_parse_error(r);
2983 /* Check for current sessions */
2984 sd_get_sessions(&sessions);
2985 STRV_FOREACH(s, sessions) {
2986 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2988 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2991 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2994 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2997 sd_session_get_tty(*s, &tty);
2998 sd_session_get_seat(*s, &seat);
2999 sd_session_get_service(*s, &service);
3000 user = uid_to_name(uid);
3002 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
3009 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3010 action_table[a].verb);
3018 static int start_special(sd_bus *bus, char **args) {
3024 a = verb_to_action(args[0]);
3026 r = check_inhibitors(bus, a);
3030 if (arg_force >= 2 && geteuid() != 0) {
3031 log_error("Must be root.");
3035 if (arg_force >= 2 &&
3036 (a == ACTION_HALT ||
3037 a == ACTION_POWEROFF ||
3038 a == ACTION_REBOOT))
3041 if (arg_force >= 1 &&
3042 (a == ACTION_HALT ||
3043 a == ACTION_POWEROFF ||
3044 a == ACTION_REBOOT ||
3045 a == ACTION_KEXEC ||
3047 return daemon_reload(bus, args);
3049 /* first try logind, to allow authentication with polkit */
3050 if (geteuid() != 0 &&
3051 (a == ACTION_POWEROFF ||
3052 a == ACTION_REBOOT ||
3053 a == ACTION_SUSPEND ||
3054 a == ACTION_HIBERNATE ||
3055 a == ACTION_HYBRID_SLEEP)) {
3056 r = reboot_with_logind(bus, a);
3061 r = start_unit(bus, args);
3062 if (r == EXIT_SUCCESS)
3068 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3069 _cleanup_strv_free_ char **names = NULL;
3076 r = expand_names(bus, args, NULL, &names);
3078 log_error_errno(-r, "Failed to expand names: %m");
3082 STRV_FOREACH(name, names) {
3085 state = check_one_unit(bus, *name, good_states, arg_quiet);
3095 static int check_unit_active(sd_bus *bus, char **args) {
3096 /* According to LSB: 3, "program is not running" */
3097 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3100 static int check_unit_failed(sd_bus *bus, char **args) {
3101 return check_unit_generic(bus, 1, "failed\0", args + 1);
3104 static int kill_unit(sd_bus *bus, char **args) {
3105 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3106 _cleanup_strv_free_ char **names = NULL;
3114 arg_kill_who = "all";
3116 r = expand_names(bus, args + 1, NULL, &names);
3118 log_error_errno(-r, "Failed to expand names: %m");
3120 STRV_FOREACH(name, names) {
3121 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3123 q = sd_bus_message_new_method_call(
3126 "org.freedesktop.systemd1",
3127 "/org/freedesktop/systemd1",
3128 "org.freedesktop.systemd1.Manager",
3131 return bus_log_create_error(q);
3133 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3135 return bus_log_create_error(q);
3137 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3139 return bus_log_create_error(q);
3141 q = sd_bus_call(bus, m, 0, &error, NULL);
3143 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3152 typedef struct ExecStatusInfo {
3160 usec_t start_timestamp;
3161 usec_t exit_timestamp;
3166 LIST_FIELDS(struct ExecStatusInfo, exec);
3169 static void exec_status_info_free(ExecStatusInfo *i) {
3178 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3179 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3182 int32_t code, status;
3188 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3190 return bus_log_parse_error(r);
3194 r = sd_bus_message_read(m, "s", &path);
3196 return bus_log_parse_error(r);
3198 i->path = strdup(path);
3202 r = sd_bus_message_read_strv(m, &i->argv);
3204 return bus_log_parse_error(r);
3206 r = sd_bus_message_read(m,
3209 &start_timestamp, &start_timestamp_monotonic,
3210 &exit_timestamp, &exit_timestamp_monotonic,
3214 return bus_log_parse_error(r);
3217 i->start_timestamp = (usec_t) start_timestamp;
3218 i->exit_timestamp = (usec_t) exit_timestamp;
3219 i->pid = (pid_t) pid;
3223 r = sd_bus_message_exit_container(m);
3225 return bus_log_parse_error(r);
3230 typedef struct UnitStatusInfo {
3232 const char *load_state;
3233 const char *active_state;
3234 const char *sub_state;
3235 const char *unit_file_state;
3237 const char *description;
3238 const char *following;
3240 char **documentation;
3242 const char *fragment_path;
3243 const char *source_path;
3244 const char *control_group;
3246 char **dropin_paths;
3248 const char *load_error;
3251 usec_t inactive_exit_timestamp;
3252 usec_t inactive_exit_timestamp_monotonic;
3253 usec_t active_enter_timestamp;
3254 usec_t active_exit_timestamp;
3255 usec_t inactive_enter_timestamp;
3257 bool need_daemon_reload;
3262 const char *status_text;
3263 const char *pid_file;
3267 usec_t start_timestamp;
3268 usec_t exit_timestamp;
3270 int exit_code, exit_status;
3272 usec_t condition_timestamp;
3273 bool condition_result;
3274 bool failed_condition_trigger;
3275 bool failed_condition_negate;
3276 const char *failed_condition;
3277 const char *failed_condition_parameter;
3279 usec_t assert_timestamp;
3281 bool failed_assert_trigger;
3282 bool failed_assert_negate;
3283 const char *failed_assert;
3284 const char *failed_assert_parameter;
3287 unsigned n_accepted;
3288 unsigned n_connections;
3291 /* Pairs of type, path */
3295 const char *sysfs_path;
3297 /* Mount, Automount */
3303 LIST_HEAD(ExecStatusInfo, exec);
3306 static void print_status_info(
3311 const char *active_on, *active_off, *on, *off, *ss;
3313 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3314 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3317 arg_all * OUTPUT_SHOW_ALL |
3318 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3319 on_tty() * OUTPUT_COLOR |
3320 !arg_quiet * OUTPUT_WARN_CUTOFF |
3321 arg_full * OUTPUT_FULL_WIDTH;
3326 /* This shows pretty information about a unit. See
3327 * print_property() for a low-level property printer */
3329 if (streq_ptr(i->active_state, "failed")) {
3330 active_on = ansi_highlight_red();
3331 active_off = ansi_highlight_off();
3332 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3333 active_on = ansi_highlight_green();
3334 active_off = ansi_highlight_off();
3336 active_on = active_off = "";
3338 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3340 if (i->description && !streq_ptr(i->id, i->description))
3341 printf(" - %s", i->description);
3346 printf(" Follow: unit currently follows state of %s\n", i->following);
3348 if (streq_ptr(i->load_state, "error")) {
3349 on = ansi_highlight_red();
3350 off = ansi_highlight_off();
3354 path = i->source_path ? i->source_path : i->fragment_path;
3357 printf(" Loaded: %s%s%s (Reason: %s)\n",
3358 on, strna(i->load_state), off, i->load_error);
3359 else if (path && i->unit_file_state)
3360 printf(" Loaded: %s%s%s (%s; %s)\n",
3361 on, strna(i->load_state), off, path, i->unit_file_state);
3363 printf(" Loaded: %s%s%s (%s)\n",
3364 on, strna(i->load_state), off, path);
3366 printf(" Loaded: %s%s%s\n",
3367 on, strna(i->load_state), off);
3369 if (!strv_isempty(i->dropin_paths)) {
3370 _cleanup_free_ char *dir = NULL;
3374 STRV_FOREACH(dropin, i->dropin_paths) {
3375 if (! dir || last) {
3376 printf(dir ? " " : " Drop-In: ");
3381 if (path_get_parent(*dropin, &dir) < 0) {
3386 printf("%s\n %s", dir,
3387 draw_special_char(DRAW_TREE_RIGHT));
3390 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3392 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3396 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3398 printf(" Active: %s%s (%s)%s",
3399 active_on, strna(i->active_state), ss, active_off);
3401 printf(" Active: %s%s%s",
3402 active_on, strna(i->active_state), active_off);
3404 if (!isempty(i->result) && !streq(i->result, "success"))
3405 printf(" (Result: %s)", i->result);
3407 timestamp = (streq_ptr(i->active_state, "active") ||
3408 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3409 (streq_ptr(i->active_state, "inactive") ||
3410 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3411 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3412 i->active_exit_timestamp;
3414 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3415 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3418 printf(" since %s; %s\n", s2, s1);
3420 printf(" since %s\n", s2);
3424 if (!i->condition_result && i->condition_timestamp > 0) {
3425 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3426 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3428 printf("Condition: start %scondition failed%s at %s%s%s\n",
3429 ansi_highlight_yellow(), ansi_highlight_off(),
3430 s2, s1 ? "; " : "", s1 ? s1 : "");
3431 if (i->failed_condition_trigger)
3432 printf(" none of the trigger conditions were met\n");
3433 else if (i->failed_condition)
3434 printf(" %s=%s%s was not met\n",
3435 i->failed_condition,
3436 i->failed_condition_negate ? "!" : "",
3437 i->failed_condition_parameter);
3440 if (!i->assert_result && i->assert_timestamp > 0) {
3441 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3442 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3444 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3445 ansi_highlight_red(), ansi_highlight_off(),
3446 s2, s1 ? "; " : "", s1 ? s1 : "");
3447 if (i->failed_assert_trigger)
3448 printf(" none of the trigger assertions were met\n");
3449 else if (i->failed_assert)
3450 printf(" %s=%s%s was not met\n",
3452 i->failed_assert_negate ? "!" : "",
3453 i->failed_assert_parameter);
3457 printf(" Device: %s\n", i->sysfs_path);
3459 printf(" Where: %s\n", i->where);
3461 printf(" What: %s\n", i->what);
3463 STRV_FOREACH(t, i->documentation)
3464 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3466 STRV_FOREACH_PAIR(t, t2, i->listen)
3467 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3470 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3472 LIST_FOREACH(exec, p, i->exec) {
3473 _cleanup_free_ char *argv = NULL;
3476 /* Only show exited processes here */
3480 argv = strv_join(p->argv, " ");
3481 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3483 good = is_clean_exit_lsb(p->code, p->status, NULL);
3485 on = ansi_highlight_red();
3486 off = ansi_highlight_off();
3490 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3492 if (p->code == CLD_EXITED) {
3495 printf("status=%i", p->status);
3497 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3502 printf("signal=%s", signal_to_string(p->status));
3504 printf(")%s\n", off);
3506 if (i->main_pid == p->pid &&
3507 i->start_timestamp == p->start_timestamp &&
3508 i->exit_timestamp == p->start_timestamp)
3509 /* Let's not show this twice */
3512 if (p->pid == i->control_pid)
3516 if (i->main_pid > 0 || i->control_pid > 0) {
3517 if (i->main_pid > 0) {
3518 printf(" Main PID: "PID_FMT, i->main_pid);
3521 _cleanup_free_ char *comm = NULL;
3522 get_process_comm(i->main_pid, &comm);
3524 printf(" (%s)", comm);
3525 } else if (i->exit_code > 0) {
3526 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3528 if (i->exit_code == CLD_EXITED) {
3531 printf("status=%i", i->exit_status);
3533 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3538 printf("signal=%s", signal_to_string(i->exit_status));
3542 if (i->control_pid > 0)
3546 if (i->control_pid > 0) {
3547 _cleanup_free_ char *c = NULL;
3549 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3551 get_process_comm(i->control_pid, &c);
3560 printf(" Status: \"%s\"\n", i->status_text);
3561 if (i->status_errno > 0)
3562 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3564 if (i->control_group &&
3565 (i->main_pid > 0 || i->control_pid > 0 ||
3566 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3569 printf(" CGroup: %s\n", i->control_group);
3571 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3574 static const char prefix[] = " ";
3577 if (c > sizeof(prefix) - 1)
3578 c -= sizeof(prefix) - 1;
3582 if (i->main_pid > 0)
3583 extra[k++] = i->main_pid;
3585 if (i->control_pid > 0)
3586 extra[k++] = i->control_pid;
3588 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3592 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3593 show_journal_by_unit(stdout,
3597 i->inactive_exit_timestamp_monotonic,
3600 flags | OUTPUT_BEGIN_NEWLINE,
3601 arg_scope == UNIT_FILE_SYSTEM,
3605 if (i->need_daemon_reload)
3606 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3607 ansi_highlight_red(),
3608 ansi_highlight_off(),
3609 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3612 static void show_unit_help(UnitStatusInfo *i) {
3617 if (!i->documentation) {
3618 log_info("Documentation for %s not known.", i->id);
3622 STRV_FOREACH(p, i->documentation)
3623 if (startswith(*p, "man:"))
3624 show_man_page(*p + 4, false);
3626 log_info("Can't show: %s", *p);
3629 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3636 switch (contents[0]) {
3638 case SD_BUS_TYPE_STRING: {
3641 r = sd_bus_message_read(m, "s", &s);
3643 return bus_log_parse_error(r);
3646 if (streq(name, "Id"))
3648 else if (streq(name, "LoadState"))
3650 else if (streq(name, "ActiveState"))
3651 i->active_state = s;
3652 else if (streq(name, "SubState"))
3654 else if (streq(name, "Description"))
3656 else if (streq(name, "FragmentPath"))
3657 i->fragment_path = s;
3658 else if (streq(name, "SourcePath"))
3661 else if (streq(name, "DefaultControlGroup")) {
3663 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3665 i->control_group = e;
3668 else if (streq(name, "ControlGroup"))
3669 i->control_group = s;
3670 else if (streq(name, "StatusText"))
3672 else if (streq(name, "PIDFile"))
3674 else if (streq(name, "SysFSPath"))
3676 else if (streq(name, "Where"))
3678 else if (streq(name, "What"))
3680 else if (streq(name, "Following"))
3682 else if (streq(name, "UnitFileState"))
3683 i->unit_file_state = s;
3684 else if (streq(name, "Result"))
3691 case SD_BUS_TYPE_BOOLEAN: {
3694 r = sd_bus_message_read(m, "b", &b);
3696 return bus_log_parse_error(r);
3698 if (streq(name, "Accept"))
3700 else if (streq(name, "NeedDaemonReload"))
3701 i->need_daemon_reload = b;
3702 else if (streq(name, "ConditionResult"))
3703 i->condition_result = b;
3704 else if (streq(name, "AssertResult"))
3705 i->assert_result = b;
3710 case SD_BUS_TYPE_UINT32: {
3713 r = sd_bus_message_read(m, "u", &u);
3715 return bus_log_parse_error(r);
3717 if (streq(name, "MainPID")) {
3719 i->main_pid = (pid_t) u;
3722 } else if (streq(name, "ControlPID"))
3723 i->control_pid = (pid_t) u;
3724 else if (streq(name, "ExecMainPID")) {
3726 i->main_pid = (pid_t) u;
3727 } else if (streq(name, "NAccepted"))
3729 else if (streq(name, "NConnections"))
3730 i->n_connections = u;
3735 case SD_BUS_TYPE_INT32: {
3738 r = sd_bus_message_read(m, "i", &j);
3740 return bus_log_parse_error(r);
3742 if (streq(name, "ExecMainCode"))
3743 i->exit_code = (int) j;
3744 else if (streq(name, "ExecMainStatus"))
3745 i->exit_status = (int) j;
3746 else if (streq(name, "StatusErrno"))
3747 i->status_errno = (int) j;
3752 case SD_BUS_TYPE_UINT64: {
3755 r = sd_bus_message_read(m, "t", &u);
3757 return bus_log_parse_error(r);
3759 if (streq(name, "ExecMainStartTimestamp"))
3760 i->start_timestamp = (usec_t) u;
3761 else if (streq(name, "ExecMainExitTimestamp"))
3762 i->exit_timestamp = (usec_t) u;
3763 else if (streq(name, "ActiveEnterTimestamp"))
3764 i->active_enter_timestamp = (usec_t) u;
3765 else if (streq(name, "InactiveEnterTimestamp"))
3766 i->inactive_enter_timestamp = (usec_t) u;
3767 else if (streq(name, "InactiveExitTimestamp"))
3768 i->inactive_exit_timestamp = (usec_t) u;
3769 else if (streq(name, "InactiveExitTimestampMonotonic"))
3770 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3771 else if (streq(name, "ActiveExitTimestamp"))
3772 i->active_exit_timestamp = (usec_t) u;
3773 else if (streq(name, "ConditionTimestamp"))
3774 i->condition_timestamp = (usec_t) u;
3775 else if (streq(name, "AssertTimestamp"))
3776 i->assert_timestamp = (usec_t) u;
3781 case SD_BUS_TYPE_ARRAY:
3783 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3784 _cleanup_free_ ExecStatusInfo *info = NULL;
3786 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3788 return bus_log_parse_error(r);
3790 info = new0(ExecStatusInfo, 1);
3794 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3796 info->name = strdup(name);
3800 LIST_PREPEND(exec, i->exec, info);
3802 info = new0(ExecStatusInfo, 1);
3808 return bus_log_parse_error(r);
3810 r = sd_bus_message_exit_container(m);
3812 return bus_log_parse_error(r);
3816 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3817 const char *type, *path;
3819 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3821 return bus_log_parse_error(r);
3823 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3825 r = strv_extend(&i->listen, type);
3829 r = strv_extend(&i->listen, path);
3834 return bus_log_parse_error(r);
3836 r = sd_bus_message_exit_container(m);
3838 return bus_log_parse_error(r);
3842 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3844 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3846 return bus_log_parse_error(r);
3848 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3850 r = sd_bus_message_read_strv(m, &i->documentation);
3852 return bus_log_parse_error(r);
3854 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3855 const char *cond, *param;
3856 int trigger, negate;
3859 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3861 return bus_log_parse_error(r);
3863 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3864 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3865 if (state < 0 && (!trigger || !i->failed_condition)) {
3866 i->failed_condition = cond;
3867 i->failed_condition_trigger = trigger;
3868 i->failed_condition_negate = negate;
3869 i->failed_condition_parameter = param;
3873 return bus_log_parse_error(r);
3875 r = sd_bus_message_exit_container(m);
3877 return bus_log_parse_error(r);
3879 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3880 const char *cond, *param;
3881 int trigger, negate;
3884 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3886 return bus_log_parse_error(r);
3888 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3889 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3890 if (state < 0 && (!trigger || !i->failed_assert)) {
3891 i->failed_assert = cond;
3892 i->failed_assert_trigger = trigger;
3893 i->failed_assert_negate = negate;
3894 i->failed_assert_parameter = param;
3898 return bus_log_parse_error(r);
3900 r = sd_bus_message_exit_container(m);
3902 return bus_log_parse_error(r);
3909 case SD_BUS_TYPE_STRUCT_BEGIN:
3911 if (streq(name, "LoadError")) {
3912 const char *n, *message;
3914 r = sd_bus_message_read(m, "(ss)", &n, &message);
3916 return bus_log_parse_error(r);
3918 if (!isempty(message))
3919 i->load_error = message;
3932 r = sd_bus_message_skip(m, contents);
3934 return bus_log_parse_error(r);
3939 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3945 /* This is a low-level property printer, see
3946 * print_status_info() for the nicer output */
3948 if (arg_properties && !strv_find(arg_properties, name)) {
3949 /* skip what we didn't read */
3950 r = sd_bus_message_skip(m, contents);
3954 switch (contents[0]) {
3956 case SD_BUS_TYPE_STRUCT_BEGIN:
3958 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3961 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3963 return bus_log_parse_error(r);
3966 printf("%s=%"PRIu32"\n", name, u);
3968 printf("%s=\n", name);
3972 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3975 r = sd_bus_message_read(m, "(so)", &s, NULL);
3977 return bus_log_parse_error(r);
3979 if (arg_all || !isempty(s))
3980 printf("%s=%s\n", name, s);
3984 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3985 const char *a = NULL, *b = NULL;
3987 r = sd_bus_message_read(m, "(ss)", &a, &b);
3989 return bus_log_parse_error(r);
3991 if (arg_all || !isempty(a) || !isempty(b))
3992 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3995 } else if (streq_ptr(name, "SystemCallFilter")) {
3996 _cleanup_strv_free_ char **l = NULL;
3999 r = sd_bus_message_enter_container(m, 'r', "bas");
4001 return bus_log_parse_error(r);
4003 r = sd_bus_message_read(m, "b", &whitelist);
4005 return bus_log_parse_error(r);
4007 r = sd_bus_message_read_strv(m, &l);
4009 return bus_log_parse_error(r);
4011 r = sd_bus_message_exit_container(m);
4013 return bus_log_parse_error(r);
4015 if (arg_all || whitelist || !strv_isempty(l)) {
4019 fputs(name, stdout);
4025 STRV_FOREACH(i, l) {
4033 fputc('\n', stdout);
4041 case SD_BUS_TYPE_ARRAY:
4043 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4047 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4049 return bus_log_parse_error(r);
4051 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4052 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4055 return bus_log_parse_error(r);
4057 r = sd_bus_message_exit_container(m);
4059 return bus_log_parse_error(r);
4063 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4064 const char *type, *path;
4066 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4068 return bus_log_parse_error(r);
4070 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4071 printf("%s=%s\n", type, path);
4073 return bus_log_parse_error(r);
4075 r = sd_bus_message_exit_container(m);
4077 return bus_log_parse_error(r);
4081 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4082 const char *type, *path;
4084 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4086 return bus_log_parse_error(r);
4088 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4089 printf("Listen%s=%s\n", type, path);
4091 return bus_log_parse_error(r);
4093 r = sd_bus_message_exit_container(m);
4095 return bus_log_parse_error(r);
4099 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4101 uint64_t value, next_elapse;
4103 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4105 return bus_log_parse_error(r);
4107 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4108 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4110 printf("%s={ value=%s ; next_elapse=%s }\n",
4112 format_timespan(timespan1, sizeof(timespan1), value, 0),
4113 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4116 return bus_log_parse_error(r);
4118 r = sd_bus_message_exit_container(m);
4120 return bus_log_parse_error(r);
4124 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4125 ExecStatusInfo info = {};
4127 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4129 return bus_log_parse_error(r);
4131 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4132 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4133 _cleanup_free_ char *tt;
4135 tt = strv_join(info.argv, " ");
4137 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",
4141 yes_no(info.ignore),
4142 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4143 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4145 sigchld_code_to_string(info.code),
4147 info.code == CLD_EXITED ? "" : "/",
4148 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4151 strv_free(info.argv);
4155 r = sd_bus_message_exit_container(m);
4157 return bus_log_parse_error(r);
4161 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4162 const char *path, *rwm;
4164 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4166 return bus_log_parse_error(r);
4168 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4169 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4171 return bus_log_parse_error(r);
4173 r = sd_bus_message_exit_container(m);
4175 return bus_log_parse_error(r);
4179 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4183 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4185 return bus_log_parse_error(r);
4187 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4188 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4190 return bus_log_parse_error(r);
4192 r = sd_bus_message_exit_container(m);
4194 return bus_log_parse_error(r);
4198 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4202 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4204 return bus_log_parse_error(r);
4206 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4207 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4209 return bus_log_parse_error(r);
4211 r = sd_bus_message_exit_container(m);
4213 return bus_log_parse_error(r);
4221 r = bus_print_property(name, m, arg_all);
4223 return bus_log_parse_error(r);
4226 r = sd_bus_message_skip(m, contents);
4228 return bus_log_parse_error(r);
4231 printf("%s=[unprintable]\n", name);
4237 static int show_one(
4241 bool show_properties,
4245 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4246 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4247 UnitStatusInfo info = {};
4254 log_debug("Showing one %s", path);
4256 r = sd_bus_call_method(
4258 "org.freedesktop.systemd1",
4260 "org.freedesktop.DBus.Properties",
4266 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4270 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4272 return bus_log_parse_error(r);
4279 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4280 const char *name, *contents;
4282 r = sd_bus_message_read(reply, "s", &name);
4284 return bus_log_parse_error(r);
4286 r = sd_bus_message_peek_type(reply, NULL, &contents);
4288 return bus_log_parse_error(r);
4290 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4292 return bus_log_parse_error(r);
4294 if (show_properties)
4295 r = print_property(name, reply, contents);
4297 r = status_property(name, reply, &info, contents);
4301 r = sd_bus_message_exit_container(reply);
4303 return bus_log_parse_error(r);
4305 r = sd_bus_message_exit_container(reply);
4307 return bus_log_parse_error(r);
4310 return bus_log_parse_error(r);
4312 r = sd_bus_message_exit_container(reply);
4314 return bus_log_parse_error(r);
4318 if (!show_properties) {
4319 if (streq(verb, "help"))
4320 show_unit_help(&info);
4322 print_status_info(&info, ellipsized);
4325 strv_free(info.documentation);
4326 strv_free(info.dropin_paths);
4327 strv_free(info.listen);
4329 if (!streq_ptr(info.active_state, "active") &&
4330 !streq_ptr(info.active_state, "reloading") &&
4331 streq(verb, "status")) {
4332 /* According to LSB: "program not running" */
4333 /* 0: program is running or service is OK
4334 * 1: program is dead and /run PID file exists
4335 * 2: program is dead and /run/lock lock file exists
4336 * 3: program is not running
4337 * 4: program or service status is unknown
4339 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4345 while ((p = info.exec)) {
4346 LIST_REMOVE(exec, info.exec, p);
4347 exec_status_info_free(p);
4353 static int get_unit_dbus_path_by_pid(
4358 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4359 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4363 r = sd_bus_call_method(
4365 "org.freedesktop.systemd1",
4366 "/org/freedesktop/systemd1",
4367 "org.freedesktop.systemd1.Manager",
4373 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4377 r = sd_bus_message_read(reply, "o", &u);
4379 return bus_log_parse_error(r);
4389 static int show_all(
4392 bool show_properties,
4396 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4397 _cleanup_free_ UnitInfo *unit_infos = NULL;
4402 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4406 pager_open_if_enabled();
4410 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4412 for (u = unit_infos; u < unit_infos + c; u++) {
4413 _cleanup_free_ char *p = NULL;
4415 p = unit_dbus_path_from_name(u->id);
4419 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4422 else if (r > 0 && ret == 0)
4429 static int show_system_status(sd_bus *bus) {
4430 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4431 _cleanup_free_ char *hn = NULL;
4432 struct machine_info mi = {};
4433 const char *on, *off;
4436 hn = gethostname_malloc();
4440 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4442 log_error_errno(-r, "Failed to read server status: %m");
4446 if (streq_ptr(mi.state, "degraded")) {
4447 on = ansi_highlight_red();
4448 off = ansi_highlight_off();
4449 } else if (!streq_ptr(mi.state, "running")) {
4450 on = ansi_highlight_yellow();
4451 off = ansi_highlight_off();
4455 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4457 printf(" State: %s%s%s\n",
4458 on, strna(mi.state), off);
4460 printf(" Jobs: %u queued\n", mi.n_jobs);
4461 printf(" Failed: %u units\n", mi.n_failed_units);
4463 printf(" Since: %s; %s\n",
4464 format_timestamp(since2, sizeof(since2), mi.timestamp),
4465 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4467 printf(" CGroup: %s\n", mi.control_group ?: "/");
4468 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4470 arg_all * OUTPUT_SHOW_ALL |
4471 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4472 on_tty() * OUTPUT_COLOR |
4473 !arg_quiet * OUTPUT_WARN_CUTOFF |
4474 arg_full * OUTPUT_FULL_WIDTH;
4476 static const char prefix[] = " ";
4480 if (c > sizeof(prefix) - 1)
4481 c -= sizeof(prefix) - 1;
4485 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4489 free(mi.control_group);
4494 static int show(sd_bus *bus, char **args) {
4495 bool show_properties, show_status, new_line = false;
4496 bool ellipsized = false;
4502 show_properties = streq(args[0], "show");
4503 show_status = streq(args[0], "status");
4505 if (show_properties)
4506 pager_open_if_enabled();
4508 /* If no argument is specified inspect the manager itself */
4510 if (show_properties && strv_length(args) <= 1)
4511 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4513 if (show_status && strv_length(args) <= 1) {
4515 pager_open_if_enabled();
4516 show_system_status(bus);
4520 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4522 _cleanup_free_ char **patterns = NULL;
4525 STRV_FOREACH(name, args + 1) {
4526 _cleanup_free_ char *unit = NULL;
4529 if (safe_atou32(*name, &id) < 0) {
4530 if (strv_push(&patterns, *name) < 0)
4534 } else if (show_properties) {
4535 /* Interpret as job id */
4536 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4540 /* Interpret as PID */
4541 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4548 r = show_one(args[0], bus, unit, show_properties,
4549 &new_line, &ellipsized);
4552 else if (r > 0 && ret == 0)
4556 if (!strv_isempty(patterns)) {
4557 _cleanup_strv_free_ char **names = NULL;
4559 r = expand_names(bus, patterns, NULL, &names);
4561 log_error_errno(-r, "Failed to expand names: %m");
4563 STRV_FOREACH(name, names) {
4564 _cleanup_free_ char *unit;
4566 unit = unit_dbus_path_from_name(*name);
4570 r = show_one(args[0], bus, unit, show_properties,
4571 &new_line, &ellipsized);
4574 else if (r > 0 && ret == 0)
4580 if (ellipsized && !arg_quiet)
4581 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4586 static int cat(sd_bus *bus, char **args) {
4587 _cleanup_strv_free_ char **names = NULL;
4595 r = expand_names(bus, args + 1, NULL, &names);
4597 log_error_errno(-r, "Failed to expand names: %m");
4599 pager_open_if_enabled();
4601 STRV_FOREACH(name, names) {
4602 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4603 _cleanup_strv_free_ char **dropin_paths = NULL;
4604 _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
4607 unit = unit_dbus_path_from_name(*name);
4611 if (need_daemon_reload(bus, *name) > 0)
4612 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4613 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4615 r = sd_bus_get_property_string(
4617 "org.freedesktop.systemd1",
4619 "org.freedesktop.systemd1.Unit",
4624 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4628 r = sd_bus_get_property_strv(
4630 "org.freedesktop.systemd1",
4632 "org.freedesktop.systemd1.Unit",
4637 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4646 if (!isempty(fragment_path)) {
4647 printf("%s# %s%s\n",
4648 ansi_highlight_blue(),
4650 ansi_highlight_off());
4653 r = copy_file_fd(fragment_path, STDOUT_FILENO);
4655 log_warning_errno(-r, "Failed to cat %s: %m", fragment_path);
4660 STRV_FOREACH(path, dropin_paths) {
4661 printf("%s%s# %s%s\n",
4662 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4663 ansi_highlight_blue(),
4665 ansi_highlight_off());
4668 r = copy_file_fd(*path, STDOUT_FILENO);
4670 log_warning_errno(-r, "Failed to cat %s: %m", *path);
4676 return r < 0 ? r : 0;
4679 static int set_property(sd_bus *bus, char **args) {
4680 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4681 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4682 _cleanup_free_ char *n = NULL;
4686 r = sd_bus_message_new_method_call(
4689 "org.freedesktop.systemd1",
4690 "/org/freedesktop/systemd1",
4691 "org.freedesktop.systemd1.Manager",
4692 "SetUnitProperties");
4694 return bus_log_create_error(r);
4696 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4698 return bus_log_create_error(r);
4700 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4704 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4706 return bus_log_create_error(r);
4708 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4710 return bus_log_create_error(r);
4712 STRV_FOREACH(i, args + 2) {
4713 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4715 return bus_log_create_error(r);
4717 r = bus_append_unit_property_assignment(m, *i);
4721 r = sd_bus_message_close_container(m);
4723 return bus_log_create_error(r);
4726 r = sd_bus_message_close_container(m);
4728 return bus_log_create_error(r);
4730 r = sd_bus_call(bus, m, 0, &error, NULL);
4732 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4739 static int snapshot(sd_bus *bus, char **args) {
4740 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4741 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4742 _cleanup_free_ char *n = NULL, *id = NULL;
4746 if (strv_length(args) > 1)
4747 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4753 r = sd_bus_message_new_method_call(
4756 "org.freedesktop.systemd1",
4757 "/org/freedesktop/systemd1",
4758 "org.freedesktop.systemd1.Manager",
4761 return bus_log_create_error(r);
4763 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4765 return bus_log_create_error(r);
4767 r = sd_bus_message_append(m, "sb", n, false);
4769 return bus_log_create_error(r);
4771 r = sd_bus_call(bus, m, 0, &error, &reply);
4773 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4777 r = sd_bus_message_read(reply, "o", &path);
4779 return bus_log_parse_error(r);
4781 r = sd_bus_get_property_string(
4783 "org.freedesktop.systemd1",
4785 "org.freedesktop.systemd1.Unit",
4790 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4800 static int delete_snapshot(sd_bus *bus, char **args) {
4801 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4802 _cleanup_strv_free_ char **names = NULL;
4808 r = expand_names(bus, args + 1, ".snapshot", &names);
4810 log_error_errno(-r, "Failed to expand names: %m");
4812 STRV_FOREACH(name, names) {
4813 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4816 q = sd_bus_message_new_method_call(
4819 "org.freedesktop.systemd1",
4820 "/org/freedesktop/systemd1",
4821 "org.freedesktop.systemd1.Manager",
4824 return bus_log_create_error(q);
4826 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4828 return bus_log_create_error(q);
4830 q = sd_bus_message_append(m, "s", *name);
4832 return bus_log_create_error(q);
4834 q = sd_bus_call(bus, m, 0, &error, NULL);
4836 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4845 static int daemon_reload(sd_bus *bus, char **args) {
4846 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4847 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4851 if (arg_action == ACTION_RELOAD)
4853 else if (arg_action == ACTION_REEXEC)
4854 method = "Reexecute";
4856 assert(arg_action == ACTION_SYSTEMCTL);
4859 streq(args[0], "clear-jobs") ||
4860 streq(args[0], "cancel") ? "ClearJobs" :
4861 streq(args[0], "daemon-reexec") ? "Reexecute" :
4862 streq(args[0], "reset-failed") ? "ResetFailed" :
4863 streq(args[0], "halt") ? "Halt" :
4864 streq(args[0], "poweroff") ? "PowerOff" :
4865 streq(args[0], "reboot") ? "Reboot" :
4866 streq(args[0], "kexec") ? "KExec" :
4867 streq(args[0], "exit") ? "Exit" :
4868 /* "daemon-reload" */ "Reload";
4871 r = sd_bus_message_new_method_call(
4874 "org.freedesktop.systemd1",
4875 "/org/freedesktop/systemd1",
4876 "org.freedesktop.systemd1.Manager",
4879 return bus_log_create_error(r);
4881 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4883 return bus_log_create_error(r);
4885 r = sd_bus_call(bus, m, 0, &error, NULL);
4886 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4887 /* There's always a fallback possible for
4888 * legacy actions. */
4890 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4891 /* On reexecution, we expect a disconnect, not a
4895 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4897 return r < 0 ? r : 0;
4900 static int reset_failed(sd_bus *bus, char **args) {
4901 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4902 _cleanup_strv_free_ char **names = NULL;
4906 if (strv_length(args) <= 1)
4907 return daemon_reload(bus, args);
4909 r = expand_names(bus, args + 1, NULL, &names);
4911 log_error_errno(-r, "Failed to expand names: %m");
4913 STRV_FOREACH(name, names) {
4914 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4916 q = sd_bus_message_new_method_call(
4919 "org.freedesktop.systemd1",
4920 "/org/freedesktop/systemd1",
4921 "org.freedesktop.systemd1.Manager",
4924 return bus_log_create_error(q);
4926 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4928 return bus_log_create_error(q);
4930 q = sd_bus_message_append(m, "s", *name);
4932 return bus_log_create_error(q);
4934 q = sd_bus_call(bus, m, 0, &error, NULL);
4936 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4945 static int show_environment(sd_bus *bus, char **args) {
4946 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4947 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4951 pager_open_if_enabled();
4953 r = sd_bus_get_property(
4955 "org.freedesktop.systemd1",
4956 "/org/freedesktop/systemd1",
4957 "org.freedesktop.systemd1.Manager",
4963 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4967 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4969 return bus_log_parse_error(r);
4971 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4974 return bus_log_parse_error(r);
4976 r = sd_bus_message_exit_container(reply);
4978 return bus_log_parse_error(r);
4983 static int switch_root(sd_bus *bus, char **args) {
4984 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4985 _cleanup_free_ char *cmdline_init = NULL;
4986 const char *root, *init;
4990 l = strv_length(args);
4991 if (l < 2 || l > 3) {
4992 log_error("Wrong number of arguments.");
5001 r = parse_env_file("/proc/cmdline", WHITESPACE,
5002 "init", &cmdline_init,
5005 log_debug_errno(-r, "Failed to parse /proc/cmdline: %m");
5007 init = cmdline_init;
5014 const char *root_systemd_path = NULL, *root_init_path = NULL;
5016 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
5017 root_init_path = strappenda(root, "/", init);
5019 /* If the passed init is actually the same as the
5020 * systemd binary, then let's suppress it. */
5021 if (files_same(root_init_path, root_systemd_path) > 0)
5025 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5027 r = sd_bus_call_method(
5029 "org.freedesktop.systemd1",
5030 "/org/freedesktop/systemd1",
5031 "org.freedesktop.systemd1.Manager",
5037 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5044 static int set_environment(sd_bus *bus, char **args) {
5045 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5046 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5053 method = streq(args[0], "set-environment")
5055 : "UnsetEnvironment";
5057 r = sd_bus_message_new_method_call(
5060 "org.freedesktop.systemd1",
5061 "/org/freedesktop/systemd1",
5062 "org.freedesktop.systemd1.Manager",
5065 return bus_log_create_error(r);
5067 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5069 return bus_log_create_error(r);
5071 r = sd_bus_message_append_strv(m, args + 1);
5073 return bus_log_create_error(r);
5075 r = sd_bus_call(bus, m, 0, &error, NULL);
5077 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5084 static int import_environment(sd_bus *bus, char **args) {
5085 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5086 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5092 r = sd_bus_message_new_method_call(
5095 "org.freedesktop.systemd1",
5096 "/org/freedesktop/systemd1",
5097 "org.freedesktop.systemd1.Manager",
5100 return bus_log_create_error(r);
5102 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5104 return bus_log_create_error(r);
5106 if (strv_isempty(args + 1))
5107 r = sd_bus_message_append_strv(m, environ);
5111 r = sd_bus_message_open_container(m, 'a', "s");
5113 return bus_log_create_error(r);
5115 STRV_FOREACH(a, args + 1) {
5117 if (!env_name_is_valid(*a)) {
5118 log_error("Not a valid environment variable name: %s", *a);
5122 STRV_FOREACH(b, environ) {
5125 eq = startswith(*b, *a);
5126 if (eq && *eq == '=') {
5128 r = sd_bus_message_append(m, "s", *b);
5130 return bus_log_create_error(r);
5137 r = sd_bus_message_close_container(m);
5140 return bus_log_create_error(r);
5142 r = sd_bus_call(bus, m, 0, &error, NULL);
5144 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5151 static int enable_sysv_units(const char *verb, char **args) {
5154 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5155 unsigned f = 1, t = 1;
5156 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5158 if (arg_scope != UNIT_FILE_SYSTEM)
5161 if (!streq(verb, "enable") &&
5162 !streq(verb, "disable") &&
5163 !streq(verb, "is-enabled"))
5166 /* Processes all SysV units, and reshuffles the array so that
5167 * afterwards only the native units remain */
5169 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5174 for (f = 0; args[f]; f++) {
5176 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5177 bool found_native = false, found_sysv;
5179 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5187 if (!endswith(name, ".service"))
5190 if (path_is_absolute(name))
5193 STRV_FOREACH(k, paths.unit_path) {
5194 _cleanup_free_ char *path = NULL;
5196 path = path_join(arg_root, *k, name);
5200 found_native = access(path, F_OK) >= 0;
5208 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5212 p[strlen(p) - strlen(".service")] = 0;
5213 found_sysv = access(p, F_OK) >= 0;
5217 /* Mark this entry, so that we don't try enabling it as native unit */
5218 args[f] = (char*) "";
5220 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5222 if (!isempty(arg_root))
5223 argv[c++] = q = strappend("--root=", arg_root);
5225 argv[c++] = basename(p);
5227 streq(verb, "enable") ? "on" :
5228 streq(verb, "disable") ? "off" : "--level=5";
5231 l = strv_join((char**)argv, " ");
5235 log_info("Executing %s", l);
5239 log_error("Failed to fork: %m");
5241 } else if (pid == 0) {
5244 execv(argv[0], (char**) argv);
5245 _exit(EXIT_FAILURE);
5248 j = wait_for_terminate(pid, &status);
5250 log_error_errno(-r, "Failed to wait for child: %m");
5254 if (status.si_code == CLD_EXITED) {
5255 if (streq(verb, "is-enabled")) {
5256 if (status.si_status == 0) {
5265 } else if (status.si_status != 0)
5271 /* Drop all SysV units */
5272 for (f = 0, t = 0; args[f]; f++) {
5274 if (isempty(args[f]))
5277 args[t++] = args[f];
5286 static int mangle_names(char **original_names, char ***mangled_names) {
5287 char **i, **l, **name;
5289 l = new(char*, strv_length(original_names) + 1);
5294 STRV_FOREACH(name, original_names) {
5296 /* When enabling units qualified path names are OK,
5297 * too, hence allow them explicitly. */
5302 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5318 static int enable_unit(sd_bus *bus, char **args) {
5319 _cleanup_strv_free_ char **names = NULL;
5320 const char *verb = args[0];
5321 UnitFileChange *changes = NULL;
5322 unsigned n_changes = 0;
5323 int carries_install_info = -1;
5329 r = mangle_names(args+1, &names);
5333 r = enable_sysv_units(verb, names);
5337 /* If the operation was fully executed by the SysV compat,
5338 * let's finish early */
5339 if (strv_isempty(names))
5342 if (!bus || avoid_bus()) {
5343 if (streq(verb, "enable")) {
5344 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5345 carries_install_info = r;
5346 } else if (streq(verb, "disable"))
5347 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5348 else if (streq(verb, "reenable")) {
5349 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5350 carries_install_info = r;
5351 } else if (streq(verb, "link"))
5352 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5353 else if (streq(verb, "preset")) {
5354 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5355 carries_install_info = r;
5356 } else if (streq(verb, "mask"))
5357 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5358 else if (streq(verb, "unmask"))
5359 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5361 assert_not_reached("Unknown verb");
5364 log_error_errno(-r, "Operation failed: %m");
5369 dump_unit_file_changes(changes, n_changes);
5373 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5374 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5375 int expect_carries_install_info = false;
5376 bool send_force = true, send_preset_mode = false;
5379 if (streq(verb, "enable")) {
5380 method = "EnableUnitFiles";
5381 expect_carries_install_info = true;
5382 } else if (streq(verb, "disable")) {
5383 method = "DisableUnitFiles";
5385 } else if (streq(verb, "reenable")) {
5386 method = "ReenableUnitFiles";
5387 expect_carries_install_info = true;
5388 } else if (streq(verb, "link"))
5389 method = "LinkUnitFiles";
5390 else if (streq(verb, "preset")) {
5392 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5393 method = "PresetUnitFilesWithMode";
5394 send_preset_mode = true;
5396 method = "PresetUnitFiles";
5398 expect_carries_install_info = true;
5399 } else if (streq(verb, "mask"))
5400 method = "MaskUnitFiles";
5401 else if (streq(verb, "unmask")) {
5402 method = "UnmaskUnitFiles";
5405 assert_not_reached("Unknown verb");
5407 r = sd_bus_message_new_method_call(
5410 "org.freedesktop.systemd1",
5411 "/org/freedesktop/systemd1",
5412 "org.freedesktop.systemd1.Manager",
5415 return bus_log_create_error(r);
5417 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5419 return bus_log_create_error(r);
5421 r = sd_bus_message_append_strv(m, names);
5423 return bus_log_create_error(r);
5425 if (send_preset_mode) {
5426 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5428 return bus_log_create_error(r);
5431 r = sd_bus_message_append(m, "b", arg_runtime);
5433 return bus_log_create_error(r);
5436 r = sd_bus_message_append(m, "b", arg_force);
5438 return bus_log_create_error(r);
5441 r = sd_bus_call(bus, m, 0, &error, &reply);
5443 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5447 if (expect_carries_install_info) {
5448 r = sd_bus_message_read(reply, "b", &carries_install_info);
5450 return bus_log_parse_error(r);
5453 r = deserialize_and_dump_unit_file_changes(reply);
5457 /* Try to reload if enabled */
5459 r = daemon_reload(bus, args);
5464 if (carries_install_info == 0)
5465 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5466 "using systemctl.\n"
5467 "Possible reasons for having this kind of units are:\n"
5468 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5469 " .wants/ or .requires/ directory.\n"
5470 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5471 " a requirement dependency on it.\n"
5472 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5473 " D-Bus, udev, scripted systemctl call, ...).\n");
5476 unit_file_changes_free(changes, n_changes);
5481 static int add_dependency(sd_bus *bus, char **args) {
5482 _cleanup_strv_free_ char **names = NULL;
5483 _cleanup_free_ char *target = NULL;
5484 const char *verb = args[0];
5491 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5495 r = mangle_names(args+2, &names);
5499 if (streq(verb, "add-wants"))
5501 else if (streq(verb, "add-requires"))
5502 dep = UNIT_REQUIRES;
5504 assert_not_reached("Unknown verb");
5506 if (!bus || avoid_bus()) {
5507 UnitFileChange *changes = NULL;
5508 unsigned n_changes = 0;
5510 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5513 log_error_errno(-r, "Can't add dependency: %m");
5518 dump_unit_file_changes(changes, n_changes);
5520 unit_file_changes_free(changes, n_changes);
5523 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5524 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5526 r = sd_bus_message_new_method_call(
5529 "org.freedesktop.systemd1",
5530 "/org/freedesktop/systemd1",
5531 "org.freedesktop.systemd1.Manager",
5532 "AddDependencyUnitFiles");
5534 return bus_log_create_error(r);
5536 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5538 return bus_log_create_error(r);
5540 r = sd_bus_message_append_strv(m, names);
5542 return bus_log_create_error(r);
5544 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5546 return bus_log_create_error(r);
5548 r = sd_bus_call(bus, m, 0, &error, &reply);
5550 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5554 r = deserialize_and_dump_unit_file_changes(reply);
5559 r = daemon_reload(bus, args);
5567 static int preset_all(sd_bus *bus, char **args) {
5568 UnitFileChange *changes = NULL;
5569 unsigned n_changes = 0;
5572 if (!bus || avoid_bus()) {
5574 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5576 log_error_errno(-r, "Operation failed: %m");
5581 dump_unit_file_changes(changes, n_changes);
5586 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5587 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5589 r = sd_bus_message_new_method_call(
5592 "org.freedesktop.systemd1",
5593 "/org/freedesktop/systemd1",
5594 "org.freedesktop.systemd1.Manager",
5595 "PresetAllUnitFiles");
5597 return bus_log_create_error(r);
5599 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5601 return bus_log_create_error(r);
5603 r = sd_bus_message_append(
5606 unit_file_preset_mode_to_string(arg_preset_mode),
5610 return bus_log_create_error(r);
5612 r = sd_bus_call(bus, m, 0, &error, &reply);
5614 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5618 r = deserialize_and_dump_unit_file_changes(reply);
5623 r = daemon_reload(bus, args);
5629 unit_file_changes_free(changes, n_changes);
5634 static int unit_is_enabled(sd_bus *bus, char **args) {
5636 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5637 _cleanup_strv_free_ char **names = NULL;
5642 r = mangle_names(args+1, &names);
5646 r = enable_sysv_units(args[0], names);
5652 if (!bus || avoid_bus()) {
5654 STRV_FOREACH(name, names) {
5655 UnitFileState state;
5657 state = unit_file_get_state(arg_scope, arg_root, *name);
5659 log_error_errno(-state, "Failed to get unit file state for %s: %m", *name);
5663 if (state == UNIT_FILE_ENABLED ||
5664 state == UNIT_FILE_ENABLED_RUNTIME ||
5665 state == UNIT_FILE_STATIC ||
5666 state == UNIT_FILE_INDIRECT)
5670 puts(unit_file_state_to_string(state));
5674 STRV_FOREACH(name, names) {
5675 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5678 r = sd_bus_call_method(
5680 "org.freedesktop.systemd1",
5681 "/org/freedesktop/systemd1",
5682 "org.freedesktop.systemd1.Manager",
5688 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5692 r = sd_bus_message_read(reply, "s", &s);
5694 return bus_log_parse_error(r);
5696 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5707 static int is_system_running(sd_bus *bus, char **args) {
5708 _cleanup_free_ char *state = NULL;
5711 r = sd_bus_get_property_string(
5713 "org.freedesktop.systemd1",
5714 "/org/freedesktop/systemd1",
5715 "org.freedesktop.systemd1.Manager",
5728 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5731 static void systemctl_help(void) {
5733 pager_open_if_enabled();
5735 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5736 "Query or send control commands to the systemd manager.\n\n"
5737 " -h --help Show this help\n"
5738 " --version Show package version\n"
5739 " --system Connect to system manager\n"
5740 " --user Connect to user service manager\n"
5741 " -H --host=[USER@]HOST\n"
5742 " Operate on remote host\n"
5743 " -M --machine=CONTAINER\n"
5744 " Operate on local container\n"
5745 " -t --type=TYPE List only units of a particular type\n"
5746 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5747 " -p --property=NAME Show only properties by this name\n"
5748 " -a --all Show all loaded units/properties, including dead/empty\n"
5749 " ones. To list all units installed on the system, use\n"
5750 " the 'list-unit-files' command instead.\n"
5751 " -l --full Don't ellipsize unit names on output\n"
5752 " -r --recursive Show unit list of host and local containers\n"
5753 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5754 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5755 " queueing a new job\n"
5756 " --show-types When showing sockets, explicitly show their type\n"
5757 " -i --ignore-inhibitors\n"
5758 " When shutting down or sleeping, ignore inhibitors\n"
5759 " --kill-who=WHO Who to send signal to\n"
5760 " -s --signal=SIGNAL Which signal to send\n"
5761 " -q --quiet Suppress output\n"
5762 " --no-block Do not wait until operation finished\n"
5763 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5764 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5766 " --no-legend Do not print a legend (column headers and hints)\n"
5767 " --no-pager Do not pipe output into a pager\n"
5768 " --no-ask-password\n"
5769 " Do not ask for system passwords\n"
5770 " --global Enable/disable unit files globally\n"
5771 " --runtime Enable unit files only temporarily until next reboot\n"
5772 " -f --force When enabling unit files, override existing symlinks\n"
5773 " When shutting down, execute action immediately\n"
5774 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
5775 " or only disable\n"
5776 " --root=PATH Enable unit files in the specified root directory\n"
5777 " -n --lines=INTEGER Number of journal entries to show\n"
5778 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5779 " verbose, export, json, json-pretty, json-sse, cat)\n"
5780 " --plain Print unit dependencies as a list instead of a tree\n\n"
5782 " list-units [PATTERN...] List loaded units\n"
5783 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5784 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5785 " start NAME... Start (activate) one or more units\n"
5786 " stop NAME... Stop (deactivate) one or more units\n"
5787 " reload NAME... Reload one or more units\n"
5788 " restart NAME... Start or restart one or more units\n"
5789 " try-restart NAME... Restart one or more units if active\n"
5790 " reload-or-restart NAME... Reload one or more units if possible,\n"
5791 " otherwise start or restart\n"
5792 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5793 " otherwise restart if active\n"
5794 " isolate NAME Start one unit and stop all others\n"
5795 " kill NAME... Send signal to processes of a unit\n"
5796 " is-active PATTERN... Check whether units are active\n"
5797 " is-failed PATTERN... Check whether units are failed\n"
5798 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5799 " show [PATTERN...|JOB...] Show properties of one or more\n"
5800 " units/jobs or the manager\n"
5801 " cat PATTERN... Show files and drop-ins of one or more units\n"
5802 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5803 " help PATTERN...|PID... Show manual for one or more units\n"
5804 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5806 " list-dependencies [NAME] Recursively show units which are required\n"
5807 " or wanted by this unit or by which this\n"
5808 " unit is required or wanted\n\n"
5809 "Unit File Commands:\n"
5810 " list-unit-files [PATTERN...] List installed unit files\n"
5811 " enable NAME... Enable one or more unit files\n"
5812 " disable NAME... Disable one or more unit files\n"
5813 " reenable NAME... Reenable one or more unit files\n"
5814 " preset NAME... Enable/disable one or more unit files\n"
5815 " based on preset configuration\n"
5816 " preset-all Enable/disable all unit files based on\n"
5817 " preset configuration\n"
5818 " is-enabled NAME... Check whether unit files are enabled\n\n"
5819 " mask NAME... Mask one or more units\n"
5820 " unmask NAME... Unmask one or more units\n"
5821 " link PATH... Link one or more units files into\n"
5822 " the search path\n"
5823 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
5824 " on specified one or more units\n"
5825 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
5826 " on specified one or more units\n"
5827 " get-default Get the name of the default target\n"
5828 " set-default NAME Set the default target\n\n"
5829 "Machine Commands:\n"
5830 " list-machines [PATTERN...] List local containers and host\n\n"
5832 " list-jobs [PATTERN...] List jobs\n"
5833 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5834 "Snapshot Commands:\n"
5835 " snapshot [NAME] Create a snapshot\n"
5836 " delete NAME... Remove one or more snapshots\n\n"
5837 "Environment Commands:\n"
5838 " show-environment Dump environment\n"
5839 " set-environment NAME=VALUE... Set one or more environment variables\n"
5840 " unset-environment NAME... Unset one or more environment variables\n"
5841 " import-environment NAME... Import all, one or more environment variables\n\n"
5842 "Manager Lifecycle Commands:\n"
5843 " daemon-reload Reload systemd manager configuration\n"
5844 " daemon-reexec Reexecute systemd manager\n\n"
5845 "System Commands:\n"
5846 " is-system-running Check whether system is fully running\n"
5847 " default Enter system default mode\n"
5848 " rescue Enter system rescue mode\n"
5849 " emergency Enter system emergency mode\n"
5850 " halt Shut down and halt the system\n"
5851 " poweroff Shut down and power-off the system\n"
5852 " reboot [ARG] Shut down and reboot the system\n"
5853 " kexec Shut down and reboot the system with kexec\n"
5854 " exit Request user instance exit\n"
5855 " switch-root ROOT [INIT] Change to a different root file system\n"
5856 " suspend Suspend the system\n"
5857 " hibernate Hibernate the system\n"
5858 " hybrid-sleep Hibernate and suspend the system\n",
5859 program_invocation_short_name);
5862 static void halt_help(void) {
5863 printf("%s [OPTIONS...]%s\n\n"
5864 "%s the system.\n\n"
5865 " --help Show this help\n"
5866 " --halt Halt the machine\n"
5867 " -p --poweroff Switch off the machine\n"
5868 " --reboot Reboot the machine\n"
5869 " -f --force Force immediate halt/power-off/reboot\n"
5870 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5871 " -d --no-wtmp Don't write wtmp record\n"
5872 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5873 program_invocation_short_name,
5874 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5875 arg_action == ACTION_REBOOT ? "Reboot" :
5876 arg_action == ACTION_POWEROFF ? "Power off" :
5880 static void shutdown_help(void) {
5881 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5882 "Shut down the system.\n\n"
5883 " --help Show this help\n"
5884 " -H --halt Halt the machine\n"
5885 " -P --poweroff Power-off the machine\n"
5886 " -r --reboot Reboot the machine\n"
5887 " -h Equivalent to --poweroff, overridden by --halt\n"
5888 " -k Don't halt/power-off/reboot, just send warnings\n"
5889 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5890 " -c Cancel a pending shutdown\n",
5891 program_invocation_short_name);
5894 static void telinit_help(void) {
5895 printf("%s [OPTIONS...] {COMMAND}\n\n"
5896 "Send control commands to the init daemon.\n\n"
5897 " --help Show this help\n"
5898 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5900 " 0 Power-off the machine\n"
5901 " 6 Reboot the machine\n"
5902 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5903 " 1, s, S Enter rescue mode\n"
5904 " q, Q Reload init daemon configuration\n"
5905 " u, U Reexecute init daemon\n",
5906 program_invocation_short_name);
5909 static void runlevel_help(void) {
5910 printf("%s [OPTIONS...]\n\n"
5911 "Prints the previous and current runlevel of the init system.\n\n"
5912 " --help Show this help\n",
5913 program_invocation_short_name);
5916 static void help_types(void) {
5921 puts("Available unit types:");
5922 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5923 t = unit_type_to_string(i);
5929 static int systemctl_parse_argv(int argc, char *argv[]) {
5938 ARG_IGNORE_DEPENDENCIES,
5950 ARG_NO_ASK_PASSWORD,
5960 static const struct option options[] = {
5961 { "help", no_argument, NULL, 'h' },
5962 { "version", no_argument, NULL, ARG_VERSION },
5963 { "type", required_argument, NULL, 't' },
5964 { "property", required_argument, NULL, 'p' },
5965 { "all", no_argument, NULL, 'a' },
5966 { "reverse", no_argument, NULL, ARG_REVERSE },
5967 { "after", no_argument, NULL, ARG_AFTER },
5968 { "before", no_argument, NULL, ARG_BEFORE },
5969 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5970 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5971 { "full", no_argument, NULL, 'l' },
5972 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5973 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5974 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5975 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5976 { "ignore-inhibitors", no_argument, NULL, 'i' },
5977 { "user", no_argument, NULL, ARG_USER },
5978 { "system", no_argument, NULL, ARG_SYSTEM },
5979 { "global", no_argument, NULL, ARG_GLOBAL },
5980 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5981 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5982 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5983 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5984 { "quiet", no_argument, NULL, 'q' },
5985 { "root", required_argument, NULL, ARG_ROOT },
5986 { "force", no_argument, NULL, ARG_FORCE },
5987 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5988 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5989 { "signal", required_argument, NULL, 's' },
5990 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5991 { "host", required_argument, NULL, 'H' },
5992 { "machine", required_argument, NULL, 'M' },
5993 { "runtime", no_argument, NULL, ARG_RUNTIME },
5994 { "lines", required_argument, NULL, 'n' },
5995 { "output", required_argument, NULL, 'o' },
5996 { "plain", no_argument, NULL, ARG_PLAIN },
5997 { "state", required_argument, NULL, ARG_STATE },
5998 { "recursive", no_argument, NULL, 'r' },
5999 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6008 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6017 puts(PACKAGE_STRING);
6018 puts(SYSTEMD_FEATURES);
6022 const char *word, *state;
6025 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6026 _cleanup_free_ char *type;
6028 type = strndup(word, size);
6032 if (streq(type, "help")) {
6037 if (unit_type_from_string(type) >= 0) {
6038 if (strv_push(&arg_types, type))
6044 /* It's much nicer to use --state= for
6045 * load states, but let's support this
6046 * in --types= too for compatibility
6047 * with old versions */
6048 if (unit_load_state_from_string(optarg) >= 0) {
6049 if (strv_push(&arg_states, type) < 0)
6055 log_error("Unknown unit type or load state '%s'.", type);
6056 log_info("Use -t help to see a list of allowed values.");
6064 /* Make sure that if the empty property list
6065 was specified, we won't show any properties. */
6066 if (isempty(optarg) && !arg_properties) {
6067 arg_properties = new0(char*, 1);
6068 if (!arg_properties)
6071 const char *word, *state;
6074 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6077 prop = strndup(word, size);
6081 if (strv_consume(&arg_properties, prop) < 0)
6086 /* If the user asked for a particular
6087 * property, show it to him, even if it is
6099 arg_dependency = DEPENDENCY_REVERSE;
6103 arg_dependency = DEPENDENCY_AFTER;
6107 arg_dependency = DEPENDENCY_BEFORE;
6110 case ARG_SHOW_TYPES:
6111 arg_show_types = true;
6115 arg_job_mode = optarg;
6119 arg_job_mode = "fail";
6122 case ARG_IRREVERSIBLE:
6123 arg_job_mode = "replace-irreversibly";
6126 case ARG_IGNORE_DEPENDENCIES:
6127 arg_job_mode = "ignore-dependencies";
6131 arg_scope = UNIT_FILE_USER;
6135 arg_scope = UNIT_FILE_SYSTEM;
6139 arg_scope = UNIT_FILE_GLOBAL;
6143 arg_no_block = true;
6147 arg_no_legend = true;
6151 arg_no_pager = true;
6167 if (strv_extend(&arg_states, "failed") < 0)
6185 arg_no_reload = true;
6189 arg_kill_who = optarg;
6193 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6194 log_error("Failed to parse signal string %s.", optarg);
6199 case ARG_NO_ASK_PASSWORD:
6200 arg_ask_password = false;
6204 arg_transport = BUS_TRANSPORT_REMOTE;
6209 arg_transport = BUS_TRANSPORT_CONTAINER;
6218 if (safe_atou(optarg, &arg_lines) < 0) {
6219 log_error("Failed to parse lines '%s'", optarg);
6225 arg_output = output_mode_from_string(optarg);
6226 if (arg_output < 0) {
6227 log_error("Unknown output '%s'.", optarg);
6233 arg_ignore_inhibitors = true;
6241 const char *word, *state;
6244 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6247 s = strndup(word, size);
6251 if (strv_consume(&arg_states, s) < 0)
6258 if (geteuid() != 0) {
6259 log_error("--recursive requires root privileges.");
6263 arg_recursive = true;
6266 case ARG_PRESET_MODE:
6268 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6269 if (arg_preset_mode < 0) {
6270 log_error("Failed to parse preset mode: %s.", optarg);
6280 assert_not_reached("Unhandled option");
6283 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6284 log_error("Cannot access user instance remotely.");
6291 static int halt_parse_argv(int argc, char *argv[]) {
6300 static const struct option options[] = {
6301 { "help", no_argument, NULL, ARG_HELP },
6302 { "halt", no_argument, NULL, ARG_HALT },
6303 { "poweroff", no_argument, NULL, 'p' },
6304 { "reboot", no_argument, NULL, ARG_REBOOT },
6305 { "force", no_argument, NULL, 'f' },
6306 { "wtmp-only", no_argument, NULL, 'w' },
6307 { "no-wtmp", no_argument, NULL, 'd' },
6308 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6317 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6318 if (runlevel == '0' || runlevel == '6')
6321 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6329 arg_action = ACTION_HALT;
6333 if (arg_action != ACTION_REBOOT)
6334 arg_action = ACTION_POWEROFF;
6338 arg_action = ACTION_REBOOT;
6360 /* Compatibility nops */
6367 assert_not_reached("Unhandled option");
6370 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6371 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6374 } else if (optind < argc) {
6375 log_error("Too many arguments.");
6382 static int parse_time_spec(const char *t, usec_t *_u) {
6386 if (streq(t, "now"))
6388 else if (!strchr(t, ':')) {
6391 if (safe_atou64(t, &u) < 0)
6394 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6403 hour = strtol(t, &e, 10);
6404 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6407 minute = strtol(e+1, &e, 10);
6408 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6411 n = now(CLOCK_REALTIME);
6412 s = (time_t) (n / USEC_PER_SEC);
6414 assert_se(localtime_r(&s, &tm));
6416 tm.tm_hour = (int) hour;
6417 tm.tm_min = (int) minute;
6420 assert_se(s = mktime(&tm));
6422 *_u = (usec_t) s * USEC_PER_SEC;
6425 *_u += USEC_PER_DAY;
6431 static int shutdown_parse_argv(int argc, char *argv[]) {
6438 static const struct option options[] = {
6439 { "help", no_argument, NULL, ARG_HELP },
6440 { "halt", no_argument, NULL, 'H' },
6441 { "poweroff", no_argument, NULL, 'P' },
6442 { "reboot", no_argument, NULL, 'r' },
6443 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6444 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6453 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6461 arg_action = ACTION_HALT;
6465 arg_action = ACTION_POWEROFF;
6470 arg_action = ACTION_KEXEC;
6472 arg_action = ACTION_REBOOT;
6476 arg_action = ACTION_KEXEC;
6480 if (arg_action != ACTION_HALT)
6481 arg_action = ACTION_POWEROFF;
6494 /* Compatibility nops */
6498 arg_action = ACTION_CANCEL_SHUTDOWN;
6505 assert_not_reached("Unhandled option");
6508 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6509 r = parse_time_spec(argv[optind], &arg_when);
6511 log_error("Failed to parse time specification: %s", argv[optind]);
6515 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6517 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6518 /* No time argument for shutdown cancel */
6519 arg_wall = argv + optind;
6520 else if (argc > optind + 1)
6521 /* We skip the time argument */
6522 arg_wall = argv + optind + 1;
6529 static int telinit_parse_argv(int argc, char *argv[]) {
6536 static const struct option options[] = {
6537 { "help", no_argument, NULL, ARG_HELP },
6538 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6542 static const struct {
6546 { '0', ACTION_POWEROFF },
6547 { '6', ACTION_REBOOT },
6548 { '1', ACTION_RESCUE },
6549 { '2', ACTION_RUNLEVEL2 },
6550 { '3', ACTION_RUNLEVEL3 },
6551 { '4', ACTION_RUNLEVEL4 },
6552 { '5', ACTION_RUNLEVEL5 },
6553 { 's', ACTION_RESCUE },
6554 { 'S', ACTION_RESCUE },
6555 { 'q', ACTION_RELOAD },
6556 { 'Q', ACTION_RELOAD },
6557 { 'u', ACTION_REEXEC },
6558 { 'U', ACTION_REEXEC }
6567 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6582 assert_not_reached("Unhandled option");
6585 if (optind >= argc) {
6586 log_error("%s: required argument missing.",
6587 program_invocation_short_name);
6591 if (optind + 1 < argc) {
6592 log_error("Too many arguments.");
6596 if (strlen(argv[optind]) != 1) {
6597 log_error("Expected single character argument.");
6601 for (i = 0; i < ELEMENTSOF(table); i++)
6602 if (table[i].from == argv[optind][0])
6605 if (i >= ELEMENTSOF(table)) {
6606 log_error("Unknown command '%s'.", argv[optind]);
6610 arg_action = table[i].to;
6617 static int runlevel_parse_argv(int argc, char *argv[]) {
6623 static const struct option options[] = {
6624 { "help", no_argument, NULL, ARG_HELP },
6633 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6644 assert_not_reached("Unhandled option");
6647 if (optind < argc) {
6648 log_error("Too many arguments.");
6655 static int parse_argv(int argc, char *argv[]) {
6659 if (program_invocation_short_name) {
6661 if (strstr(program_invocation_short_name, "halt")) {
6662 arg_action = ACTION_HALT;
6663 return halt_parse_argv(argc, argv);
6664 } else if (strstr(program_invocation_short_name, "poweroff")) {
6665 arg_action = ACTION_POWEROFF;
6666 return halt_parse_argv(argc, argv);
6667 } else if (strstr(program_invocation_short_name, "reboot")) {
6669 arg_action = ACTION_KEXEC;
6671 arg_action = ACTION_REBOOT;
6672 return halt_parse_argv(argc, argv);
6673 } else if (strstr(program_invocation_short_name, "shutdown")) {
6674 arg_action = ACTION_POWEROFF;
6675 return shutdown_parse_argv(argc, argv);
6676 } else if (strstr(program_invocation_short_name, "init")) {
6678 if (sd_booted() > 0) {
6679 arg_action = _ACTION_INVALID;
6680 return telinit_parse_argv(argc, argv);
6682 /* Hmm, so some other init system is
6683 * running, we need to forward this
6684 * request to it. For now we simply
6685 * guess that it is Upstart. */
6687 execv(TELINIT, argv);
6689 log_error("Couldn't find an alternative telinit implementation to spawn.");
6693 } else if (strstr(program_invocation_short_name, "runlevel")) {
6694 arg_action = ACTION_RUNLEVEL;
6695 return runlevel_parse_argv(argc, argv);
6699 arg_action = ACTION_SYSTEMCTL;
6700 return systemctl_parse_argv(argc, argv);
6703 _pure_ static int action_to_runlevel(void) {
6705 static const char table[_ACTION_MAX] = {
6706 [ACTION_HALT] = '0',
6707 [ACTION_POWEROFF] = '0',
6708 [ACTION_REBOOT] = '6',
6709 [ACTION_RUNLEVEL2] = '2',
6710 [ACTION_RUNLEVEL3] = '3',
6711 [ACTION_RUNLEVEL4] = '4',
6712 [ACTION_RUNLEVEL5] = '5',
6713 [ACTION_RESCUE] = '1'
6716 assert(arg_action < _ACTION_MAX);
6718 return table[arg_action];
6721 static int talk_initctl(void) {
6723 struct init_request request = {
6724 .magic = INIT_MAGIC,
6726 .cmd = INIT_CMD_RUNLVL
6729 _cleanup_close_ int fd = -1;
6733 rl = action_to_runlevel();
6737 request.runlevel = rl;
6739 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6741 if (errno == ENOENT)
6744 log_error("Failed to open "INIT_FIFO": %m");
6749 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6751 log_error("Failed to write to "INIT_FIFO": %m");
6752 return errno > 0 ? -errno : -EIO;
6758 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6760 static const struct {
6768 int (* const dispatch)(sd_bus *bus, char **args);
6774 { "list-units", MORE, 0, list_units },
6775 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6776 { "list-sockets", MORE, 1, list_sockets },
6777 { "list-timers", MORE, 1, list_timers },
6778 { "list-jobs", MORE, 1, list_jobs },
6779 { "list-machines", MORE, 1, list_machines },
6780 { "clear-jobs", EQUAL, 1, daemon_reload },
6781 { "cancel", MORE, 2, cancel_job },
6782 { "start", MORE, 2, start_unit },
6783 { "stop", MORE, 2, start_unit },
6784 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6785 { "reload", MORE, 2, start_unit },
6786 { "restart", MORE, 2, start_unit },
6787 { "try-restart", MORE, 2, start_unit },
6788 { "reload-or-restart", MORE, 2, start_unit },
6789 { "reload-or-try-restart", MORE, 2, start_unit },
6790 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6791 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6792 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6793 { "isolate", EQUAL, 2, start_unit },
6794 { "kill", MORE, 2, kill_unit },
6795 { "is-active", MORE, 2, check_unit_active },
6796 { "check", MORE, 2, check_unit_active },
6797 { "is-failed", MORE, 2, check_unit_failed },
6798 { "show", MORE, 1, show },
6799 { "cat", MORE, 2, cat },
6800 { "status", MORE, 1, show },
6801 { "help", MORE, 2, show },
6802 { "snapshot", LESS, 2, snapshot },
6803 { "delete", MORE, 2, delete_snapshot },
6804 { "daemon-reload", EQUAL, 1, daemon_reload },
6805 { "daemon-reexec", EQUAL, 1, daemon_reload },
6806 { "show-environment", EQUAL, 1, show_environment },
6807 { "set-environment", MORE, 2, set_environment },
6808 { "unset-environment", MORE, 2, set_environment },
6809 { "import-environment", MORE, 1, import_environment},
6810 { "halt", EQUAL, 1, start_special, FORCE },
6811 { "poweroff", EQUAL, 1, start_special, FORCE },
6812 { "reboot", EQUAL, 1, start_special, FORCE },
6813 { "kexec", EQUAL, 1, start_special },
6814 { "suspend", EQUAL, 1, start_special },
6815 { "hibernate", EQUAL, 1, start_special },
6816 { "hybrid-sleep", EQUAL, 1, start_special },
6817 { "default", EQUAL, 1, start_special },
6818 { "rescue", EQUAL, 1, start_special },
6819 { "emergency", EQUAL, 1, start_special },
6820 { "exit", EQUAL, 1, start_special },
6821 { "reset-failed", MORE, 1, reset_failed },
6822 { "enable", MORE, 2, enable_unit, NOBUS },
6823 { "disable", MORE, 2, enable_unit, NOBUS },
6824 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6825 { "reenable", MORE, 2, enable_unit, NOBUS },
6826 { "preset", MORE, 2, enable_unit, NOBUS },
6827 { "preset-all", EQUAL, 1, preset_all, NOBUS },
6828 { "mask", MORE, 2, enable_unit, NOBUS },
6829 { "unmask", MORE, 2, enable_unit, NOBUS },
6830 { "link", MORE, 2, enable_unit, NOBUS },
6831 { "switch-root", MORE, 2, switch_root },
6832 { "list-dependencies", LESS, 2, list_dependencies },
6833 { "set-default", EQUAL, 2, set_default, NOBUS },
6834 { "get-default", EQUAL, 1, get_default, NOBUS },
6835 { "set-property", MORE, 3, set_property },
6836 { "is-system-running", EQUAL, 1, is_system_running },
6837 { "add-wants", MORE, 3, add_dependency, NOBUS },
6838 { "add-requires", MORE, 3, add_dependency, NOBUS },
6847 left = argc - optind;
6849 /* Special rule: no arguments (left == 0) means "list-units" */
6851 if (streq(argv[optind], "help") && !argv[optind+1]) {
6852 log_error("This command expects one or more "
6853 "unit names. Did you mean --help?");
6857 for (; verb->verb; verb++)
6858 if (streq(argv[optind], verb->verb))
6861 log_error("Unknown operation '%s'.", argv[optind]);
6866 switch (verb->argc_cmp) {
6869 if (left != verb->argc) {
6870 log_error("Invalid number of arguments.");
6877 if (left < verb->argc) {
6878 log_error("Too few arguments.");
6885 if (left > verb->argc) {
6886 log_error("Too many arguments.");
6893 assert_not_reached("Unknown comparison operator.");
6896 /* Require a bus connection for all operations but
6898 if (verb->bus == NOBUS) {
6899 if (!bus && !avoid_bus()) {
6900 log_error_errno(-bus_error, "Failed to get D-Bus connection: %m");
6905 if (running_in_chroot() > 0) {
6906 log_info("Running in chroot, ignoring request.");
6910 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6911 log_error_errno(-bus_error, "Failed to get D-Bus connection: %m");
6916 return verb->dispatch(bus, argv + optind);
6919 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6921 struct sd_shutdown_command c = {
6928 union sockaddr_union sockaddr = {
6929 .un.sun_family = AF_UNIX,
6930 .un.sun_path = "/run/systemd/shutdownd",
6933 struct iovec iovec[2] = {{
6934 .iov_base = (char*) &c,
6935 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6938 struct msghdr msghdr = {
6939 .msg_name = &sockaddr,
6940 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6941 + strlen("/run/systemd/shutdownd"),
6946 _cleanup_close_ int fd;
6948 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6952 if (!isempty(message)) {
6953 iovec[1].iov_base = (char*) message;
6954 iovec[1].iov_len = strlen(message);
6955 msghdr.msg_iovlen++;
6958 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6964 static int reload_with_fallback(sd_bus *bus) {
6967 /* First, try systemd via D-Bus. */
6968 if (daemon_reload(bus, NULL) >= 0)
6972 /* Nothing else worked, so let's try signals */
6973 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6975 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6976 log_error("kill() failed: %m");
6983 static int start_with_fallback(sd_bus *bus) {
6986 /* First, try systemd via D-Bus. */
6987 if (start_unit(bus, NULL) >= 0)
6991 /* Nothing else worked, so let's try
6993 if (talk_initctl() > 0)
6996 log_error("Failed to talk to init daemon.");
7000 warn_wall(arg_action);
7004 static int halt_now(enum action a) {
7006 /* The kernel will automaticall flush ATA disks and suchlike
7007 * on reboot(), but the file systems need to be synce'd
7008 * explicitly in advance. */
7011 /* Make sure C-A-D is handled by the kernel from this point
7013 reboot(RB_ENABLE_CAD);
7018 log_info("Halting.");
7019 reboot(RB_HALT_SYSTEM);
7022 case ACTION_POWEROFF:
7023 log_info("Powering off.");
7024 reboot(RB_POWER_OFF);
7027 case ACTION_REBOOT: {
7028 _cleanup_free_ char *param = NULL;
7030 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7031 log_info("Rebooting with argument '%s'.", param);
7032 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7033 LINUX_REBOOT_CMD_RESTART2, param);
7036 log_info("Rebooting.");
7037 reboot(RB_AUTOBOOT);
7042 assert_not_reached("Unknown action.");
7046 static int halt_main(sd_bus *bus) {
7049 r = check_inhibitors(bus, arg_action);
7053 if (geteuid() != 0) {
7054 /* Try logind if we are a normal user and no special
7055 * mode applies. Maybe PolicyKit allows us to shutdown
7058 if (arg_when <= 0 &&
7061 (arg_action == ACTION_POWEROFF ||
7062 arg_action == ACTION_REBOOT)) {
7063 r = reboot_with_logind(bus, arg_action);
7068 log_error("Must be root.");
7073 _cleanup_free_ char *m;
7075 m = strv_join(arg_wall, " ");
7079 r = send_shutdownd(arg_when,
7080 arg_action == ACTION_HALT ? 'H' :
7081 arg_action == ACTION_POWEROFF ? 'P' :
7082 arg_action == ACTION_KEXEC ? 'K' :
7089 log_warning_errno(-r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7091 char date[FORMAT_TIMESTAMP_MAX];
7093 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7094 format_timestamp(date, sizeof(date), arg_when));
7099 if (!arg_dry && !arg_force)
7100 return start_with_fallback(bus);
7103 if (sd_booted() > 0)
7104 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7106 r = utmp_put_shutdown();
7108 log_warning_errno(-r, "Failed to write utmp record: %m");
7115 r = halt_now(arg_action);
7116 log_error_errno(-r, "Failed to reboot: %m");
7121 static int runlevel_main(void) {
7122 int r, runlevel, previous;
7124 r = utmp_get_runlevel(&runlevel, &previous);
7131 previous <= 0 ? 'N' : previous,
7132 runlevel <= 0 ? 'N' : runlevel);
7137 int main(int argc, char*argv[]) {
7138 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7141 setlocale(LC_ALL, "");
7142 log_parse_environment();
7145 /* Explicitly not on_tty() to avoid setting cached value.
7146 * This becomes relevant for piping output which might be
7148 original_stdout_is_tty = isatty(STDOUT_FILENO);
7150 r = parse_argv(argc, argv);
7154 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7155 * let's shortcut this */
7156 if (arg_action == ACTION_RUNLEVEL) {
7157 r = runlevel_main();
7161 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7162 log_info("Running in chroot, ignoring request.");
7168 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7170 /* systemctl_main() will print an error message for the bus
7171 * connection, but only if it needs to */
7173 switch (arg_action) {
7175 case ACTION_SYSTEMCTL:
7176 r = systemctl_main(bus, argc, argv, r);
7180 case ACTION_POWEROFF:
7186 case ACTION_RUNLEVEL2:
7187 case ACTION_RUNLEVEL3:
7188 case ACTION_RUNLEVEL4:
7189 case ACTION_RUNLEVEL5:
7191 case ACTION_EMERGENCY:
7192 case ACTION_DEFAULT:
7193 r = start_with_fallback(bus);
7198 r = reload_with_fallback(bus);
7201 case ACTION_CANCEL_SHUTDOWN: {
7202 _cleanup_free_ char *m = NULL;
7205 m = strv_join(arg_wall, " ");
7212 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7214 log_warning_errno(-r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7218 case ACTION_RUNLEVEL:
7219 case _ACTION_INVALID:
7221 assert_not_reached("Unknown action");
7226 ask_password_agent_close();
7227 polkit_agent_close();
7229 strv_free(arg_types);
7230 strv_free(arg_states);
7231 strv_free(arg_properties);
7233 return r < 0 ? EXIT_FAILURE : r;