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"
61 #include "bus-errors.h"
63 #include "unit-name.h"
65 #include "spawn-ask-password-agent.h"
66 #include "spawn-polkit-agent.h"
68 #include "logs-show.h"
69 #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 bool original_stdout_is_tty;
81 static enum dependency {
87 } arg_dependency = DEPENDENCY_FORWARD;
88 static const char *arg_job_mode = "replace";
89 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
90 static bool arg_no_block = false;
91 static bool arg_no_legend = false;
92 static bool arg_no_pager = false;
93 static bool arg_no_wtmp = false;
94 static bool arg_no_wall = false;
95 static bool arg_no_reload = false;
96 static bool arg_show_types = false;
97 static bool arg_ignore_inhibitors = false;
98 static bool arg_dry = false;
99 static bool arg_quiet = false;
100 static bool arg_full = false;
101 static int arg_force = 0;
102 static bool arg_ask_password = true;
103 static bool arg_runtime = false;
104 static char **arg_wall = NULL;
105 static const char *arg_kill_who = NULL;
106 static int arg_signal = SIGTERM;
107 static const char *arg_root = NULL;
108 static usec_t arg_when = 0;
130 ACTION_CANCEL_SHUTDOWN,
132 } arg_action = ACTION_SYSTEMCTL;
133 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
134 static char *arg_host = NULL;
135 static unsigned arg_lines = 10;
136 static OutputMode arg_output = OUTPUT_SHORT;
137 static bool arg_plain = false;
138 static const struct {
142 { "start", "StartUnit" },
143 { "stop", "StopUnit" },
144 { "condstop", "StopUnit" },
145 { "reload", "ReloadUnit" },
146 { "restart", "RestartUnit" },
147 { "try-restart", "TryRestartUnit" },
148 { "condrestart", "TryRestartUnit" },
149 { "reload-or-restart", "ReloadOrRestartUnit" },
150 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
151 { "condreload", "ReloadOrTryRestartUnit" },
152 { "force-reload", "ReloadOrTryRestartUnit" }
155 static int daemon_reload(sd_bus *bus, char **args);
156 static int halt_now(enum action a);
158 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
160 static char** strv_skip_first(char **strv) {
161 if (strv_length(strv) > 0)
166 static void pager_open_if_enabled(void) {
174 static void ask_password_agent_open_if_enabled(void) {
176 /* Open the password agent as a child process if necessary */
178 if (!arg_ask_password)
181 if (arg_scope != UNIT_FILE_SYSTEM)
184 if (arg_transport != BUS_TRANSPORT_LOCAL)
187 ask_password_agent_open();
191 static void polkit_agent_open_if_enabled(void) {
193 /* Open the polkit agent as a child process if necessary */
195 if (!arg_ask_password)
198 if (arg_scope != UNIT_FILE_SYSTEM)
201 if (arg_transport != BUS_TRANSPORT_LOCAL)
208 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
211 if (!sd_bus_error_is_set(error))
214 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
215 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
216 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
217 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
218 return EXIT_NOPERMISSION;
220 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
221 return EXIT_NOTINSTALLED;
223 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
224 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
225 return EXIT_NOTIMPLEMENTED;
227 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
228 return EXIT_NOTCONFIGURED;
236 static void warn_wall(enum action a) {
237 static const char *table[_ACTION_MAX] = {
238 [ACTION_HALT] = "The system is going down for system halt NOW!",
239 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
240 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
241 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
242 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
243 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
244 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
251 _cleanup_free_ char *p;
253 p = strv_join(arg_wall, " ");
268 utmp_wall(table[a], NULL);
271 static bool avoid_bus(void) {
273 if (running_in_chroot() > 0)
276 if (sd_booted() <= 0)
279 if (!isempty(arg_root))
282 if (arg_scope == UNIT_FILE_GLOBAL)
288 static int compare_unit_info(const void *a, const void *b) {
289 const UnitInfo *u = a, *v = b;
292 d1 = strrchr(u->id, '.');
293 d2 = strrchr(v->id, '.');
298 r = strcasecmp(d1, d2);
303 return strcasecmp(u->id, v->id);
306 static bool output_show_unit(const UnitInfo *u, char **patterns) {
309 if (!strv_isempty(arg_states))
311 strv_contains(arg_states, u->load_state) ||
312 strv_contains(arg_states, u->sub_state) ||
313 strv_contains(arg_states, u->active_state);
315 if (!strv_isempty(patterns)) {
318 STRV_FOREACH(pattern, patterns)
319 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
324 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
325 strv_find(arg_types, dot+1))) &&
326 (arg_all || !(streq(u->active_state, "inactive")
327 || u->following[0]) || u->job_id > 0);
330 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
331 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
333 unsigned n_shown = 0;
336 max_id_len = sizeof("UNIT")-1;
337 load_len = sizeof("LOAD")-1;
338 active_len = sizeof("ACTIVE")-1;
339 sub_len = sizeof("SUB")-1;
340 job_len = sizeof("JOB")-1;
343 for (u = unit_infos; u < unit_infos + c; u++) {
344 max_id_len = MAX(max_id_len, strlen(u->id));
345 load_len = MAX(load_len, strlen(u->load_state));
346 active_len = MAX(active_len, strlen(u->active_state));
347 sub_len = MAX(sub_len, strlen(u->sub_state));
349 if (u->job_id != 0) {
350 job_len = MAX(job_len, strlen(u->job_type));
355 if (!arg_full && original_stdout_is_tty) {
358 id_len = MIN(max_id_len, 25u);
359 basic_len = 5 + id_len + 5 + active_len + sub_len;
362 basic_len += job_len + 1;
364 if (basic_len < (unsigned) columns()) {
365 unsigned extra_len, incr;
366 extra_len = columns() - basic_len;
368 /* Either UNIT already got 25, or is fully satisfied.
369 * Grant up to 25 to DESC now. */
370 incr = MIN(extra_len, 25u);
374 /* split the remaining space between UNIT and DESC,
375 * but do not give UNIT more than it needs. */
377 incr = MIN(extra_len / 2, max_id_len - id_len);
379 desc_len += extra_len - incr;
385 for (u = unit_infos; u < unit_infos + c; u++) {
386 _cleanup_free_ char *e = NULL;
387 const char *on_loaded, *off_loaded, *on = "";
388 const char *on_active, *off_active, *off = "";
390 if (!n_shown && !arg_no_legend) {
391 printf("%-*s %-*s %-*s %-*s ",
394 active_len, "ACTIVE",
398 printf("%-*s ", job_len, "JOB");
400 if (!arg_full && arg_no_pager)
401 printf("%.*s\n", desc_len, "DESCRIPTION");
403 printf("%s\n", "DESCRIPTION");
408 if (streq(u->load_state, "error") ||
409 streq(u->load_state, "not-found")) {
410 on_loaded = on = ansi_highlight_red();
411 off_loaded = off = ansi_highlight_off();
413 on_loaded = off_loaded = "";
415 if (streq(u->active_state, "failed")) {
416 on_active = on = ansi_highlight_red();
417 off_active = off = ansi_highlight_off();
419 on_active = off_active = "";
421 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
423 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
424 on, id_len, e ? e : u->id, off,
425 on_loaded, load_len, u->load_state, off_loaded,
426 on_active, active_len, u->active_state,
427 sub_len, u->sub_state, off_active,
428 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
431 printf("%.*s\n", desc_len, u->description);
433 printf("%s\n", u->description);
436 if (!arg_no_legend) {
437 const char *on, *off;
440 puts("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
441 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
442 "SUB = The low-level unit activation state, values depend on unit type.");
443 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
444 on = ansi_highlight();
445 off = ansi_highlight_off();
447 on = ansi_highlight_red();
448 off = ansi_highlight_off();
452 printf("%s%u loaded units listed.%s\n"
453 "To show all installed unit files use 'systemctl list-unit-files'.\n",
456 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
457 "To show all installed unit files use 'systemctl list-unit-files'.\n",
462 static int get_unit_list(
464 sd_bus_message **_reply,
465 UnitInfo **_unit_infos,
468 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
469 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
470 _cleanup_free_ UnitInfo *unit_infos = NULL;
479 r = sd_bus_call_method(
481 "org.freedesktop.systemd1",
482 "/org/freedesktop/systemd1",
483 "org.freedesktop.systemd1.Manager",
489 log_error("Failed to list units: %s", bus_error_message(&error, r));
493 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
495 return bus_log_parse_error(r);
497 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
498 if (!output_show_unit(&u, patterns))
501 if (!GREEDY_REALLOC(unit_infos, size, c+1))
507 return bus_log_parse_error(r);
509 r = sd_bus_message_exit_container(reply);
511 return bus_log_parse_error(r);
516 *_unit_infos = unit_infos;
522 static int list_units(sd_bus *bus, char **args) {
523 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
524 _cleanup_free_ UnitInfo *unit_infos = NULL;
527 pager_open_if_enabled();
529 r = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
533 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
534 output_units_list(unit_infos, r);
539 static int get_triggered_units(
544 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
547 r = sd_bus_get_property_strv(
549 "org.freedesktop.systemd1",
551 "org.freedesktop.systemd1.Unit",
557 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
562 static int get_listening(
564 const char* unit_path,
567 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
568 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
569 const char *type, *path;
572 r = sd_bus_get_property(
574 "org.freedesktop.systemd1",
576 "org.freedesktop.systemd1.Socket",
582 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
586 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
588 return bus_log_parse_error(r);
590 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
592 r = strv_extend(listening, type);
596 r = strv_extend(listening, path);
603 return bus_log_parse_error(r);
605 r = sd_bus_message_exit_container(reply);
607 return bus_log_parse_error(r);
618 /* Note: triggered is a list here, although it almost certainly
619 * will always be one unit. Nevertheless, dbus API allows for multiple
620 * values, so let's follow that.*/
623 /* The strv above is shared. free is set only in the first one. */
627 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
633 o = strcmp(a->path, b->path);
635 o = strcmp(a->type, b->type);
640 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
641 struct socket_info *s;
642 unsigned pathlen = sizeof("LISTEN") - 1,
643 typelen = (sizeof("TYPE") - 1) * arg_show_types,
644 socklen = sizeof("UNIT") - 1,
645 servlen = sizeof("ACTIVATES") - 1;
646 const char *on, *off;
648 for (s = socket_infos; s < socket_infos + cs; s++) {
652 socklen = MAX(socklen, strlen(s->id));
654 typelen = MAX(typelen, strlen(s->type));
655 pathlen = MAX(pathlen, strlen(s->path));
657 STRV_FOREACH(a, s->triggered)
658 tmp += strlen(*a) + 2*(a != s->triggered);
659 servlen = MAX(servlen, tmp);
664 printf("%-*s %-*.*s%-*s %s\n",
666 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
670 for (s = socket_infos; s < socket_infos + cs; s++) {
674 printf("%-*s %-*s %-*s",
675 pathlen, s->path, typelen, s->type, socklen, s->id);
678 pathlen, s->path, socklen, s->id);
679 STRV_FOREACH(a, s->triggered)
681 a == s->triggered ? "" : ",", *a);
685 on = ansi_highlight();
686 off = ansi_highlight_off();
690 on = ansi_highlight_red();
691 off = ansi_highlight_off();
694 if (!arg_no_legend) {
695 printf("%s%u sockets listed.%s\n", on, cs, off);
697 printf("Pass --all to see loaded but inactive sockets, too.\n");
703 static int list_sockets(sd_bus *bus, char **args) {
704 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
705 _cleanup_free_ UnitInfo *unit_infos = NULL;
706 _cleanup_free_ struct socket_info *socket_infos = NULL;
708 struct socket_info *s;
713 pager_open_if_enabled();
715 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
719 for (u = unit_infos; u < unit_infos + n; u++) {
720 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
723 if (!endswith(u->id, ".socket"))
726 r = get_triggered_units(bus, u->unit_path, &triggered);
730 c = get_listening(bus, u->unit_path, &listening);
736 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
741 for (i = 0; i < c; i++)
742 socket_infos[cs + i] = (struct socket_info) {
744 .type = listening[i*2],
745 .path = listening[i*2 + 1],
746 .triggered = triggered,
747 .own_triggered = i==0,
750 /* from this point on we will cleanup those socket_infos */
753 listening = triggered = NULL; /* avoid cleanup */
756 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
757 (__compar_fn_t) socket_info_compare);
759 output_sockets_list(socket_infos, cs);
762 assert(cs == 0 || socket_infos);
763 for (s = socket_infos; s < socket_infos + cs; s++) {
766 if (s->own_triggered)
767 strv_free(s->triggered);
773 static int get_next_elapse(
776 dual_timestamp *next) {
778 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
786 r = sd_bus_get_property_trivial(
788 "org.freedesktop.systemd1",
790 "org.freedesktop.systemd1.Timer",
791 "NextElapseUSecMonotonic",
796 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
800 r = sd_bus_get_property_trivial(
802 "org.freedesktop.systemd1",
804 "org.freedesktop.systemd1.Timer",
805 "NextElapseUSecRealtime",
810 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
824 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
828 if (a->next_elapse < b->next_elapse)
830 if (a->next_elapse > b->next_elapse)
833 return strcmp(a->id, b->id);
836 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
837 struct timer_info *t;
839 nextlen = sizeof("NEXT") - 1,
840 leftlen = sizeof("LEFT") - 1,
841 unitlen = sizeof("UNIT") - 1,
842 activatelen = sizeof("ACTIVATES") - 1;
844 const char *on, *off;
846 assert(timer_infos || n == 0);
848 for (t = timer_infos; t < timer_infos + n; t++) {
852 if (t->next_elapse > 0) {
853 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
855 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
856 nextlen = MAX(nextlen, strlen(tstamp) + 1);
858 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
859 leftlen = MAX(leftlen, strlen(trel));
862 unitlen = MAX(unitlen, strlen(t->id));
864 STRV_FOREACH(a, t->triggered)
865 ul += strlen(*a) + 2*(a != t->triggered);
866 activatelen = MAX(activatelen, ul);
871 printf("%-*s %-*s %-*s %s\n",
877 for (t = timer_infos; t < timer_infos + n; t++) {
878 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
881 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
882 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
884 printf("%-*s %-*s %-*s",
885 nextlen, tstamp, leftlen, trel, unitlen, t->id);
887 STRV_FOREACH(a, t->triggered)
889 a == t->triggered ? "" : ",", *a);
893 on = ansi_highlight();
894 off = ansi_highlight_off();
898 on = ansi_highlight_red();
899 off = ansi_highlight_off();
902 if (!arg_no_legend) {
903 printf("%s%u timers listed.%s\n", on, n, off);
905 printf("Pass --all to see loaded but inactive timers, too.\n");
911 static int list_timers(sd_bus *bus, char **args) {
913 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
914 _cleanup_free_ struct timer_info *timer_infos = NULL;
915 _cleanup_free_ UnitInfo *unit_infos = NULL;
916 struct timer_info *t;
923 pager_open_if_enabled();
925 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
929 dual_timestamp_get(&nw);
931 for (u = unit_infos; u < unit_infos + n; u++) {
932 _cleanup_strv_free_ char **triggered = NULL;
936 if (!endswith(u->id, ".timer"))
939 r = get_triggered_units(bus, u->unit_path, &triggered);
943 r = get_next_elapse(bus, u->unit_path, &next);
947 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
950 if (next.monotonic > nw.monotonic)
951 converted = nw.realtime + (next.monotonic - nw.monotonic);
953 converted = nw.realtime - (nw.monotonic - next.monotonic);
955 if (next.realtime != (usec_t) -1 && next.realtime > 0)
956 m = MIN(converted, next.realtime);
962 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
967 timer_infos[c++] = (struct timer_info) {
970 .triggered = triggered,
973 triggered = NULL; /* avoid cleanup */
976 qsort_safe(timer_infos, c, sizeof(struct timer_info),
977 (__compar_fn_t) timer_info_compare);
979 output_timers_list(timer_infos, c);
982 for (t = timer_infos; t < timer_infos + c; t++)
983 strv_free(t->triggered);
988 static int compare_unit_file_list(const void *a, const void *b) {
990 const UnitFileList *u = a, *v = b;
992 d1 = strrchr(u->path, '.');
993 d2 = strrchr(v->path, '.');
998 r = strcasecmp(d1, d2);
1003 return strcasecmp(basename(u->path), basename(v->path));
1006 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1009 if (!strv_isempty(patterns)) {
1012 STRV_FOREACH(pattern, patterns)
1013 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1018 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1021 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1022 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
1023 const UnitFileList *u;
1025 max_id_len = sizeof("UNIT FILE")-1;
1026 state_cols = sizeof("STATE")-1;
1028 for (u = units; u < units + c; u++) {
1029 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1030 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1034 unsigned basic_cols;
1036 id_cols = MIN(max_id_len, 25u);
1037 basic_cols = 1 + id_cols + state_cols;
1038 if (basic_cols < (unsigned) columns())
1039 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1041 id_cols = max_id_len;
1044 printf("%-*s %-*s\n",
1045 id_cols, "UNIT FILE",
1046 state_cols, "STATE");
1048 for (u = units; u < units + c; u++) {
1049 _cleanup_free_ char *e = NULL;
1050 const char *on, *off;
1055 if (u->state == UNIT_FILE_MASKED ||
1056 u->state == UNIT_FILE_MASKED_RUNTIME ||
1057 u->state == UNIT_FILE_DISABLED ||
1058 u->state == UNIT_FILE_INVALID) {
1059 on = ansi_highlight_red();
1060 off = ansi_highlight_off();
1061 } else if (u->state == UNIT_FILE_ENABLED) {
1062 on = ansi_highlight_green();
1063 off = ansi_highlight_off();
1067 id = basename(u->path);
1069 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1071 printf("%-*s %s%-*s%s\n",
1072 id_cols, e ? e : id,
1073 on, state_cols, unit_file_state_to_string(u->state), off);
1077 printf("\n%u unit files listed.\n", n_shown);
1080 static int list_unit_files(sd_bus *bus, char **args) {
1081 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1082 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1083 _cleanup_free_ UnitFileList *units = NULL;
1091 pager_open_if_enabled();
1099 h = hashmap_new(string_hash_func, string_compare_func);
1103 r = unit_file_get_list(arg_scope, arg_root, h);
1105 unit_file_list_free(h);
1106 log_error("Failed to get unit file list: %s", strerror(-r));
1110 n_units = hashmap_size(h);
1111 units = new(UnitFileList, n_units);
1113 unit_file_list_free(h);
1117 HASHMAP_FOREACH(u, h, i) {
1118 if (!output_show_unit_file(u, strv_skip_first(args)))
1125 assert(c <= n_units);
1128 r = sd_bus_call_method(
1130 "org.freedesktop.systemd1",
1131 "/org/freedesktop/systemd1",
1132 "org.freedesktop.systemd1.Manager",
1138 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1142 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1144 return bus_log_parse_error(r);
1146 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1148 if (!GREEDY_REALLOC(units, size, c + 1))
1151 units[c] = (struct UnitFileList) {
1153 unit_file_state_from_string(state)
1156 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1161 return bus_log_parse_error(r);
1163 r = sd_bus_message_exit_container(reply);
1165 return bus_log_parse_error(r);
1169 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1170 output_unit_file_list(units, c);
1174 for (unit = units; unit < units + c; unit++)
1180 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1181 _cleanup_free_ char *n = NULL;
1182 size_t max_len = MAX(columns(),20u);
1188 for (i = level - 1; i >= 0; i--) {
1190 if (len > max_len - 3 && !arg_full) {
1191 printf("%s...\n",max_len % 2 ? "" : " ");
1194 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1198 if (len > max_len - 3 && !arg_full) {
1199 printf("%s...\n",max_len % 2 ? "" : " ");
1203 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1207 printf("%s\n", name);
1211 n = ellipsize(name, max_len-len, 100);
1219 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1221 static const char *dependencies[_DEPENDENCY_MAX] = {
1222 [DEPENDENCY_FORWARD] = "Requires\0"
1223 "RequiresOverridable\0"
1225 "RequisiteOverridable\0"
1227 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1228 "RequiredByOverridable\0"
1231 [DEPENDENCY_AFTER] = "After\0",
1232 [DEPENDENCY_BEFORE] = "Before\0",
1235 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1236 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1237 _cleanup_strv_free_ char **ret = NULL;
1238 _cleanup_free_ char *path = NULL;
1244 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1246 path = unit_dbus_path_from_name(name);
1250 r = sd_bus_call_method(
1252 "org.freedesktop.systemd1",
1254 "org.freedesktop.DBus.Properties",
1258 "s", "org.freedesktop.systemd1.Unit");
1260 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1264 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1266 return bus_log_parse_error(r);
1268 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1271 r = sd_bus_message_read(reply, "s", &prop);
1273 return bus_log_parse_error(r);
1275 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1276 r = sd_bus_message_skip(reply, "v");
1278 return bus_log_parse_error(r);
1281 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1283 return bus_log_parse_error(r);
1285 r = bus_message_read_strv_extend(reply, &ret);
1287 return bus_log_parse_error(r);
1289 r = sd_bus_message_exit_container(reply);
1291 return bus_log_parse_error(r);
1294 r = sd_bus_message_exit_container(reply);
1296 return bus_log_parse_error(r);
1300 return bus_log_parse_error(r);
1302 r = sd_bus_message_exit_container(reply);
1304 return bus_log_parse_error(r);
1312 static int list_dependencies_compare(const void *_a, const void *_b) {
1313 const char **a = (const char**) _a, **b = (const char**) _b;
1315 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1317 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1320 return strcasecmp(*a, *b);
1323 static int list_dependencies_one(
1328 unsigned int branches) {
1330 _cleanup_strv_free_ char **deps = NULL, **u;
1338 u = strv_append(*units, name);
1342 r = list_dependencies_get_dependencies(bus, name, &deps);
1346 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1348 STRV_FOREACH(c, deps) {
1351 if (strv_contains(u, *c)) {
1353 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1360 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1362 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1364 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1366 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1370 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1371 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1386 static int list_dependencies(sd_bus *bus, char **args) {
1387 _cleanup_strv_free_ char **units = NULL;
1388 _cleanup_free_ char *unit = NULL;
1394 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1399 u = SPECIAL_DEFAULT_TARGET;
1401 pager_open_if_enabled();
1405 return list_dependencies_one(bus, u, 0, &units, 0);
1408 static int get_default(sd_bus *bus, char **args) {
1409 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1410 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1411 _cleanup_free_ char *_path = NULL;
1415 if (!bus || avoid_bus()) {
1416 r = unit_file_get_default(arg_scope, arg_root, &_path);
1418 log_error("Failed to get default target: %s", strerror(-r));
1424 r = sd_bus_call_method(
1426 "org.freedesktop.systemd1",
1427 "/org/freedesktop/systemd1",
1428 "org.freedesktop.systemd1.Manager",
1434 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1438 r = sd_bus_message_read(reply, "s", &path);
1440 return bus_log_parse_error(r);
1444 printf("%s\n", path);
1449 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1452 assert(changes || n_changes == 0);
1454 for (i = 0; i < n_changes; i++) {
1455 if (changes[i].type == UNIT_FILE_SYMLINK)
1456 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1458 log_info("rm '%s'", changes[i].path);
1462 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1463 const char *type, *path, *source;
1466 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1468 return bus_log_parse_error(r);
1470 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1472 if (streq(type, "symlink"))
1473 log_info("ln -s '%s' '%s'", source, path);
1475 log_info("rm '%s'", path);
1479 return bus_log_parse_error(r);
1481 r = sd_bus_message_exit_container(m);
1483 return bus_log_parse_error(r);
1488 static int set_default(sd_bus *bus, char **args) {
1489 _cleanup_free_ char *unit = NULL;
1490 UnitFileChange *changes = NULL;
1491 unsigned n_changes = 0;
1494 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1498 if (!bus || avoid_bus()) {
1499 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1501 log_error("Failed to set default target: %s", strerror(-r));
1506 dump_unit_file_changes(changes, n_changes);
1510 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1511 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1513 r = sd_bus_call_method(
1515 "org.freedesktop.systemd1",
1516 "/org/freedesktop/systemd1",
1517 "org.freedesktop.systemd1.Manager",
1521 "sb", unit, arg_force);
1523 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1527 r = deserialize_and_dump_unit_file_changes(reply);
1531 /* Try to reload if enabeld */
1533 r = daemon_reload(bus, args);
1538 unit_file_changes_free(changes, n_changes);
1545 const char *name, *type, *state;
1548 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1549 unsigned id_len, unit_len, type_len, state_len;
1550 const struct job_info *j;
1551 const char *on, *off;
1552 bool shorten = false;
1554 assert(n == 0 || jobs);
1557 on = ansi_highlight_green();
1558 off = ansi_highlight_off();
1560 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1564 pager_open_if_enabled();
1566 id_len = sizeof("JOB")-1;
1567 unit_len = sizeof("UNIT")-1;
1568 type_len = sizeof("TYPE")-1;
1569 state_len = sizeof("STATE")-1;
1571 for (j = jobs; j < jobs + n; j++) {
1572 uint32_t id = j->id;
1573 assert(j->name && j->type && j->state);
1575 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1576 unit_len = MAX(unit_len, strlen(j->name));
1577 type_len = MAX(type_len, strlen(j->type));
1578 state_len = MAX(state_len, strlen(j->state));
1581 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1582 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1587 printf("%*s %-*s %-*s %-*s\n",
1591 state_len, "STATE");
1593 for (j = jobs; j < jobs + n; j++) {
1594 _cleanup_free_ char *e = NULL;
1596 if (streq(j->state, "running")) {
1597 on = ansi_highlight();
1598 off = ansi_highlight_off();
1602 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1603 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1605 on, unit_len, e ? e : j->name, off,
1607 on, state_len, j->state, off);
1610 if (!arg_no_legend) {
1611 on = ansi_highlight();
1612 off = ansi_highlight_off();
1614 printf("\n%s%u jobs listed%s.\n", on, n, off);
1618 static bool output_show_job(struct job_info *job, char **patterns) {
1619 if (!strv_isempty(patterns)) {
1622 STRV_FOREACH(pattern, patterns)
1623 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1631 static int list_jobs(sd_bus *bus, char **args) {
1632 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1633 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1634 const char *name, *type, *state, *job_path, *unit_path;
1635 _cleanup_free_ struct job_info *jobs = NULL;
1640 bool skipped = false;
1642 r = sd_bus_call_method(
1644 "org.freedesktop.systemd1",
1645 "/org/freedesktop/systemd1",
1646 "org.freedesktop.systemd1.Manager",
1652 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1656 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1658 return bus_log_parse_error(r);
1660 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1661 struct job_info job = { id, name, type, state };
1663 if (!output_show_job(&job, strv_skip_first(args))) {
1668 if (!GREEDY_REALLOC(jobs, size, c + 1))
1674 return bus_log_parse_error(r);
1676 r = sd_bus_message_exit_container(reply);
1678 return bus_log_parse_error(r);
1680 output_jobs_list(jobs, c, skipped);
1684 static int cancel_job(sd_bus *bus, char **args) {
1685 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1690 if (strv_length(args) <= 1)
1691 return daemon_reload(bus, args);
1693 STRV_FOREACH(name, args+1) {
1697 r = safe_atou32(*name, &id);
1699 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1703 r = sd_bus_call_method(
1705 "org.freedesktop.systemd1",
1706 "/org/freedesktop/systemd1",
1707 "org.freedesktop.systemd1.Manager",
1713 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1721 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1722 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1726 /* We ignore all errors here, since this is used to show a
1729 /* We don't use unit_dbus_path_from_name() directly since we
1730 * don't want to load the unit if it isn't loaded. */
1732 r = sd_bus_call_method(
1734 "org.freedesktop.systemd1",
1735 "/org/freedesktop/systemd1",
1736 "org.freedesktop.systemd1.Manager",
1744 r = sd_bus_message_read(reply, "o", &path);
1748 r = sd_bus_get_property_trivial(
1750 "org.freedesktop.systemd1",
1752 "org.freedesktop.systemd1.Unit",
1762 typedef struct WaitData {
1769 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1776 log_debug("Got D-Bus request: %s.%s() on %s",
1777 sd_bus_message_get_interface(m),
1778 sd_bus_message_get_member(m),
1779 sd_bus_message_get_path(m));
1781 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1782 log_error("Warning! D-Bus connection terminated.");
1784 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1786 const char *path, *result, *unit;
1790 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1792 ret = set_remove(d->set, (char*) path);
1798 if (!isempty(result))
1799 d->result = strdup(result);
1802 d->name = strdup(unit);
1807 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1809 ret = set_remove(d->set, (char*) path);
1816 d->result = strdup(result);
1822 bus_log_parse_error(r);
1828 static int enable_wait_for_jobs(sd_bus *bus) {
1833 r = sd_bus_add_match(
1836 "sender='org.freedesktop.systemd1',"
1837 "interface='org.freedesktop.systemd1.Manager',"
1838 "member='JobRemoved',"
1839 "path='/org/freedesktop/systemd1'",
1842 log_error("Failed to add match");
1846 /* This is slightly dirty, since we don't undo the match registrations. */
1850 static int bus_process_wait(sd_bus *bus) {
1854 r = sd_bus_process(bus, NULL);
1859 r = sd_bus_wait(bus, (uint64_t) -1);
1865 static int check_wait_response(WaitData *d) {
1871 if (streq(d->result, "timeout"))
1872 log_error("Job for %s timed out.", strna(d->name));
1873 else if (streq(d->result, "canceled"))
1874 log_error("Job for %s canceled.", strna(d->name));
1875 else if (streq(d->result, "dependency"))
1876 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1877 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1878 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1881 if (streq(d->result, "timeout"))
1883 else if (streq(d->result, "canceled"))
1885 else if (streq(d->result, "dependency"))
1887 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1893 static int wait_for_jobs(sd_bus *bus, Set *s) {
1894 WaitData d = { .set = s };
1900 q = sd_bus_add_filter(bus, wait_filter, &d);
1904 while (!set_isempty(s)) {
1905 q = bus_process_wait(bus);
1907 log_error("Failed to wait for response: %s", strerror(-r));
1912 q = check_wait_response(&d);
1913 /* Return the first error as it is most likely to be
1915 if (q < 0 && r == 0)
1917 log_debug("Got result %s/%s for job %s",
1918 strna(d.result), strerror(-q), strna(d.name));
1928 q = sd_bus_remove_filter(bus, wait_filter, &d);
1929 if (q < 0 && r == 0)
1935 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1936 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1937 _cleanup_free_ char *n = NULL, *state = NULL;
1943 n = unit_name_mangle(name, MANGLE_NOGLOB);
1947 /* We don't use unit_dbus_path_from_name() directly since we
1948 * don't want to load the unit if it isn't loaded. */
1950 r = sd_bus_call_method(
1952 "org.freedesktop.systemd1",
1953 "/org/freedesktop/systemd1",
1954 "org.freedesktop.systemd1.Manager",
1965 r = sd_bus_message_read(reply, "o", &path);
1967 return bus_log_parse_error(r);
1969 r = sd_bus_get_property_string(
1971 "org.freedesktop.systemd1",
1973 "org.freedesktop.systemd1.Unit",
1986 return nulstr_contains(good_states, state);
1989 static int check_triggering_units(
1993 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1994 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1995 _cleanup_strv_free_ char **triggered_by = NULL;
1996 bool print_warning_label = true;
2000 n = unit_name_mangle(name, MANGLE_NOGLOB);
2004 path = unit_dbus_path_from_name(n);
2008 r = sd_bus_get_property_string(
2010 "org.freedesktop.systemd1",
2012 "org.freedesktop.systemd1.Unit",
2017 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2021 if (streq(state, "masked"))
2024 r = sd_bus_get_property_strv(
2026 "org.freedesktop.systemd1",
2028 "org.freedesktop.systemd1.Unit",
2033 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2037 STRV_FOREACH(i, triggered_by) {
2038 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2040 log_error("Failed to check unit: %s", strerror(-r));
2047 if (print_warning_label) {
2048 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2049 print_warning_label = false;
2052 log_warning(" %s", *i);
2058 static const char *verb_to_method(const char *verb) {
2061 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2062 if (streq_ptr(unit_actions[i].verb, verb))
2063 return unit_actions[i].method;
2068 static const char *method_to_verb(const char *method) {
2071 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2072 if (streq_ptr(unit_actions[i].method, method))
2073 return unit_actions[i].verb;
2078 static int start_unit_one(
2083 sd_bus_error *error,
2086 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2095 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2096 r = sd_bus_call_method(
2098 "org.freedesktop.systemd1",
2099 "/org/freedesktop/systemd1",
2100 "org.freedesktop.systemd1.Manager",
2108 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2109 /* There's always a fallback possible for
2110 * legacy actions. */
2111 return -EADDRNOTAVAIL;
2113 verb = method_to_verb(method);
2115 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2119 r = sd_bus_message_read(reply, "o", &path);
2121 return bus_log_parse_error(r);
2123 if (need_daemon_reload(bus, name) > 0)
2124 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2125 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2134 log_debug("Adding %s to the set", p);
2135 r = set_consume(s, p);
2143 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2145 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2146 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2150 STRV_FOREACH(name, names) {
2154 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2156 t = unit_name_mangle(*name, MANGLE_GLOB);
2160 if (string_is_glob(t))
2161 r = strv_push(&globs, t);
2163 r = strv_push(&mangled, t);
2170 /* Query the manager only if any of the names are a glob, since
2171 * this is fairly expensive */
2172 if (!strv_isempty(globs)) {
2173 _cleanup_free_ UnitInfo *unit_infos = NULL;
2175 r = get_unit_list(bus, &reply, &unit_infos, globs);
2179 for (i = 0; i < r; i++)
2180 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2185 mangled = NULL; /* do not free */
2189 static const struct {
2193 } action_table[_ACTION_MAX] = {
2194 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2195 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2196 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2197 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2198 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2199 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2200 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2201 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2202 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2203 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2204 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2205 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2206 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2207 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2208 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2211 static enum action verb_to_action(const char *verb) {
2214 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2215 if (streq_ptr(action_table[i].verb, verb))
2218 return _ACTION_INVALID;
2221 static int start_unit(sd_bus *bus, char **args) {
2222 _cleanup_set_free_free_ Set *s = NULL;
2223 _cleanup_strv_free_ char **names = NULL;
2224 const char *method, *mode, *one_name;
2230 ask_password_agent_open_if_enabled();
2232 if (arg_action == ACTION_SYSTEMCTL) {
2234 method = verb_to_method(args[0]);
2235 action = verb_to_action(args[0]);
2237 mode = streq(args[0], "isolate") ? "isolate" :
2238 action_table[action].mode ?: arg_job_mode;
2240 one_name = action_table[action].target;
2242 assert(arg_action < ELEMENTSOF(action_table));
2243 assert(action_table[arg_action].target);
2245 method = "StartUnit";
2247 mode = action_table[arg_action].mode;
2248 one_name = action_table[arg_action].target;
2252 names = strv_new(one_name, NULL);
2254 r = expand_names(bus, args + 1, NULL, &names);
2256 log_error("Failed to expand names: %s", strerror(-r));
2259 if (!arg_no_block) {
2260 r = enable_wait_for_jobs(bus);
2262 log_error("Could not watch jobs: %s", strerror(-r));
2266 s = set_new(string_hash_func, string_compare_func);
2271 STRV_FOREACH(name, names) {
2272 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2275 q = start_unit_one(bus, method, *name, mode, &error, s);
2276 if (r >= 0 && q < 0)
2277 r = translate_bus_error_to_exit_status(q, &error);
2280 if (!arg_no_block) {
2283 q = wait_for_jobs(bus, s);
2287 /* When stopping units, warn if they can still be triggered by
2288 * another active unit (socket, path, timer) */
2289 if (!arg_quiet && streq(method, "StopUnit"))
2290 STRV_FOREACH(name, names)
2291 check_triggering_units(bus, *name);
2297 /* Ask systemd-logind, which might grant access to unprivileged users
2298 * through PolicyKit */
2299 static int reboot_with_logind(sd_bus *bus, enum action a) {
2301 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2308 polkit_agent_open_if_enabled();
2316 case ACTION_POWEROFF:
2317 method = "PowerOff";
2320 case ACTION_SUSPEND:
2324 case ACTION_HIBERNATE:
2325 method = "Hibernate";
2328 case ACTION_HYBRID_SLEEP:
2329 method = "HybridSleep";
2336 r = sd_bus_call_method(
2338 "org.freedesktop.login1",
2339 "/org/freedesktop/login1",
2340 "org.freedesktop.login1.Manager",
2346 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2354 static int check_inhibitors(sd_bus *bus, enum action a) {
2356 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2357 _cleanup_strv_free_ char **sessions = NULL;
2358 const char *what, *who, *why, *mode;
2367 if (arg_ignore_inhibitors || arg_force > 0)
2379 r = sd_bus_call_method(
2381 "org.freedesktop.login1",
2382 "/org/freedesktop/login1",
2383 "org.freedesktop.login1.Manager",
2389 /* If logind is not around, then there are no inhibitors... */
2392 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2394 return bus_log_parse_error(r);
2396 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2397 _cleanup_free_ char *comm = NULL, *user = NULL;
2398 _cleanup_strv_free_ char **sv = NULL;
2400 if (!streq(mode, "block"))
2403 sv = strv_split(what, ":");
2407 if (!strv_contains(sv,
2409 a == ACTION_POWEROFF ||
2410 a == ACTION_REBOOT ||
2411 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2414 get_process_comm(pid, &comm);
2415 user = uid_to_name(uid);
2417 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2418 who, (unsigned long) pid, strna(comm), strna(user), why);
2423 return bus_log_parse_error(r);
2425 r = sd_bus_message_exit_container(reply);
2427 return bus_log_parse_error(r);
2429 /* Check for current sessions */
2430 sd_get_sessions(&sessions);
2431 STRV_FOREACH(s, sessions) {
2432 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2434 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2437 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2440 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2443 sd_session_get_tty(*s, &tty);
2444 sd_session_get_seat(*s, &seat);
2445 sd_session_get_service(*s, &service);
2446 user = uid_to_name(uid);
2448 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2455 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2456 action_table[a].verb);
2464 static int start_special(sd_bus *bus, char **args) {
2470 a = verb_to_action(args[0]);
2472 r = check_inhibitors(bus, a);
2476 if (arg_force >= 2 && geteuid() != 0) {
2477 log_error("Must be root.");
2481 if (arg_force >= 2 &&
2482 (a == ACTION_HALT ||
2483 a == ACTION_POWEROFF ||
2484 a == ACTION_REBOOT))
2487 if (arg_force >= 1 &&
2488 (a == ACTION_HALT ||
2489 a == ACTION_POWEROFF ||
2490 a == ACTION_REBOOT ||
2491 a == ACTION_KEXEC ||
2493 return daemon_reload(bus, args);
2495 /* first try logind, to allow authentication with polkit */
2496 if (geteuid() != 0 &&
2497 (a == ACTION_POWEROFF ||
2498 a == ACTION_REBOOT ||
2499 a == ACTION_SUSPEND ||
2500 a == ACTION_HIBERNATE ||
2501 a == ACTION_HYBRID_SLEEP)) {
2502 r = reboot_with_logind(bus, a);
2507 r = start_unit(bus, args);
2508 if (r == EXIT_SUCCESS)
2514 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2515 _cleanup_strv_free_ char **names = NULL;
2522 r = expand_names(bus, args, NULL, &names);
2524 log_error("Failed to expand names: %s", strerror(-r));
2526 STRV_FOREACH(name, names) {
2529 state = check_one_unit(bus, *name, good_states, arg_quiet);
2539 static int check_unit_active(sd_bus *bus, char **args) {
2540 /* According to LSB: 3, "program is not running" */
2541 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2544 static int check_unit_failed(sd_bus *bus, char **args) {
2545 return check_unit_generic(bus, 1, "failed\0", args + 1);
2548 static int kill_unit(sd_bus *bus, char **args) {
2549 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2550 _cleanup_strv_free_ char **names = NULL;
2558 arg_kill_who = "all";
2560 r = expand_names(bus, args + 1, NULL, &names);
2562 log_error("Failed to expand names: %s", strerror(-r));
2564 STRV_FOREACH(name, names) {
2565 q = sd_bus_call_method(
2567 "org.freedesktop.systemd1",
2568 "/org/freedesktop/systemd1",
2569 "org.freedesktop.systemd1.Manager",
2573 "ssi", *names, arg_kill_who, arg_signal);
2575 log_error("Failed to kill unit %s: %s",
2576 *names, bus_error_message(&error, r));
2585 typedef struct ExecStatusInfo {
2593 usec_t start_timestamp;
2594 usec_t exit_timestamp;
2599 LIST_FIELDS(struct ExecStatusInfo, exec);
2602 static void exec_status_info_free(ExecStatusInfo *i) {
2611 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2612 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2615 int32_t code, status;
2621 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2623 return bus_log_parse_error(r);
2627 r = sd_bus_message_read(m, "s", &path);
2629 return bus_log_parse_error(r);
2631 i->path = strdup(path);
2635 r = sd_bus_message_read_strv(m, &i->argv);
2637 return bus_log_parse_error(r);
2639 r = sd_bus_message_read(m,
2642 &start_timestamp, &start_timestamp_monotonic,
2643 &exit_timestamp, &exit_timestamp_monotonic,
2647 return bus_log_parse_error(r);
2650 i->start_timestamp = (usec_t) start_timestamp;
2651 i->exit_timestamp = (usec_t) exit_timestamp;
2652 i->pid = (pid_t) pid;
2656 r = sd_bus_message_exit_container(m);
2658 return bus_log_parse_error(r);
2663 typedef struct UnitStatusInfo {
2665 const char *load_state;
2666 const char *active_state;
2667 const char *sub_state;
2668 const char *unit_file_state;
2670 const char *description;
2671 const char *following;
2673 char **documentation;
2675 const char *fragment_path;
2676 const char *source_path;
2677 const char *control_group;
2679 char **dropin_paths;
2681 const char *load_error;
2684 usec_t inactive_exit_timestamp;
2685 usec_t inactive_exit_timestamp_monotonic;
2686 usec_t active_enter_timestamp;
2687 usec_t active_exit_timestamp;
2688 usec_t inactive_enter_timestamp;
2690 bool need_daemon_reload;
2695 const char *status_text;
2696 const char *pid_file;
2699 usec_t start_timestamp;
2700 usec_t exit_timestamp;
2702 int exit_code, exit_status;
2704 usec_t condition_timestamp;
2705 bool condition_result;
2706 bool failed_condition_trigger;
2707 bool failed_condition_negate;
2708 const char *failed_condition;
2709 const char *failed_condition_param;
2712 unsigned n_accepted;
2713 unsigned n_connections;
2716 /* Pairs of type, path */
2720 const char *sysfs_path;
2722 /* Mount, Automount */
2728 LIST_HEAD(ExecStatusInfo, exec);
2731 static void print_status_info(
2736 const char *on, *off, *ss;
2738 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2739 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2742 arg_all * OUTPUT_SHOW_ALL |
2743 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2744 on_tty() * OUTPUT_COLOR |
2745 !arg_quiet * OUTPUT_WARN_CUTOFF |
2746 arg_full * OUTPUT_FULL_WIDTH;
2751 /* This shows pretty information about a unit. See
2752 * print_property() for a low-level property printer */
2754 printf("%s", strna(i->id));
2756 if (i->description && !streq_ptr(i->id, i->description))
2757 printf(" - %s", i->description);
2762 printf(" Follow: unit currently follows state of %s\n", i->following);
2764 if (streq_ptr(i->load_state, "error")) {
2765 on = ansi_highlight_red();
2766 off = ansi_highlight_off();
2770 path = i->source_path ? i->source_path : i->fragment_path;
2773 printf(" Loaded: %s%s%s (Reason: %s)\n",
2774 on, strna(i->load_state), off, i->load_error);
2775 else if (path && i->unit_file_state)
2776 printf(" Loaded: %s%s%s (%s; %s)\n",
2777 on, strna(i->load_state), off, path, i->unit_file_state);
2779 printf(" Loaded: %s%s%s (%s)\n",
2780 on, strna(i->load_state), off, path);
2782 printf(" Loaded: %s%s%s\n",
2783 on, strna(i->load_state), off);
2785 if (!strv_isempty(i->dropin_paths)) {
2786 _cleanup_free_ char *dir = NULL;
2790 STRV_FOREACH(dropin, i->dropin_paths) {
2791 if (! dir || last) {
2792 printf(dir ? " " : " Drop-In: ");
2797 if (path_get_parent(*dropin, &dir) < 0) {
2802 printf("%s\n %s", dir,
2803 draw_special_char(DRAW_TREE_RIGHT));
2806 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2808 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2812 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2814 if (streq_ptr(i->active_state, "failed")) {
2815 on = ansi_highlight_red();
2816 off = ansi_highlight_off();
2817 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2818 on = ansi_highlight_green();
2819 off = ansi_highlight_off();
2824 printf(" Active: %s%s (%s)%s",
2825 on, strna(i->active_state), ss, off);
2827 printf(" Active: %s%s%s",
2828 on, strna(i->active_state), off);
2830 if (!isempty(i->result) && !streq(i->result, "success"))
2831 printf(" (Result: %s)", i->result);
2833 timestamp = (streq_ptr(i->active_state, "active") ||
2834 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2835 (streq_ptr(i->active_state, "inactive") ||
2836 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2837 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2838 i->active_exit_timestamp;
2840 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2841 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2844 printf(" since %s; %s\n", s2, s1);
2846 printf(" since %s\n", s2);
2850 if (!i->condition_result && i->condition_timestamp > 0) {
2851 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2852 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2854 printf(" start condition failed at %s%s%s\n",
2855 s2, s1 ? "; " : "", s1 ? s1 : "");
2856 if (i->failed_condition_trigger)
2857 printf(" none of the trigger conditions were met\n");
2858 else if (i->failed_condition)
2859 printf(" %s=%s%s was not met\n",
2860 i->failed_condition,
2861 i->failed_condition_negate ? "!" : "",
2862 i->failed_condition_param);
2866 printf(" Device: %s\n", i->sysfs_path);
2868 printf(" Where: %s\n", i->where);
2870 printf(" What: %s\n", i->what);
2872 STRV_FOREACH(t, i->documentation)
2873 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2875 STRV_FOREACH_PAIR(t, t2, i->listen)
2876 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2879 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2881 LIST_FOREACH(exec, p, i->exec) {
2882 _cleanup_free_ char *argv = NULL;
2885 /* Only show exited processes here */
2889 argv = strv_join(p->argv, " ");
2890 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2892 good = is_clean_exit_lsb(p->code, p->status, NULL);
2894 on = ansi_highlight_red();
2895 off = ansi_highlight_off();
2899 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2901 if (p->code == CLD_EXITED) {
2904 printf("status=%i", p->status);
2906 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2911 printf("signal=%s", signal_to_string(p->status));
2913 printf(")%s\n", off);
2915 if (i->main_pid == p->pid &&
2916 i->start_timestamp == p->start_timestamp &&
2917 i->exit_timestamp == p->start_timestamp)
2918 /* Let's not show this twice */
2921 if (p->pid == i->control_pid)
2925 if (i->main_pid > 0 || i->control_pid > 0) {
2926 if (i->main_pid > 0) {
2927 printf(" Main PID: %u", (unsigned) i->main_pid);
2930 _cleanup_free_ char *comm = NULL;
2931 get_process_comm(i->main_pid, &comm);
2933 printf(" (%s)", comm);
2934 } else if (i->exit_code > 0) {
2935 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2937 if (i->exit_code == CLD_EXITED) {
2940 printf("status=%i", i->exit_status);
2942 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2947 printf("signal=%s", signal_to_string(i->exit_status));
2951 if (i->control_pid > 0)
2955 if (i->control_pid > 0) {
2956 _cleanup_free_ char *c = NULL;
2958 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2960 get_process_comm(i->control_pid, &c);
2969 printf(" Status: \"%s\"\n", i->status_text);
2971 if (i->control_group &&
2972 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2975 printf(" CGroup: %s\n", i->control_group);
2977 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2980 char prefix[] = " ";
2983 if (c > sizeof(prefix) - 1)
2984 c -= sizeof(prefix) - 1;
2988 if (i->main_pid > 0)
2989 extra[k++] = i->main_pid;
2991 if (i->control_pid > 0)
2992 extra[k++] = i->control_pid;
2994 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2995 c, false, extra, k, flags);
2999 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3001 show_journal_by_unit(stdout,
3005 i->inactive_exit_timestamp_monotonic,
3009 arg_scope == UNIT_FILE_SYSTEM,
3013 if (i->need_daemon_reload)
3014 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3015 ansi_highlight_red(),
3016 ansi_highlight_off(),
3017 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3020 static void show_unit_help(UnitStatusInfo *i) {
3025 if (!i->documentation) {
3026 log_info("Documentation for %s not known.", i->id);
3030 STRV_FOREACH(p, i->documentation) {
3032 if (startswith(*p, "man:")) {
3033 const char *args[4] = { "man", NULL, NULL, NULL };
3034 _cleanup_free_ char *page = NULL, *section = NULL;
3041 if ((*p)[k-1] == ')')
3042 e = strrchr(*p, '(');
3045 page = strndup((*p) + 4, e - *p - 4);
3046 section = strndup(e + 1, *p + k - e - 2);
3047 if (!page || !section) {
3059 log_error("Failed to fork: %m");
3065 execvp(args[0], (char**) args);
3066 log_error("Failed to execute man: %m");
3067 _exit(EXIT_FAILURE);
3070 wait_for_terminate(pid, NULL);
3072 log_info("Can't show: %s", *p);
3076 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3083 switch (contents[0]) {
3085 case SD_BUS_TYPE_STRING: {
3088 r = sd_bus_message_read(m, "s", &s);
3090 return bus_log_parse_error(r);
3093 if (streq(name, "Id"))
3095 else if (streq(name, "LoadState"))
3097 else if (streq(name, "ActiveState"))
3098 i->active_state = s;
3099 else if (streq(name, "SubState"))
3101 else if (streq(name, "Description"))
3103 else if (streq(name, "FragmentPath"))
3104 i->fragment_path = s;
3105 else if (streq(name, "SourcePath"))
3108 else if (streq(name, "DefaultControlGroup")) {
3110 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3112 i->control_group = e;
3115 else if (streq(name, "ControlGroup"))
3116 i->control_group = s;
3117 else if (streq(name, "StatusText"))
3119 else if (streq(name, "PIDFile"))
3121 else if (streq(name, "SysFSPath"))
3123 else if (streq(name, "Where"))
3125 else if (streq(name, "What"))
3127 else if (streq(name, "Following"))
3129 else if (streq(name, "UnitFileState"))
3130 i->unit_file_state = s;
3131 else if (streq(name, "Result"))
3138 case SD_BUS_TYPE_BOOLEAN: {
3141 r = sd_bus_message_read(m, "b", &b);
3143 return bus_log_parse_error(r);
3145 if (streq(name, "Accept"))
3147 else if (streq(name, "NeedDaemonReload"))
3148 i->need_daemon_reload = b;
3149 else if (streq(name, "ConditionResult"))
3150 i->condition_result = b;
3155 case SD_BUS_TYPE_UINT32: {
3158 r = sd_bus_message_read(m, "u", &u);
3160 return bus_log_parse_error(r);
3162 if (streq(name, "MainPID")) {
3164 i->main_pid = (pid_t) u;
3167 } else if (streq(name, "ControlPID"))
3168 i->control_pid = (pid_t) u;
3169 else if (streq(name, "ExecMainPID")) {
3171 i->main_pid = (pid_t) u;
3172 } else if (streq(name, "NAccepted"))
3174 else if (streq(name, "NConnections"))
3175 i->n_connections = u;
3180 case SD_BUS_TYPE_INT32: {
3183 r = sd_bus_message_read(m, "i", &j);
3185 return bus_log_parse_error(r);
3187 if (streq(name, "ExecMainCode"))
3188 i->exit_code = (int) j;
3189 else if (streq(name, "ExecMainStatus"))
3190 i->exit_status = (int) j;
3195 case SD_BUS_TYPE_UINT64: {
3198 r = sd_bus_message_read(m, "t", &u);
3200 return bus_log_parse_error(r);
3202 if (streq(name, "ExecMainStartTimestamp"))
3203 i->start_timestamp = (usec_t) u;
3204 else if (streq(name, "ExecMainExitTimestamp"))
3205 i->exit_timestamp = (usec_t) u;
3206 else if (streq(name, "ActiveEnterTimestamp"))
3207 i->active_enter_timestamp = (usec_t) u;
3208 else if (streq(name, "InactiveEnterTimestamp"))
3209 i->inactive_enter_timestamp = (usec_t) u;
3210 else if (streq(name, "InactiveExitTimestamp"))
3211 i->inactive_exit_timestamp = (usec_t) u;
3212 else if (streq(name, "InactiveExitTimestampMonotonic"))
3213 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3214 else if (streq(name, "ActiveExitTimestamp"))
3215 i->active_exit_timestamp = (usec_t) u;
3216 else if (streq(name, "ConditionTimestamp"))
3217 i->condition_timestamp = (usec_t) u;
3222 case SD_BUS_TYPE_ARRAY:
3224 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3225 _cleanup_free_ ExecStatusInfo *info = NULL;
3227 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3229 return bus_log_parse_error(r);
3231 info = new0(ExecStatusInfo, 1);
3235 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3237 info->name = strdup(name);
3241 LIST_PREPEND(exec, i->exec, info);
3243 info = new0(ExecStatusInfo, 1);
3249 return bus_log_parse_error(r);
3251 r = sd_bus_message_exit_container(m);
3253 return bus_log_parse_error(r);
3257 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3258 const char *type, *path;
3260 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3262 return bus_log_parse_error(r);
3264 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3266 r = strv_extend(&i->listen, type);
3270 r = strv_extend(&i->listen, path);
3275 return bus_log_parse_error(r);
3277 r = sd_bus_message_exit_container(m);
3279 return bus_log_parse_error(r);
3283 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3285 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3287 return bus_log_parse_error(r);
3289 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3291 r = sd_bus_message_read_strv(m, &i->documentation);
3293 return bus_log_parse_error(r);
3295 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3296 const char *cond, *param;
3297 int trigger, negate;
3300 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3302 return bus_log_parse_error(r);
3304 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3305 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3306 if (state < 0 && (!trigger || !i->failed_condition)) {
3307 i->failed_condition = cond;
3308 i->failed_condition_trigger = trigger;
3309 i->failed_condition_negate = negate;
3310 i->failed_condition_param = param;
3314 return bus_log_parse_error(r);
3316 r = sd_bus_message_exit_container(m);
3318 return bus_log_parse_error(r);
3325 case SD_BUS_TYPE_STRUCT_BEGIN:
3327 if (streq(name, "LoadError")) {
3328 const char *n, *message;
3330 r = sd_bus_message_read(m, "(ss)", &n, &message);
3332 return bus_log_parse_error(r);
3334 if (!isempty(message))
3335 i->load_error = message;
3348 r = sd_bus_message_skip(m, contents);
3350 return bus_log_parse_error(r);
3355 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3361 /* This is a low-level property printer, see
3362 * print_status_info() for the nicer output */
3364 if (arg_properties && !strv_find(arg_properties, name)) {
3365 /* skip what we didn't read */
3366 r = sd_bus_message_skip(m, contents);
3370 switch (contents[0]) {
3372 case SD_BUS_TYPE_STRUCT_BEGIN:
3374 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3377 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3379 return bus_log_parse_error(r);
3382 printf("%s=%u\n", name, (unsigned) u);
3384 printf("%s=\n", name);
3388 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3391 r = sd_bus_message_read(m, "(so)", &s, NULL);
3393 return bus_log_parse_error(r);
3395 if (arg_all || !isempty(s))
3396 printf("%s=%s\n", name, s);
3400 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3401 const char *a = NULL, *b = NULL;
3403 r = sd_bus_message_read(m, "(ss)", &a, &b);
3405 return bus_log_parse_error(r);
3407 if (arg_all || !isempty(a) || !isempty(b))
3408 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3415 case SD_BUS_TYPE_ARRAY:
3417 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3421 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3423 return bus_log_parse_error(r);
3425 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3426 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3429 return bus_log_parse_error(r);
3431 r = sd_bus_message_exit_container(m);
3433 return bus_log_parse_error(r);
3437 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3438 const char *type, *path;
3440 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3442 return bus_log_parse_error(r);
3444 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3445 printf("%s=%s\n", type, path);
3447 return bus_log_parse_error(r);
3449 r = sd_bus_message_exit_container(m);
3451 return bus_log_parse_error(r);
3455 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3456 const char *type, *path;
3458 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3460 return bus_log_parse_error(r);
3462 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3463 printf("Listen%s=%s\n", type, path);
3465 return bus_log_parse_error(r);
3467 r = sd_bus_message_exit_container(m);
3469 return bus_log_parse_error(r);
3473 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3475 uint64_t value, next_elapse;
3477 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3479 return bus_log_parse_error(r);
3481 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3482 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3484 printf("%s={ value=%s ; next_elapse=%s }\n",
3486 format_timespan(timespan1, sizeof(timespan1), value, 0),
3487 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3490 return bus_log_parse_error(r);
3492 r = sd_bus_message_exit_container(m);
3494 return bus_log_parse_error(r);
3498 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3499 ExecStatusInfo info = {};
3501 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3503 return bus_log_parse_error(r);
3505 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3506 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3507 _cleanup_free_ char *tt;
3509 tt = strv_join(info.argv, " ");
3511 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3515 yes_no(info.ignore),
3516 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3517 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3518 (unsigned) info. pid,
3519 sigchld_code_to_string(info.code),
3521 info.code == CLD_EXITED ? "" : "/",
3522 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3525 strv_free(info.argv);
3529 r = sd_bus_message_exit_container(m);
3531 return bus_log_parse_error(r);
3535 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3536 const char *path, *rwm;
3538 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3540 return bus_log_parse_error(r);
3542 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3543 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3545 return bus_log_parse_error(r);
3547 r = sd_bus_message_exit_container(m);
3549 return bus_log_parse_error(r);
3553 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3557 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3559 return bus_log_parse_error(r);
3561 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3562 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3564 return bus_log_parse_error(r);
3566 r = sd_bus_message_exit_container(m);
3568 return bus_log_parse_error(r);
3572 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3576 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3578 return bus_log_parse_error(r);
3580 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3581 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3583 return bus_log_parse_error(r);
3585 r = sd_bus_message_exit_container(m);
3587 return bus_log_parse_error(r);
3595 r = bus_print_property(name, m, arg_all);
3597 return bus_log_parse_error(r);
3600 r = sd_bus_message_skip(m, contents);
3602 return bus_log_parse_error(r);
3605 printf("%s=[unprintable]\n", name);
3611 static int show_one(
3615 bool show_properties,
3619 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3620 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3621 UnitStatusInfo info = {};
3628 log_debug("Showing one %s", path);
3630 r = sd_bus_call_method(
3632 "org.freedesktop.systemd1",
3634 "org.freedesktop.DBus.Properties",
3640 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3644 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3646 return bus_log_parse_error(r);
3653 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3654 const char *name, *contents;
3656 r = sd_bus_message_read(reply, "s", &name);
3658 return bus_log_parse_error(r);
3660 r = sd_bus_message_peek_type(reply, NULL, &contents);
3662 return bus_log_parse_error(r);
3664 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3666 return bus_log_parse_error(r);
3668 if (show_properties)
3669 r = print_property(name, reply, contents);
3671 r = status_property(name, reply, &info, contents);
3675 r = sd_bus_message_exit_container(reply);
3677 return bus_log_parse_error(r);
3679 r = sd_bus_message_exit_container(reply);
3681 return bus_log_parse_error(r);
3684 return bus_log_parse_error(r);
3686 r = sd_bus_message_exit_container(reply);
3688 return bus_log_parse_error(r);
3692 if (!show_properties) {
3693 if (streq(verb, "help"))
3694 show_unit_help(&info);
3696 print_status_info(&info, ellipsized);
3699 strv_free(info.documentation);
3700 strv_free(info.dropin_paths);
3701 strv_free(info.listen);
3703 if (!streq_ptr(info.active_state, "active") &&
3704 !streq_ptr(info.active_state, "reloading") &&
3705 streq(verb, "status")) {
3706 /* According to LSB: "program not running" */
3707 /* 0: program is running or service is OK
3708 * 1: program is dead and /var/run pid file exists
3709 * 2: program is dead and /var/lock lock file exists
3710 * 3: program is not running
3711 * 4: program or service status is unknown
3713 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3719 while ((p = info.exec)) {
3720 LIST_REMOVE(exec, info.exec, p);
3721 exec_status_info_free(p);
3727 static int get_unit_dbus_path_by_pid(
3732 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3733 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3737 r = sd_bus_call_method(
3739 "org.freedesktop.systemd1",
3740 "/org/freedesktop/systemd1",
3741 "org.freedesktop.systemd1.Manager",
3747 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3751 r = sd_bus_message_read(reply, "o", &u);
3753 return bus_log_parse_error(r);
3763 static int show_all(
3766 bool show_properties,
3770 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3771 _cleanup_free_ UnitInfo *unit_infos = NULL;
3776 r = get_unit_list(bus, &reply, &unit_infos, NULL);
3780 pager_open_if_enabled();
3784 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3786 for (u = unit_infos; u < unit_infos + c; u++) {
3787 _cleanup_free_ char *p = NULL;
3789 p = unit_dbus_path_from_name(u->id);
3793 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3801 static int cat(sd_bus *bus, char **args) {
3802 _cleanup_free_ char *unit = NULL;
3803 _cleanup_strv_free_ char **names = NULL;
3811 r = expand_names(bus, args + 1, NULL, &names);
3813 log_error("Failed to expand names: %s", strerror(-r));
3815 pager_open_if_enabled();
3817 STRV_FOREACH(name, names) {
3818 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3819 _cleanup_strv_free_ char **dropin_paths = NULL;
3820 _cleanup_free_ char *fragment_path = NULL;
3823 unit = unit_dbus_path_from_name(*name);
3827 if (need_daemon_reload(bus, *name) > 0)
3828 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3829 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3831 r = sd_bus_get_property_string(
3833 "org.freedesktop.systemd1",
3835 "org.freedesktop.systemd1.Unit",
3840 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3844 r = sd_bus_get_property_strv(
3846 "org.freedesktop.systemd1",
3848 "org.freedesktop.systemd1.Unit",
3853 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3862 if (!isempty(fragment_path)) {
3863 printf("%s# %s%s\n",
3864 ansi_highlight_blue(),
3866 ansi_highlight_off());
3869 r = sendfile_full(STDOUT_FILENO, fragment_path);
3871 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3876 STRV_FOREACH(path, dropin_paths) {
3877 printf("%s%s# %s%s\n",
3878 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3879 ansi_highlight_blue(),
3881 ansi_highlight_off());
3884 r = sendfile_full(STDOUT_FILENO, *path);
3886 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3892 return r < 0 ? r : 0;
3895 static int show(sd_bus *bus, char **args) {
3896 bool show_properties, show_status, new_line = false;
3897 bool ellipsized = false;
3903 show_properties = streq(args[0], "show");
3904 show_status = streq(args[0], "status");
3906 if (show_properties)
3907 pager_open_if_enabled();
3909 /* If no argument is specified inspect the manager itself */
3911 if (show_properties && strv_length(args) <= 1)
3912 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3914 if (show_status && strv_length(args) <= 1)
3915 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3917 _cleanup_free_ char **patterns = NULL;
3920 STRV_FOREACH(name, args + 1) {
3921 _cleanup_free_ char *unit = NULL;
3924 if (safe_atou32(*name, &id) < 0) {
3925 if (strv_push(&patterns, *name) < 0)
3929 } else if (show_properties) {
3930 /* Interpret as job id */
3931 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3935 /* Interpret as PID */
3936 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3943 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3946 if (!strv_isempty(patterns)) {
3947 _cleanup_strv_free_ char **names = NULL;
3949 r = expand_names(bus, patterns, NULL, &names);
3951 log_error("Failed to expand names: %s", strerror(-r));
3953 STRV_FOREACH(name, names) {
3954 _cleanup_free_ char *unit;
3956 unit = unit_dbus_path_from_name(*name);
3960 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3965 if (ellipsized && !arg_quiet)
3966 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3971 static int append_assignment(sd_bus_message *m, const char *assignment) {
3979 eq = strchr(assignment, '=');
3981 log_error("Not an assignment: %s", assignment);
3985 field = strndupa(assignment, eq - assignment);
3988 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3990 return bus_log_create_error(r);
3992 if (streq(field, "CPUAccounting") ||
3993 streq(field, "MemoryAccounting") ||
3994 streq(field, "BlockIOAccounting")) {
3996 r = parse_boolean(eq);
3998 log_error("Failed to parse boolean assignment %s.", assignment);
4002 r = sd_bus_message_append(m, "v", "b", r);
4004 } else if (streq(field, "MemoryLimit")) {
4007 r = parse_bytes(eq, &bytes);
4009 log_error("Failed to parse bytes specification %s", assignment);
4013 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
4015 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
4018 r = safe_atou64(eq, &u);
4020 log_error("Failed to parse %s value %s.", field, eq);
4024 r = sd_bus_message_append(m, "v", "t", u);
4026 } else if (streq(field, "DevicePolicy"))
4027 r = sd_bus_message_append(m, "v", "s", eq);
4029 else if (streq(field, "DeviceAllow")) {
4032 r = sd_bus_message_append(m, "v", "a(ss)", 0);
4034 const char *path, *rwm;
4037 e = strchr(eq, ' ');
4039 path = strndupa(eq, e - eq);
4046 if (!path_startswith(path, "/dev")) {
4047 log_error("%s is not a device file in /dev.", path);
4051 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
4054 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
4057 r = sd_bus_message_append(m, "v", "a(st)", 0);
4059 const char *path, *bandwidth;
4063 e = strchr(eq, ' ');
4065 path = strndupa(eq, e - eq);
4068 log_error("Failed to parse %s value %s.", field, eq);
4072 if (!path_startswith(path, "/dev")) {
4073 log_error("%s is not a device file in /dev.", path);
4077 r = parse_bytes(bandwidth, &bytes);
4079 log_error("Failed to parse byte value %s.", bandwidth);
4083 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4086 } else if (streq(field, "BlockIODeviceWeight")) {
4089 r = sd_bus_message_append(m, "v", "a(st)", 0);
4091 const char *path, *weight;
4095 e = strchr(eq, ' ');
4097 path = strndupa(eq, e - eq);
4100 log_error("Failed to parse %s value %s.", field, eq);
4104 if (!path_startswith(path, "/dev")) {
4105 log_error("%s is not a device file in /dev.", path);
4109 r = safe_atou64(weight, &u);
4111 log_error("Failed to parse %s value %s.", field, weight);
4114 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4118 log_error("Unknown assignment %s.", assignment);
4123 return bus_log_create_error(r);
4128 static int set_property(sd_bus *bus, char **args) {
4129 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4130 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4131 _cleanup_free_ char *n = NULL;
4135 r = sd_bus_message_new_method_call(
4137 "org.freedesktop.systemd1",
4138 "/org/freedesktop/systemd1",
4139 "org.freedesktop.systemd1.Manager",
4140 "SetUnitProperties",
4143 return bus_log_create_error(r);
4145 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4149 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4151 return bus_log_create_error(r);
4153 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4155 return bus_log_create_error(r);
4157 STRV_FOREACH(i, args + 2) {
4158 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4160 return bus_log_create_error(r);
4162 r = append_assignment(m, *i);
4166 r = sd_bus_message_close_container(m);
4168 return bus_log_create_error(r);
4171 r = sd_bus_message_close_container(m);
4173 return bus_log_create_error(r);
4175 r = sd_bus_call(bus, m, 0, &error, NULL);
4177 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4184 static int snapshot(sd_bus *bus, char **args) {
4185 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4186 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4187 _cleanup_free_ char *n = NULL, *id = NULL;
4191 if (strv_length(args) > 1)
4192 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4198 r = sd_bus_call_method(
4200 "org.freedesktop.systemd1",
4201 "/org/freedesktop/systemd1",
4202 "org.freedesktop.systemd1.Manager",
4208 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4212 r = sd_bus_message_read(reply, "o", &path);
4214 return bus_log_parse_error(r);
4216 r = sd_bus_get_property_string(
4218 "org.freedesktop.systemd1",
4220 "org.freedesktop.systemd1.Unit",
4225 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4235 static int delete_snapshot(sd_bus *bus, char **args) {
4236 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4237 _cleanup_strv_free_ char **names = NULL;
4243 r = expand_names(bus, args + 1, ".snapshot", &names);
4245 log_error("Failed to expand names: %s", strerror(-r));
4247 STRV_FOREACH(name, names) {
4248 q = sd_bus_call_method(
4250 "org.freedesktop.systemd1",
4251 "/org/freedesktop/systemd1",
4252 "org.freedesktop.systemd1.Manager",
4258 log_error("Failed to remove snapshot %s: %s",
4259 *name, bus_error_message(&error, r));
4268 static int daemon_reload(sd_bus *bus, char **args) {
4269 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4273 if (arg_action == ACTION_RELOAD)
4275 else if (arg_action == ACTION_REEXEC)
4276 method = "Reexecute";
4278 assert(arg_action == ACTION_SYSTEMCTL);
4281 streq(args[0], "clear-jobs") ||
4282 streq(args[0], "cancel") ? "ClearJobs" :
4283 streq(args[0], "daemon-reexec") ? "Reexecute" :
4284 streq(args[0], "reset-failed") ? "ResetFailed" :
4285 streq(args[0], "halt") ? "Halt" :
4286 streq(args[0], "poweroff") ? "PowerOff" :
4287 streq(args[0], "reboot") ? "Reboot" :
4288 streq(args[0], "kexec") ? "KExec" :
4289 streq(args[0], "exit") ? "Exit" :
4290 /* "daemon-reload" */ "Reload";
4293 r = sd_bus_call_method(
4295 "org.freedesktop.systemd1",
4296 "/org/freedesktop/systemd1",
4297 "org.freedesktop.systemd1.Manager",
4303 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4304 /* There's always a fallback possible for
4305 * legacy actions. */
4307 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4308 /* On reexecution, we expect a disconnect, not a
4312 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4314 return r < 0 ? r : 0;
4317 static int reset_failed(sd_bus *bus, char **args) {
4318 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4319 _cleanup_strv_free_ char **names = NULL;
4323 if (strv_length(args) <= 1)
4324 return daemon_reload(bus, args);
4326 r = expand_names(bus, args + 1, NULL, &names);
4328 log_error("Failed to expand names: %s", strerror(-r));
4330 STRV_FOREACH(name, names) {
4331 q = sd_bus_call_method(
4333 "org.freedesktop.systemd1",
4334 "/org/freedesktop/systemd1",
4335 "org.freedesktop.systemd1.Manager",
4341 log_error("Failed to reset failed state of unit %s: %s",
4342 *name, bus_error_message(&error, r));
4351 static int show_environment(sd_bus *bus, char **args) {
4352 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4353 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4357 pager_open_if_enabled();
4359 r = sd_bus_get_property(
4361 "org.freedesktop.systemd1",
4362 "/org/freedesktop/systemd1",
4363 "org.freedesktop.systemd1.Manager",
4369 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4373 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4375 return bus_log_parse_error(r);
4377 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4380 return bus_log_parse_error(r);
4382 r = sd_bus_message_exit_container(reply);
4384 return bus_log_parse_error(r);
4389 static int switch_root(sd_bus *bus, char **args) {
4390 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4391 _cleanup_free_ char *init = NULL;
4396 l = strv_length(args);
4397 if (l < 2 || l > 3) {
4398 log_error("Wrong number of arguments.");
4405 init = strdup(args[2]);
4407 parse_env_file("/proc/cmdline", WHITESPACE,
4418 log_debug("switching root - root: %s; init: %s", root, init);
4420 r = sd_bus_call_method(
4422 "org.freedesktop.systemd1",
4423 "/org/freedesktop/systemd1",
4424 "org.freedesktop.systemd1.Manager",
4430 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4437 static int set_environment(sd_bus *bus, char **args) {
4438 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4439 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4446 method = streq(args[0], "set-environment")
4448 : "UnsetEnvironment";
4450 r = sd_bus_message_new_method_call(
4452 "org.freedesktop.systemd1",
4453 "/org/freedesktop/systemd1",
4454 "org.freedesktop.systemd1.Manager",
4458 return bus_log_create_error(r);
4460 r = sd_bus_message_append_strv(m, args + 1);
4462 return bus_log_create_error(r);
4464 r = sd_bus_call(bus, m, 0, &error, NULL);
4466 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4473 static int enable_sysv_units(const char *verb, char **args) {
4476 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4477 unsigned f = 1, t = 1;
4478 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4480 if (arg_scope != UNIT_FILE_SYSTEM)
4483 if (!streq(verb, "enable") &&
4484 !streq(verb, "disable") &&
4485 !streq(verb, "is-enabled"))
4488 /* Processes all SysV units, and reshuffles the array so that
4489 * afterwards only the native units remain */
4491 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4496 for (f = 0; args[f]; f++) {
4498 _cleanup_free_ char *p = NULL, *q = NULL;
4499 bool found_native = false, found_sysv;
4501 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4509 if (!endswith(name, ".service"))
4512 if (path_is_absolute(name))
4515 STRV_FOREACH(k, paths.unit_path) {
4516 if (!isempty(arg_root))
4517 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4519 asprintf(&p, "%s/%s", *k, name);
4526 found_native = access(p, F_OK) >= 0;
4537 if (!isempty(arg_root))
4538 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4540 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4546 p[strlen(p) - sizeof(".service") + 1] = 0;
4547 found_sysv = access(p, F_OK) >= 0;
4552 /* Mark this entry, so that we don't try enabling it as native unit */
4553 args[f] = (char*) "";
4555 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4557 if (!isempty(arg_root))
4558 argv[c++] = q = strappend("--root=", arg_root);
4560 argv[c++] = basename(p);
4562 streq(verb, "enable") ? "on" :
4563 streq(verb, "disable") ? "off" : "--level=5";
4566 l = strv_join((char**)argv, " ");
4572 log_info("Executing %s", l);
4577 log_error("Failed to fork: %m");
4580 } else if (pid == 0) {
4583 execv(argv[0], (char**) argv);
4584 _exit(EXIT_FAILURE);
4587 j = wait_for_terminate(pid, &status);
4589 log_error("Failed to wait for child: %s", strerror(-r));
4594 if (status.si_code == CLD_EXITED) {
4595 if (streq(verb, "is-enabled")) {
4596 if (status.si_status == 0) {
4605 } else if (status.si_status != 0) {
4616 /* Drop all SysV units */
4617 for (f = 0, t = 0; args[f]; f++) {
4619 if (isempty(args[f]))
4622 args[t++] = args[f];
4631 static int mangle_names(char **original_names, char ***mangled_names) {
4632 char **i, **l, **name;
4634 l = new(char*, strv_length(original_names) + 1);
4639 STRV_FOREACH(name, original_names) {
4641 /* When enabling units qualified path names are OK,
4642 * too, hence allow them explicitly. */
4647 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4663 static int enable_unit(sd_bus *bus, char **args) {
4664 _cleanup_strv_free_ char **names = NULL;
4665 const char *verb = args[0];
4666 UnitFileChange *changes = NULL;
4667 unsigned n_changes = 0;
4668 int carries_install_info = -1;
4674 r = mangle_names(args+1, &names);
4678 r = enable_sysv_units(verb, names);
4682 if (!bus || avoid_bus()) {
4683 if (streq(verb, "enable")) {
4684 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4685 carries_install_info = r;
4686 } else if (streq(verb, "disable"))
4687 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4688 else if (streq(verb, "reenable")) {
4689 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4690 carries_install_info = r;
4691 } else if (streq(verb, "link"))
4692 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4693 else if (streq(verb, "preset")) {
4694 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4695 carries_install_info = r;
4696 } else if (streq(verb, "mask"))
4697 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4698 else if (streq(verb, "unmask"))
4699 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4701 assert_not_reached("Unknown verb");
4704 log_error("Operation failed: %s", strerror(-r));
4709 dump_unit_file_changes(changes, n_changes);
4713 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4714 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4715 int expect_carries_install_info = false;
4716 bool send_force = true;
4719 if (streq(verb, "enable")) {
4720 method = "EnableUnitFiles";
4721 expect_carries_install_info = true;
4722 } else if (streq(verb, "disable")) {
4723 method = "DisableUnitFiles";
4725 } else if (streq(verb, "reenable")) {
4726 method = "ReenableUnitFiles";
4727 expect_carries_install_info = true;
4728 } else if (streq(verb, "link"))
4729 method = "LinkUnitFiles";
4730 else if (streq(verb, "preset")) {
4731 method = "PresetUnitFiles";
4732 expect_carries_install_info = true;
4733 } else if (streq(verb, "mask"))
4734 method = "MaskUnitFiles";
4735 else if (streq(verb, "unmask")) {
4736 method = "UnmaskUnitFiles";
4739 assert_not_reached("Unknown verb");
4741 r = sd_bus_message_new_method_call(
4743 "org.freedesktop.systemd1",
4744 "/org/freedesktop/systemd1",
4745 "org.freedesktop.systemd1.Manager",
4749 return bus_log_create_error(r);
4751 r = sd_bus_message_append_strv(m, names);
4753 return bus_log_create_error(r);
4755 r = sd_bus_message_append(m, "b", arg_runtime);
4757 return bus_log_create_error(r);
4760 r = sd_bus_message_append(m, "b", arg_force);
4762 return bus_log_create_error(r);
4765 r = sd_bus_call(bus, m, 0, &error, &reply);
4767 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4771 if (expect_carries_install_info) {
4772 r = sd_bus_message_read(reply, "b", &carries_install_info);
4774 return bus_log_parse_error(r);
4777 r = deserialize_and_dump_unit_file_changes(reply);
4781 /* Try to reload if enabeld */
4783 r = daemon_reload(bus, args);
4788 if (carries_install_info == 0)
4789 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4790 "using systemctl.\n"
4791 "Possible reasons for having this kind of units are:\n"
4792 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4793 " .wants/ or .requires/ directory.\n"
4794 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4795 " a requirement dependency on it.\n"
4796 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4797 " D-Bus, udev, scripted systemctl call, ...).\n");
4800 unit_file_changes_free(changes, n_changes);
4805 static int unit_is_enabled(sd_bus *bus, char **args) {
4807 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4808 _cleanup_strv_free_ char **names = NULL;
4813 r = mangle_names(args+1, &names);
4817 r = enable_sysv_units(args[0], names);
4823 if (!bus || avoid_bus()) {
4825 STRV_FOREACH(name, names) {
4826 UnitFileState state;
4828 state = unit_file_get_state(arg_scope, arg_root, *name);
4830 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4834 if (state == UNIT_FILE_ENABLED ||
4835 state == UNIT_FILE_ENABLED_RUNTIME ||
4836 state == UNIT_FILE_STATIC)
4840 puts(unit_file_state_to_string(state));
4844 STRV_FOREACH(name, names) {
4845 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4848 r = sd_bus_call_method(
4850 "org.freedesktop.systemd1",
4851 "/org/freedesktop/systemd1",
4852 "org.freedesktop.systemd1.Manager",
4858 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4862 r = sd_bus_message_read(reply, "s", &s);
4864 return bus_log_parse_error(r);
4866 if (streq(s, "enabled") ||
4867 streq(s, "enabled-runtime") ||
4879 static int systemctl_help(void) {
4881 pager_open_if_enabled();
4883 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4884 "Query or send control commands to the systemd manager.\n\n"
4885 " -h --help Show this help\n"
4886 " --version Show package version\n"
4887 " --system Connect to system manager\n"
4888 " --user Connect to user service manager\n"
4889 " -H --host=[USER@]HOST\n"
4890 " Operate on remote host\n"
4891 " -M --machine=CONTAINER\n"
4892 " Operate on local container\n"
4893 " -t --type=TYPE List only units of a particular type\n"
4894 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4895 " -p --property=NAME Show only properties by this name\n"
4896 " -a --all Show all loaded units/properties, including dead/empty\n"
4897 " ones. To list all units installed on the system, use\n"
4898 " the 'list-unit-files' command instead.\n"
4899 " -l --full Don't ellipsize unit names on output\n"
4900 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4901 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4902 " queueing a new job\n"
4903 " --show-types When showing sockets, explicitly show their type\n"
4904 " -i --ignore-inhibitors\n"
4905 " When shutting down or sleeping, ignore inhibitors\n"
4906 " --kill-who=WHO Who to send signal to\n"
4907 " -s --signal=SIGNAL Which signal to send\n"
4908 " -q --quiet Suppress output\n"
4909 " --no-block Do not wait until operation finished\n"
4910 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4911 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4913 " --no-legend Do not print a legend (column headers and hints)\n"
4914 " --no-pager Do not pipe output into a pager\n"
4915 " --no-ask-password\n"
4916 " Do not ask for system passwords\n"
4917 " --global Enable/disable unit files globally\n"
4918 " --runtime Enable unit files only temporarily until next reboot\n"
4919 " -f --force When enabling unit files, override existing symlinks\n"
4920 " When shutting down, execute action immediately\n"
4921 " --root=PATH Enable unit files in the specified root directory\n"
4922 " -n --lines=INTEGER Number of journal entries to show\n"
4923 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4924 " verbose, export, json, json-pretty, json-sse, cat)\n"
4925 " --plain Print unit dependencies as a list instead of a tree\n\n"
4927 " list-units [PATTERN...] List loaded units\n"
4928 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4929 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4930 " start NAME... Start (activate) one or more units\n"
4931 " stop NAME... Stop (deactivate) one or more units\n"
4932 " reload NAME... Reload one or more units\n"
4933 " restart NAME... Start or restart one or more units\n"
4934 " try-restart NAME... Restart one or more units if active\n"
4935 " reload-or-restart NAME... Reload one or more units if possible,\n"
4936 " otherwise start or restart\n"
4937 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
4938 " otherwise restart if active\n"
4939 " isolate NAME Start one unit and stop all others\n"
4940 " kill NAME... Send signal to processes of a unit\n"
4941 " is-active NAME... Check whether units are active\n"
4942 " is-failed NAME... Check whether units are failed\n"
4943 " status [NAME...|PID...] Show runtime status of one or more units\n"
4944 " show [NAME...|JOB...] Show properties of one or more\n"
4945 " units/jobs or the manager\n"
4946 " cat NAME... Show files and drop-ins of one or more units\n"
4947 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
4948 " help NAME...|PID... Show manual for one or more units\n"
4949 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4951 " list-dependencies [NAME] Recursively show units which are required\n"
4952 " or wanted by this unit or by which this\n"
4953 " unit is required or wanted\n\n"
4954 "Unit File Commands:\n"
4955 " list-unit-files [PATTERN...] List installed unit files\n"
4956 " enable NAME... Enable one or more unit files\n"
4957 " disable NAME... Disable one or more unit files\n"
4958 " reenable NAME... Reenable one or more unit files\n"
4959 " preset NAME... Enable/disable one or more unit files\n"
4960 " based on preset configuration\n"
4961 " is-enabled NAME... Check whether unit files are enabled\n\n"
4962 " mask NAME... Mask one or more units\n"
4963 " unmask NAME... Unmask one or more units\n"
4964 " link PATH... Link one or more units files into\n"
4965 " the search path\n"
4966 " get-default Get the name of the default target\n"
4967 " set-default NAME Set the default target\n\n"
4969 " list-jobs [PATTERN...] List jobs\n"
4970 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4971 "Snapshot Commands:\n"
4972 " snapshot [NAME] Create a snapshot\n"
4973 " delete NAME... Remove one or more snapshots\n\n"
4974 "Environment Commands:\n"
4975 " show-environment Dump environment\n"
4976 " set-environment NAME=VALUE... Set one or more environment variables\n"
4977 " unset-environment NAME... Unset one or more environment variables\n\n"
4978 "Manager Lifecycle Commands:\n"
4979 " daemon-reload Reload systemd manager configuration\n"
4980 " daemon-reexec Reexecute systemd manager\n\n"
4981 "System Commands:\n"
4982 " default Enter system default mode\n"
4983 " rescue Enter system rescue mode\n"
4984 " emergency Enter system emergency mode\n"
4985 " halt Shut down and halt the system\n"
4986 " poweroff Shut down and power-off the system\n"
4987 " reboot [ARG] Shut down and reboot the system\n"
4988 " kexec Shut down and reboot the system with kexec\n"
4989 " exit Request user instance exit\n"
4990 " switch-root ROOT [INIT] Change to a different root file system\n"
4991 " suspend Suspend the system\n"
4992 " hibernate Hibernate the system\n"
4993 " hybrid-sleep Hibernate and suspend the system\n",
4994 program_invocation_short_name);
4999 static int halt_help(void) {
5001 printf("%s [OPTIONS...]%s\n\n"
5002 "%s the system.\n\n"
5003 " --help Show this help\n"
5004 " --halt Halt the machine\n"
5005 " -p --poweroff Switch off the machine\n"
5006 " --reboot Reboot the machine\n"
5007 " -f --force Force immediate halt/power-off/reboot\n"
5008 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5009 " -d --no-wtmp Don't write wtmp record\n"
5010 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5011 program_invocation_short_name,
5012 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5013 arg_action == ACTION_REBOOT ? "Reboot" :
5014 arg_action == ACTION_POWEROFF ? "Power off" :
5020 static int shutdown_help(void) {
5022 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5023 "Shut down the system.\n\n"
5024 " --help Show this help\n"
5025 " -H --halt Halt the machine\n"
5026 " -P --poweroff Power-off the machine\n"
5027 " -r --reboot Reboot the machine\n"
5028 " -h Equivalent to --poweroff, overridden by --halt\n"
5029 " -k Don't halt/power-off/reboot, just send warnings\n"
5030 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5031 " -c Cancel a pending shutdown\n",
5032 program_invocation_short_name);
5037 static int telinit_help(void) {
5039 printf("%s [OPTIONS...] {COMMAND}\n\n"
5040 "Send control commands to the init daemon.\n\n"
5041 " --help Show this help\n"
5042 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5044 " 0 Power-off the machine\n"
5045 " 6 Reboot the machine\n"
5046 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5047 " 1, s, S Enter rescue mode\n"
5048 " q, Q Reload init daemon configuration\n"
5049 " u, U Reexecute init daemon\n",
5050 program_invocation_short_name);
5055 static int runlevel_help(void) {
5057 printf("%s [OPTIONS...]\n\n"
5058 "Prints the previous and current runlevel of the init system.\n\n"
5059 " --help Show this help\n",
5060 program_invocation_short_name);
5065 static int help_types(void) {
5069 puts("Available unit types:");
5070 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5071 t = unit_type_to_string(i);
5079 static int systemctl_parse_argv(int argc, char *argv[]) {
5088 ARG_IGNORE_DEPENDENCIES,
5100 ARG_NO_ASK_PASSWORD,
5109 static const struct option options[] = {
5110 { "help", no_argument, NULL, 'h' },
5111 { "version", no_argument, NULL, ARG_VERSION },
5112 { "type", required_argument, NULL, 't' },
5113 { "property", required_argument, NULL, 'p' },
5114 { "all", no_argument, NULL, 'a' },
5115 { "reverse", no_argument, NULL, ARG_REVERSE },
5116 { "after", no_argument, NULL, ARG_AFTER },
5117 { "before", no_argument, NULL, ARG_BEFORE },
5118 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5119 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5120 { "full", no_argument, NULL, 'l' },
5121 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5122 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5123 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5124 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5125 { "ignore-inhibitors", no_argument, NULL, 'i' },
5126 { "user", no_argument, NULL, ARG_USER },
5127 { "system", no_argument, NULL, ARG_SYSTEM },
5128 { "global", no_argument, NULL, ARG_GLOBAL },
5129 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5130 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5131 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5132 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5133 { "quiet", no_argument, NULL, 'q' },
5134 { "root", required_argument, NULL, ARG_ROOT },
5135 { "force", no_argument, NULL, ARG_FORCE },
5136 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5137 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5138 { "signal", required_argument, NULL, 's' },
5139 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5140 { "host", required_argument, NULL, 'H' },
5141 { "machine", required_argument, NULL, 'M' },
5142 { "runtime", no_argument, NULL, ARG_RUNTIME },
5143 { "lines", required_argument, NULL, 'n' },
5144 { "output", required_argument, NULL, 'o' },
5145 { "plain", no_argument, NULL, ARG_PLAIN },
5146 { "state", required_argument, NULL, ARG_STATE },
5155 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5160 return systemctl_help();
5163 puts(PACKAGE_STRING);
5164 puts(SYSTEMD_FEATURES);
5171 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5172 _cleanup_free_ char *type;
5174 type = strndup(word, size);
5178 if (streq(type, "help")) {
5183 if (unit_type_from_string(type) >= 0) {
5184 if (strv_push(&arg_types, type))
5190 /* It's much nicer to use --state= for
5191 * load states, but let's support this
5192 * in --types= too for compatibility
5193 * with old versions */
5194 if (unit_load_state_from_string(optarg) >= 0) {
5195 if (strv_push(&arg_states, type) < 0)
5201 log_error("Unknown unit type or load state '%s'.", type);
5202 log_info("Use -t help to see a list of allowed values.");
5210 /* Make sure that if the empty property list
5211 was specified, we won't show any properties. */
5212 if (isempty(optarg) && !arg_properties) {
5213 arg_properties = new0(char*, 1);
5214 if (!arg_properties)
5220 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5223 prop = strndup(word, size);
5227 if (strv_push(&arg_properties, prop) < 0) {
5234 /* If the user asked for a particular
5235 * property, show it to him, even if it is
5247 arg_dependency = DEPENDENCY_REVERSE;
5251 arg_dependency = DEPENDENCY_AFTER;
5255 arg_dependency = DEPENDENCY_BEFORE;
5258 case ARG_SHOW_TYPES:
5259 arg_show_types = true;
5263 arg_job_mode = optarg;
5267 arg_job_mode = "fail";
5270 case ARG_IRREVERSIBLE:
5271 arg_job_mode = "replace-irreversibly";
5274 case ARG_IGNORE_DEPENDENCIES:
5275 arg_job_mode = "ignore-dependencies";
5279 arg_scope = UNIT_FILE_USER;
5283 arg_scope = UNIT_FILE_SYSTEM;
5287 arg_scope = UNIT_FILE_GLOBAL;
5291 arg_no_block = true;
5295 arg_no_legend = true;
5299 arg_no_pager = true;
5315 if (strv_extend(&arg_states, "failed") < 0)
5333 arg_no_reload = true;
5337 arg_kill_who = optarg;
5341 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5342 log_error("Failed to parse signal string %s.", optarg);
5347 case ARG_NO_ASK_PASSWORD:
5348 arg_ask_password = false;
5352 arg_transport = BUS_TRANSPORT_REMOTE;
5357 arg_transport = BUS_TRANSPORT_CONTAINER;
5366 if (safe_atou(optarg, &arg_lines) < 0) {
5367 log_error("Failed to parse lines '%s'", optarg);
5373 arg_output = output_mode_from_string(optarg);
5374 if (arg_output < 0) {
5375 log_error("Unknown output '%s'.", optarg);
5381 arg_ignore_inhibitors = true;
5392 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5395 s = strndup(word, size);
5399 if (strv_push(&arg_states, s) < 0) {
5411 assert_not_reached("Unhandled option");
5415 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5416 log_error("Cannot access user instance remotely.");
5423 static int halt_parse_argv(int argc, char *argv[]) {
5432 static const struct option options[] = {
5433 { "help", no_argument, NULL, ARG_HELP },
5434 { "halt", no_argument, NULL, ARG_HALT },
5435 { "poweroff", no_argument, NULL, 'p' },
5436 { "reboot", no_argument, NULL, ARG_REBOOT },
5437 { "force", no_argument, NULL, 'f' },
5438 { "wtmp-only", no_argument, NULL, 'w' },
5439 { "no-wtmp", no_argument, NULL, 'd' },
5440 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5449 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5450 if (runlevel == '0' || runlevel == '6')
5453 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5460 arg_action = ACTION_HALT;
5464 if (arg_action != ACTION_REBOOT)
5465 arg_action = ACTION_POWEROFF;
5469 arg_action = ACTION_REBOOT;
5491 /* Compatibility nops */
5498 assert_not_reached("Unhandled option");
5502 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5503 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5505 log_error("Failed to write reboot param to "
5506 REBOOT_PARAM_FILE": %s", strerror(-r));
5509 } else if (optind < argc) {
5510 log_error("Too many arguments.");
5517 static int parse_time_spec(const char *t, usec_t *_u) {
5521 if (streq(t, "now"))
5523 else if (!strchr(t, ':')) {
5526 if (safe_atou64(t, &u) < 0)
5529 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5538 hour = strtol(t, &e, 10);
5539 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5542 minute = strtol(e+1, &e, 10);
5543 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5546 n = now(CLOCK_REALTIME);
5547 s = (time_t) (n / USEC_PER_SEC);
5549 assert_se(localtime_r(&s, &tm));
5551 tm.tm_hour = (int) hour;
5552 tm.tm_min = (int) minute;
5555 assert_se(s = mktime(&tm));
5557 *_u = (usec_t) s * USEC_PER_SEC;
5560 *_u += USEC_PER_DAY;
5566 static int shutdown_parse_argv(int argc, char *argv[]) {
5573 static const struct option options[] = {
5574 { "help", no_argument, NULL, ARG_HELP },
5575 { "halt", no_argument, NULL, 'H' },
5576 { "poweroff", no_argument, NULL, 'P' },
5577 { "reboot", no_argument, NULL, 'r' },
5578 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5579 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5588 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5592 return shutdown_help();
5595 arg_action = ACTION_HALT;
5599 arg_action = ACTION_POWEROFF;
5604 arg_action = ACTION_KEXEC;
5606 arg_action = ACTION_REBOOT;
5610 arg_action = ACTION_KEXEC;
5614 if (arg_action != ACTION_HALT)
5615 arg_action = ACTION_POWEROFF;
5628 /* Compatibility nops */
5632 arg_action = ACTION_CANCEL_SHUTDOWN;
5639 assert_not_reached("Unhandled option");
5643 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5644 r = parse_time_spec(argv[optind], &arg_when);
5646 log_error("Failed to parse time specification: %s", argv[optind]);
5650 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5652 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5653 /* No time argument for shutdown cancel */
5654 arg_wall = argv + optind;
5655 else if (argc > optind + 1)
5656 /* We skip the time argument */
5657 arg_wall = argv + optind + 1;
5664 static int telinit_parse_argv(int argc, char *argv[]) {
5671 static const struct option options[] = {
5672 { "help", no_argument, NULL, ARG_HELP },
5673 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5677 static const struct {
5681 { '0', ACTION_POWEROFF },
5682 { '6', ACTION_REBOOT },
5683 { '1', ACTION_RESCUE },
5684 { '2', ACTION_RUNLEVEL2 },
5685 { '3', ACTION_RUNLEVEL3 },
5686 { '4', ACTION_RUNLEVEL4 },
5687 { '5', ACTION_RUNLEVEL5 },
5688 { 's', ACTION_RESCUE },
5689 { 'S', ACTION_RESCUE },
5690 { 'q', ACTION_RELOAD },
5691 { 'Q', ACTION_RELOAD },
5692 { 'u', ACTION_REEXEC },
5693 { 'U', ACTION_REEXEC }
5702 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5706 return telinit_help();
5716 assert_not_reached("Unhandled option");
5720 if (optind >= argc) {
5725 if (optind + 1 < argc) {
5726 log_error("Too many arguments.");
5730 if (strlen(argv[optind]) != 1) {
5731 log_error("Expected single character argument.");
5735 for (i = 0; i < ELEMENTSOF(table); i++)
5736 if (table[i].from == argv[optind][0])
5739 if (i >= ELEMENTSOF(table)) {
5740 log_error("Unknown command '%s'.", argv[optind]);
5744 arg_action = table[i].to;
5751 static int runlevel_parse_argv(int argc, char *argv[]) {
5757 static const struct option options[] = {
5758 { "help", no_argument, NULL, ARG_HELP },
5767 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5771 return runlevel_help();
5778 assert_not_reached("Unhandled option");
5782 if (optind < argc) {
5783 log_error("Too many arguments.");
5790 static int parse_argv(int argc, char *argv[]) {
5794 if (program_invocation_short_name) {
5796 if (strstr(program_invocation_short_name, "halt")) {
5797 arg_action = ACTION_HALT;
5798 return halt_parse_argv(argc, argv);
5799 } else if (strstr(program_invocation_short_name, "poweroff")) {
5800 arg_action = ACTION_POWEROFF;
5801 return halt_parse_argv(argc, argv);
5802 } else if (strstr(program_invocation_short_name, "reboot")) {
5804 arg_action = ACTION_KEXEC;
5806 arg_action = ACTION_REBOOT;
5807 return halt_parse_argv(argc, argv);
5808 } else if (strstr(program_invocation_short_name, "shutdown")) {
5809 arg_action = ACTION_POWEROFF;
5810 return shutdown_parse_argv(argc, argv);
5811 } else if (strstr(program_invocation_short_name, "init")) {
5813 if (sd_booted() > 0) {
5814 arg_action = _ACTION_INVALID;
5815 return telinit_parse_argv(argc, argv);
5817 /* Hmm, so some other init system is
5818 * running, we need to forward this
5819 * request to it. For now we simply
5820 * guess that it is Upstart. */
5822 execv(TELINIT, argv);
5824 log_error("Couldn't find an alternative telinit implementation to spawn.");
5828 } else if (strstr(program_invocation_short_name, "runlevel")) {
5829 arg_action = ACTION_RUNLEVEL;
5830 return runlevel_parse_argv(argc, argv);
5834 arg_action = ACTION_SYSTEMCTL;
5835 return systemctl_parse_argv(argc, argv);
5838 _pure_ static int action_to_runlevel(void) {
5840 static const char table[_ACTION_MAX] = {
5841 [ACTION_HALT] = '0',
5842 [ACTION_POWEROFF] = '0',
5843 [ACTION_REBOOT] = '6',
5844 [ACTION_RUNLEVEL2] = '2',
5845 [ACTION_RUNLEVEL3] = '3',
5846 [ACTION_RUNLEVEL4] = '4',
5847 [ACTION_RUNLEVEL5] = '5',
5848 [ACTION_RESCUE] = '1'
5851 assert(arg_action < _ACTION_MAX);
5853 return table[arg_action];
5856 static int talk_initctl(void) {
5858 struct init_request request = {
5859 .magic = INIT_MAGIC,
5861 .cmd = INIT_CMD_RUNLVL
5864 _cleanup_close_ int fd = -1;
5868 rl = action_to_runlevel();
5872 request.runlevel = rl;
5874 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5876 if (errno == ENOENT)
5879 log_error("Failed to open "INIT_FIFO": %m");
5884 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5886 log_error("Failed to write to "INIT_FIFO": %m");
5887 return errno > 0 ? -errno : -EIO;
5893 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5895 static const struct {
5903 int (* const dispatch)(sd_bus *bus, char **args);
5909 { "list-units", MORE, 0, list_units },
5910 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
5911 { "list-sockets", MORE, 1, list_sockets },
5912 { "list-timers", MORE, 1, list_timers },
5913 { "list-jobs", MORE, 1, list_jobs },
5914 { "clear-jobs", EQUAL, 1, daemon_reload },
5915 { "cancel", MORE, 2, cancel_job },
5916 { "start", MORE, 2, start_unit },
5917 { "stop", MORE, 2, start_unit },
5918 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5919 { "reload", MORE, 2, start_unit },
5920 { "restart", MORE, 2, start_unit },
5921 { "try-restart", MORE, 2, start_unit },
5922 { "reload-or-restart", MORE, 2, start_unit },
5923 { "reload-or-try-restart", MORE, 2, start_unit },
5924 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5925 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5926 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5927 { "isolate", EQUAL, 2, start_unit },
5928 { "kill", MORE, 2, kill_unit },
5929 { "is-active", MORE, 2, check_unit_active },
5930 { "check", MORE, 2, check_unit_active },
5931 { "is-failed", MORE, 2, check_unit_failed },
5932 { "show", MORE, 1, show },
5933 { "cat", MORE, 2, cat },
5934 { "status", MORE, 1, show },
5935 { "help", MORE, 2, show },
5936 { "snapshot", LESS, 2, snapshot },
5937 { "delete", MORE, 2, delete_snapshot },
5938 { "daemon-reload", EQUAL, 1, daemon_reload },
5939 { "daemon-reexec", EQUAL, 1, daemon_reload },
5940 { "show-environment", EQUAL, 1, show_environment },
5941 { "set-environment", MORE, 2, set_environment },
5942 { "unset-environment", MORE, 2, set_environment },
5943 { "halt", EQUAL, 1, start_special, FORCE },
5944 { "poweroff", EQUAL, 1, start_special, FORCE },
5945 { "reboot", EQUAL, 1, start_special, FORCE },
5946 { "kexec", EQUAL, 1, start_special },
5947 { "suspend", EQUAL, 1, start_special },
5948 { "hibernate", EQUAL, 1, start_special },
5949 { "hybrid-sleep", EQUAL, 1, start_special },
5950 { "default", EQUAL, 1, start_special },
5951 { "rescue", EQUAL, 1, start_special },
5952 { "emergency", EQUAL, 1, start_special },
5953 { "exit", EQUAL, 1, start_special },
5954 { "reset-failed", MORE, 1, reset_failed },
5955 { "enable", MORE, 2, enable_unit, NOBUS },
5956 { "disable", MORE, 2, enable_unit, NOBUS },
5957 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
5958 { "reenable", MORE, 2, enable_unit, NOBUS },
5959 { "preset", MORE, 2, enable_unit, NOBUS },
5960 { "mask", MORE, 2, enable_unit, NOBUS },
5961 { "unmask", MORE, 2, enable_unit, NOBUS },
5962 { "link", MORE, 2, enable_unit, NOBUS },
5963 { "switch-root", MORE, 2, switch_root },
5964 { "list-dependencies", LESS, 2, list_dependencies },
5965 { "set-default", EQUAL, 2, set_default, NOBUS },
5966 { "get-default", EQUAL, 1, get_default, NOBUS },
5967 { "set-property", MORE, 3, set_property },
5976 left = argc - optind;
5978 /* Special rule: no arguments (left == 0) means "list-units" */
5980 if (streq(argv[optind], "help") && !argv[optind+1]) {
5981 log_error("This command expects one or more "
5982 "unit names. Did you mean --help?");
5986 for (; verb->verb; verb++)
5987 if (streq(argv[optind], verb->verb))
5990 log_error("Unknown operation '%s'.", argv[optind]);
5995 switch (verb->argc_cmp) {
5998 if (left != verb->argc) {
5999 log_error("Invalid number of arguments.");
6006 if (left < verb->argc) {
6007 log_error("Too few arguments.");
6014 if (left > verb->argc) {
6015 log_error("Too many arguments.");
6022 assert_not_reached("Unknown comparison operator.");
6025 /* Require a bus connection for all operations but
6027 if (verb->bus == NOBUS) {
6028 if (!bus && !avoid_bus()) {
6029 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6034 if (running_in_chroot() > 0) {
6035 log_info("Running in chroot, ignoring request.");
6039 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6040 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6045 return verb->dispatch(bus, argv + optind);
6048 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6050 struct sd_shutdown_command c = {
6057 union sockaddr_union sockaddr = {
6058 .un.sun_family = AF_UNIX,
6059 .un.sun_path = "/run/systemd/shutdownd",
6062 struct iovec iovec[2] = {{
6063 .iov_base = (char*) &c,
6064 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6067 struct msghdr msghdr = {
6068 .msg_name = &sockaddr,
6069 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6070 + sizeof("/run/systemd/shutdownd") - 1,
6075 _cleanup_close_ int fd;
6077 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6081 if (!isempty(message)) {
6082 iovec[1].iov_base = (char*) message;
6083 iovec[1].iov_len = strlen(message);
6084 msghdr.msg_iovlen++;
6087 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6093 static int reload_with_fallback(sd_bus *bus) {
6096 /* First, try systemd via D-Bus. */
6097 if (daemon_reload(bus, NULL) >= 0)
6101 /* Nothing else worked, so let's try signals */
6102 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6104 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6105 log_error("kill() failed: %m");
6112 static int start_with_fallback(sd_bus *bus) {
6115 /* First, try systemd via D-Bus. */
6116 if (start_unit(bus, NULL) >= 0)
6120 /* Nothing else worked, so let's try
6122 if (talk_initctl() > 0)
6125 log_error("Failed to talk to init daemon.");
6129 warn_wall(arg_action);
6133 static int halt_now(enum action a) {
6135 /* Make sure C-A-D is handled by the kernel from this
6137 reboot(RB_ENABLE_CAD);
6142 log_info("Halting.");
6143 reboot(RB_HALT_SYSTEM);
6146 case ACTION_POWEROFF:
6147 log_info("Powering off.");
6148 reboot(RB_POWER_OFF);
6151 case ACTION_REBOOT: {
6152 _cleanup_free_ char *param = NULL;
6154 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6155 log_info("Rebooting with argument '%s'.", param);
6156 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6157 LINUX_REBOOT_CMD_RESTART2, param);
6160 log_info("Rebooting.");
6161 reboot(RB_AUTOBOOT);
6166 assert_not_reached("Unknown action.");
6170 static int halt_main(sd_bus *bus) {
6173 r = check_inhibitors(bus, arg_action);
6177 if (geteuid() != 0) {
6178 /* Try logind if we are a normal user and no special
6179 * mode applies. Maybe PolicyKit allows us to shutdown
6182 if (arg_when <= 0 &&
6185 (arg_action == ACTION_POWEROFF ||
6186 arg_action == ACTION_REBOOT)) {
6187 r = reboot_with_logind(bus, arg_action);
6192 log_error("Must be root.");
6197 _cleanup_free_ char *m;
6199 m = strv_join(arg_wall, " ");
6203 r = send_shutdownd(arg_when,
6204 arg_action == ACTION_HALT ? 'H' :
6205 arg_action == ACTION_POWEROFF ? 'P' :
6206 arg_action == ACTION_KEXEC ? 'K' :
6213 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6215 char date[FORMAT_TIMESTAMP_MAX];
6217 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6218 format_timestamp(date, sizeof(date), arg_when));
6223 if (!arg_dry && !arg_force)
6224 return start_with_fallback(bus);
6227 if (sd_booted() > 0)
6228 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6230 r = utmp_put_shutdown();
6232 log_warning("Failed to write utmp record: %s", strerror(-r));
6239 r = halt_now(arg_action);
6240 log_error("Failed to reboot: %s", strerror(-r));
6245 static int runlevel_main(void) {
6246 int r, runlevel, previous;
6248 r = utmp_get_runlevel(&runlevel, &previous);
6255 previous <= 0 ? 'N' : previous,
6256 runlevel <= 0 ? 'N' : runlevel);
6261 int main(int argc, char*argv[]) {
6262 _cleanup_bus_unref_ sd_bus *bus = NULL;
6265 setlocale(LC_ALL, "");
6266 log_parse_environment();
6269 /* Explicitly not on_tty() to avoid setting cached value.
6270 * This becomes relevant for piping output which might be
6272 original_stdout_is_tty = isatty(STDOUT_FILENO);
6274 r = parse_argv(argc, argv);
6278 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6279 * let's shortcut this */
6280 if (arg_action == ACTION_RUNLEVEL) {
6281 r = runlevel_main();
6285 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6286 log_info("Running in chroot, ignoring request.");
6292 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6294 /* systemctl_main() will print an error message for the bus
6295 * connection, but only if it needs to */
6297 switch (arg_action) {
6299 case ACTION_SYSTEMCTL:
6300 r = systemctl_main(bus, argc, argv, r);
6304 case ACTION_POWEROFF:
6310 case ACTION_RUNLEVEL2:
6311 case ACTION_RUNLEVEL3:
6312 case ACTION_RUNLEVEL4:
6313 case ACTION_RUNLEVEL5:
6315 case ACTION_EMERGENCY:
6316 case ACTION_DEFAULT:
6317 r = start_with_fallback(bus);
6322 r = reload_with_fallback(bus);
6325 case ACTION_CANCEL_SHUTDOWN: {
6326 _cleanup_free_ char *m = NULL;
6329 m = strv_join(arg_wall, " ");
6336 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6338 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6342 case ACTION_RUNLEVEL:
6343 case _ACTION_INVALID:
6345 assert_not_reached("Unknown action");
6350 ask_password_agent_close();
6351 polkit_agent_close();
6353 strv_free(arg_types);
6354 strv_free(arg_states);
6355 strv_free(arg_properties);
6357 return r < 0 ? EXIT_FAILURE : r;