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"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
76 static char **arg_types = NULL;
77 static char **arg_states = NULL;
78 static char **arg_properties = NULL;
79 static bool arg_all = false;
80 static enum dependency {
86 } arg_dependency = DEPENDENCY_FORWARD;
87 static const char *arg_job_mode = "replace";
88 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
89 static bool arg_no_block = false;
90 static bool arg_no_legend = false;
91 static bool arg_no_pager = false;
92 static bool arg_no_wtmp = false;
93 static bool arg_no_wall = false;
94 static bool arg_no_reload = false;
95 static bool arg_show_types = false;
96 static bool arg_ignore_inhibitors = false;
97 static bool arg_dry = false;
98 static bool arg_quiet = false;
99 static bool arg_full = false;
100 static bool arg_recursive = false;
101 static int arg_force = 0;
102 static bool arg_ask_password = true;
103 static bool arg_runtime = false;
104 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
105 static char **arg_wall = NULL;
106 static const char *arg_kill_who = NULL;
107 static int arg_signal = SIGTERM;
108 static const char *arg_root = NULL;
109 static usec_t arg_when = 0;
131 ACTION_CANCEL_SHUTDOWN,
133 } arg_action = ACTION_SYSTEMCTL;
134 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
135 static char *arg_host = NULL;
136 static unsigned arg_lines = 10;
137 static OutputMode arg_output = OUTPUT_SHORT;
138 static bool arg_plain = false;
140 static bool original_stdout_is_tty;
142 static int daemon_reload(sd_bus *bus, char **args);
143 static int halt_now(enum action a);
144 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
146 static char** strv_skip_first(char **strv) {
147 if (strv_length(strv) > 0)
152 static void pager_open_if_enabled(void) {
160 static void ask_password_agent_open_if_enabled(void) {
162 /* Open the password agent as a child process if necessary */
164 if (!arg_ask_password)
167 if (arg_scope != UNIT_FILE_SYSTEM)
170 if (arg_transport != BUS_TRANSPORT_LOCAL)
173 ask_password_agent_open();
177 static void polkit_agent_open_if_enabled(void) {
179 /* Open the polkit agent as a child process if necessary */
181 if (!arg_ask_password)
184 if (arg_scope != UNIT_FILE_SYSTEM)
187 if (arg_transport != BUS_TRANSPORT_LOCAL)
194 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
197 if (!sd_bus_error_is_set(error))
200 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
201 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
202 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
203 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
204 return EXIT_NOPERMISSION;
206 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
207 return EXIT_NOTINSTALLED;
209 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
210 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
211 return EXIT_NOTIMPLEMENTED;
213 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
214 return EXIT_NOTCONFIGURED;
222 static void warn_wall(enum action a) {
223 static const char *table[_ACTION_MAX] = {
224 [ACTION_HALT] = "The system is going down for system halt NOW!",
225 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
226 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
227 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
228 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
229 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
230 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
237 _cleanup_free_ char *p;
239 p = strv_join(arg_wall, " ");
246 utmp_wall(p, NULL, NULL);
254 utmp_wall(table[a], NULL, NULL);
257 static bool avoid_bus(void) {
259 if (running_in_chroot() > 0)
262 if (sd_booted() <= 0)
265 if (!isempty(arg_root))
268 if (arg_scope == UNIT_FILE_GLOBAL)
274 static int compare_unit_info(const void *a, const void *b) {
275 const UnitInfo *u = a, *v = b;
279 /* First, order by machine */
280 if (!u->machine && v->machine)
282 if (u->machine && !v->machine)
284 if (u->machine && v->machine) {
285 r = strcasecmp(u->machine, v->machine);
290 /* Second, order by unit type */
291 d1 = strrchr(u->id, '.');
292 d2 = strrchr(v->id, '.');
294 r = strcasecmp(d1, d2);
299 /* Third, order by name */
300 return strcasecmp(u->id, v->id);
303 static bool output_show_unit(const UnitInfo *u, char **patterns) {
304 if (!strv_isempty(patterns)) {
307 STRV_FOREACH(pattern, patterns)
308 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
317 dot = strrchr(u->id, '.');
321 if (!strv_find(arg_types, dot+1))
331 if (streq(u->active_state, "inactive") || u->following[0])
337 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
338 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
340 unsigned n_shown = 0;
343 max_id_len = strlen("UNIT");
344 load_len = strlen("LOAD");
345 active_len = strlen("ACTIVE");
346 sub_len = strlen("SUB");
347 job_len = strlen("JOB");
350 for (u = unit_infos; u < unit_infos + c; u++) {
351 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
352 load_len = MAX(load_len, strlen(u->load_state));
353 active_len = MAX(active_len, strlen(u->active_state));
354 sub_len = MAX(sub_len, strlen(u->sub_state));
356 if (u->job_id != 0) {
357 job_len = MAX(job_len, strlen(u->job_type));
361 if (!arg_no_legend &&
362 (streq(u->active_state, "failed") ||
363 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
367 if (!arg_full && original_stdout_is_tty) {
370 id_len = MIN(max_id_len, 25u);
371 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
374 basic_len += job_len + 1;
376 if (basic_len < (unsigned) columns()) {
377 unsigned extra_len, incr;
378 extra_len = columns() - basic_len;
380 /* Either UNIT already got 25, or is fully satisfied.
381 * Grant up to 25 to DESC now. */
382 incr = MIN(extra_len, 25u);
386 /* split the remaining space between UNIT and DESC,
387 * but do not give UNIT more than it needs. */
389 incr = MIN(extra_len / 2, max_id_len - id_len);
391 desc_len += extra_len - incr;
397 for (u = unit_infos; u < unit_infos + c; u++) {
398 _cleanup_free_ char *e = NULL, *j = NULL;
399 const char *on_loaded = "", *off_loaded = "";
400 const char *on_active = "", *off_active = "";
401 const char *on_circle = "", *off_circle = "";
405 if (!n_shown && !arg_no_legend) {
410 printf("%-*s %-*s %-*s %-*s ",
413 active_len, "ACTIVE",
417 printf("%-*s ", job_len, "JOB");
419 if (!arg_full && arg_no_pager)
420 printf("%.*s\n", desc_len, "DESCRIPTION");
422 printf("%s\n", "DESCRIPTION");
427 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
428 on_loaded = ansi_highlight_red();
429 on_circle = ansi_highlight_yellow();
430 off_loaded = off_circle = ansi_highlight_off();
434 if (streq(u->active_state, "failed")) {
435 on_circle = on_active = ansi_highlight_red();
436 off_circle = off_active = ansi_highlight_off();
441 j = strjoin(u->machine, ":", u->id, NULL);
450 e = ellipsize(id, id_len, 33);
458 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
460 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
461 on_active, id_len, id, off_active,
462 on_loaded, load_len, u->load_state, off_loaded,
463 on_active, active_len, u->active_state,
464 sub_len, u->sub_state, off_active,
465 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
468 printf("%.*s\n", desc_len, u->description);
470 printf("%s\n", u->description);
473 if (!arg_no_legend) {
474 const char *on, *off;
478 "LOAD = Reflects whether the unit definition was properly loaded.\n"
479 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
480 "SUB = The low-level unit activation state, values depend on unit type.");
481 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
482 on = ansi_highlight();
483 off = ansi_highlight_off();
485 on = ansi_highlight_red();
486 off = ansi_highlight_off();
490 printf("%s%u loaded units listed.%s\n"
491 "To show all installed unit files use 'systemctl list-unit-files'.\n",
494 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
495 "To show all installed unit files use 'systemctl list-unit-files'.\n",
502 static int get_unit_list(
506 UnitInfo **unit_infos,
508 sd_bus_message **_reply) {
510 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
511 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
521 r = sd_bus_message_new_method_call(
524 "org.freedesktop.systemd1",
525 "/org/freedesktop/systemd1",
526 "org.freedesktop.systemd1.Manager",
527 "ListUnitsFiltered");
530 return bus_log_create_error(r);
532 r = sd_bus_message_append_strv(m, arg_states);
534 return bus_log_create_error(r);
536 r = sd_bus_call(bus, m, 0, &error, &reply);
538 log_error("Failed to list units: %s", bus_error_message(&error, r));
542 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
544 return bus_log_parse_error(r);
546 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
549 if (!output_show_unit(&u, patterns))
552 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
555 (*unit_infos)[c++] = u;
558 return bus_log_parse_error(r);
560 r = sd_bus_message_exit_container(reply);
562 return bus_log_parse_error(r);
570 static void message_set_freep(Set **set) {
573 while ((m = set_steal_first(*set)))
574 sd_bus_message_unref(m);
579 static int get_unit_list_recursive(
582 UnitInfo **_unit_infos,
586 _cleanup_free_ UnitInfo *unit_infos = NULL;
587 _cleanup_(message_set_freep) Set *replies;
588 sd_bus_message *reply;
596 replies = set_new(NULL);
600 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
604 r = set_put(replies, reply);
606 sd_bus_message_unref(reply);
611 _cleanup_strv_free_ char **machines = NULL;
614 r = sd_get_machine_names(&machines);
618 STRV_FOREACH(i, machines) {
619 _cleanup_bus_close_unref_ sd_bus *container = NULL;
622 r = sd_bus_open_system_container(&container, *i);
624 log_error("Failed to connect to container %s: %s", *i, strerror(-r));
628 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
634 r = set_put(replies, reply);
636 sd_bus_message_unref(reply);
641 *_machines = machines;
646 *_unit_infos = unit_infos;
655 static int list_units(sd_bus *bus, char **args) {
656 _cleanup_free_ UnitInfo *unit_infos = NULL;
657 _cleanup_(message_set_freep) Set *replies = NULL;
658 _cleanup_strv_free_ char **machines = NULL;
661 pager_open_if_enabled();
663 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
667 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
668 return output_units_list(unit_infos, r);
671 static int get_triggered_units(
676 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
679 r = sd_bus_get_property_strv(
681 "org.freedesktop.systemd1",
683 "org.freedesktop.systemd1.Unit",
689 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
694 static int get_listening(
696 const char* unit_path,
699 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
700 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
701 const char *type, *path;
704 r = sd_bus_get_property(
706 "org.freedesktop.systemd1",
708 "org.freedesktop.systemd1.Socket",
714 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
718 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
720 return bus_log_parse_error(r);
722 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
724 r = strv_extend(listening, type);
728 r = strv_extend(listening, path);
735 return bus_log_parse_error(r);
737 r = sd_bus_message_exit_container(reply);
739 return bus_log_parse_error(r);
751 /* Note: triggered is a list here, although it almost certainly
752 * will always be one unit. Nevertheless, dbus API allows for multiple
753 * values, so let's follow that.*/
756 /* The strv above is shared. free is set only in the first one. */
760 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
766 if (!a->machine && b->machine)
768 if (a->machine && !b->machine)
770 if (a->machine && b->machine) {
771 o = strcasecmp(a->machine, b->machine);
776 o = strcmp(a->path, b->path);
778 o = strcmp(a->type, b->type);
783 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
784 struct socket_info *s;
785 unsigned pathlen = strlen("LISTEN"),
786 typelen = strlen("TYPE") * arg_show_types,
787 socklen = strlen("UNIT"),
788 servlen = strlen("ACTIVATES");
789 const char *on, *off;
791 for (s = socket_infos; s < socket_infos + cs; s++) {
795 socklen = MAX(socklen, strlen(s->id));
797 typelen = MAX(typelen, strlen(s->type));
798 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
800 STRV_FOREACH(a, s->triggered)
801 tmp += strlen(*a) + 2*(a != s->triggered);
802 servlen = MAX(servlen, tmp);
807 printf("%-*s %-*.*s%-*s %s\n",
809 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
813 for (s = socket_infos; s < socket_infos + cs; s++) {
814 _cleanup_free_ char *j = NULL;
819 j = strjoin(s->machine, ":", s->path, NULL);
827 printf("%-*s %-*s %-*s",
828 pathlen, path, typelen, s->type, socklen, s->id);
831 pathlen, path, socklen, s->id);
832 STRV_FOREACH(a, s->triggered)
834 a == s->triggered ? "" : ",", *a);
838 on = ansi_highlight();
839 off = ansi_highlight_off();
843 on = ansi_highlight_red();
844 off = ansi_highlight_off();
847 if (!arg_no_legend) {
848 printf("%s%u sockets listed.%s\n", on, cs, off);
850 printf("Pass --all to see loaded but inactive sockets, too.\n");
856 static int list_sockets(sd_bus *bus, char **args) {
857 _cleanup_(message_set_freep) Set *replies = NULL;
858 _cleanup_strv_free_ char **machines = NULL;
859 _cleanup_free_ UnitInfo *unit_infos = NULL;
860 _cleanup_free_ struct socket_info *socket_infos = NULL;
862 struct socket_info *s;
867 pager_open_if_enabled();
869 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
873 for (u = unit_infos; u < unit_infos + n; u++) {
874 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
877 if (!endswith(u->id, ".socket"))
880 r = get_triggered_units(bus, u->unit_path, &triggered);
884 c = get_listening(bus, u->unit_path, &listening);
890 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
895 for (i = 0; i < c; i++)
896 socket_infos[cs + i] = (struct socket_info) {
897 .machine = u->machine,
899 .type = listening[i*2],
900 .path = listening[i*2 + 1],
901 .triggered = triggered,
902 .own_triggered = i==0,
905 /* from this point on we will cleanup those socket_infos */
908 listening = triggered = NULL; /* avoid cleanup */
911 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
912 (__compar_fn_t) socket_info_compare);
914 output_sockets_list(socket_infos, cs);
917 assert(cs == 0 || socket_infos);
918 for (s = socket_infos; s < socket_infos + cs; s++) {
921 if (s->own_triggered)
922 strv_free(s->triggered);
928 static int get_next_elapse(
931 dual_timestamp *next) {
933 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
941 r = sd_bus_get_property_trivial(
943 "org.freedesktop.systemd1",
945 "org.freedesktop.systemd1.Timer",
946 "NextElapseUSecMonotonic",
951 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
955 r = sd_bus_get_property_trivial(
957 "org.freedesktop.systemd1",
959 "org.freedesktop.systemd1.Timer",
960 "NextElapseUSecRealtime",
965 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
973 static int get_last_trigger(
978 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
985 r = sd_bus_get_property_trivial(
987 "org.freedesktop.systemd1",
989 "org.freedesktop.systemd1.Timer",
995 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1003 const char* machine;
1006 usec_t last_trigger;
1010 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1016 if (!a->machine && b->machine)
1018 if (a->machine && !b->machine)
1020 if (a->machine && b->machine) {
1021 o = strcasecmp(a->machine, b->machine);
1026 if (a->next_elapse < b->next_elapse)
1028 if (a->next_elapse > b->next_elapse)
1031 return strcmp(a->id, b->id);
1034 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1035 struct timer_info *t;
1037 nextlen = strlen("NEXT"),
1038 leftlen = strlen("LEFT"),
1039 lastlen = strlen("LAST"),
1040 passedlen = strlen("PASSED"),
1041 unitlen = strlen("UNIT"),
1042 activatelen = strlen("ACTIVATES");
1044 const char *on, *off;
1046 assert(timer_infos || n == 0);
1048 for (t = timer_infos; t < timer_infos + n; t++) {
1052 if (t->next_elapse > 0) {
1053 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1055 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1056 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1058 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1059 leftlen = MAX(leftlen, strlen(trel));
1062 if (t->last_trigger > 0) {
1063 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1065 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1066 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1068 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1069 passedlen = MAX(passedlen, strlen(trel));
1072 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1074 STRV_FOREACH(a, t->triggered)
1075 ul += strlen(*a) + 2*(a != t->triggered);
1077 activatelen = MAX(activatelen, ul);
1082 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1086 passedlen, "PASSED",
1090 for (t = timer_infos; t < timer_infos + n; t++) {
1091 _cleanup_free_ char *j = NULL;
1093 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1094 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1097 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1098 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1100 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1101 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1104 j = strjoin(t->machine, ":", t->id, NULL);
1111 printf("%-*s %-*s %-*s %-*s %-*s",
1112 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1114 STRV_FOREACH(a, t->triggered)
1116 a == t->triggered ? "" : ",", *a);
1120 on = ansi_highlight();
1121 off = ansi_highlight_off();
1125 on = ansi_highlight_red();
1126 off = ansi_highlight_off();
1129 if (!arg_no_legend) {
1130 printf("%s%u timers listed.%s\n", on, n, off);
1132 printf("Pass --all to see loaded but inactive timers, too.\n");
1138 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1144 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1147 if (next->monotonic > nw->monotonic)
1148 converted = nw->realtime + (next->monotonic - nw->monotonic);
1150 converted = nw->realtime - (nw->monotonic - next->monotonic);
1152 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1153 next_elapse = MIN(converted, next->realtime);
1155 next_elapse = converted;
1158 next_elapse = next->realtime;
1163 static int list_timers(sd_bus *bus, char **args) {
1164 _cleanup_(message_set_freep) Set *replies = NULL;
1165 _cleanup_strv_free_ char **machines = NULL;
1166 _cleanup_free_ struct timer_info *timer_infos = NULL;
1167 _cleanup_free_ UnitInfo *unit_infos = NULL;
1168 struct timer_info *t;
1175 pager_open_if_enabled();
1177 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1181 dual_timestamp_get(&nw);
1183 for (u = unit_infos; u < unit_infos + n; u++) {
1184 _cleanup_strv_free_ char **triggered = NULL;
1185 dual_timestamp next = {};
1188 if (!endswith(u->id, ".timer"))
1191 r = get_triggered_units(bus, u->unit_path, &triggered);
1195 r = get_next_elapse(bus, u->unit_path, &next);
1199 get_last_trigger(bus, u->unit_path, &last);
1201 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1206 m = calc_next_elapse(&nw, &next);
1208 timer_infos[c++] = (struct timer_info) {
1209 .machine = u->machine,
1212 .last_trigger = last,
1213 .triggered = triggered,
1216 triggered = NULL; /* avoid cleanup */
1219 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1220 (__compar_fn_t) timer_info_compare);
1222 output_timers_list(timer_infos, c);
1225 for (t = timer_infos; t < timer_infos + c; t++)
1226 strv_free(t->triggered);
1231 static int compare_unit_file_list(const void *a, const void *b) {
1232 const char *d1, *d2;
1233 const UnitFileList *u = a, *v = b;
1235 d1 = strrchr(u->path, '.');
1236 d2 = strrchr(v->path, '.');
1241 r = strcasecmp(d1, d2);
1246 return strcasecmp(basename(u->path), basename(v->path));
1249 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1250 if (!strv_isempty(patterns)) {
1253 STRV_FOREACH(pattern, patterns)
1254 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1260 if (!strv_isempty(arg_types)) {
1263 dot = strrchr(u->path, '.');
1267 if (!strv_find(arg_types, dot+1))
1271 if (!strv_isempty(arg_states)) {
1272 if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
1279 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1280 unsigned max_id_len, id_cols, state_cols;
1281 const UnitFileList *u;
1283 max_id_len = strlen("UNIT FILE");
1284 state_cols = strlen("STATE");
1286 for (u = units; u < units + c; u++) {
1287 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1288 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1292 unsigned basic_cols;
1294 id_cols = MIN(max_id_len, 25u);
1295 basic_cols = 1 + id_cols + state_cols;
1296 if (basic_cols < (unsigned) columns())
1297 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1299 id_cols = max_id_len;
1302 printf("%-*s %-*s\n",
1303 id_cols, "UNIT FILE",
1304 state_cols, "STATE");
1306 for (u = units; u < units + c; u++) {
1307 _cleanup_free_ char *e = NULL;
1308 const char *on, *off;
1311 if (u->state == UNIT_FILE_MASKED ||
1312 u->state == UNIT_FILE_MASKED_RUNTIME ||
1313 u->state == UNIT_FILE_DISABLED ||
1314 u->state == UNIT_FILE_INVALID) {
1315 on = ansi_highlight_red();
1316 off = ansi_highlight_off();
1317 } else if (u->state == UNIT_FILE_ENABLED) {
1318 on = ansi_highlight_green();
1319 off = ansi_highlight_off();
1323 id = basename(u->path);
1325 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1327 printf("%-*s %s%-*s%s\n",
1328 id_cols, e ? e : id,
1329 on, state_cols, unit_file_state_to_string(u->state), off);
1333 printf("\n%u unit files listed.\n", c);
1336 static int list_unit_files(sd_bus *bus, char **args) {
1337 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1338 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1339 _cleanup_free_ UnitFileList *units = NULL;
1347 pager_open_if_enabled();
1355 h = hashmap_new(&string_hash_ops);
1359 r = unit_file_get_list(arg_scope, arg_root, h);
1361 unit_file_list_free(h);
1362 log_error("Failed to get unit file list: %s", strerror(-r));
1366 n_units = hashmap_size(h);
1368 units = new(UnitFileList, n_units);
1369 if (!units && n_units > 0) {
1370 unit_file_list_free(h);
1374 HASHMAP_FOREACH(u, h, i) {
1375 if (!output_show_unit_file(u, strv_skip_first(args)))
1382 assert(c <= n_units);
1385 r = sd_bus_call_method(
1387 "org.freedesktop.systemd1",
1388 "/org/freedesktop/systemd1",
1389 "org.freedesktop.systemd1.Manager",
1395 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1399 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1401 return bus_log_parse_error(r);
1403 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1405 if (!GREEDY_REALLOC(units, size, c + 1))
1408 units[c] = (struct UnitFileList) {
1410 unit_file_state_from_string(state)
1413 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1418 return bus_log_parse_error(r);
1420 r = sd_bus_message_exit_container(reply);
1422 return bus_log_parse_error(r);
1425 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1426 output_unit_file_list(units, c);
1429 for (unit = units; unit < units + c; unit++)
1436 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1437 _cleanup_free_ char *n = NULL;
1438 size_t max_len = MAX(columns(),20u);
1444 for (i = level - 1; i >= 0; i--) {
1446 if (len > max_len - 3 && !arg_full) {
1447 printf("%s...\n",max_len % 2 ? "" : " ");
1450 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1454 if (len > max_len - 3 && !arg_full) {
1455 printf("%s...\n",max_len % 2 ? "" : " ");
1459 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1463 printf("%s\n", name);
1467 n = ellipsize(name, max_len-len, 100);
1475 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1477 static const char *dependencies[_DEPENDENCY_MAX] = {
1478 [DEPENDENCY_FORWARD] = "Requires\0"
1479 "RequiresOverridable\0"
1481 "RequisiteOverridable\0"
1483 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1484 "RequiredByOverridable\0"
1487 [DEPENDENCY_AFTER] = "After\0",
1488 [DEPENDENCY_BEFORE] = "Before\0",
1491 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1492 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1493 _cleanup_strv_free_ char **ret = NULL;
1494 _cleanup_free_ char *path = NULL;
1500 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1502 path = unit_dbus_path_from_name(name);
1506 r = sd_bus_call_method(
1508 "org.freedesktop.systemd1",
1510 "org.freedesktop.DBus.Properties",
1514 "s", "org.freedesktop.systemd1.Unit");
1516 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1520 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1522 return bus_log_parse_error(r);
1524 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1527 r = sd_bus_message_read(reply, "s", &prop);
1529 return bus_log_parse_error(r);
1531 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1532 r = sd_bus_message_skip(reply, "v");
1534 return bus_log_parse_error(r);
1537 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1539 return bus_log_parse_error(r);
1541 r = bus_message_read_strv_extend(reply, &ret);
1543 return bus_log_parse_error(r);
1545 r = sd_bus_message_exit_container(reply);
1547 return bus_log_parse_error(r);
1550 r = sd_bus_message_exit_container(reply);
1552 return bus_log_parse_error(r);
1556 return bus_log_parse_error(r);
1558 r = sd_bus_message_exit_container(reply);
1560 return bus_log_parse_error(r);
1568 static int list_dependencies_compare(const void *_a, const void *_b) {
1569 const char **a = (const char**) _a, **b = (const char**) _b;
1571 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1573 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1576 return strcasecmp(*a, *b);
1579 static int list_dependencies_one(
1584 unsigned int branches) {
1586 _cleanup_strv_free_ char **deps = NULL;
1594 r = strv_extend(units, name);
1598 r = list_dependencies_get_dependencies(bus, name, &deps);
1602 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1604 STRV_FOREACH(c, deps) {
1607 if (strv_contains(*units, *c)) {
1609 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1616 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1618 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1620 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1622 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1626 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1627 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1634 strv_remove(*units, name);
1639 static int list_dependencies(sd_bus *bus, char **args) {
1640 _cleanup_strv_free_ char **units = NULL;
1641 _cleanup_free_ char *unit = NULL;
1647 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1652 u = SPECIAL_DEFAULT_TARGET;
1654 pager_open_if_enabled();
1658 return list_dependencies_one(bus, u, 0, &units, 0);
1661 struct machine_info {
1665 char *control_group;
1666 uint32_t n_failed_units;
1671 static const struct bus_properties_map machine_info_property_map[] = {
1672 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1673 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1674 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1675 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1676 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1680 static void free_machines_list(struct machine_info *machine_infos, int n) {
1686 for (i = 0; i < n; i++) {
1687 free(machine_infos[i].name);
1688 free(machine_infos[i].state);
1689 free(machine_infos[i].control_group);
1692 free(machine_infos);
1695 static int compare_machine_info(const void *a, const void *b) {
1696 const struct machine_info *u = a, *v = b;
1698 if (u->is_host != v->is_host)
1699 return u->is_host > v->is_host ? -1 : 1;
1701 return strcasecmp(u->name, v->name);
1704 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1705 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1711 r = sd_bus_open_system_container(&container, mi->name);
1718 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1725 static bool output_show_machine(const char *name, char **patterns) {
1730 if (strv_isempty(patterns))
1733 STRV_FOREACH(i, patterns)
1734 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1740 static int get_machine_list(
1742 struct machine_info **_machine_infos,
1745 struct machine_info *machine_infos = NULL;
1746 _cleanup_strv_free_ char **m = NULL;
1747 _cleanup_free_ char *hn = NULL;
1752 hn = gethostname_malloc();
1756 if (output_show_machine(hn, patterns)) {
1757 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1760 machine_infos[c].is_host = true;
1761 machine_infos[c].name = hn;
1764 get_machine_properties(bus, &machine_infos[c]);
1768 sd_get_machine_names(&m);
1769 STRV_FOREACH(i, m) {
1770 _cleanup_free_ char *class = NULL;
1772 if (!output_show_machine(*i, patterns))
1775 sd_machine_get_class(*i, &class);
1776 if (!streq_ptr(class, "container"))
1779 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1780 free_machines_list(machine_infos, c);
1784 machine_infos[c].is_host = false;
1785 machine_infos[c].name = strdup(*i);
1786 if (!machine_infos[c].name) {
1787 free_machines_list(machine_infos, c);
1791 get_machine_properties(NULL, &machine_infos[c]);
1795 *_machine_infos = machine_infos;
1799 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1800 struct machine_info *m;
1803 namelen = sizeof("NAME") - 1,
1804 statelen = sizeof("STATE") - 1,
1805 failedlen = sizeof("FAILED") - 1,
1806 jobslen = sizeof("JOBS") - 1;
1808 assert(machine_infos || n == 0);
1810 for (m = machine_infos; m < machine_infos + n; m++) {
1811 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1812 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1813 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1814 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1816 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1820 if (!arg_no_legend) {
1824 printf("%-*s %-*s %-*s %-*s\n",
1827 failedlen, "FAILED",
1831 for (m = machine_infos; m < machine_infos + n; m++) {
1832 const char *on_state = "", *off_state = "";
1833 const char *on_failed = "", *off_failed = "";
1834 bool circle = false;
1836 if (streq_ptr(m->state, "degraded")) {
1837 on_state = ansi_highlight_red();
1838 off_state = ansi_highlight_off();
1840 } else if (!streq_ptr(m->state, "running")) {
1841 on_state = ansi_highlight_yellow();
1842 off_state = ansi_highlight_off();
1846 if (m->n_failed_units > 0) {
1847 on_failed = ansi_highlight_red();
1848 off_failed = ansi_highlight_off();
1850 on_failed = off_failed = "";
1853 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1856 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1857 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1858 on_state, statelen, strna(m->state), off_state,
1859 on_failed, failedlen, m->n_failed_units, off_failed,
1860 jobslen, m->n_jobs);
1862 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1863 namelen, strna(m->name),
1864 on_state, statelen, strna(m->state), off_state,
1865 on_failed, failedlen, m->n_failed_units, off_failed,
1866 jobslen, m->n_jobs);
1870 printf("\n%u machines listed.\n", n);
1873 static int list_machines(sd_bus *bus, char **args) {
1874 struct machine_info *machine_infos = NULL;
1879 if (geteuid() != 0) {
1880 log_error("Must be root.");
1884 pager_open_if_enabled();
1886 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1890 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1891 output_machines_list(machine_infos, r);
1892 free_machines_list(machine_infos, r);
1897 static int get_default(sd_bus *bus, char **args) {
1898 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1899 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1900 _cleanup_free_ char *_path = NULL;
1904 if (!bus || avoid_bus()) {
1905 r = unit_file_get_default(arg_scope, arg_root, &_path);
1907 log_error("Failed to get default target: %s", strerror(-r));
1913 r = sd_bus_call_method(
1915 "org.freedesktop.systemd1",
1916 "/org/freedesktop/systemd1",
1917 "org.freedesktop.systemd1.Manager",
1923 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1927 r = sd_bus_message_read(reply, "s", &path);
1929 return bus_log_parse_error(r);
1933 printf("%s\n", path);
1938 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1941 assert(changes || n_changes == 0);
1943 for (i = 0; i < n_changes; i++) {
1944 if (changes[i].type == UNIT_FILE_SYMLINK)
1945 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1947 log_info("Removed symlink %s.", changes[i].path);
1951 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1952 const char *type, *path, *source;
1955 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1957 return bus_log_parse_error(r);
1959 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1961 if (streq(type, "symlink"))
1962 log_info("Created symlink from %s to %s.", path, source);
1964 log_info("Removed symlink %s.", path);
1968 return bus_log_parse_error(r);
1970 r = sd_bus_message_exit_container(m);
1972 return bus_log_parse_error(r);
1977 static int set_default(sd_bus *bus, char **args) {
1978 _cleanup_free_ char *unit = NULL;
1979 UnitFileChange *changes = NULL;
1980 unsigned n_changes = 0;
1983 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1987 if (!bus || avoid_bus()) {
1988 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1990 log_error("Failed to set default target: %s", strerror(-r));
1995 dump_unit_file_changes(changes, n_changes);
1999 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
2000 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2002 r = sd_bus_message_new_method_call(
2005 "org.freedesktop.systemd1",
2006 "/org/freedesktop/systemd1",
2007 "org.freedesktop.systemd1.Manager",
2008 "SetDefaultTarget");
2010 return bus_log_create_error(r);
2012 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2014 return bus_log_create_error(r);
2016 r = sd_bus_message_append(m, "sb", unit, 1);
2018 return bus_log_create_error(r);
2020 r = sd_bus_call(bus, m, 0, &error, &reply);
2022 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2026 r = deserialize_and_dump_unit_file_changes(reply);
2030 /* Try to reload if enabled */
2032 r = daemon_reload(bus, args);
2037 unit_file_changes_free(changes, n_changes);
2044 const char *name, *type, *state;
2047 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2048 unsigned id_len, unit_len, type_len, state_len;
2049 const struct job_info *j;
2050 const char *on, *off;
2051 bool shorten = false;
2053 assert(n == 0 || jobs);
2056 on = ansi_highlight_green();
2057 off = ansi_highlight_off();
2059 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2063 pager_open_if_enabled();
2065 id_len = strlen("JOB");
2066 unit_len = strlen("UNIT");
2067 type_len = strlen("TYPE");
2068 state_len = strlen("STATE");
2070 for (j = jobs; j < jobs + n; j++) {
2071 uint32_t id = j->id;
2072 assert(j->name && j->type && j->state);
2074 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2075 unit_len = MAX(unit_len, strlen(j->name));
2076 type_len = MAX(type_len, strlen(j->type));
2077 state_len = MAX(state_len, strlen(j->state));
2080 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2081 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2086 printf("%*s %-*s %-*s %-*s\n",
2090 state_len, "STATE");
2092 for (j = jobs; j < jobs + n; j++) {
2093 _cleanup_free_ char *e = NULL;
2095 if (streq(j->state, "running")) {
2096 on = ansi_highlight();
2097 off = ansi_highlight_off();
2101 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2102 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2104 on, unit_len, e ? e : j->name, off,
2106 on, state_len, j->state, off);
2109 if (!arg_no_legend) {
2110 on = ansi_highlight();
2111 off = ansi_highlight_off();
2113 printf("\n%s%u jobs listed%s.\n", on, n, off);
2117 static bool output_show_job(struct job_info *job, char **patterns) {
2122 if (strv_isempty(patterns))
2125 STRV_FOREACH(pattern, patterns)
2126 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2131 static int list_jobs(sd_bus *bus, char **args) {
2132 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2133 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2134 const char *name, *type, *state, *job_path, *unit_path;
2135 _cleanup_free_ struct job_info *jobs = NULL;
2140 bool skipped = false;
2142 r = sd_bus_call_method(
2144 "org.freedesktop.systemd1",
2145 "/org/freedesktop/systemd1",
2146 "org.freedesktop.systemd1.Manager",
2152 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2156 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2158 return bus_log_parse_error(r);
2160 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2161 struct job_info job = { id, name, type, state };
2163 if (!output_show_job(&job, strv_skip_first(args))) {
2168 if (!GREEDY_REALLOC(jobs, size, c + 1))
2174 return bus_log_parse_error(r);
2176 r = sd_bus_message_exit_container(reply);
2178 return bus_log_parse_error(r);
2180 output_jobs_list(jobs, c, skipped);
2184 static int cancel_job(sd_bus *bus, char **args) {
2185 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2191 if (strv_length(args) <= 1)
2192 return daemon_reload(bus, args);
2194 STRV_FOREACH(name, args+1) {
2195 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2199 q = safe_atou32(*name, &id);
2201 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-q));
2205 q = sd_bus_message_new_method_call(
2208 "org.freedesktop.systemd1",
2209 "/org/freedesktop/systemd1",
2210 "org.freedesktop.systemd1.Manager",
2213 return bus_log_create_error(q);
2215 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2217 return bus_log_create_error(1);
2219 q = sd_bus_message_append(m, "u", id);
2221 return bus_log_create_error(q);
2223 q = sd_bus_call(bus, m, 0, &error, NULL);
2225 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2234 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2235 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2239 /* We ignore all errors here, since this is used to show a
2242 /* We don't use unit_dbus_path_from_name() directly since we
2243 * don't want to load the unit if it isn't loaded. */
2245 r = sd_bus_call_method(
2247 "org.freedesktop.systemd1",
2248 "/org/freedesktop/systemd1",
2249 "org.freedesktop.systemd1.Manager",
2257 r = sd_bus_message_read(reply, "o", &path);
2261 r = sd_bus_get_property_trivial(
2263 "org.freedesktop.systemd1",
2265 "org.freedesktop.systemd1.Unit",
2275 typedef struct WaitData {
2282 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2289 log_debug("Got D-Bus request: %s.%s() on %s",
2290 sd_bus_message_get_interface(m),
2291 sd_bus_message_get_member(m),
2292 sd_bus_message_get_path(m));
2294 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2295 log_error("Warning! D-Bus connection terminated.");
2297 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2299 const char *path, *result, *unit;
2303 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2305 ret = set_remove(d->set, (char*) path);
2311 if (!isempty(result))
2312 d->result = strdup(result);
2315 d->name = strdup(unit);
2320 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2322 ret = set_remove(d->set, (char*) path);
2329 d->result = strdup(result);
2335 bus_log_parse_error(r);
2341 static int enable_wait_for_jobs(sd_bus *bus) {
2346 r = sd_bus_add_match(
2350 "sender='org.freedesktop.systemd1',"
2351 "interface='org.freedesktop.systemd1.Manager',"
2352 "member='JobRemoved',"
2353 "path='/org/freedesktop/systemd1'",
2356 log_error("Failed to add match");
2360 /* This is slightly dirty, since we don't undo the match registrations. */
2364 static int bus_process_wait(sd_bus *bus) {
2368 r = sd_bus_process(bus, NULL);
2373 r = sd_bus_wait(bus, (uint64_t) -1);
2379 static int check_wait_response(WaitData *d) {
2385 if (streq(d->result, "timeout"))
2386 log_error("Job for %s timed out.", strna(d->name));
2387 else if (streq(d->result, "canceled"))
2388 log_error("Job for %s canceled.", strna(d->name));
2389 else if (streq(d->result, "dependency"))
2390 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
2391 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
2395 quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
2397 log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
2399 quotes ? "'" : "", d->name, quotes ? "'" : "");
2401 log_error("Job failed. See \"journalctl -xe\" for details.");
2405 if (streq(d->result, "timeout"))
2407 else if (streq(d->result, "canceled"))
2409 else if (streq(d->result, "dependency"))
2411 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2417 static int wait_for_jobs(sd_bus *bus, Set *s) {
2418 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2419 WaitData d = { .set = s };
2425 q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2429 while (!set_isempty(s)) {
2430 q = bus_process_wait(bus);
2432 log_error("Failed to wait for response: %s", strerror(-q));
2437 q = check_wait_response(&d);
2438 /* Return the first error as it is most likely to be
2440 if (q < 0 && r == 0)
2442 log_debug("Got result %s/%s for job %s",
2443 strna(d.result), strerror(-q), strna(d.name));
2456 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2457 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2458 _cleanup_free_ char *n = NULL, *state = NULL;
2464 n = unit_name_mangle(name, MANGLE_NOGLOB);
2468 /* We don't use unit_dbus_path_from_name() directly since we
2469 * don't want to load the unit if it isn't loaded. */
2471 r = sd_bus_call_method(
2473 "org.freedesktop.systemd1",
2474 "/org/freedesktop/systemd1",
2475 "org.freedesktop.systemd1.Manager",
2486 r = sd_bus_message_read(reply, "o", &path);
2488 return bus_log_parse_error(r);
2490 r = sd_bus_get_property_string(
2492 "org.freedesktop.systemd1",
2494 "org.freedesktop.systemd1.Unit",
2507 return nulstr_contains(good_states, state);
2510 static int check_triggering_units(
2514 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2515 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2516 _cleanup_strv_free_ char **triggered_by = NULL;
2517 bool print_warning_label = true;
2521 n = unit_name_mangle(name, MANGLE_NOGLOB);
2525 path = unit_dbus_path_from_name(n);
2529 r = sd_bus_get_property_string(
2531 "org.freedesktop.systemd1",
2533 "org.freedesktop.systemd1.Unit",
2538 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2542 if (streq(state, "masked"))
2545 r = sd_bus_get_property_strv(
2547 "org.freedesktop.systemd1",
2549 "org.freedesktop.systemd1.Unit",
2554 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2558 STRV_FOREACH(i, triggered_by) {
2559 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2561 log_error("Failed to check unit: %s", strerror(-r));
2568 if (print_warning_label) {
2569 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2570 print_warning_label = false;
2573 log_warning(" %s", *i);
2579 static const struct {
2582 } unit_actions[] = {
2583 { "start", "StartUnit" },
2584 { "stop", "StopUnit" },
2585 { "condstop", "StopUnit" },
2586 { "reload", "ReloadUnit" },
2587 { "restart", "RestartUnit" },
2588 { "try-restart", "TryRestartUnit" },
2589 { "condrestart", "TryRestartUnit" },
2590 { "reload-or-restart", "ReloadOrRestartUnit" },
2591 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2592 { "condreload", "ReloadOrTryRestartUnit" },
2593 { "force-reload", "ReloadOrTryRestartUnit" }
2596 static const char *verb_to_method(const char *verb) {
2599 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2600 if (streq_ptr(unit_actions[i].verb, verb))
2601 return unit_actions[i].method;
2606 static const char *method_to_verb(const char *method) {
2609 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2610 if (streq_ptr(unit_actions[i].method, method))
2611 return unit_actions[i].verb;
2616 static int start_unit_one(
2621 sd_bus_error *error,
2624 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2633 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2635 r = sd_bus_message_new_method_call(
2638 "org.freedesktop.systemd1",
2639 "/org/freedesktop/systemd1",
2640 "org.freedesktop.systemd1.Manager",
2643 return bus_log_create_error(r);
2645 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2647 return bus_log_create_error(r);
2649 r = sd_bus_message_append(m, "ss", name, mode);
2651 return bus_log_create_error(r);
2653 r = sd_bus_call(bus, m, 0, error, &reply);
2657 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2658 /* There's always a fallback possible for
2659 * legacy actions. */
2660 return -EADDRNOTAVAIL;
2662 verb = method_to_verb(method);
2664 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2668 r = sd_bus_message_read(reply, "o", &path);
2670 return bus_log_parse_error(r);
2672 if (need_daemon_reload(bus, name) > 0)
2673 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2674 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2683 log_debug("Adding %s to the set", p);
2684 r = set_consume(s, p);
2692 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2694 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2698 STRV_FOREACH(name, names) {
2702 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2704 t = unit_name_mangle(*name, MANGLE_GLOB);
2708 if (string_is_glob(t))
2709 r = strv_consume(&globs, t);
2711 r = strv_consume(&mangled, t);
2716 /* Query the manager only if any of the names are a glob, since
2717 * this is fairly expensive */
2718 if (!strv_isempty(globs)) {
2719 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2720 _cleanup_free_ UnitInfo *unit_infos = NULL;
2722 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2726 for (i = 0; i < r; i++)
2727 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2732 mangled = NULL; /* do not free */
2737 static const struct {
2741 } action_table[_ACTION_MAX] = {
2742 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2743 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2744 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2745 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2746 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2747 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2748 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2749 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2750 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2751 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2752 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2753 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2754 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2755 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2756 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2759 static enum action verb_to_action(const char *verb) {
2762 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2763 if (streq_ptr(action_table[i].verb, verb))
2766 return _ACTION_INVALID;
2769 static int start_unit(sd_bus *bus, char **args) {
2770 _cleanup_set_free_free_ Set *s = NULL;
2771 _cleanup_strv_free_ char **names = NULL;
2772 const char *method, *mode, *one_name, *suffix = NULL;
2778 ask_password_agent_open_if_enabled();
2780 if (arg_action == ACTION_SYSTEMCTL) {
2782 method = verb_to_method(args[0]);
2783 action = verb_to_action(args[0]);
2785 if (streq(args[0], "isolate")) {
2789 mode = action_table[action].mode ?: arg_job_mode;
2791 one_name = action_table[action].target;
2793 assert(arg_action < ELEMENTSOF(action_table));
2794 assert(action_table[arg_action].target);
2796 method = "StartUnit";
2798 mode = action_table[arg_action].mode;
2799 one_name = action_table[arg_action].target;
2803 names = strv_new(one_name, NULL);
2805 r = expand_names(bus, args + 1, suffix, &names);
2807 log_error("Failed to expand names: %s", strerror(-r));
2810 if (!arg_no_block) {
2811 r = enable_wait_for_jobs(bus);
2813 log_error("Could not watch jobs: %s", strerror(-r));
2817 s = set_new(&string_hash_ops);
2822 STRV_FOREACH(name, names) {
2823 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2826 q = start_unit_one(bus, method, *name, mode, &error, s);
2827 if (r >= 0 && q < 0)
2828 r = translate_bus_error_to_exit_status(q, &error);
2831 if (!arg_no_block) {
2834 q = wait_for_jobs(bus, s);
2838 /* When stopping units, warn if they can still be triggered by
2839 * another active unit (socket, path, timer) */
2840 if (!arg_quiet && streq(method, "StopUnit"))
2841 STRV_FOREACH(name, names)
2842 check_triggering_units(bus, *name);
2848 /* Ask systemd-logind, which might grant access to unprivileged users
2849 * through PolicyKit */
2850 static int reboot_with_logind(sd_bus *bus, enum action a) {
2852 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2859 polkit_agent_open_if_enabled();
2867 case ACTION_POWEROFF:
2868 method = "PowerOff";
2871 case ACTION_SUSPEND:
2875 case ACTION_HIBERNATE:
2876 method = "Hibernate";
2879 case ACTION_HYBRID_SLEEP:
2880 method = "HybridSleep";
2887 r = sd_bus_call_method(
2889 "org.freedesktop.login1",
2890 "/org/freedesktop/login1",
2891 "org.freedesktop.login1.Manager",
2895 "b", arg_ask_password);
2897 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2905 static int check_inhibitors(sd_bus *bus, enum action a) {
2907 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2908 _cleanup_strv_free_ char **sessions = NULL;
2909 const char *what, *who, *why, *mode;
2918 if (arg_ignore_inhibitors || arg_force > 0)
2930 r = sd_bus_call_method(
2932 "org.freedesktop.login1",
2933 "/org/freedesktop/login1",
2934 "org.freedesktop.login1.Manager",
2940 /* If logind is not around, then there are no inhibitors... */
2943 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2945 return bus_log_parse_error(r);
2947 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2948 _cleanup_free_ char *comm = NULL, *user = NULL;
2949 _cleanup_strv_free_ char **sv = NULL;
2951 if (!streq(mode, "block"))
2954 sv = strv_split(what, ":");
2958 if (!strv_contains(sv,
2960 a == ACTION_POWEROFF ||
2961 a == ACTION_REBOOT ||
2962 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2965 get_process_comm(pid, &comm);
2966 user = uid_to_name(uid);
2968 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2969 who, pid, strna(comm), strna(user), why);
2974 return bus_log_parse_error(r);
2976 r = sd_bus_message_exit_container(reply);
2978 return bus_log_parse_error(r);
2980 /* Check for current sessions */
2981 sd_get_sessions(&sessions);
2982 STRV_FOREACH(s, sessions) {
2983 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2985 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2988 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2991 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2994 sd_session_get_tty(*s, &tty);
2995 sd_session_get_seat(*s, &seat);
2996 sd_session_get_service(*s, &service);
2997 user = uid_to_name(uid);
2999 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
3006 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3007 action_table[a].verb);
3015 static int start_special(sd_bus *bus, char **args) {
3021 a = verb_to_action(args[0]);
3023 r = check_inhibitors(bus, a);
3027 if (arg_force >= 2 && geteuid() != 0) {
3028 log_error("Must be root.");
3032 if (arg_force >= 2 &&
3033 (a == ACTION_HALT ||
3034 a == ACTION_POWEROFF ||
3035 a == ACTION_REBOOT))
3038 if (arg_force >= 1 &&
3039 (a == ACTION_HALT ||
3040 a == ACTION_POWEROFF ||
3041 a == ACTION_REBOOT ||
3042 a == ACTION_KEXEC ||
3044 return daemon_reload(bus, args);
3046 /* first try logind, to allow authentication with polkit */
3047 if (geteuid() != 0 &&
3048 (a == ACTION_POWEROFF ||
3049 a == ACTION_REBOOT ||
3050 a == ACTION_SUSPEND ||
3051 a == ACTION_HIBERNATE ||
3052 a == ACTION_HYBRID_SLEEP)) {
3053 r = reboot_with_logind(bus, a);
3058 r = start_unit(bus, args);
3059 if (r == EXIT_SUCCESS)
3065 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3066 _cleanup_strv_free_ char **names = NULL;
3073 r = expand_names(bus, args, NULL, &names);
3075 log_error("Failed to expand names: %s", strerror(-r));
3079 STRV_FOREACH(name, names) {
3082 state = check_one_unit(bus, *name, good_states, arg_quiet);
3092 static int check_unit_active(sd_bus *bus, char **args) {
3093 /* According to LSB: 3, "program is not running" */
3094 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3097 static int check_unit_failed(sd_bus *bus, char **args) {
3098 return check_unit_generic(bus, 1, "failed\0", args + 1);
3101 static int kill_unit(sd_bus *bus, char **args) {
3102 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3103 _cleanup_strv_free_ char **names = NULL;
3111 arg_kill_who = "all";
3113 r = expand_names(bus, args + 1, NULL, &names);
3115 log_error("Failed to expand names: %s", strerror(-r));
3117 STRV_FOREACH(name, names) {
3118 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3120 q = sd_bus_message_new_method_call(
3123 "org.freedesktop.systemd1",
3124 "/org/freedesktop/systemd1",
3125 "org.freedesktop.systemd1.Manager",
3128 return bus_log_create_error(q);
3130 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3132 return bus_log_create_error(q);
3134 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3136 return bus_log_create_error(q);
3138 q = sd_bus_call(bus, m, 0, &error, NULL);
3140 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3149 typedef struct ExecStatusInfo {
3157 usec_t start_timestamp;
3158 usec_t exit_timestamp;
3163 LIST_FIELDS(struct ExecStatusInfo, exec);
3166 static void exec_status_info_free(ExecStatusInfo *i) {
3175 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3176 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3179 int32_t code, status;
3185 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3187 return bus_log_parse_error(r);
3191 r = sd_bus_message_read(m, "s", &path);
3193 return bus_log_parse_error(r);
3195 i->path = strdup(path);
3199 r = sd_bus_message_read_strv(m, &i->argv);
3201 return bus_log_parse_error(r);
3203 r = sd_bus_message_read(m,
3206 &start_timestamp, &start_timestamp_monotonic,
3207 &exit_timestamp, &exit_timestamp_monotonic,
3211 return bus_log_parse_error(r);
3214 i->start_timestamp = (usec_t) start_timestamp;
3215 i->exit_timestamp = (usec_t) exit_timestamp;
3216 i->pid = (pid_t) pid;
3220 r = sd_bus_message_exit_container(m);
3222 return bus_log_parse_error(r);
3227 typedef struct UnitStatusInfo {
3229 const char *load_state;
3230 const char *active_state;
3231 const char *sub_state;
3232 const char *unit_file_state;
3234 const char *description;
3235 const char *following;
3237 char **documentation;
3239 const char *fragment_path;
3240 const char *source_path;
3241 const char *control_group;
3243 char **dropin_paths;
3245 const char *load_error;
3248 usec_t inactive_exit_timestamp;
3249 usec_t inactive_exit_timestamp_monotonic;
3250 usec_t active_enter_timestamp;
3251 usec_t active_exit_timestamp;
3252 usec_t inactive_enter_timestamp;
3254 bool need_daemon_reload;
3259 const char *status_text;
3260 const char *pid_file;
3264 usec_t start_timestamp;
3265 usec_t exit_timestamp;
3267 int exit_code, exit_status;
3269 usec_t condition_timestamp;
3270 bool condition_result;
3271 bool failed_condition_trigger;
3272 bool failed_condition_negate;
3273 const char *failed_condition;
3274 const char *failed_condition_parameter;
3276 usec_t assert_timestamp;
3278 bool failed_assert_trigger;
3279 bool failed_assert_negate;
3280 const char *failed_assert;
3281 const char *failed_assert_parameter;
3284 unsigned n_accepted;
3285 unsigned n_connections;
3288 /* Pairs of type, path */
3292 const char *sysfs_path;
3294 /* Mount, Automount */
3300 LIST_HEAD(ExecStatusInfo, exec);
3303 static void print_status_info(
3308 const char *active_on, *active_off, *on, *off, *ss;
3310 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3311 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3314 arg_all * OUTPUT_SHOW_ALL |
3315 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3316 on_tty() * OUTPUT_COLOR |
3317 !arg_quiet * OUTPUT_WARN_CUTOFF |
3318 arg_full * OUTPUT_FULL_WIDTH;
3323 /* This shows pretty information about a unit. See
3324 * print_property() for a low-level property printer */
3326 if (streq_ptr(i->active_state, "failed")) {
3327 active_on = ansi_highlight_red();
3328 active_off = ansi_highlight_off();
3329 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3330 active_on = ansi_highlight_green();
3331 active_off = ansi_highlight_off();
3333 active_on = active_off = "";
3335 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3337 if (i->description && !streq_ptr(i->id, i->description))
3338 printf(" - %s", i->description);
3343 printf(" Follow: unit currently follows state of %s\n", i->following);
3345 if (streq_ptr(i->load_state, "error")) {
3346 on = ansi_highlight_red();
3347 off = ansi_highlight_off();
3351 path = i->source_path ? i->source_path : i->fragment_path;
3354 printf(" Loaded: %s%s%s (Reason: %s)\n",
3355 on, strna(i->load_state), off, i->load_error);
3356 else if (path && i->unit_file_state)
3357 printf(" Loaded: %s%s%s (%s; %s)\n",
3358 on, strna(i->load_state), off, path, i->unit_file_state);
3360 printf(" Loaded: %s%s%s (%s)\n",
3361 on, strna(i->load_state), off, path);
3363 printf(" Loaded: %s%s%s\n",
3364 on, strna(i->load_state), off);
3366 if (!strv_isempty(i->dropin_paths)) {
3367 _cleanup_free_ char *dir = NULL;
3371 STRV_FOREACH(dropin, i->dropin_paths) {
3372 if (! dir || last) {
3373 printf(dir ? " " : " Drop-In: ");
3378 if (path_get_parent(*dropin, &dir) < 0) {
3383 printf("%s\n %s", dir,
3384 draw_special_char(DRAW_TREE_RIGHT));
3387 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3389 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3393 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3395 printf(" Active: %s%s (%s)%s",
3396 active_on, strna(i->active_state), ss, active_off);
3398 printf(" Active: %s%s%s",
3399 active_on, strna(i->active_state), active_off);
3401 if (!isempty(i->result) && !streq(i->result, "success"))
3402 printf(" (Result: %s)", i->result);
3404 timestamp = (streq_ptr(i->active_state, "active") ||
3405 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3406 (streq_ptr(i->active_state, "inactive") ||
3407 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3408 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3409 i->active_exit_timestamp;
3411 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3412 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3415 printf(" since %s; %s\n", s2, s1);
3417 printf(" since %s\n", s2);
3421 if (!i->condition_result && i->condition_timestamp > 0) {
3422 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3423 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3425 printf("Condition: start %scondition failed%s at %s%s%s\n",
3426 ansi_highlight_yellow(), ansi_highlight_off(),
3427 s2, s1 ? "; " : "", s1 ? s1 : "");
3428 if (i->failed_condition_trigger)
3429 printf(" none of the trigger conditions were met\n");
3430 else if (i->failed_condition)
3431 printf(" %s=%s%s was not met\n",
3432 i->failed_condition,
3433 i->failed_condition_negate ? "!" : "",
3434 i->failed_condition_parameter);
3437 if (!i->assert_result && i->assert_timestamp > 0) {
3438 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3439 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3441 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3442 ansi_highlight_red(), ansi_highlight_off(),
3443 s2, s1 ? "; " : "", s1 ? s1 : "");
3444 if (i->failed_assert_trigger)
3445 printf(" none of the trigger assertions were met\n");
3446 else if (i->failed_assert)
3447 printf(" %s=%s%s was not met\n",
3449 i->failed_assert_negate ? "!" : "",
3450 i->failed_assert_parameter);
3454 printf(" Device: %s\n", i->sysfs_path);
3456 printf(" Where: %s\n", i->where);
3458 printf(" What: %s\n", i->what);
3460 STRV_FOREACH(t, i->documentation)
3461 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3463 STRV_FOREACH_PAIR(t, t2, i->listen)
3464 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3467 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3469 LIST_FOREACH(exec, p, i->exec) {
3470 _cleanup_free_ char *argv = NULL;
3473 /* Only show exited processes here */
3477 argv = strv_join(p->argv, " ");
3478 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3480 good = is_clean_exit_lsb(p->code, p->status, NULL);
3482 on = ansi_highlight_red();
3483 off = ansi_highlight_off();
3487 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3489 if (p->code == CLD_EXITED) {
3492 printf("status=%i", p->status);
3494 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3499 printf("signal=%s", signal_to_string(p->status));
3501 printf(")%s\n", off);
3503 if (i->main_pid == p->pid &&
3504 i->start_timestamp == p->start_timestamp &&
3505 i->exit_timestamp == p->start_timestamp)
3506 /* Let's not show this twice */
3509 if (p->pid == i->control_pid)
3513 if (i->main_pid > 0 || i->control_pid > 0) {
3514 if (i->main_pid > 0) {
3515 printf(" Main PID: "PID_FMT, i->main_pid);
3518 _cleanup_free_ char *comm = NULL;
3519 get_process_comm(i->main_pid, &comm);
3521 printf(" (%s)", comm);
3522 } else if (i->exit_code > 0) {
3523 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3525 if (i->exit_code == CLD_EXITED) {
3528 printf("status=%i", i->exit_status);
3530 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3535 printf("signal=%s", signal_to_string(i->exit_status));
3539 if (i->control_pid > 0)
3543 if (i->control_pid > 0) {
3544 _cleanup_free_ char *c = NULL;
3546 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3548 get_process_comm(i->control_pid, &c);
3557 printf(" Status: \"%s\"\n", i->status_text);
3558 if (i->status_errno > 0)
3559 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3561 if (i->control_group &&
3562 (i->main_pid > 0 || i->control_pid > 0 ||
3563 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3566 printf(" CGroup: %s\n", i->control_group);
3568 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3571 static const char prefix[] = " ";
3574 if (c > sizeof(prefix) - 1)
3575 c -= sizeof(prefix) - 1;
3579 if (i->main_pid > 0)
3580 extra[k++] = i->main_pid;
3582 if (i->control_pid > 0)
3583 extra[k++] = i->control_pid;
3585 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3589 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3590 show_journal_by_unit(stdout,
3594 i->inactive_exit_timestamp_monotonic,
3597 flags | OUTPUT_BEGIN_NEWLINE,
3598 arg_scope == UNIT_FILE_SYSTEM,
3602 if (i->need_daemon_reload)
3603 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3604 ansi_highlight_red(),
3605 ansi_highlight_off(),
3606 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3609 static void show_unit_help(UnitStatusInfo *i) {
3614 if (!i->documentation) {
3615 log_info("Documentation for %s not known.", i->id);
3619 STRV_FOREACH(p, i->documentation)
3620 if (startswith(*p, "man:"))
3621 show_man_page(*p + 4, false);
3623 log_info("Can't show: %s", *p);
3626 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3633 switch (contents[0]) {
3635 case SD_BUS_TYPE_STRING: {
3638 r = sd_bus_message_read(m, "s", &s);
3640 return bus_log_parse_error(r);
3643 if (streq(name, "Id"))
3645 else if (streq(name, "LoadState"))
3647 else if (streq(name, "ActiveState"))
3648 i->active_state = s;
3649 else if (streq(name, "SubState"))
3651 else if (streq(name, "Description"))
3653 else if (streq(name, "FragmentPath"))
3654 i->fragment_path = s;
3655 else if (streq(name, "SourcePath"))
3658 else if (streq(name, "DefaultControlGroup")) {
3660 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3662 i->control_group = e;
3665 else if (streq(name, "ControlGroup"))
3666 i->control_group = s;
3667 else if (streq(name, "StatusText"))
3669 else if (streq(name, "PIDFile"))
3671 else if (streq(name, "SysFSPath"))
3673 else if (streq(name, "Where"))
3675 else if (streq(name, "What"))
3677 else if (streq(name, "Following"))
3679 else if (streq(name, "UnitFileState"))
3680 i->unit_file_state = s;
3681 else if (streq(name, "Result"))
3688 case SD_BUS_TYPE_BOOLEAN: {
3691 r = sd_bus_message_read(m, "b", &b);
3693 return bus_log_parse_error(r);
3695 if (streq(name, "Accept"))
3697 else if (streq(name, "NeedDaemonReload"))
3698 i->need_daemon_reload = b;
3699 else if (streq(name, "ConditionResult"))
3700 i->condition_result = b;
3701 else if (streq(name, "AssertResult"))
3702 i->assert_result = b;
3707 case SD_BUS_TYPE_UINT32: {
3710 r = sd_bus_message_read(m, "u", &u);
3712 return bus_log_parse_error(r);
3714 if (streq(name, "MainPID")) {
3716 i->main_pid = (pid_t) u;
3719 } else if (streq(name, "ControlPID"))
3720 i->control_pid = (pid_t) u;
3721 else if (streq(name, "ExecMainPID")) {
3723 i->main_pid = (pid_t) u;
3724 } else if (streq(name, "NAccepted"))
3726 else if (streq(name, "NConnections"))
3727 i->n_connections = u;
3732 case SD_BUS_TYPE_INT32: {
3735 r = sd_bus_message_read(m, "i", &j);
3737 return bus_log_parse_error(r);
3739 if (streq(name, "ExecMainCode"))
3740 i->exit_code = (int) j;
3741 else if (streq(name, "ExecMainStatus"))
3742 i->exit_status = (int) j;
3743 else if (streq(name, "StatusErrno"))
3744 i->status_errno = (int) j;
3749 case SD_BUS_TYPE_UINT64: {
3752 r = sd_bus_message_read(m, "t", &u);
3754 return bus_log_parse_error(r);
3756 if (streq(name, "ExecMainStartTimestamp"))
3757 i->start_timestamp = (usec_t) u;
3758 else if (streq(name, "ExecMainExitTimestamp"))
3759 i->exit_timestamp = (usec_t) u;
3760 else if (streq(name, "ActiveEnterTimestamp"))
3761 i->active_enter_timestamp = (usec_t) u;
3762 else if (streq(name, "InactiveEnterTimestamp"))
3763 i->inactive_enter_timestamp = (usec_t) u;
3764 else if (streq(name, "InactiveExitTimestamp"))
3765 i->inactive_exit_timestamp = (usec_t) u;
3766 else if (streq(name, "InactiveExitTimestampMonotonic"))
3767 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3768 else if (streq(name, "ActiveExitTimestamp"))
3769 i->active_exit_timestamp = (usec_t) u;
3770 else if (streq(name, "ConditionTimestamp"))
3771 i->condition_timestamp = (usec_t) u;
3772 else if (streq(name, "AssertTimestamp"))
3773 i->assert_timestamp = (usec_t) u;
3778 case SD_BUS_TYPE_ARRAY:
3780 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3781 _cleanup_free_ ExecStatusInfo *info = NULL;
3783 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3785 return bus_log_parse_error(r);
3787 info = new0(ExecStatusInfo, 1);
3791 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3793 info->name = strdup(name);
3797 LIST_PREPEND(exec, i->exec, info);
3799 info = new0(ExecStatusInfo, 1);
3805 return bus_log_parse_error(r);
3807 r = sd_bus_message_exit_container(m);
3809 return bus_log_parse_error(r);
3813 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3814 const char *type, *path;
3816 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3818 return bus_log_parse_error(r);
3820 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3822 r = strv_extend(&i->listen, type);
3826 r = strv_extend(&i->listen, path);
3831 return bus_log_parse_error(r);
3833 r = sd_bus_message_exit_container(m);
3835 return bus_log_parse_error(r);
3839 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3841 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3843 return bus_log_parse_error(r);
3845 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3847 r = sd_bus_message_read_strv(m, &i->documentation);
3849 return bus_log_parse_error(r);
3851 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3852 const char *cond, *param;
3853 int trigger, negate;
3856 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3858 return bus_log_parse_error(r);
3860 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3861 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3862 if (state < 0 && (!trigger || !i->failed_condition)) {
3863 i->failed_condition = cond;
3864 i->failed_condition_trigger = trigger;
3865 i->failed_condition_negate = negate;
3866 i->failed_condition_parameter = param;
3870 return bus_log_parse_error(r);
3872 r = sd_bus_message_exit_container(m);
3874 return bus_log_parse_error(r);
3876 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3877 const char *cond, *param;
3878 int trigger, negate;
3881 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3883 return bus_log_parse_error(r);
3885 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3886 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3887 if (state < 0 && (!trigger || !i->failed_assert)) {
3888 i->failed_assert = cond;
3889 i->failed_assert_trigger = trigger;
3890 i->failed_assert_negate = negate;
3891 i->failed_assert_parameter = param;
3895 return bus_log_parse_error(r);
3897 r = sd_bus_message_exit_container(m);
3899 return bus_log_parse_error(r);
3906 case SD_BUS_TYPE_STRUCT_BEGIN:
3908 if (streq(name, "LoadError")) {
3909 const char *n, *message;
3911 r = sd_bus_message_read(m, "(ss)", &n, &message);
3913 return bus_log_parse_error(r);
3915 if (!isempty(message))
3916 i->load_error = message;
3929 r = sd_bus_message_skip(m, contents);
3931 return bus_log_parse_error(r);
3936 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3942 /* This is a low-level property printer, see
3943 * print_status_info() for the nicer output */
3945 if (arg_properties && !strv_find(arg_properties, name)) {
3946 /* skip what we didn't read */
3947 r = sd_bus_message_skip(m, contents);
3951 switch (contents[0]) {
3953 case SD_BUS_TYPE_STRUCT_BEGIN:
3955 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3958 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3960 return bus_log_parse_error(r);
3963 printf("%s=%"PRIu32"\n", name, u);
3965 printf("%s=\n", name);
3969 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3972 r = sd_bus_message_read(m, "(so)", &s, NULL);
3974 return bus_log_parse_error(r);
3976 if (arg_all || !isempty(s))
3977 printf("%s=%s\n", name, s);
3981 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3982 const char *a = NULL, *b = NULL;
3984 r = sd_bus_message_read(m, "(ss)", &a, &b);
3986 return bus_log_parse_error(r);
3988 if (arg_all || !isempty(a) || !isempty(b))
3989 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3992 } else if (streq_ptr(name, "SystemCallFilter")) {
3993 _cleanup_strv_free_ char **l = NULL;
3996 r = sd_bus_message_enter_container(m, 'r', "bas");
3998 return bus_log_parse_error(r);
4000 r = sd_bus_message_read(m, "b", &whitelist);
4002 return bus_log_parse_error(r);
4004 r = sd_bus_message_read_strv(m, &l);
4006 return bus_log_parse_error(r);
4008 r = sd_bus_message_exit_container(m);
4010 return bus_log_parse_error(r);
4012 if (arg_all || whitelist || !strv_isempty(l)) {
4016 fputs(name, stdout);
4022 STRV_FOREACH(i, l) {
4030 fputc('\n', stdout);
4038 case SD_BUS_TYPE_ARRAY:
4040 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4044 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4046 return bus_log_parse_error(r);
4048 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4049 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4052 return bus_log_parse_error(r);
4054 r = sd_bus_message_exit_container(m);
4056 return bus_log_parse_error(r);
4060 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4061 const char *type, *path;
4063 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4065 return bus_log_parse_error(r);
4067 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4068 printf("%s=%s\n", type, path);
4070 return bus_log_parse_error(r);
4072 r = sd_bus_message_exit_container(m);
4074 return bus_log_parse_error(r);
4078 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4079 const char *type, *path;
4081 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4083 return bus_log_parse_error(r);
4085 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4086 printf("Listen%s=%s\n", type, path);
4088 return bus_log_parse_error(r);
4090 r = sd_bus_message_exit_container(m);
4092 return bus_log_parse_error(r);
4096 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4098 uint64_t value, next_elapse;
4100 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4102 return bus_log_parse_error(r);
4104 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4105 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4107 printf("%s={ value=%s ; next_elapse=%s }\n",
4109 format_timespan(timespan1, sizeof(timespan1), value, 0),
4110 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4113 return bus_log_parse_error(r);
4115 r = sd_bus_message_exit_container(m);
4117 return bus_log_parse_error(r);
4121 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4122 ExecStatusInfo info = {};
4124 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4126 return bus_log_parse_error(r);
4128 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4129 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4130 _cleanup_free_ char *tt;
4132 tt = strv_join(info.argv, " ");
4134 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4138 yes_no(info.ignore),
4139 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4140 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4142 sigchld_code_to_string(info.code),
4144 info.code == CLD_EXITED ? "" : "/",
4145 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4148 strv_free(info.argv);
4152 r = sd_bus_message_exit_container(m);
4154 return bus_log_parse_error(r);
4158 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4159 const char *path, *rwm;
4161 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4163 return bus_log_parse_error(r);
4165 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4166 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4168 return bus_log_parse_error(r);
4170 r = sd_bus_message_exit_container(m);
4172 return bus_log_parse_error(r);
4176 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4180 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4182 return bus_log_parse_error(r);
4184 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4185 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4187 return bus_log_parse_error(r);
4189 r = sd_bus_message_exit_container(m);
4191 return bus_log_parse_error(r);
4195 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4199 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4201 return bus_log_parse_error(r);
4203 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4204 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4206 return bus_log_parse_error(r);
4208 r = sd_bus_message_exit_container(m);
4210 return bus_log_parse_error(r);
4218 r = bus_print_property(name, m, arg_all);
4220 return bus_log_parse_error(r);
4223 r = sd_bus_message_skip(m, contents);
4225 return bus_log_parse_error(r);
4228 printf("%s=[unprintable]\n", name);
4234 static int show_one(
4238 bool show_properties,
4242 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4243 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4244 UnitStatusInfo info = {};
4251 log_debug("Showing one %s", path);
4253 r = sd_bus_call_method(
4255 "org.freedesktop.systemd1",
4257 "org.freedesktop.DBus.Properties",
4263 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4267 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4269 return bus_log_parse_error(r);
4276 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4277 const char *name, *contents;
4279 r = sd_bus_message_read(reply, "s", &name);
4281 return bus_log_parse_error(r);
4283 r = sd_bus_message_peek_type(reply, NULL, &contents);
4285 return bus_log_parse_error(r);
4287 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4289 return bus_log_parse_error(r);
4291 if (show_properties)
4292 r = print_property(name, reply, contents);
4294 r = status_property(name, reply, &info, contents);
4298 r = sd_bus_message_exit_container(reply);
4300 return bus_log_parse_error(r);
4302 r = sd_bus_message_exit_container(reply);
4304 return bus_log_parse_error(r);
4307 return bus_log_parse_error(r);
4309 r = sd_bus_message_exit_container(reply);
4311 return bus_log_parse_error(r);
4315 if (!show_properties) {
4316 if (streq(verb, "help"))
4317 show_unit_help(&info);
4319 print_status_info(&info, ellipsized);
4322 strv_free(info.documentation);
4323 strv_free(info.dropin_paths);
4324 strv_free(info.listen);
4326 if (!streq_ptr(info.active_state, "active") &&
4327 !streq_ptr(info.active_state, "reloading") &&
4328 streq(verb, "status")) {
4329 /* According to LSB: "program not running" */
4330 /* 0: program is running or service is OK
4331 * 1: program is dead and /run PID file exists
4332 * 2: program is dead and /run/lock lock file exists
4333 * 3: program is not running
4334 * 4: program or service status is unknown
4336 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4342 while ((p = info.exec)) {
4343 LIST_REMOVE(exec, info.exec, p);
4344 exec_status_info_free(p);
4350 static int get_unit_dbus_path_by_pid(
4355 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4356 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4360 r = sd_bus_call_method(
4362 "org.freedesktop.systemd1",
4363 "/org/freedesktop/systemd1",
4364 "org.freedesktop.systemd1.Manager",
4370 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4374 r = sd_bus_message_read(reply, "o", &u);
4376 return bus_log_parse_error(r);
4386 static int show_all(
4389 bool show_properties,
4393 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4394 _cleanup_free_ UnitInfo *unit_infos = NULL;
4399 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4403 pager_open_if_enabled();
4407 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4409 for (u = unit_infos; u < unit_infos + c; u++) {
4410 _cleanup_free_ char *p = NULL;
4412 p = unit_dbus_path_from_name(u->id);
4416 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4419 else if (r > 0 && ret == 0)
4426 static int show_system_status(sd_bus *bus) {
4427 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4428 _cleanup_free_ char *hn = NULL;
4429 struct machine_info mi = {};
4430 const char *on, *off;
4433 hn = gethostname_malloc();
4437 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4439 log_error("Failed to read server status: %s", strerror(-r));
4443 if (streq_ptr(mi.state, "degraded")) {
4444 on = ansi_highlight_red();
4445 off = ansi_highlight_off();
4446 } else if (!streq_ptr(mi.state, "running")) {
4447 on = ansi_highlight_yellow();
4448 off = ansi_highlight_off();
4452 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4454 printf(" State: %s%s%s\n",
4455 on, strna(mi.state), off);
4457 printf(" Jobs: %u queued\n", mi.n_jobs);
4458 printf(" Failed: %u units\n", mi.n_failed_units);
4460 printf(" Since: %s; %s\n",
4461 format_timestamp(since2, sizeof(since2), mi.timestamp),
4462 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4464 printf(" CGroup: %s\n", mi.control_group ?: "/");
4465 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4467 arg_all * OUTPUT_SHOW_ALL |
4468 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4469 on_tty() * OUTPUT_COLOR |
4470 !arg_quiet * OUTPUT_WARN_CUTOFF |
4471 arg_full * OUTPUT_FULL_WIDTH;
4473 static const char prefix[] = " ";
4477 if (c > sizeof(prefix) - 1)
4478 c -= sizeof(prefix) - 1;
4482 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4486 free(mi.control_group);
4491 static int show(sd_bus *bus, char **args) {
4492 bool show_properties, show_status, new_line = false;
4493 bool ellipsized = false;
4499 show_properties = streq(args[0], "show");
4500 show_status = streq(args[0], "status");
4502 if (show_properties)
4503 pager_open_if_enabled();
4505 /* If no argument is specified inspect the manager itself */
4507 if (show_properties && strv_length(args) <= 1)
4508 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4510 if (show_status && strv_length(args) <= 1) {
4512 pager_open_if_enabled();
4513 show_system_status(bus);
4517 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4519 _cleanup_free_ char **patterns = NULL;
4522 STRV_FOREACH(name, args + 1) {
4523 _cleanup_free_ char *unit = NULL;
4526 if (safe_atou32(*name, &id) < 0) {
4527 if (strv_push(&patterns, *name) < 0)
4531 } else if (show_properties) {
4532 /* Interpret as job id */
4533 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4537 /* Interpret as PID */
4538 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4545 r = show_one(args[0], bus, unit, show_properties,
4546 &new_line, &ellipsized);
4549 else if (r > 0 && ret == 0)
4553 if (!strv_isempty(patterns)) {
4554 _cleanup_strv_free_ char **names = NULL;
4556 r = expand_names(bus, patterns, NULL, &names);
4558 log_error("Failed to expand names: %s", strerror(-r));
4560 STRV_FOREACH(name, names) {
4561 _cleanup_free_ char *unit;
4563 unit = unit_dbus_path_from_name(*name);
4567 r = show_one(args[0], bus, unit, show_properties,
4568 &new_line, &ellipsized);
4571 else if (r > 0 && ret == 0)
4577 if (ellipsized && !arg_quiet)
4578 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4583 static int cat(sd_bus *bus, char **args) {
4584 _cleanup_strv_free_ char **names = NULL;
4592 r = expand_names(bus, args + 1, NULL, &names);
4594 log_error("Failed to expand names: %s", strerror(-r));
4596 pager_open_if_enabled();
4598 STRV_FOREACH(name, names) {
4599 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4600 _cleanup_strv_free_ char **dropin_paths = NULL;
4601 _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
4604 unit = unit_dbus_path_from_name(*name);
4608 if (need_daemon_reload(bus, *name) > 0)
4609 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4610 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4612 r = sd_bus_get_property_string(
4614 "org.freedesktop.systemd1",
4616 "org.freedesktop.systemd1.Unit",
4621 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4625 r = sd_bus_get_property_strv(
4627 "org.freedesktop.systemd1",
4629 "org.freedesktop.systemd1.Unit",
4634 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4643 if (!isempty(fragment_path)) {
4644 printf("%s# %s%s\n",
4645 ansi_highlight_blue(),
4647 ansi_highlight_off());
4650 r = sendfile_full(STDOUT_FILENO, fragment_path);
4652 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4657 STRV_FOREACH(path, dropin_paths) {
4658 printf("%s%s# %s%s\n",
4659 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4660 ansi_highlight_blue(),
4662 ansi_highlight_off());
4665 r = sendfile_full(STDOUT_FILENO, *path);
4667 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4673 return r < 0 ? r : 0;
4676 static int set_property(sd_bus *bus, char **args) {
4677 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4678 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4679 _cleanup_free_ char *n = NULL;
4683 r = sd_bus_message_new_method_call(
4686 "org.freedesktop.systemd1",
4687 "/org/freedesktop/systemd1",
4688 "org.freedesktop.systemd1.Manager",
4689 "SetUnitProperties");
4691 return bus_log_create_error(r);
4693 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4695 return bus_log_create_error(r);
4697 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4701 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4703 return bus_log_create_error(r);
4705 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4707 return bus_log_create_error(r);
4709 STRV_FOREACH(i, args + 2) {
4710 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4712 return bus_log_create_error(r);
4714 r = bus_append_unit_property_assignment(m, *i);
4718 r = sd_bus_message_close_container(m);
4720 return bus_log_create_error(r);
4723 r = sd_bus_message_close_container(m);
4725 return bus_log_create_error(r);
4727 r = sd_bus_call(bus, m, 0, &error, NULL);
4729 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4736 static int snapshot(sd_bus *bus, char **args) {
4737 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4738 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4739 _cleanup_free_ char *n = NULL, *id = NULL;
4743 if (strv_length(args) > 1)
4744 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4750 r = sd_bus_message_new_method_call(
4753 "org.freedesktop.systemd1",
4754 "/org/freedesktop/systemd1",
4755 "org.freedesktop.systemd1.Manager",
4758 return bus_log_create_error(r);
4760 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4762 return bus_log_create_error(r);
4764 r = sd_bus_message_append(m, "sb", n, false);
4766 return bus_log_create_error(r);
4768 r = sd_bus_call(bus, m, 0, &error, &reply);
4770 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4774 r = sd_bus_message_read(reply, "o", &path);
4776 return bus_log_parse_error(r);
4778 r = sd_bus_get_property_string(
4780 "org.freedesktop.systemd1",
4782 "org.freedesktop.systemd1.Unit",
4787 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4797 static int delete_snapshot(sd_bus *bus, char **args) {
4798 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4799 _cleanup_strv_free_ char **names = NULL;
4805 r = expand_names(bus, args + 1, ".snapshot", &names);
4807 log_error("Failed to expand names: %s", strerror(-r));
4809 STRV_FOREACH(name, names) {
4810 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4813 q = sd_bus_message_new_method_call(
4816 "org.freedesktop.systemd1",
4817 "/org/freedesktop/systemd1",
4818 "org.freedesktop.systemd1.Manager",
4821 return bus_log_create_error(q);
4823 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4825 return bus_log_create_error(q);
4827 q = sd_bus_message_append(m, "s", *name);
4829 return bus_log_create_error(q);
4831 q = sd_bus_call(bus, m, 0, &error, NULL);
4833 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4842 static int daemon_reload(sd_bus *bus, char **args) {
4843 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4844 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4848 if (arg_action == ACTION_RELOAD)
4850 else if (arg_action == ACTION_REEXEC)
4851 method = "Reexecute";
4853 assert(arg_action == ACTION_SYSTEMCTL);
4856 streq(args[0], "clear-jobs") ||
4857 streq(args[0], "cancel") ? "ClearJobs" :
4858 streq(args[0], "daemon-reexec") ? "Reexecute" :
4859 streq(args[0], "reset-failed") ? "ResetFailed" :
4860 streq(args[0], "halt") ? "Halt" :
4861 streq(args[0], "poweroff") ? "PowerOff" :
4862 streq(args[0], "reboot") ? "Reboot" :
4863 streq(args[0], "kexec") ? "KExec" :
4864 streq(args[0], "exit") ? "Exit" :
4865 /* "daemon-reload" */ "Reload";
4868 r = sd_bus_message_new_method_call(
4871 "org.freedesktop.systemd1",
4872 "/org/freedesktop/systemd1",
4873 "org.freedesktop.systemd1.Manager",
4876 return bus_log_create_error(r);
4878 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4880 return bus_log_create_error(r);
4882 r = sd_bus_call(bus, m, 0, &error, NULL);
4883 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4884 /* There's always a fallback possible for
4885 * legacy actions. */
4887 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4888 /* On reexecution, we expect a disconnect, not a
4892 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4894 return r < 0 ? r : 0;
4897 static int reset_failed(sd_bus *bus, char **args) {
4898 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4899 _cleanup_strv_free_ char **names = NULL;
4903 if (strv_length(args) <= 1)
4904 return daemon_reload(bus, args);
4906 r = expand_names(bus, args + 1, NULL, &names);
4908 log_error("Failed to expand names: %s", strerror(-r));
4910 STRV_FOREACH(name, names) {
4911 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4913 q = sd_bus_message_new_method_call(
4916 "org.freedesktop.systemd1",
4917 "/org/freedesktop/systemd1",
4918 "org.freedesktop.systemd1.Manager",
4921 return bus_log_create_error(q);
4923 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4925 return bus_log_create_error(q);
4927 q = sd_bus_message_append(m, "s", *name);
4929 return bus_log_create_error(q);
4931 q = sd_bus_call(bus, m, 0, &error, NULL);
4933 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4942 static int show_environment(sd_bus *bus, char **args) {
4943 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4944 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4948 pager_open_if_enabled();
4950 r = sd_bus_get_property(
4952 "org.freedesktop.systemd1",
4953 "/org/freedesktop/systemd1",
4954 "org.freedesktop.systemd1.Manager",
4960 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4964 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4966 return bus_log_parse_error(r);
4968 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4971 return bus_log_parse_error(r);
4973 r = sd_bus_message_exit_container(reply);
4975 return bus_log_parse_error(r);
4980 static int switch_root(sd_bus *bus, char **args) {
4981 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4982 _cleanup_free_ char *cmdline_init = NULL;
4983 const char *root, *init;
4987 l = strv_length(args);
4988 if (l < 2 || l > 3) {
4989 log_error("Wrong number of arguments.");
4998 r = parse_env_file("/proc/cmdline", WHITESPACE,
4999 "init", &cmdline_init,
5002 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
5004 init = cmdline_init;
5011 const char *root_systemd_path = NULL, *root_init_path = NULL;
5013 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
5014 root_init_path = strappenda(root, "/", init);
5016 /* If the passed init is actually the same as the
5017 * systemd binary, then let's suppress it. */
5018 if (files_same(root_init_path, root_systemd_path) > 0)
5022 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5024 r = sd_bus_call_method(
5026 "org.freedesktop.systemd1",
5027 "/org/freedesktop/systemd1",
5028 "org.freedesktop.systemd1.Manager",
5034 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5041 static int set_environment(sd_bus *bus, char **args) {
5042 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5043 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5050 method = streq(args[0], "set-environment")
5052 : "UnsetEnvironment";
5054 r = sd_bus_message_new_method_call(
5057 "org.freedesktop.systemd1",
5058 "/org/freedesktop/systemd1",
5059 "org.freedesktop.systemd1.Manager",
5062 return bus_log_create_error(r);
5064 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5066 return bus_log_create_error(r);
5068 r = sd_bus_message_append_strv(m, args + 1);
5070 return bus_log_create_error(r);
5072 r = sd_bus_call(bus, m, 0, &error, NULL);
5074 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5081 static int import_environment(sd_bus *bus, char **args) {
5082 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5083 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5089 r = sd_bus_message_new_method_call(
5092 "org.freedesktop.systemd1",
5093 "/org/freedesktop/systemd1",
5094 "org.freedesktop.systemd1.Manager",
5097 return bus_log_create_error(r);
5099 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5101 return bus_log_create_error(r);
5103 if (strv_isempty(args + 1))
5104 r = sd_bus_message_append_strv(m, environ);
5108 r = sd_bus_message_open_container(m, 'a', "s");
5110 return bus_log_create_error(r);
5112 STRV_FOREACH(a, args + 1) {
5114 if (!env_name_is_valid(*a)) {
5115 log_error("Not a valid environment variable name: %s", *a);
5119 STRV_FOREACH(b, environ) {
5122 eq = startswith(*b, *a);
5123 if (eq && *eq == '=') {
5125 r = sd_bus_message_append(m, "s", *b);
5127 return bus_log_create_error(r);
5134 r = sd_bus_message_close_container(m);
5137 return bus_log_create_error(r);
5139 r = sd_bus_call(bus, m, 0, &error, NULL);
5141 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5148 static int enable_sysv_units(const char *verb, char **args) {
5151 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5152 unsigned f = 1, t = 1;
5153 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5155 if (arg_scope != UNIT_FILE_SYSTEM)
5158 if (!streq(verb, "enable") &&
5159 !streq(verb, "disable") &&
5160 !streq(verb, "is-enabled"))
5163 /* Processes all SysV units, and reshuffles the array so that
5164 * afterwards only the native units remain */
5166 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5171 for (f = 0; args[f]; f++) {
5173 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5174 bool found_native = false, found_sysv;
5176 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5184 if (!endswith(name, ".service"))
5187 if (path_is_absolute(name))
5190 STRV_FOREACH(k, paths.unit_path) {
5191 _cleanup_free_ char *path = NULL;
5193 path = path_join(arg_root, *k, name);
5197 found_native = access(path, F_OK) >= 0;
5205 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5209 p[strlen(p) - strlen(".service")] = 0;
5210 found_sysv = access(p, F_OK) >= 0;
5214 /* Mark this entry, so that we don't try enabling it as native unit */
5215 args[f] = (char*) "";
5217 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5219 if (!isempty(arg_root))
5220 argv[c++] = q = strappend("--root=", arg_root);
5222 argv[c++] = basename(p);
5224 streq(verb, "enable") ? "on" :
5225 streq(verb, "disable") ? "off" : "--level=5";
5228 l = strv_join((char**)argv, " ");
5232 log_info("Executing %s", l);
5236 log_error("Failed to fork: %m");
5238 } else if (pid == 0) {
5241 execv(argv[0], (char**) argv);
5242 _exit(EXIT_FAILURE);
5245 j = wait_for_terminate(pid, &status);
5247 log_error("Failed to wait for child: %s", strerror(-r));
5251 if (status.si_code == CLD_EXITED) {
5252 if (streq(verb, "is-enabled")) {
5253 if (status.si_status == 0) {
5262 } else if (status.si_status != 0)
5268 /* Drop all SysV units */
5269 for (f = 0, t = 0; args[f]; f++) {
5271 if (isempty(args[f]))
5274 args[t++] = args[f];
5283 static int mangle_names(char **original_names, char ***mangled_names) {
5284 char **i, **l, **name;
5286 l = new(char*, strv_length(original_names) + 1);
5291 STRV_FOREACH(name, original_names) {
5293 /* When enabling units qualified path names are OK,
5294 * too, hence allow them explicitly. */
5299 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5315 static int enable_unit(sd_bus *bus, char **args) {
5316 _cleanup_strv_free_ char **names = NULL;
5317 const char *verb = args[0];
5318 UnitFileChange *changes = NULL;
5319 unsigned n_changes = 0;
5320 int carries_install_info = -1;
5326 r = mangle_names(args+1, &names);
5330 r = enable_sysv_units(verb, names);
5334 /* If the operation was fully executed by the SysV compat,
5335 * let's finish early */
5336 if (strv_isempty(names))
5339 if (!bus || avoid_bus()) {
5340 if (streq(verb, "enable")) {
5341 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5342 carries_install_info = r;
5343 } else if (streq(verb, "disable"))
5344 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5345 else if (streq(verb, "reenable")) {
5346 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5347 carries_install_info = r;
5348 } else if (streq(verb, "link"))
5349 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5350 else if (streq(verb, "preset")) {
5351 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5352 carries_install_info = r;
5353 } else if (streq(verb, "mask"))
5354 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5355 else if (streq(verb, "unmask"))
5356 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5358 assert_not_reached("Unknown verb");
5361 log_error("Operation failed: %s", strerror(-r));
5366 dump_unit_file_changes(changes, n_changes);
5370 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5371 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5372 int expect_carries_install_info = false;
5373 bool send_force = true, send_preset_mode = false;
5376 if (streq(verb, "enable")) {
5377 method = "EnableUnitFiles";
5378 expect_carries_install_info = true;
5379 } else if (streq(verb, "disable")) {
5380 method = "DisableUnitFiles";
5382 } else if (streq(verb, "reenable")) {
5383 method = "ReenableUnitFiles";
5384 expect_carries_install_info = true;
5385 } else if (streq(verb, "link"))
5386 method = "LinkUnitFiles";
5387 else if (streq(verb, "preset")) {
5389 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5390 method = "PresetUnitFilesWithMode";
5391 send_preset_mode = true;
5393 method = "PresetUnitFiles";
5395 expect_carries_install_info = true;
5396 } else if (streq(verb, "mask"))
5397 method = "MaskUnitFiles";
5398 else if (streq(verb, "unmask")) {
5399 method = "UnmaskUnitFiles";
5402 assert_not_reached("Unknown verb");
5404 r = sd_bus_message_new_method_call(
5407 "org.freedesktop.systemd1",
5408 "/org/freedesktop/systemd1",
5409 "org.freedesktop.systemd1.Manager",
5412 return bus_log_create_error(r);
5414 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5416 return bus_log_create_error(r);
5418 r = sd_bus_message_append_strv(m, names);
5420 return bus_log_create_error(r);
5422 if (send_preset_mode) {
5423 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5425 return bus_log_create_error(r);
5428 r = sd_bus_message_append(m, "b", arg_runtime);
5430 return bus_log_create_error(r);
5433 r = sd_bus_message_append(m, "b", arg_force);
5435 return bus_log_create_error(r);
5438 r = sd_bus_call(bus, m, 0, &error, &reply);
5440 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5444 if (expect_carries_install_info) {
5445 r = sd_bus_message_read(reply, "b", &carries_install_info);
5447 return bus_log_parse_error(r);
5450 r = deserialize_and_dump_unit_file_changes(reply);
5454 /* Try to reload if enabled */
5456 r = daemon_reload(bus, args);
5461 if (carries_install_info == 0)
5462 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5463 "using systemctl.\n"
5464 "Possible reasons for having this kind of units are:\n"
5465 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5466 " .wants/ or .requires/ directory.\n"
5467 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5468 " a requirement dependency on it.\n"
5469 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5470 " D-Bus, udev, scripted systemctl call, ...).\n");
5473 unit_file_changes_free(changes, n_changes);
5478 static int add_dependency(sd_bus *bus, char **args) {
5479 _cleanup_strv_free_ char **names = NULL;
5480 _cleanup_free_ char *target = NULL;
5481 const char *verb = args[0];
5488 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5492 r = mangle_names(args+2, &names);
5496 if (streq(verb, "add-wants"))
5498 else if (streq(verb, "add-requires"))
5499 dep = UNIT_REQUIRES;
5501 assert_not_reached("Unknown verb");
5503 if (!bus || avoid_bus()) {
5504 UnitFileChange *changes = NULL;
5505 unsigned n_changes = 0;
5507 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5510 log_error("Can't add dependency: %s", strerror(-r));
5515 dump_unit_file_changes(changes, n_changes);
5517 unit_file_changes_free(changes, n_changes);
5520 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5521 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5523 r = sd_bus_message_new_method_call(
5526 "org.freedesktop.systemd1",
5527 "/org/freedesktop/systemd1",
5528 "org.freedesktop.systemd1.Manager",
5529 "AddDependencyUnitFiles");
5531 return bus_log_create_error(r);
5533 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5535 return bus_log_create_error(r);
5537 r = sd_bus_message_append_strv(m, names);
5539 return bus_log_create_error(r);
5541 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5543 return bus_log_create_error(r);
5545 r = sd_bus_call(bus, m, 0, &error, &reply);
5547 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5551 r = deserialize_and_dump_unit_file_changes(reply);
5556 r = daemon_reload(bus, args);
5564 static int preset_all(sd_bus *bus, char **args) {
5565 UnitFileChange *changes = NULL;
5566 unsigned n_changes = 0;
5569 if (!bus || avoid_bus()) {
5571 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5573 log_error("Operation failed: %s", strerror(-r));
5578 dump_unit_file_changes(changes, n_changes);
5583 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5584 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5586 r = sd_bus_message_new_method_call(
5589 "org.freedesktop.systemd1",
5590 "/org/freedesktop/systemd1",
5591 "org.freedesktop.systemd1.Manager",
5592 "PresetAllUnitFiles");
5594 return bus_log_create_error(r);
5596 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5598 return bus_log_create_error(r);
5600 r = sd_bus_message_append(
5603 unit_file_preset_mode_to_string(arg_preset_mode),
5607 return bus_log_create_error(r);
5609 r = sd_bus_call(bus, m, 0, &error, &reply);
5611 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5615 r = deserialize_and_dump_unit_file_changes(reply);
5620 r = daemon_reload(bus, args);
5626 unit_file_changes_free(changes, n_changes);
5631 static int unit_is_enabled(sd_bus *bus, char **args) {
5633 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5634 _cleanup_strv_free_ char **names = NULL;
5639 r = mangle_names(args+1, &names);
5643 r = enable_sysv_units(args[0], names);
5649 if (!bus || avoid_bus()) {
5651 STRV_FOREACH(name, names) {
5652 UnitFileState state;
5654 state = unit_file_get_state(arg_scope, arg_root, *name);
5656 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5660 if (state == UNIT_FILE_ENABLED ||
5661 state == UNIT_FILE_ENABLED_RUNTIME ||
5662 state == UNIT_FILE_STATIC)
5666 puts(unit_file_state_to_string(state));
5670 STRV_FOREACH(name, names) {
5671 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5674 r = sd_bus_call_method(
5676 "org.freedesktop.systemd1",
5677 "/org/freedesktop/systemd1",
5678 "org.freedesktop.systemd1.Manager",
5684 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5688 r = sd_bus_message_read(reply, "s", &s);
5690 return bus_log_parse_error(r);
5692 if (streq(s, "enabled") ||
5693 streq(s, "enabled-runtime") ||
5705 static int is_system_running(sd_bus *bus, char **args) {
5706 _cleanup_free_ char *state = NULL;
5709 r = sd_bus_get_property_string(
5711 "org.freedesktop.systemd1",
5712 "/org/freedesktop/systemd1",
5713 "org.freedesktop.systemd1.Manager",
5726 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5729 static void systemctl_help(void) {
5731 pager_open_if_enabled();
5733 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5734 "Query or send control commands to the systemd manager.\n\n"
5735 " -h --help Show this help\n"
5736 " --version Show package version\n"
5737 " --system Connect to system manager\n"
5738 " --user Connect to user service manager\n"
5739 " -H --host=[USER@]HOST\n"
5740 " Operate on remote host\n"
5741 " -M --machine=CONTAINER\n"
5742 " Operate on local container\n"
5743 " -t --type=TYPE List only units of a particular type\n"
5744 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5745 " -p --property=NAME Show only properties by this name\n"
5746 " -a --all Show all loaded units/properties, including dead/empty\n"
5747 " ones. To list all units installed on the system, use\n"
5748 " the 'list-unit-files' command instead.\n"
5749 " -l --full Don't ellipsize unit names on output\n"
5750 " -r --recursive Show unit list of host and local containers\n"
5751 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5752 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5753 " queueing a new job\n"
5754 " --show-types When showing sockets, explicitly show their type\n"
5755 " -i --ignore-inhibitors\n"
5756 " When shutting down or sleeping, ignore inhibitors\n"
5757 " --kill-who=WHO Who to send signal to\n"
5758 " -s --signal=SIGNAL Which signal to send\n"
5759 " -q --quiet Suppress output\n"
5760 " --no-block Do not wait until operation finished\n"
5761 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5762 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5764 " --no-legend Do not print a legend (column headers and hints)\n"
5765 " --no-pager Do not pipe output into a pager\n"
5766 " --no-ask-password\n"
5767 " Do not ask for system passwords\n"
5768 " --global Enable/disable unit files globally\n"
5769 " --runtime Enable unit files only temporarily until next reboot\n"
5770 " -f --force When enabling unit files, override existing symlinks\n"
5771 " When shutting down, execute action immediately\n"
5772 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
5773 " or only disable\n"
5774 " --root=PATH Enable unit files in the specified root directory\n"
5775 " -n --lines=INTEGER Number of journal entries to show\n"
5776 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5777 " verbose, export, json, json-pretty, json-sse, cat)\n"
5778 " --plain Print unit dependencies as a list instead of a tree\n\n"
5780 " list-units [PATTERN...] List loaded units\n"
5781 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5782 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5783 " start NAME... Start (activate) one or more units\n"
5784 " stop NAME... Stop (deactivate) one or more units\n"
5785 " reload NAME... Reload one or more units\n"
5786 " restart NAME... Start or restart one or more units\n"
5787 " try-restart NAME... Restart one or more units if active\n"
5788 " reload-or-restart NAME... Reload one or more units if possible,\n"
5789 " otherwise start or restart\n"
5790 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5791 " otherwise restart if active\n"
5792 " isolate NAME Start one unit and stop all others\n"
5793 " kill NAME... Send signal to processes of a unit\n"
5794 " is-active PATTERN... Check whether units are active\n"
5795 " is-failed PATTERN... Check whether units are failed\n"
5796 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5797 " show [PATTERN...|JOB...] Show properties of one or more\n"
5798 " units/jobs or the manager\n"
5799 " cat PATTERN... Show files and drop-ins of one or more units\n"
5800 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5801 " help PATTERN...|PID... Show manual for one or more units\n"
5802 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5804 " list-dependencies [NAME] Recursively show units which are required\n"
5805 " or wanted by this unit or by which this\n"
5806 " unit is required or wanted\n\n"
5807 "Unit File Commands:\n"
5808 " list-unit-files [PATTERN...] List installed unit files\n"
5809 " enable NAME... Enable one or more unit files\n"
5810 " disable NAME... Disable one or more unit files\n"
5811 " reenable NAME... Reenable one or more unit files\n"
5812 " preset NAME... Enable/disable one or more unit files\n"
5813 " based on preset configuration\n"
5814 " preset-all Enable/disable all unit files based on\n"
5815 " preset configuration\n"
5816 " is-enabled NAME... Check whether unit files are enabled\n\n"
5817 " mask NAME... Mask one or more units\n"
5818 " unmask NAME... Unmask one or more units\n"
5819 " link PATH... Link one or more units files into\n"
5820 " the search path\n"
5821 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
5822 " on specified one or more units\n"
5823 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
5824 " on specified one or more units\n"
5825 " get-default Get the name of the default target\n"
5826 " set-default NAME Set the default target\n\n"
5827 "Machine Commands:\n"
5828 " list-machines [PATTERN...] List local containers and host\n\n"
5830 " list-jobs [PATTERN...] List jobs\n"
5831 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5832 "Snapshot Commands:\n"
5833 " snapshot [NAME] Create a snapshot\n"
5834 " delete NAME... Remove one or more snapshots\n\n"
5835 "Environment Commands:\n"
5836 " show-environment Dump environment\n"
5837 " set-environment NAME=VALUE... Set one or more environment variables\n"
5838 " unset-environment NAME... Unset one or more environment variables\n"
5839 " import-environment NAME... Import all, one or more environment variables\n\n"
5840 "Manager Lifecycle Commands:\n"
5841 " daemon-reload Reload systemd manager configuration\n"
5842 " daemon-reexec Reexecute systemd manager\n\n"
5843 "System Commands:\n"
5844 " is-system-running Check whether system is fully running\n"
5845 " default Enter system default mode\n"
5846 " rescue Enter system rescue mode\n"
5847 " emergency Enter system emergency mode\n"
5848 " halt Shut down and halt the system\n"
5849 " poweroff Shut down and power-off the system\n"
5850 " reboot [ARG] Shut down and reboot the system\n"
5851 " kexec Shut down and reboot the system with kexec\n"
5852 " exit Request user instance exit\n"
5853 " switch-root ROOT [INIT] Change to a different root file system\n"
5854 " suspend Suspend the system\n"
5855 " hibernate Hibernate the system\n"
5856 " hybrid-sleep Hibernate and suspend the system\n",
5857 program_invocation_short_name);
5860 static void halt_help(void) {
5861 printf("%s [OPTIONS...]%s\n\n"
5862 "%s the system.\n\n"
5863 " --help Show this help\n"
5864 " --halt Halt the machine\n"
5865 " -p --poweroff Switch off the machine\n"
5866 " --reboot Reboot the machine\n"
5867 " -f --force Force immediate halt/power-off/reboot\n"
5868 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5869 " -d --no-wtmp Don't write wtmp record\n"
5870 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5871 program_invocation_short_name,
5872 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5873 arg_action == ACTION_REBOOT ? "Reboot" :
5874 arg_action == ACTION_POWEROFF ? "Power off" :
5878 static void shutdown_help(void) {
5879 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5880 "Shut down the system.\n\n"
5881 " --help Show this help\n"
5882 " -H --halt Halt the machine\n"
5883 " -P --poweroff Power-off the machine\n"
5884 " -r --reboot Reboot the machine\n"
5885 " -h Equivalent to --poweroff, overridden by --halt\n"
5886 " -k Don't halt/power-off/reboot, just send warnings\n"
5887 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5888 " -c Cancel a pending shutdown\n",
5889 program_invocation_short_name);
5892 static void telinit_help(void) {
5893 printf("%s [OPTIONS...] {COMMAND}\n\n"
5894 "Send control commands to the init daemon.\n\n"
5895 " --help Show this help\n"
5896 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5898 " 0 Power-off the machine\n"
5899 " 6 Reboot the machine\n"
5900 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5901 " 1, s, S Enter rescue mode\n"
5902 " q, Q Reload init daemon configuration\n"
5903 " u, U Reexecute init daemon\n",
5904 program_invocation_short_name);
5907 static void runlevel_help(void) {
5908 printf("%s [OPTIONS...]\n\n"
5909 "Prints the previous and current runlevel of the init system.\n\n"
5910 " --help Show this help\n",
5911 program_invocation_short_name);
5914 static void help_types(void) {
5919 puts("Available unit types:");
5920 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5921 t = unit_type_to_string(i);
5927 static int systemctl_parse_argv(int argc, char *argv[]) {
5936 ARG_IGNORE_DEPENDENCIES,
5948 ARG_NO_ASK_PASSWORD,
5958 static const struct option options[] = {
5959 { "help", no_argument, NULL, 'h' },
5960 { "version", no_argument, NULL, ARG_VERSION },
5961 { "type", required_argument, NULL, 't' },
5962 { "property", required_argument, NULL, 'p' },
5963 { "all", no_argument, NULL, 'a' },
5964 { "reverse", no_argument, NULL, ARG_REVERSE },
5965 { "after", no_argument, NULL, ARG_AFTER },
5966 { "before", no_argument, NULL, ARG_BEFORE },
5967 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5968 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5969 { "full", no_argument, NULL, 'l' },
5970 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5971 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5972 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5973 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5974 { "ignore-inhibitors", no_argument, NULL, 'i' },
5975 { "user", no_argument, NULL, ARG_USER },
5976 { "system", no_argument, NULL, ARG_SYSTEM },
5977 { "global", no_argument, NULL, ARG_GLOBAL },
5978 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5979 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5980 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5981 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5982 { "quiet", no_argument, NULL, 'q' },
5983 { "root", required_argument, NULL, ARG_ROOT },
5984 { "force", no_argument, NULL, ARG_FORCE },
5985 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5986 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5987 { "signal", required_argument, NULL, 's' },
5988 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5989 { "host", required_argument, NULL, 'H' },
5990 { "machine", required_argument, NULL, 'M' },
5991 { "runtime", no_argument, NULL, ARG_RUNTIME },
5992 { "lines", required_argument, NULL, 'n' },
5993 { "output", required_argument, NULL, 'o' },
5994 { "plain", no_argument, NULL, ARG_PLAIN },
5995 { "state", required_argument, NULL, ARG_STATE },
5996 { "recursive", no_argument, NULL, 'r' },
5997 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6006 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6015 puts(PACKAGE_STRING);
6016 puts(SYSTEMD_FEATURES);
6020 const char *word, *state;
6023 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6024 _cleanup_free_ char *type;
6026 type = strndup(word, size);
6030 if (streq(type, "help")) {
6035 if (unit_type_from_string(type) >= 0) {
6036 if (strv_push(&arg_types, type))
6042 /* It's much nicer to use --state= for
6043 * load states, but let's support this
6044 * in --types= too for compatibility
6045 * with old versions */
6046 if (unit_load_state_from_string(optarg) >= 0) {
6047 if (strv_push(&arg_states, type) < 0)
6053 log_error("Unknown unit type or load state '%s'.", type);
6054 log_info("Use -t help to see a list of allowed values.");
6062 /* Make sure that if the empty property list
6063 was specified, we won't show any properties. */
6064 if (isempty(optarg) && !arg_properties) {
6065 arg_properties = new0(char*, 1);
6066 if (!arg_properties)
6069 const char *word, *state;
6072 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6075 prop = strndup(word, size);
6079 if (strv_consume(&arg_properties, prop) < 0)
6084 /* If the user asked for a particular
6085 * property, show it to him, even if it is
6097 arg_dependency = DEPENDENCY_REVERSE;
6101 arg_dependency = DEPENDENCY_AFTER;
6105 arg_dependency = DEPENDENCY_BEFORE;
6108 case ARG_SHOW_TYPES:
6109 arg_show_types = true;
6113 arg_job_mode = optarg;
6117 arg_job_mode = "fail";
6120 case ARG_IRREVERSIBLE:
6121 arg_job_mode = "replace-irreversibly";
6124 case ARG_IGNORE_DEPENDENCIES:
6125 arg_job_mode = "ignore-dependencies";
6129 arg_scope = UNIT_FILE_USER;
6133 arg_scope = UNIT_FILE_SYSTEM;
6137 arg_scope = UNIT_FILE_GLOBAL;
6141 arg_no_block = true;
6145 arg_no_legend = true;
6149 arg_no_pager = true;
6165 if (strv_extend(&arg_states, "failed") < 0)
6183 arg_no_reload = true;
6187 arg_kill_who = optarg;
6191 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6192 log_error("Failed to parse signal string %s.", optarg);
6197 case ARG_NO_ASK_PASSWORD:
6198 arg_ask_password = false;
6202 arg_transport = BUS_TRANSPORT_REMOTE;
6207 arg_transport = BUS_TRANSPORT_CONTAINER;
6216 if (safe_atou(optarg, &arg_lines) < 0) {
6217 log_error("Failed to parse lines '%s'", optarg);
6223 arg_output = output_mode_from_string(optarg);
6224 if (arg_output < 0) {
6225 log_error("Unknown output '%s'.", optarg);
6231 arg_ignore_inhibitors = true;
6239 const char *word, *state;
6242 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6245 s = strndup(word, size);
6249 if (strv_consume(&arg_states, s) < 0)
6256 if (geteuid() != 0) {
6257 log_error("--recursive requires root privileges.");
6261 arg_recursive = true;
6264 case ARG_PRESET_MODE:
6266 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6267 if (arg_preset_mode < 0) {
6268 log_error("Failed to parse preset mode: %s.", optarg);
6278 assert_not_reached("Unhandled option");
6281 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6282 log_error("Cannot access user instance remotely.");
6289 static int halt_parse_argv(int argc, char *argv[]) {
6298 static const struct option options[] = {
6299 { "help", no_argument, NULL, ARG_HELP },
6300 { "halt", no_argument, NULL, ARG_HALT },
6301 { "poweroff", no_argument, NULL, 'p' },
6302 { "reboot", no_argument, NULL, ARG_REBOOT },
6303 { "force", no_argument, NULL, 'f' },
6304 { "wtmp-only", no_argument, NULL, 'w' },
6305 { "no-wtmp", no_argument, NULL, 'd' },
6306 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6315 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6316 if (runlevel == '0' || runlevel == '6')
6319 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6327 arg_action = ACTION_HALT;
6331 if (arg_action != ACTION_REBOOT)
6332 arg_action = ACTION_POWEROFF;
6336 arg_action = ACTION_REBOOT;
6358 /* Compatibility nops */
6365 assert_not_reached("Unhandled option");
6368 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6369 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6372 } else if (optind < argc) {
6373 log_error("Too many arguments.");
6380 static int parse_time_spec(const char *t, usec_t *_u) {
6384 if (streq(t, "now"))
6386 else if (!strchr(t, ':')) {
6389 if (safe_atou64(t, &u) < 0)
6392 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6401 hour = strtol(t, &e, 10);
6402 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6405 minute = strtol(e+1, &e, 10);
6406 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6409 n = now(CLOCK_REALTIME);
6410 s = (time_t) (n / USEC_PER_SEC);
6412 assert_se(localtime_r(&s, &tm));
6414 tm.tm_hour = (int) hour;
6415 tm.tm_min = (int) minute;
6418 assert_se(s = mktime(&tm));
6420 *_u = (usec_t) s * USEC_PER_SEC;
6423 *_u += USEC_PER_DAY;
6429 static int shutdown_parse_argv(int argc, char *argv[]) {
6436 static const struct option options[] = {
6437 { "help", no_argument, NULL, ARG_HELP },
6438 { "halt", no_argument, NULL, 'H' },
6439 { "poweroff", no_argument, NULL, 'P' },
6440 { "reboot", no_argument, NULL, 'r' },
6441 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6442 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6451 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6459 arg_action = ACTION_HALT;
6463 arg_action = ACTION_POWEROFF;
6468 arg_action = ACTION_KEXEC;
6470 arg_action = ACTION_REBOOT;
6474 arg_action = ACTION_KEXEC;
6478 if (arg_action != ACTION_HALT)
6479 arg_action = ACTION_POWEROFF;
6492 /* Compatibility nops */
6496 arg_action = ACTION_CANCEL_SHUTDOWN;
6503 assert_not_reached("Unhandled option");
6506 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6507 r = parse_time_spec(argv[optind], &arg_when);
6509 log_error("Failed to parse time specification: %s", argv[optind]);
6513 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6515 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6516 /* No time argument for shutdown cancel */
6517 arg_wall = argv + optind;
6518 else if (argc > optind + 1)
6519 /* We skip the time argument */
6520 arg_wall = argv + optind + 1;
6527 static int telinit_parse_argv(int argc, char *argv[]) {
6534 static const struct option options[] = {
6535 { "help", no_argument, NULL, ARG_HELP },
6536 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6540 static const struct {
6544 { '0', ACTION_POWEROFF },
6545 { '6', ACTION_REBOOT },
6546 { '1', ACTION_RESCUE },
6547 { '2', ACTION_RUNLEVEL2 },
6548 { '3', ACTION_RUNLEVEL3 },
6549 { '4', ACTION_RUNLEVEL4 },
6550 { '5', ACTION_RUNLEVEL5 },
6551 { 's', ACTION_RESCUE },
6552 { 'S', ACTION_RESCUE },
6553 { 'q', ACTION_RELOAD },
6554 { 'Q', ACTION_RELOAD },
6555 { 'u', ACTION_REEXEC },
6556 { 'U', ACTION_REEXEC }
6565 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6580 assert_not_reached("Unhandled option");
6583 if (optind >= argc) {
6584 log_error("%s: required argument missing.",
6585 program_invocation_short_name);
6589 if (optind + 1 < argc) {
6590 log_error("Too many arguments.");
6594 if (strlen(argv[optind]) != 1) {
6595 log_error("Expected single character argument.");
6599 for (i = 0; i < ELEMENTSOF(table); i++)
6600 if (table[i].from == argv[optind][0])
6603 if (i >= ELEMENTSOF(table)) {
6604 log_error("Unknown command '%s'.", argv[optind]);
6608 arg_action = table[i].to;
6615 static int runlevel_parse_argv(int argc, char *argv[]) {
6621 static const struct option options[] = {
6622 { "help", no_argument, NULL, ARG_HELP },
6631 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6642 assert_not_reached("Unhandled option");
6645 if (optind < argc) {
6646 log_error("Too many arguments.");
6653 static int parse_argv(int argc, char *argv[]) {
6657 if (program_invocation_short_name) {
6659 if (strstr(program_invocation_short_name, "halt")) {
6660 arg_action = ACTION_HALT;
6661 return halt_parse_argv(argc, argv);
6662 } else if (strstr(program_invocation_short_name, "poweroff")) {
6663 arg_action = ACTION_POWEROFF;
6664 return halt_parse_argv(argc, argv);
6665 } else if (strstr(program_invocation_short_name, "reboot")) {
6667 arg_action = ACTION_KEXEC;
6669 arg_action = ACTION_REBOOT;
6670 return halt_parse_argv(argc, argv);
6671 } else if (strstr(program_invocation_short_name, "shutdown")) {
6672 arg_action = ACTION_POWEROFF;
6673 return shutdown_parse_argv(argc, argv);
6674 } else if (strstr(program_invocation_short_name, "init")) {
6676 if (sd_booted() > 0) {
6677 arg_action = _ACTION_INVALID;
6678 return telinit_parse_argv(argc, argv);
6680 /* Hmm, so some other init system is
6681 * running, we need to forward this
6682 * request to it. For now we simply
6683 * guess that it is Upstart. */
6685 execv(TELINIT, argv);
6687 log_error("Couldn't find an alternative telinit implementation to spawn.");
6691 } else if (strstr(program_invocation_short_name, "runlevel")) {
6692 arg_action = ACTION_RUNLEVEL;
6693 return runlevel_parse_argv(argc, argv);
6697 arg_action = ACTION_SYSTEMCTL;
6698 return systemctl_parse_argv(argc, argv);
6701 _pure_ static int action_to_runlevel(void) {
6703 static const char table[_ACTION_MAX] = {
6704 [ACTION_HALT] = '0',
6705 [ACTION_POWEROFF] = '0',
6706 [ACTION_REBOOT] = '6',
6707 [ACTION_RUNLEVEL2] = '2',
6708 [ACTION_RUNLEVEL3] = '3',
6709 [ACTION_RUNLEVEL4] = '4',
6710 [ACTION_RUNLEVEL5] = '5',
6711 [ACTION_RESCUE] = '1'
6714 assert(arg_action < _ACTION_MAX);
6716 return table[arg_action];
6719 static int talk_initctl(void) {
6721 struct init_request request = {
6722 .magic = INIT_MAGIC,
6724 .cmd = INIT_CMD_RUNLVL
6727 _cleanup_close_ int fd = -1;
6731 rl = action_to_runlevel();
6735 request.runlevel = rl;
6737 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6739 if (errno == ENOENT)
6742 log_error("Failed to open "INIT_FIFO": %m");
6747 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6749 log_error("Failed to write to "INIT_FIFO": %m");
6750 return errno > 0 ? -errno : -EIO;
6756 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6758 static const struct {
6766 int (* const dispatch)(sd_bus *bus, char **args);
6772 { "list-units", MORE, 0, list_units },
6773 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6774 { "list-sockets", MORE, 1, list_sockets },
6775 { "list-timers", MORE, 1, list_timers },
6776 { "list-jobs", MORE, 1, list_jobs },
6777 { "list-machines", MORE, 1, list_machines },
6778 { "clear-jobs", EQUAL, 1, daemon_reload },
6779 { "cancel", MORE, 2, cancel_job },
6780 { "start", MORE, 2, start_unit },
6781 { "stop", MORE, 2, start_unit },
6782 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6783 { "reload", MORE, 2, start_unit },
6784 { "restart", MORE, 2, start_unit },
6785 { "try-restart", MORE, 2, start_unit },
6786 { "reload-or-restart", MORE, 2, start_unit },
6787 { "reload-or-try-restart", MORE, 2, start_unit },
6788 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6789 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6790 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6791 { "isolate", EQUAL, 2, start_unit },
6792 { "kill", MORE, 2, kill_unit },
6793 { "is-active", MORE, 2, check_unit_active },
6794 { "check", MORE, 2, check_unit_active },
6795 { "is-failed", MORE, 2, check_unit_failed },
6796 { "show", MORE, 1, show },
6797 { "cat", MORE, 2, cat },
6798 { "status", MORE, 1, show },
6799 { "help", MORE, 2, show },
6800 { "snapshot", LESS, 2, snapshot },
6801 { "delete", MORE, 2, delete_snapshot },
6802 { "daemon-reload", EQUAL, 1, daemon_reload },
6803 { "daemon-reexec", EQUAL, 1, daemon_reload },
6804 { "show-environment", EQUAL, 1, show_environment },
6805 { "set-environment", MORE, 2, set_environment },
6806 { "unset-environment", MORE, 2, set_environment },
6807 { "import-environment", MORE, 1, import_environment},
6808 { "halt", EQUAL, 1, start_special, FORCE },
6809 { "poweroff", EQUAL, 1, start_special, FORCE },
6810 { "reboot", EQUAL, 1, start_special, FORCE },
6811 { "kexec", EQUAL, 1, start_special },
6812 { "suspend", EQUAL, 1, start_special },
6813 { "hibernate", EQUAL, 1, start_special },
6814 { "hybrid-sleep", EQUAL, 1, start_special },
6815 { "default", EQUAL, 1, start_special },
6816 { "rescue", EQUAL, 1, start_special },
6817 { "emergency", EQUAL, 1, start_special },
6818 { "exit", EQUAL, 1, start_special },
6819 { "reset-failed", MORE, 1, reset_failed },
6820 { "enable", MORE, 2, enable_unit, NOBUS },
6821 { "disable", MORE, 2, enable_unit, NOBUS },
6822 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6823 { "reenable", MORE, 2, enable_unit, NOBUS },
6824 { "preset", MORE, 2, enable_unit, NOBUS },
6825 { "preset-all", EQUAL, 1, preset_all, NOBUS },
6826 { "mask", MORE, 2, enable_unit, NOBUS },
6827 { "unmask", MORE, 2, enable_unit, NOBUS },
6828 { "link", MORE, 2, enable_unit, NOBUS },
6829 { "switch-root", MORE, 2, switch_root },
6830 { "list-dependencies", LESS, 2, list_dependencies },
6831 { "set-default", EQUAL, 2, set_default, NOBUS },
6832 { "get-default", EQUAL, 1, get_default, NOBUS },
6833 { "set-property", MORE, 3, set_property },
6834 { "is-system-running", EQUAL, 1, is_system_running },
6835 { "add-wants", MORE, 3, add_dependency, NOBUS },
6836 { "add-requires", MORE, 3, add_dependency, NOBUS },
6845 left = argc - optind;
6847 /* Special rule: no arguments (left == 0) means "list-units" */
6849 if (streq(argv[optind], "help") && !argv[optind+1]) {
6850 log_error("This command expects one or more "
6851 "unit names. Did you mean --help?");
6855 for (; verb->verb; verb++)
6856 if (streq(argv[optind], verb->verb))
6859 log_error("Unknown operation '%s'.", argv[optind]);
6864 switch (verb->argc_cmp) {
6867 if (left != verb->argc) {
6868 log_error("Invalid number of arguments.");
6875 if (left < verb->argc) {
6876 log_error("Too few arguments.");
6883 if (left > verb->argc) {
6884 log_error("Too many arguments.");
6891 assert_not_reached("Unknown comparison operator.");
6894 /* Require a bus connection for all operations but
6896 if (verb->bus == NOBUS) {
6897 if (!bus && !avoid_bus()) {
6898 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6903 if (running_in_chroot() > 0) {
6904 log_info("Running in chroot, ignoring request.");
6908 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6909 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6914 return verb->dispatch(bus, argv + optind);
6917 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6919 struct sd_shutdown_command c = {
6926 union sockaddr_union sockaddr = {
6927 .un.sun_family = AF_UNIX,
6928 .un.sun_path = "/run/systemd/shutdownd",
6931 struct iovec iovec[2] = {{
6932 .iov_base = (char*) &c,
6933 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6936 struct msghdr msghdr = {
6937 .msg_name = &sockaddr,
6938 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6939 + strlen("/run/systemd/shutdownd"),
6944 _cleanup_close_ int fd;
6946 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6950 if (!isempty(message)) {
6951 iovec[1].iov_base = (char*) message;
6952 iovec[1].iov_len = strlen(message);
6953 msghdr.msg_iovlen++;
6956 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6962 static int reload_with_fallback(sd_bus *bus) {
6965 /* First, try systemd via D-Bus. */
6966 if (daemon_reload(bus, NULL) >= 0)
6970 /* Nothing else worked, so let's try signals */
6971 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6973 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6974 log_error("kill() failed: %m");
6981 static int start_with_fallback(sd_bus *bus) {
6984 /* First, try systemd via D-Bus. */
6985 if (start_unit(bus, NULL) >= 0)
6989 /* Nothing else worked, so let's try
6991 if (talk_initctl() > 0)
6994 log_error("Failed to talk to init daemon.");
6998 warn_wall(arg_action);
7002 static int halt_now(enum action a) {
7004 /* The kernel will automaticall flush ATA disks and suchlike
7005 * on reboot(), but the file systems need to be synce'd
7006 * explicitly in advance. */
7009 /* Make sure C-A-D is handled by the kernel from this point
7011 reboot(RB_ENABLE_CAD);
7016 log_info("Halting.");
7017 reboot(RB_HALT_SYSTEM);
7020 case ACTION_POWEROFF:
7021 log_info("Powering off.");
7022 reboot(RB_POWER_OFF);
7025 case ACTION_REBOOT: {
7026 _cleanup_free_ char *param = NULL;
7028 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7029 log_info("Rebooting with argument '%s'.", param);
7030 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7031 LINUX_REBOOT_CMD_RESTART2, param);
7034 log_info("Rebooting.");
7035 reboot(RB_AUTOBOOT);
7040 assert_not_reached("Unknown action.");
7044 static int halt_main(sd_bus *bus) {
7047 r = check_inhibitors(bus, arg_action);
7051 if (geteuid() != 0) {
7052 /* Try logind if we are a normal user and no special
7053 * mode applies. Maybe PolicyKit allows us to shutdown
7056 if (arg_when <= 0 &&
7059 (arg_action == ACTION_POWEROFF ||
7060 arg_action == ACTION_REBOOT)) {
7061 r = reboot_with_logind(bus, arg_action);
7066 log_error("Must be root.");
7071 _cleanup_free_ char *m;
7073 m = strv_join(arg_wall, " ");
7077 r = send_shutdownd(arg_when,
7078 arg_action == ACTION_HALT ? 'H' :
7079 arg_action == ACTION_POWEROFF ? 'P' :
7080 arg_action == ACTION_KEXEC ? 'K' :
7087 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
7089 char date[FORMAT_TIMESTAMP_MAX];
7091 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7092 format_timestamp(date, sizeof(date), arg_when));
7097 if (!arg_dry && !arg_force)
7098 return start_with_fallback(bus);
7101 if (sd_booted() > 0)
7102 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7104 r = utmp_put_shutdown();
7106 log_warning("Failed to write utmp record: %s", strerror(-r));
7113 r = halt_now(arg_action);
7114 log_error("Failed to reboot: %s", strerror(-r));
7119 static int runlevel_main(void) {
7120 int r, runlevel, previous;
7122 r = utmp_get_runlevel(&runlevel, &previous);
7129 previous <= 0 ? 'N' : previous,
7130 runlevel <= 0 ? 'N' : runlevel);
7135 int main(int argc, char*argv[]) {
7136 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7139 setlocale(LC_ALL, "");
7140 log_parse_environment();
7143 /* Explicitly not on_tty() to avoid setting cached value.
7144 * This becomes relevant for piping output which might be
7146 original_stdout_is_tty = isatty(STDOUT_FILENO);
7148 r = parse_argv(argc, argv);
7152 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7153 * let's shortcut this */
7154 if (arg_action == ACTION_RUNLEVEL) {
7155 r = runlevel_main();
7159 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7160 log_info("Running in chroot, ignoring request.");
7166 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7168 /* systemctl_main() will print an error message for the bus
7169 * connection, but only if it needs to */
7171 switch (arg_action) {
7173 case ACTION_SYSTEMCTL:
7174 r = systemctl_main(bus, argc, argv, r);
7178 case ACTION_POWEROFF:
7184 case ACTION_RUNLEVEL2:
7185 case ACTION_RUNLEVEL3:
7186 case ACTION_RUNLEVEL4:
7187 case ACTION_RUNLEVEL5:
7189 case ACTION_EMERGENCY:
7190 case ACTION_DEFAULT:
7191 r = start_with_fallback(bus);
7196 r = reload_with_fallback(bus);
7199 case ACTION_CANCEL_SHUTDOWN: {
7200 _cleanup_free_ char *m = NULL;
7203 m = strv_join(arg_wall, " ");
7210 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7212 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
7216 case ACTION_RUNLEVEL:
7217 case _ACTION_INVALID:
7219 assert_not_reached("Unknown action");
7224 ask_password_agent_close();
7225 polkit_agent_close();
7227 strv_free(arg_types);
7228 strv_free(arg_states);
7229 strv_free(arg_properties);
7231 return r < 0 ? EXIT_FAILURE : r;