1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
50 #include "utmp-wtmp.h"
53 #include "path-util.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
76 static char **arg_types = NULL;
77 static char **arg_states = NULL;
78 static char **arg_properties = NULL;
79 static bool arg_all = false;
80 static 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;
1338 r = strv_extend(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(*units, *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, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1378 strv_remove(*units, name);
1383 static int list_dependencies(sd_bus *bus, char **args) {
1384 _cleanup_strv_free_ char **units = NULL;
1385 _cleanup_free_ char *unit = NULL;
1391 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1396 u = SPECIAL_DEFAULT_TARGET;
1398 pager_open_if_enabled();
1402 return list_dependencies_one(bus, u, 0, &units, 0);
1405 static int get_default(sd_bus *bus, char **args) {
1406 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1407 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1408 _cleanup_free_ char *_path = NULL;
1412 if (!bus || avoid_bus()) {
1413 r = unit_file_get_default(arg_scope, arg_root, &_path);
1415 log_error("Failed to get default target: %s", strerror(-r));
1421 r = sd_bus_call_method(
1423 "org.freedesktop.systemd1",
1424 "/org/freedesktop/systemd1",
1425 "org.freedesktop.systemd1.Manager",
1431 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1435 r = sd_bus_message_read(reply, "s", &path);
1437 return bus_log_parse_error(r);
1441 printf("%s\n", path);
1446 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1449 assert(changes || n_changes == 0);
1451 for (i = 0; i < n_changes; i++) {
1452 if (changes[i].type == UNIT_FILE_SYMLINK)
1453 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1455 log_info("rm '%s'", changes[i].path);
1459 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1460 const char *type, *path, *source;
1463 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1465 return bus_log_parse_error(r);
1467 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1469 if (streq(type, "symlink"))
1470 log_info("ln -s '%s' '%s'", source, path);
1472 log_info("rm '%s'", path);
1476 return bus_log_parse_error(r);
1478 r = sd_bus_message_exit_container(m);
1480 return bus_log_parse_error(r);
1485 static int set_default(sd_bus *bus, char **args) {
1486 _cleanup_free_ char *unit = NULL;
1487 UnitFileChange *changes = NULL;
1488 unsigned n_changes = 0;
1491 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1495 if (!bus || avoid_bus()) {
1496 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1498 log_error("Failed to set default target: %s", strerror(-r));
1503 dump_unit_file_changes(changes, n_changes);
1507 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1508 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1510 r = sd_bus_call_method(
1512 "org.freedesktop.systemd1",
1513 "/org/freedesktop/systemd1",
1514 "org.freedesktop.systemd1.Manager",
1518 "sb", unit, arg_force);
1520 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1524 r = deserialize_and_dump_unit_file_changes(reply);
1528 /* Try to reload if enabeld */
1530 r = daemon_reload(bus, args);
1535 unit_file_changes_free(changes, n_changes);
1542 const char *name, *type, *state;
1545 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1546 unsigned id_len, unit_len, type_len, state_len;
1547 const struct job_info *j;
1548 const char *on, *off;
1549 bool shorten = false;
1551 assert(n == 0 || jobs);
1554 on = ansi_highlight_green();
1555 off = ansi_highlight_off();
1557 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1561 pager_open_if_enabled();
1563 id_len = sizeof("JOB")-1;
1564 unit_len = sizeof("UNIT")-1;
1565 type_len = sizeof("TYPE")-1;
1566 state_len = sizeof("STATE")-1;
1568 for (j = jobs; j < jobs + n; j++) {
1569 uint32_t id = j->id;
1570 assert(j->name && j->type && j->state);
1572 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1573 unit_len = MAX(unit_len, strlen(j->name));
1574 type_len = MAX(type_len, strlen(j->type));
1575 state_len = MAX(state_len, strlen(j->state));
1578 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1579 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1584 printf("%*s %-*s %-*s %-*s\n",
1588 state_len, "STATE");
1590 for (j = jobs; j < jobs + n; j++) {
1591 _cleanup_free_ char *e = NULL;
1593 if (streq(j->state, "running")) {
1594 on = ansi_highlight();
1595 off = ansi_highlight_off();
1599 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1600 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1602 on, unit_len, e ? e : j->name, off,
1604 on, state_len, j->state, off);
1607 if (!arg_no_legend) {
1608 on = ansi_highlight();
1609 off = ansi_highlight_off();
1611 printf("\n%s%u jobs listed%s.\n", on, n, off);
1615 static bool output_show_job(struct job_info *job, char **patterns) {
1616 if (!strv_isempty(patterns)) {
1619 STRV_FOREACH(pattern, patterns)
1620 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1628 static int list_jobs(sd_bus *bus, char **args) {
1629 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1630 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1631 const char *name, *type, *state, *job_path, *unit_path;
1632 _cleanup_free_ struct job_info *jobs = NULL;
1637 bool skipped = false;
1639 r = sd_bus_call_method(
1641 "org.freedesktop.systemd1",
1642 "/org/freedesktop/systemd1",
1643 "org.freedesktop.systemd1.Manager",
1649 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1653 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1655 return bus_log_parse_error(r);
1657 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1658 struct job_info job = { id, name, type, state };
1660 if (!output_show_job(&job, strv_skip_first(args))) {
1665 if (!GREEDY_REALLOC(jobs, size, c + 1))
1671 return bus_log_parse_error(r);
1673 r = sd_bus_message_exit_container(reply);
1675 return bus_log_parse_error(r);
1677 output_jobs_list(jobs, c, skipped);
1681 static int cancel_job(sd_bus *bus, char **args) {
1682 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1687 if (strv_length(args) <= 1)
1688 return daemon_reload(bus, args);
1690 STRV_FOREACH(name, args+1) {
1694 r = safe_atou32(*name, &id);
1696 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1700 r = sd_bus_call_method(
1702 "org.freedesktop.systemd1",
1703 "/org/freedesktop/systemd1",
1704 "org.freedesktop.systemd1.Manager",
1710 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1718 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1719 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1723 /* We ignore all errors here, since this is used to show a
1726 /* We don't use unit_dbus_path_from_name() directly since we
1727 * don't want to load the unit if it isn't loaded. */
1729 r = sd_bus_call_method(
1731 "org.freedesktop.systemd1",
1732 "/org/freedesktop/systemd1",
1733 "org.freedesktop.systemd1.Manager",
1741 r = sd_bus_message_read(reply, "o", &path);
1745 r = sd_bus_get_property_trivial(
1747 "org.freedesktop.systemd1",
1749 "org.freedesktop.systemd1.Unit",
1759 typedef struct WaitData {
1766 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1773 log_debug("Got D-Bus request: %s.%s() on %s",
1774 sd_bus_message_get_interface(m),
1775 sd_bus_message_get_member(m),
1776 sd_bus_message_get_path(m));
1778 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1779 log_error("Warning! D-Bus connection terminated.");
1781 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1783 const char *path, *result, *unit;
1787 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1789 ret = set_remove(d->set, (char*) path);
1795 if (!isempty(result))
1796 d->result = strdup(result);
1799 d->name = strdup(unit);
1804 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1806 ret = set_remove(d->set, (char*) path);
1813 d->result = strdup(result);
1819 bus_log_parse_error(r);
1825 static int enable_wait_for_jobs(sd_bus *bus) {
1830 r = sd_bus_add_match(
1833 "sender='org.freedesktop.systemd1',"
1834 "interface='org.freedesktop.systemd1.Manager',"
1835 "member='JobRemoved',"
1836 "path='/org/freedesktop/systemd1'",
1839 log_error("Failed to add match");
1843 /* This is slightly dirty, since we don't undo the match registrations. */
1847 static int bus_process_wait(sd_bus *bus) {
1851 r = sd_bus_process(bus, NULL);
1856 r = sd_bus_wait(bus, (uint64_t) -1);
1862 static int check_wait_response(WaitData *d) {
1868 if (streq(d->result, "timeout"))
1869 log_error("Job for %s timed out.", strna(d->name));
1870 else if (streq(d->result, "canceled"))
1871 log_error("Job for %s canceled.", strna(d->name));
1872 else if (streq(d->result, "dependency"))
1873 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1874 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1875 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1878 if (streq(d->result, "timeout"))
1880 else if (streq(d->result, "canceled"))
1882 else if (streq(d->result, "dependency"))
1884 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1890 static int wait_for_jobs(sd_bus *bus, Set *s) {
1891 WaitData d = { .set = s };
1897 q = sd_bus_add_filter(bus, wait_filter, &d);
1901 while (!set_isempty(s)) {
1902 q = bus_process_wait(bus);
1904 log_error("Failed to wait for response: %s", strerror(-r));
1909 q = check_wait_response(&d);
1910 /* Return the first error as it is most likely to be
1912 if (q < 0 && r == 0)
1914 log_debug("Got result %s/%s for job %s",
1915 strna(d.result), strerror(-q), strna(d.name));
1925 q = sd_bus_remove_filter(bus, wait_filter, &d);
1926 if (q < 0 && r == 0)
1932 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1933 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1934 _cleanup_free_ char *n = NULL, *state = NULL;
1940 n = unit_name_mangle(name, MANGLE_NOGLOB);
1944 /* We don't use unit_dbus_path_from_name() directly since we
1945 * don't want to load the unit if it isn't loaded. */
1947 r = sd_bus_call_method(
1949 "org.freedesktop.systemd1",
1950 "/org/freedesktop/systemd1",
1951 "org.freedesktop.systemd1.Manager",
1962 r = sd_bus_message_read(reply, "o", &path);
1964 return bus_log_parse_error(r);
1966 r = sd_bus_get_property_string(
1968 "org.freedesktop.systemd1",
1970 "org.freedesktop.systemd1.Unit",
1983 return nulstr_contains(good_states, state);
1986 static int check_triggering_units(
1990 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1991 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1992 _cleanup_strv_free_ char **triggered_by = NULL;
1993 bool print_warning_label = true;
1997 n = unit_name_mangle(name, MANGLE_NOGLOB);
2001 path = unit_dbus_path_from_name(n);
2005 r = sd_bus_get_property_string(
2007 "org.freedesktop.systemd1",
2009 "org.freedesktop.systemd1.Unit",
2014 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2018 if (streq(state, "masked"))
2021 r = sd_bus_get_property_strv(
2023 "org.freedesktop.systemd1",
2025 "org.freedesktop.systemd1.Unit",
2030 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2034 STRV_FOREACH(i, triggered_by) {
2035 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2037 log_error("Failed to check unit: %s", strerror(-r));
2044 if (print_warning_label) {
2045 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2046 print_warning_label = false;
2049 log_warning(" %s", *i);
2055 static const char *verb_to_method(const char *verb) {
2058 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2059 if (streq_ptr(unit_actions[i].verb, verb))
2060 return unit_actions[i].method;
2065 static const char *method_to_verb(const char *method) {
2068 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2069 if (streq_ptr(unit_actions[i].method, method))
2070 return unit_actions[i].verb;
2075 static int start_unit_one(
2080 sd_bus_error *error,
2083 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2092 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2093 r = sd_bus_call_method(
2095 "org.freedesktop.systemd1",
2096 "/org/freedesktop/systemd1",
2097 "org.freedesktop.systemd1.Manager",
2105 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2106 /* There's always a fallback possible for
2107 * legacy actions. */
2108 return -EADDRNOTAVAIL;
2110 verb = method_to_verb(method);
2112 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2116 r = sd_bus_message_read(reply, "o", &path);
2118 return bus_log_parse_error(r);
2120 if (need_daemon_reload(bus, name) > 0)
2121 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2122 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2131 log_debug("Adding %s to the set", p);
2132 r = set_consume(s, p);
2140 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2142 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2143 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2147 STRV_FOREACH(name, names) {
2151 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2153 t = unit_name_mangle(*name, MANGLE_GLOB);
2157 if (string_is_glob(t))
2158 r = strv_push(&globs, t);
2160 r = strv_push(&mangled, t);
2167 /* Query the manager only if any of the names are a glob, since
2168 * this is fairly expensive */
2169 if (!strv_isempty(globs)) {
2170 _cleanup_free_ UnitInfo *unit_infos = NULL;
2172 r = get_unit_list(bus, &reply, &unit_infos, globs);
2176 for (i = 0; i < r; i++)
2177 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2182 mangled = NULL; /* do not free */
2186 static const struct {
2190 } action_table[_ACTION_MAX] = {
2191 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2192 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2193 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2194 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2195 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2196 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2197 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2198 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2199 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2200 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2201 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2202 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2203 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2204 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2205 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2208 static enum action verb_to_action(const char *verb) {
2211 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2212 if (streq_ptr(action_table[i].verb, verb))
2215 return _ACTION_INVALID;
2218 static int start_unit(sd_bus *bus, char **args) {
2219 _cleanup_set_free_free_ Set *s = NULL;
2220 _cleanup_strv_free_ char **names = NULL;
2221 const char *method, *mode, *one_name;
2227 ask_password_agent_open_if_enabled();
2229 if (arg_action == ACTION_SYSTEMCTL) {
2231 method = verb_to_method(args[0]);
2232 action = verb_to_action(args[0]);
2234 mode = streq(args[0], "isolate") ? "isolate" :
2235 action_table[action].mode ?: arg_job_mode;
2237 one_name = action_table[action].target;
2239 assert(arg_action < ELEMENTSOF(action_table));
2240 assert(action_table[arg_action].target);
2242 method = "StartUnit";
2244 mode = action_table[arg_action].mode;
2245 one_name = action_table[arg_action].target;
2249 names = strv_new(one_name, NULL);
2251 r = expand_names(bus, args + 1, NULL, &names);
2253 log_error("Failed to expand names: %s", strerror(-r));
2256 if (!arg_no_block) {
2257 r = enable_wait_for_jobs(bus);
2259 log_error("Could not watch jobs: %s", strerror(-r));
2263 s = set_new(string_hash_func, string_compare_func);
2268 STRV_FOREACH(name, names) {
2269 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2272 q = start_unit_one(bus, method, *name, mode, &error, s);
2273 if (r >= 0 && q < 0)
2274 r = translate_bus_error_to_exit_status(q, &error);
2277 if (!arg_no_block) {
2280 q = wait_for_jobs(bus, s);
2284 /* When stopping units, warn if they can still be triggered by
2285 * another active unit (socket, path, timer) */
2286 if (!arg_quiet && streq(method, "StopUnit"))
2287 STRV_FOREACH(name, names)
2288 check_triggering_units(bus, *name);
2294 /* Ask systemd-logind, which might grant access to unprivileged users
2295 * through PolicyKit */
2296 static int reboot_with_logind(sd_bus *bus, enum action a) {
2298 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2305 polkit_agent_open_if_enabled();
2313 case ACTION_POWEROFF:
2314 method = "PowerOff";
2317 case ACTION_SUSPEND:
2321 case ACTION_HIBERNATE:
2322 method = "Hibernate";
2325 case ACTION_HYBRID_SLEEP:
2326 method = "HybridSleep";
2333 r = sd_bus_call_method(
2335 "org.freedesktop.login1",
2336 "/org/freedesktop/login1",
2337 "org.freedesktop.login1.Manager",
2343 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2351 static int check_inhibitors(sd_bus *bus, enum action a) {
2353 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2354 _cleanup_strv_free_ char **sessions = NULL;
2355 const char *what, *who, *why, *mode;
2364 if (arg_ignore_inhibitors || arg_force > 0)
2376 r = sd_bus_call_method(
2378 "org.freedesktop.login1",
2379 "/org/freedesktop/login1",
2380 "org.freedesktop.login1.Manager",
2386 /* If logind is not around, then there are no inhibitors... */
2389 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2391 return bus_log_parse_error(r);
2393 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2394 _cleanup_free_ char *comm = NULL, *user = NULL;
2395 _cleanup_strv_free_ char **sv = NULL;
2397 if (!streq(mode, "block"))
2400 sv = strv_split(what, ":");
2404 if (!strv_contains(sv,
2406 a == ACTION_POWEROFF ||
2407 a == ACTION_REBOOT ||
2408 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2411 get_process_comm(pid, &comm);
2412 user = uid_to_name(uid);
2414 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2415 who, (unsigned long) pid, strna(comm), strna(user), why);
2420 return bus_log_parse_error(r);
2422 r = sd_bus_message_exit_container(reply);
2424 return bus_log_parse_error(r);
2426 /* Check for current sessions */
2427 sd_get_sessions(&sessions);
2428 STRV_FOREACH(s, sessions) {
2429 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2431 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2434 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2437 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2440 sd_session_get_tty(*s, &tty);
2441 sd_session_get_seat(*s, &seat);
2442 sd_session_get_service(*s, &service);
2443 user = uid_to_name(uid);
2445 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2452 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2453 action_table[a].verb);
2461 static int start_special(sd_bus *bus, char **args) {
2467 a = verb_to_action(args[0]);
2469 r = check_inhibitors(bus, a);
2473 if (arg_force >= 2 && geteuid() != 0) {
2474 log_error("Must be root.");
2478 if (arg_force >= 2 &&
2479 (a == ACTION_HALT ||
2480 a == ACTION_POWEROFF ||
2481 a == ACTION_REBOOT))
2484 if (arg_force >= 1 &&
2485 (a == ACTION_HALT ||
2486 a == ACTION_POWEROFF ||
2487 a == ACTION_REBOOT ||
2488 a == ACTION_KEXEC ||
2490 return daemon_reload(bus, args);
2492 /* first try logind, to allow authentication with polkit */
2493 if (geteuid() != 0 &&
2494 (a == ACTION_POWEROFF ||
2495 a == ACTION_REBOOT ||
2496 a == ACTION_SUSPEND ||
2497 a == ACTION_HIBERNATE ||
2498 a == ACTION_HYBRID_SLEEP)) {
2499 r = reboot_with_logind(bus, a);
2504 r = start_unit(bus, args);
2505 if (r == EXIT_SUCCESS)
2511 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2512 _cleanup_strv_free_ char **names = NULL;
2519 r = expand_names(bus, args, NULL, &names);
2521 log_error("Failed to expand names: %s", strerror(-r));
2525 STRV_FOREACH(name, names) {
2528 state = check_one_unit(bus, *name, good_states, arg_quiet);
2538 static int check_unit_active(sd_bus *bus, char **args) {
2539 /* According to LSB: 3, "program is not running" */
2540 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2543 static int check_unit_failed(sd_bus *bus, char **args) {
2544 return check_unit_generic(bus, 1, "failed\0", args + 1);
2547 static int kill_unit(sd_bus *bus, char **args) {
2548 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2549 _cleanup_strv_free_ char **names = NULL;
2557 arg_kill_who = "all";
2559 r = expand_names(bus, args + 1, NULL, &names);
2561 log_error("Failed to expand names: %s", strerror(-r));
2563 STRV_FOREACH(name, names) {
2564 q = sd_bus_call_method(
2566 "org.freedesktop.systemd1",
2567 "/org/freedesktop/systemd1",
2568 "org.freedesktop.systemd1.Manager",
2572 "ssi", *names, arg_kill_who, arg_signal);
2574 log_error("Failed to kill unit %s: %s",
2575 *names, bus_error_message(&error, r));
2584 typedef struct ExecStatusInfo {
2592 usec_t start_timestamp;
2593 usec_t exit_timestamp;
2598 LIST_FIELDS(struct ExecStatusInfo, exec);
2601 static void exec_status_info_free(ExecStatusInfo *i) {
2610 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2611 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2614 int32_t code, status;
2620 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2622 return bus_log_parse_error(r);
2626 r = sd_bus_message_read(m, "s", &path);
2628 return bus_log_parse_error(r);
2630 i->path = strdup(path);
2634 r = sd_bus_message_read_strv(m, &i->argv);
2636 return bus_log_parse_error(r);
2638 r = sd_bus_message_read(m,
2641 &start_timestamp, &start_timestamp_monotonic,
2642 &exit_timestamp, &exit_timestamp_monotonic,
2646 return bus_log_parse_error(r);
2649 i->start_timestamp = (usec_t) start_timestamp;
2650 i->exit_timestamp = (usec_t) exit_timestamp;
2651 i->pid = (pid_t) pid;
2655 r = sd_bus_message_exit_container(m);
2657 return bus_log_parse_error(r);
2662 typedef struct UnitStatusInfo {
2664 const char *load_state;
2665 const char *active_state;
2666 const char *sub_state;
2667 const char *unit_file_state;
2669 const char *description;
2670 const char *following;
2672 char **documentation;
2674 const char *fragment_path;
2675 const char *source_path;
2676 const char *control_group;
2678 char **dropin_paths;
2680 const char *load_error;
2683 usec_t inactive_exit_timestamp;
2684 usec_t inactive_exit_timestamp_monotonic;
2685 usec_t active_enter_timestamp;
2686 usec_t active_exit_timestamp;
2687 usec_t inactive_enter_timestamp;
2689 bool need_daemon_reload;
2694 const char *status_text;
2695 const char *pid_file;
2698 usec_t start_timestamp;
2699 usec_t exit_timestamp;
2701 int exit_code, exit_status;
2703 usec_t condition_timestamp;
2704 bool condition_result;
2705 bool failed_condition_trigger;
2706 bool failed_condition_negate;
2707 const char *failed_condition;
2708 const char *failed_condition_param;
2711 unsigned n_accepted;
2712 unsigned n_connections;
2715 /* Pairs of type, path */
2719 const char *sysfs_path;
2721 /* Mount, Automount */
2727 LIST_HEAD(ExecStatusInfo, exec);
2730 static void print_status_info(
2735 const char *on, *off, *ss;
2737 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2738 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2741 arg_all * OUTPUT_SHOW_ALL |
2742 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2743 on_tty() * OUTPUT_COLOR |
2744 !arg_quiet * OUTPUT_WARN_CUTOFF |
2745 arg_full * OUTPUT_FULL_WIDTH;
2750 /* This shows pretty information about a unit. See
2751 * print_property() for a low-level property printer */
2753 printf("%s", strna(i->id));
2755 if (i->description && !streq_ptr(i->id, i->description))
2756 printf(" - %s", i->description);
2761 printf(" Follow: unit currently follows state of %s\n", i->following);
2763 if (streq_ptr(i->load_state, "error")) {
2764 on = ansi_highlight_red();
2765 off = ansi_highlight_off();
2769 path = i->source_path ? i->source_path : i->fragment_path;
2772 printf(" Loaded: %s%s%s (Reason: %s)\n",
2773 on, strna(i->load_state), off, i->load_error);
2774 else if (path && i->unit_file_state)
2775 printf(" Loaded: %s%s%s (%s; %s)\n",
2776 on, strna(i->load_state), off, path, i->unit_file_state);
2778 printf(" Loaded: %s%s%s (%s)\n",
2779 on, strna(i->load_state), off, path);
2781 printf(" Loaded: %s%s%s\n",
2782 on, strna(i->load_state), off);
2784 if (!strv_isempty(i->dropin_paths)) {
2785 _cleanup_free_ char *dir = NULL;
2789 STRV_FOREACH(dropin, i->dropin_paths) {
2790 if (! dir || last) {
2791 printf(dir ? " " : " Drop-In: ");
2796 if (path_get_parent(*dropin, &dir) < 0) {
2801 printf("%s\n %s", dir,
2802 draw_special_char(DRAW_TREE_RIGHT));
2805 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2807 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2811 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2813 if (streq_ptr(i->active_state, "failed")) {
2814 on = ansi_highlight_red();
2815 off = ansi_highlight_off();
2816 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2817 on = ansi_highlight_green();
2818 off = ansi_highlight_off();
2823 printf(" Active: %s%s (%s)%s",
2824 on, strna(i->active_state), ss, off);
2826 printf(" Active: %s%s%s",
2827 on, strna(i->active_state), off);
2829 if (!isempty(i->result) && !streq(i->result, "success"))
2830 printf(" (Result: %s)", i->result);
2832 timestamp = (streq_ptr(i->active_state, "active") ||
2833 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2834 (streq_ptr(i->active_state, "inactive") ||
2835 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2836 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2837 i->active_exit_timestamp;
2839 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2840 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2843 printf(" since %s; %s\n", s2, s1);
2845 printf(" since %s\n", s2);
2849 if (!i->condition_result && i->condition_timestamp > 0) {
2850 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2851 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2853 printf(" start condition failed at %s%s%s\n",
2854 s2, s1 ? "; " : "", s1 ? s1 : "");
2855 if (i->failed_condition_trigger)
2856 printf(" none of the trigger conditions were met\n");
2857 else if (i->failed_condition)
2858 printf(" %s=%s%s was not met\n",
2859 i->failed_condition,
2860 i->failed_condition_negate ? "!" : "",
2861 i->failed_condition_param);
2865 printf(" Device: %s\n", i->sysfs_path);
2867 printf(" Where: %s\n", i->where);
2869 printf(" What: %s\n", i->what);
2871 STRV_FOREACH(t, i->documentation)
2872 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2874 STRV_FOREACH_PAIR(t, t2, i->listen)
2875 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2878 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2880 LIST_FOREACH(exec, p, i->exec) {
2881 _cleanup_free_ char *argv = NULL;
2884 /* Only show exited processes here */
2888 argv = strv_join(p->argv, " ");
2889 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2891 good = is_clean_exit_lsb(p->code, p->status, NULL);
2893 on = ansi_highlight_red();
2894 off = ansi_highlight_off();
2898 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2900 if (p->code == CLD_EXITED) {
2903 printf("status=%i", p->status);
2905 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2910 printf("signal=%s", signal_to_string(p->status));
2912 printf(")%s\n", off);
2914 if (i->main_pid == p->pid &&
2915 i->start_timestamp == p->start_timestamp &&
2916 i->exit_timestamp == p->start_timestamp)
2917 /* Let's not show this twice */
2920 if (p->pid == i->control_pid)
2924 if (i->main_pid > 0 || i->control_pid > 0) {
2925 if (i->main_pid > 0) {
2926 printf(" Main PID: %u", (unsigned) i->main_pid);
2929 _cleanup_free_ char *comm = NULL;
2930 get_process_comm(i->main_pid, &comm);
2932 printf(" (%s)", comm);
2933 } else if (i->exit_code > 0) {
2934 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2936 if (i->exit_code == CLD_EXITED) {
2939 printf("status=%i", i->exit_status);
2941 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2946 printf("signal=%s", signal_to_string(i->exit_status));
2950 if (i->control_pid > 0)
2954 if (i->control_pid > 0) {
2955 _cleanup_free_ char *c = NULL;
2957 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2959 get_process_comm(i->control_pid, &c);
2968 printf(" Status: \"%s\"\n", i->status_text);
2970 if (i->control_group &&
2971 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2974 printf(" CGroup: %s\n", i->control_group);
2976 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2979 char prefix[] = " ";
2982 if (c > sizeof(prefix) - 1)
2983 c -= sizeof(prefix) - 1;
2987 if (i->main_pid > 0)
2988 extra[k++] = i->main_pid;
2990 if (i->control_pid > 0)
2991 extra[k++] = i->control_pid;
2993 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2994 c, false, extra, k, flags);
2998 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3000 show_journal_by_unit(stdout,
3004 i->inactive_exit_timestamp_monotonic,
3008 arg_scope == UNIT_FILE_SYSTEM,
3012 if (i->need_daemon_reload)
3013 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3014 ansi_highlight_red(),
3015 ansi_highlight_off(),
3016 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3019 static void show_unit_help(UnitStatusInfo *i) {
3024 if (!i->documentation) {
3025 log_info("Documentation for %s not known.", i->id);
3029 STRV_FOREACH(p, i->documentation) {
3031 if (startswith(*p, "man:")) {
3032 const char *args[4] = { "man", NULL, NULL, NULL };
3033 _cleanup_free_ char *page = NULL, *section = NULL;
3040 if ((*p)[k-1] == ')')
3041 e = strrchr(*p, '(');
3044 page = strndup((*p) + 4, e - *p - 4);
3045 section = strndup(e + 1, *p + k - e - 2);
3046 if (!page || !section) {
3058 log_error("Failed to fork: %m");
3064 execvp(args[0], (char**) args);
3065 log_error("Failed to execute man: %m");
3066 _exit(EXIT_FAILURE);
3069 wait_for_terminate(pid, NULL);
3071 log_info("Can't show: %s", *p);
3075 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3082 switch (contents[0]) {
3084 case SD_BUS_TYPE_STRING: {
3087 r = sd_bus_message_read(m, "s", &s);
3089 return bus_log_parse_error(r);
3092 if (streq(name, "Id"))
3094 else if (streq(name, "LoadState"))
3096 else if (streq(name, "ActiveState"))
3097 i->active_state = s;
3098 else if (streq(name, "SubState"))
3100 else if (streq(name, "Description"))
3102 else if (streq(name, "FragmentPath"))
3103 i->fragment_path = s;
3104 else if (streq(name, "SourcePath"))
3107 else if (streq(name, "DefaultControlGroup")) {
3109 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3111 i->control_group = e;
3114 else if (streq(name, "ControlGroup"))
3115 i->control_group = s;
3116 else if (streq(name, "StatusText"))
3118 else if (streq(name, "PIDFile"))
3120 else if (streq(name, "SysFSPath"))
3122 else if (streq(name, "Where"))
3124 else if (streq(name, "What"))
3126 else if (streq(name, "Following"))
3128 else if (streq(name, "UnitFileState"))
3129 i->unit_file_state = s;
3130 else if (streq(name, "Result"))
3137 case SD_BUS_TYPE_BOOLEAN: {
3140 r = sd_bus_message_read(m, "b", &b);
3142 return bus_log_parse_error(r);
3144 if (streq(name, "Accept"))
3146 else if (streq(name, "NeedDaemonReload"))
3147 i->need_daemon_reload = b;
3148 else if (streq(name, "ConditionResult"))
3149 i->condition_result = b;
3154 case SD_BUS_TYPE_UINT32: {
3157 r = sd_bus_message_read(m, "u", &u);
3159 return bus_log_parse_error(r);
3161 if (streq(name, "MainPID")) {
3163 i->main_pid = (pid_t) u;
3166 } else if (streq(name, "ControlPID"))
3167 i->control_pid = (pid_t) u;
3168 else if (streq(name, "ExecMainPID")) {
3170 i->main_pid = (pid_t) u;
3171 } else if (streq(name, "NAccepted"))
3173 else if (streq(name, "NConnections"))
3174 i->n_connections = u;
3179 case SD_BUS_TYPE_INT32: {
3182 r = sd_bus_message_read(m, "i", &j);
3184 return bus_log_parse_error(r);
3186 if (streq(name, "ExecMainCode"))
3187 i->exit_code = (int) j;
3188 else if (streq(name, "ExecMainStatus"))
3189 i->exit_status = (int) j;
3194 case SD_BUS_TYPE_UINT64: {
3197 r = sd_bus_message_read(m, "t", &u);
3199 return bus_log_parse_error(r);
3201 if (streq(name, "ExecMainStartTimestamp"))
3202 i->start_timestamp = (usec_t) u;
3203 else if (streq(name, "ExecMainExitTimestamp"))
3204 i->exit_timestamp = (usec_t) u;
3205 else if (streq(name, "ActiveEnterTimestamp"))
3206 i->active_enter_timestamp = (usec_t) u;
3207 else if (streq(name, "InactiveEnterTimestamp"))
3208 i->inactive_enter_timestamp = (usec_t) u;
3209 else if (streq(name, "InactiveExitTimestamp"))
3210 i->inactive_exit_timestamp = (usec_t) u;
3211 else if (streq(name, "InactiveExitTimestampMonotonic"))
3212 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3213 else if (streq(name, "ActiveExitTimestamp"))
3214 i->active_exit_timestamp = (usec_t) u;
3215 else if (streq(name, "ConditionTimestamp"))
3216 i->condition_timestamp = (usec_t) u;
3221 case SD_BUS_TYPE_ARRAY:
3223 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3224 _cleanup_free_ ExecStatusInfo *info = NULL;
3226 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3228 return bus_log_parse_error(r);
3230 info = new0(ExecStatusInfo, 1);
3234 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3236 info->name = strdup(name);
3240 LIST_PREPEND(exec, i->exec, info);
3242 info = new0(ExecStatusInfo, 1);
3248 return bus_log_parse_error(r);
3250 r = sd_bus_message_exit_container(m);
3252 return bus_log_parse_error(r);
3256 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3257 const char *type, *path;
3259 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3261 return bus_log_parse_error(r);
3263 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3265 r = strv_extend(&i->listen, type);
3269 r = strv_extend(&i->listen, path);
3274 return bus_log_parse_error(r);
3276 r = sd_bus_message_exit_container(m);
3278 return bus_log_parse_error(r);
3282 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3284 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3286 return bus_log_parse_error(r);
3288 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3290 r = sd_bus_message_read_strv(m, &i->documentation);
3292 return bus_log_parse_error(r);
3294 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3295 const char *cond, *param;
3296 int trigger, negate;
3299 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3301 return bus_log_parse_error(r);
3303 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3304 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3305 if (state < 0 && (!trigger || !i->failed_condition)) {
3306 i->failed_condition = cond;
3307 i->failed_condition_trigger = trigger;
3308 i->failed_condition_negate = negate;
3309 i->failed_condition_param = param;
3313 return bus_log_parse_error(r);
3315 r = sd_bus_message_exit_container(m);
3317 return bus_log_parse_error(r);
3324 case SD_BUS_TYPE_STRUCT_BEGIN:
3326 if (streq(name, "LoadError")) {
3327 const char *n, *message;
3329 r = sd_bus_message_read(m, "(ss)", &n, &message);
3331 return bus_log_parse_error(r);
3333 if (!isempty(message))
3334 i->load_error = message;
3347 r = sd_bus_message_skip(m, contents);
3349 return bus_log_parse_error(r);
3354 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3360 /* This is a low-level property printer, see
3361 * print_status_info() for the nicer output */
3363 if (arg_properties && !strv_find(arg_properties, name)) {
3364 /* skip what we didn't read */
3365 r = sd_bus_message_skip(m, contents);
3369 switch (contents[0]) {
3371 case SD_BUS_TYPE_STRUCT_BEGIN:
3373 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3376 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3378 return bus_log_parse_error(r);
3381 printf("%s=%u\n", name, (unsigned) u);
3383 printf("%s=\n", name);
3387 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3390 r = sd_bus_message_read(m, "(so)", &s, NULL);
3392 return bus_log_parse_error(r);
3394 if (arg_all || !isempty(s))
3395 printf("%s=%s\n", name, s);
3399 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3400 const char *a = NULL, *b = NULL;
3402 r = sd_bus_message_read(m, "(ss)", &a, &b);
3404 return bus_log_parse_error(r);
3406 if (arg_all || !isempty(a) || !isempty(b))
3407 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3410 } else if (streq_ptr(name, "SystemCallFilter")) {
3411 _cleanup_strv_free_ char **l = NULL;
3414 r = sd_bus_message_enter_container(m, 'r', "bas");
3416 return bus_log_parse_error(r);
3418 r = sd_bus_message_read(m, "b", &whitelist);
3420 return bus_log_parse_error(r);
3422 r = sd_bus_message_read_strv(m, &l);
3424 return bus_log_parse_error(r);
3426 r = sd_bus_message_exit_container(m);
3428 return bus_log_parse_error(r);
3430 if (arg_all || whitelist || !strv_isempty(l)) {
3434 fputs(name, stdout);
3440 STRV_FOREACH(i, l) {
3448 fputc('\n', stdout);
3456 case SD_BUS_TYPE_ARRAY:
3458 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3462 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3464 return bus_log_parse_error(r);
3466 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3467 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3470 return bus_log_parse_error(r);
3472 r = sd_bus_message_exit_container(m);
3474 return bus_log_parse_error(r);
3478 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3479 const char *type, *path;
3481 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3483 return bus_log_parse_error(r);
3485 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3486 printf("%s=%s\n", type, path);
3488 return bus_log_parse_error(r);
3490 r = sd_bus_message_exit_container(m);
3492 return bus_log_parse_error(r);
3496 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3497 const char *type, *path;
3499 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3501 return bus_log_parse_error(r);
3503 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3504 printf("Listen%s=%s\n", type, path);
3506 return bus_log_parse_error(r);
3508 r = sd_bus_message_exit_container(m);
3510 return bus_log_parse_error(r);
3514 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3516 uint64_t value, next_elapse;
3518 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3520 return bus_log_parse_error(r);
3522 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3523 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3525 printf("%s={ value=%s ; next_elapse=%s }\n",
3527 format_timespan(timespan1, sizeof(timespan1), value, 0),
3528 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3531 return bus_log_parse_error(r);
3533 r = sd_bus_message_exit_container(m);
3535 return bus_log_parse_error(r);
3539 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3540 ExecStatusInfo info = {};
3542 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3544 return bus_log_parse_error(r);
3546 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3547 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3548 _cleanup_free_ char *tt;
3550 tt = strv_join(info.argv, " ");
3552 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3556 yes_no(info.ignore),
3557 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3558 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3559 (unsigned) info. pid,
3560 sigchld_code_to_string(info.code),
3562 info.code == CLD_EXITED ? "" : "/",
3563 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3566 strv_free(info.argv);
3570 r = sd_bus_message_exit_container(m);
3572 return bus_log_parse_error(r);
3576 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3577 const char *path, *rwm;
3579 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3581 return bus_log_parse_error(r);
3583 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3584 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3586 return bus_log_parse_error(r);
3588 r = sd_bus_message_exit_container(m);
3590 return bus_log_parse_error(r);
3594 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3598 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3600 return bus_log_parse_error(r);
3602 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3603 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3605 return bus_log_parse_error(r);
3607 r = sd_bus_message_exit_container(m);
3609 return bus_log_parse_error(r);
3613 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3617 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3619 return bus_log_parse_error(r);
3621 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3622 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3624 return bus_log_parse_error(r);
3626 r = sd_bus_message_exit_container(m);
3628 return bus_log_parse_error(r);
3636 r = bus_print_property(name, m, arg_all);
3638 return bus_log_parse_error(r);
3641 r = sd_bus_message_skip(m, contents);
3643 return bus_log_parse_error(r);
3646 printf("%s=[unprintable]\n", name);
3652 static int show_one(
3656 bool show_properties,
3660 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3661 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3662 UnitStatusInfo info = {};
3669 log_debug("Showing one %s", path);
3671 r = sd_bus_call_method(
3673 "org.freedesktop.systemd1",
3675 "org.freedesktop.DBus.Properties",
3681 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3685 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3687 return bus_log_parse_error(r);
3694 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3695 const char *name, *contents;
3697 r = sd_bus_message_read(reply, "s", &name);
3699 return bus_log_parse_error(r);
3701 r = sd_bus_message_peek_type(reply, NULL, &contents);
3703 return bus_log_parse_error(r);
3705 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3707 return bus_log_parse_error(r);
3709 if (show_properties)
3710 r = print_property(name, reply, contents);
3712 r = status_property(name, reply, &info, contents);
3716 r = sd_bus_message_exit_container(reply);
3718 return bus_log_parse_error(r);
3720 r = sd_bus_message_exit_container(reply);
3722 return bus_log_parse_error(r);
3725 return bus_log_parse_error(r);
3727 r = sd_bus_message_exit_container(reply);
3729 return bus_log_parse_error(r);
3733 if (!show_properties) {
3734 if (streq(verb, "help"))
3735 show_unit_help(&info);
3737 print_status_info(&info, ellipsized);
3740 strv_free(info.documentation);
3741 strv_free(info.dropin_paths);
3742 strv_free(info.listen);
3744 if (!streq_ptr(info.active_state, "active") &&
3745 !streq_ptr(info.active_state, "reloading") &&
3746 streq(verb, "status")) {
3747 /* According to LSB: "program not running" */
3748 /* 0: program is running or service is OK
3749 * 1: program is dead and /var/run pid file exists
3750 * 2: program is dead and /var/lock lock file exists
3751 * 3: program is not running
3752 * 4: program or service status is unknown
3754 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3760 while ((p = info.exec)) {
3761 LIST_REMOVE(exec, info.exec, p);
3762 exec_status_info_free(p);
3768 static int get_unit_dbus_path_by_pid(
3773 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3774 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3778 r = sd_bus_call_method(
3780 "org.freedesktop.systemd1",
3781 "/org/freedesktop/systemd1",
3782 "org.freedesktop.systemd1.Manager",
3788 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3792 r = sd_bus_message_read(reply, "o", &u);
3794 return bus_log_parse_error(r);
3804 static int show_all(
3807 bool show_properties,
3811 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3812 _cleanup_free_ UnitInfo *unit_infos = NULL;
3817 r = get_unit_list(bus, &reply, &unit_infos, NULL);
3821 pager_open_if_enabled();
3825 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3827 for (u = unit_infos; u < unit_infos + c; u++) {
3828 _cleanup_free_ char *p = NULL;
3830 p = unit_dbus_path_from_name(u->id);
3834 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3842 static int cat(sd_bus *bus, char **args) {
3843 _cleanup_free_ char *unit = NULL;
3844 _cleanup_strv_free_ char **names = NULL;
3852 r = expand_names(bus, args + 1, NULL, &names);
3854 log_error("Failed to expand names: %s", strerror(-r));
3856 pager_open_if_enabled();
3858 STRV_FOREACH(name, names) {
3859 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3860 _cleanup_strv_free_ char **dropin_paths = NULL;
3861 _cleanup_free_ char *fragment_path = NULL;
3864 unit = unit_dbus_path_from_name(*name);
3868 if (need_daemon_reload(bus, *name) > 0)
3869 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3870 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3872 r = sd_bus_get_property_string(
3874 "org.freedesktop.systemd1",
3876 "org.freedesktop.systemd1.Unit",
3881 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3885 r = sd_bus_get_property_strv(
3887 "org.freedesktop.systemd1",
3889 "org.freedesktop.systemd1.Unit",
3894 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3903 if (!isempty(fragment_path)) {
3904 printf("%s# %s%s\n",
3905 ansi_highlight_blue(),
3907 ansi_highlight_off());
3910 r = sendfile_full(STDOUT_FILENO, fragment_path);
3912 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3917 STRV_FOREACH(path, dropin_paths) {
3918 printf("%s%s# %s%s\n",
3919 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3920 ansi_highlight_blue(),
3922 ansi_highlight_off());
3925 r = sendfile_full(STDOUT_FILENO, *path);
3927 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3933 return r < 0 ? r : 0;
3936 static int show(sd_bus *bus, char **args) {
3937 bool show_properties, show_status, new_line = false;
3938 bool ellipsized = false;
3944 show_properties = streq(args[0], "show");
3945 show_status = streq(args[0], "status");
3947 if (show_properties)
3948 pager_open_if_enabled();
3950 /* If no argument is specified inspect the manager itself */
3952 if (show_properties && strv_length(args) <= 1)
3953 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3955 if (show_status && strv_length(args) <= 1)
3956 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3958 _cleanup_free_ char **patterns = NULL;
3961 STRV_FOREACH(name, args + 1) {
3962 _cleanup_free_ char *unit = NULL;
3965 if (safe_atou32(*name, &id) < 0) {
3966 if (strv_push(&patterns, *name) < 0)
3970 } else if (show_properties) {
3971 /* Interpret as job id */
3972 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3976 /* Interpret as PID */
3977 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3984 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3987 if (!strv_isempty(patterns)) {
3988 _cleanup_strv_free_ char **names = NULL;
3990 r = expand_names(bus, patterns, NULL, &names);
3992 log_error("Failed to expand names: %s", strerror(-r));
3994 STRV_FOREACH(name, names) {
3995 _cleanup_free_ char *unit;
3997 unit = unit_dbus_path_from_name(*name);
4001 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4006 if (ellipsized && !arg_quiet)
4007 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4012 static int append_assignment(sd_bus_message *m, const char *assignment) {
4020 eq = strchr(assignment, '=');
4022 log_error("Not an assignment: %s", assignment);
4026 field = strndupa(assignment, eq - assignment);
4029 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
4031 return bus_log_create_error(r);
4033 if (streq(field, "CPUAccounting") ||
4034 streq(field, "MemoryAccounting") ||
4035 streq(field, "BlockIOAccounting")) {
4037 r = parse_boolean(eq);
4039 log_error("Failed to parse boolean assignment %s.", assignment);
4043 r = sd_bus_message_append(m, "v", "b", r);
4045 } else if (streq(field, "MemoryLimit")) {
4048 r = parse_bytes(eq, &bytes);
4050 log_error("Failed to parse bytes specification %s", assignment);
4054 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
4056 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
4059 r = safe_atou64(eq, &u);
4061 log_error("Failed to parse %s value %s.", field, eq);
4065 r = sd_bus_message_append(m, "v", "t", u);
4067 } else if (streq(field, "DevicePolicy"))
4068 r = sd_bus_message_append(m, "v", "s", eq);
4070 else if (streq(field, "DeviceAllow")) {
4073 r = sd_bus_message_append(m, "v", "a(ss)", 0);
4075 const char *path, *rwm;
4078 e = strchr(eq, ' ');
4080 path = strndupa(eq, e - eq);
4087 if (!path_startswith(path, "/dev")) {
4088 log_error("%s is not a device file in /dev.", path);
4092 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
4095 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
4098 r = sd_bus_message_append(m, "v", "a(st)", 0);
4100 const char *path, *bandwidth;
4104 e = strchr(eq, ' ');
4106 path = strndupa(eq, e - eq);
4109 log_error("Failed to parse %s value %s.", field, eq);
4113 if (!path_startswith(path, "/dev")) {
4114 log_error("%s is not a device file in /dev.", path);
4118 r = parse_bytes(bandwidth, &bytes);
4120 log_error("Failed to parse byte value %s.", bandwidth);
4124 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4127 } else if (streq(field, "BlockIODeviceWeight")) {
4130 r = sd_bus_message_append(m, "v", "a(st)", 0);
4132 const char *path, *weight;
4136 e = strchr(eq, ' ');
4138 path = strndupa(eq, e - eq);
4141 log_error("Failed to parse %s value %s.", field, eq);
4145 if (!path_startswith(path, "/dev")) {
4146 log_error("%s is not a device file in /dev.", path);
4150 r = safe_atou64(weight, &u);
4152 log_error("Failed to parse %s value %s.", field, weight);
4155 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4159 log_error("Unknown assignment %s.", assignment);
4164 return bus_log_create_error(r);
4169 static int set_property(sd_bus *bus, char **args) {
4170 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4171 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4172 _cleanup_free_ char *n = NULL;
4176 r = sd_bus_message_new_method_call(
4178 "org.freedesktop.systemd1",
4179 "/org/freedesktop/systemd1",
4180 "org.freedesktop.systemd1.Manager",
4181 "SetUnitProperties",
4184 return bus_log_create_error(r);
4186 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4190 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4192 return bus_log_create_error(r);
4194 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4196 return bus_log_create_error(r);
4198 STRV_FOREACH(i, args + 2) {
4199 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4201 return bus_log_create_error(r);
4203 r = append_assignment(m, *i);
4207 r = sd_bus_message_close_container(m);
4209 return bus_log_create_error(r);
4212 r = sd_bus_message_close_container(m);
4214 return bus_log_create_error(r);
4216 r = sd_bus_call(bus, m, 0, &error, NULL);
4218 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4225 static int snapshot(sd_bus *bus, char **args) {
4226 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4227 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4228 _cleanup_free_ char *n = NULL, *id = NULL;
4232 if (strv_length(args) > 1)
4233 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4239 r = sd_bus_call_method(
4241 "org.freedesktop.systemd1",
4242 "/org/freedesktop/systemd1",
4243 "org.freedesktop.systemd1.Manager",
4249 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4253 r = sd_bus_message_read(reply, "o", &path);
4255 return bus_log_parse_error(r);
4257 r = sd_bus_get_property_string(
4259 "org.freedesktop.systemd1",
4261 "org.freedesktop.systemd1.Unit",
4266 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4276 static int delete_snapshot(sd_bus *bus, char **args) {
4277 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4278 _cleanup_strv_free_ char **names = NULL;
4284 r = expand_names(bus, args + 1, ".snapshot", &names);
4286 log_error("Failed to expand names: %s", strerror(-r));
4288 STRV_FOREACH(name, names) {
4289 q = sd_bus_call_method(
4291 "org.freedesktop.systemd1",
4292 "/org/freedesktop/systemd1",
4293 "org.freedesktop.systemd1.Manager",
4299 log_error("Failed to remove snapshot %s: %s",
4300 *name, bus_error_message(&error, r));
4309 static int daemon_reload(sd_bus *bus, char **args) {
4310 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4314 if (arg_action == ACTION_RELOAD)
4316 else if (arg_action == ACTION_REEXEC)
4317 method = "Reexecute";
4319 assert(arg_action == ACTION_SYSTEMCTL);
4322 streq(args[0], "clear-jobs") ||
4323 streq(args[0], "cancel") ? "ClearJobs" :
4324 streq(args[0], "daemon-reexec") ? "Reexecute" :
4325 streq(args[0], "reset-failed") ? "ResetFailed" :
4326 streq(args[0], "halt") ? "Halt" :
4327 streq(args[0], "poweroff") ? "PowerOff" :
4328 streq(args[0], "reboot") ? "Reboot" :
4329 streq(args[0], "kexec") ? "KExec" :
4330 streq(args[0], "exit") ? "Exit" :
4331 /* "daemon-reload" */ "Reload";
4334 r = sd_bus_call_method(
4336 "org.freedesktop.systemd1",
4337 "/org/freedesktop/systemd1",
4338 "org.freedesktop.systemd1.Manager",
4344 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4345 /* There's always a fallback possible for
4346 * legacy actions. */
4348 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4349 /* On reexecution, we expect a disconnect, not a
4353 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4355 return r < 0 ? r : 0;
4358 static int reset_failed(sd_bus *bus, char **args) {
4359 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4360 _cleanup_strv_free_ char **names = NULL;
4364 if (strv_length(args) <= 1)
4365 return daemon_reload(bus, args);
4367 r = expand_names(bus, args + 1, NULL, &names);
4369 log_error("Failed to expand names: %s", strerror(-r));
4371 STRV_FOREACH(name, names) {
4372 q = sd_bus_call_method(
4374 "org.freedesktop.systemd1",
4375 "/org/freedesktop/systemd1",
4376 "org.freedesktop.systemd1.Manager",
4382 log_error("Failed to reset failed state of unit %s: %s",
4383 *name, bus_error_message(&error, r));
4392 static int show_environment(sd_bus *bus, char **args) {
4393 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4394 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4398 pager_open_if_enabled();
4400 r = sd_bus_get_property(
4402 "org.freedesktop.systemd1",
4403 "/org/freedesktop/systemd1",
4404 "org.freedesktop.systemd1.Manager",
4410 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4414 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4416 return bus_log_parse_error(r);
4418 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4421 return bus_log_parse_error(r);
4423 r = sd_bus_message_exit_container(reply);
4425 return bus_log_parse_error(r);
4430 static int switch_root(sd_bus *bus, char **args) {
4431 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4432 _cleanup_free_ char *init = NULL;
4437 l = strv_length(args);
4438 if (l < 2 || l > 3) {
4439 log_error("Wrong number of arguments.");
4446 init = strdup(args[2]);
4448 parse_env_file("/proc/cmdline", WHITESPACE,
4459 log_debug("switching root - root: %s; init: %s", root, init);
4461 r = sd_bus_call_method(
4463 "org.freedesktop.systemd1",
4464 "/org/freedesktop/systemd1",
4465 "org.freedesktop.systemd1.Manager",
4471 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4478 static int set_environment(sd_bus *bus, char **args) {
4479 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4480 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4487 method = streq(args[0], "set-environment")
4489 : "UnsetEnvironment";
4491 r = sd_bus_message_new_method_call(
4493 "org.freedesktop.systemd1",
4494 "/org/freedesktop/systemd1",
4495 "org.freedesktop.systemd1.Manager",
4499 return bus_log_create_error(r);
4501 r = sd_bus_message_append_strv(m, args + 1);
4503 return bus_log_create_error(r);
4505 r = sd_bus_call(bus, m, 0, &error, NULL);
4507 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4514 static int import_environment(sd_bus *bus, char **args) {
4515 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4516 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4522 r = sd_bus_message_new_method_call(
4524 "org.freedesktop.systemd1",
4525 "/org/freedesktop/systemd1",
4526 "org.freedesktop.systemd1.Manager",
4530 return bus_log_create_error(r);
4532 if (strv_isempty(args + 1))
4533 r = sd_bus_message_append_strv(m, environ);
4537 r = sd_bus_message_open_container(m, 'a', "s");
4539 return bus_log_create_error(r);
4541 STRV_FOREACH(a, args + 1) {
4543 if (!env_name_is_valid(*a)) {
4544 log_error("Not a valid environment variable name: %s", *a);
4548 STRV_FOREACH(b, environ) {
4551 eq = startswith(*b, *a);
4552 if (eq && *eq == '=') {
4554 r = sd_bus_message_append(m, "s", *b);
4556 return bus_log_create_error(r);
4563 r = sd_bus_message_close_container(m);
4566 return bus_log_create_error(r);
4568 r = sd_bus_call(bus, m, 0, &error, NULL);
4570 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4577 static int enable_sysv_units(const char *verb, char **args) {
4580 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4581 unsigned f = 1, t = 1;
4582 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4584 if (arg_scope != UNIT_FILE_SYSTEM)
4587 if (!streq(verb, "enable") &&
4588 !streq(verb, "disable") &&
4589 !streq(verb, "is-enabled"))
4592 /* Processes all SysV units, and reshuffles the array so that
4593 * afterwards only the native units remain */
4595 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4600 for (f = 0; args[f]; f++) {
4602 _cleanup_free_ char *p = NULL, *q = NULL;
4603 bool found_native = false, found_sysv;
4605 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4613 if (!endswith(name, ".service"))
4616 if (path_is_absolute(name))
4619 STRV_FOREACH(k, paths.unit_path) {
4620 if (!isempty(arg_root))
4621 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4623 asprintf(&p, "%s/%s", *k, name);
4630 found_native = access(p, F_OK) >= 0;
4641 if (!isempty(arg_root))
4642 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4644 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4650 p[strlen(p) - sizeof(".service") + 1] = 0;
4651 found_sysv = access(p, F_OK) >= 0;
4656 /* Mark this entry, so that we don't try enabling it as native unit */
4657 args[f] = (char*) "";
4659 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4661 if (!isempty(arg_root))
4662 argv[c++] = q = strappend("--root=", arg_root);
4664 argv[c++] = basename(p);
4666 streq(verb, "enable") ? "on" :
4667 streq(verb, "disable") ? "off" : "--level=5";
4670 l = strv_join((char**)argv, " ");
4676 log_info("Executing %s", l);
4681 log_error("Failed to fork: %m");
4684 } else if (pid == 0) {
4687 execv(argv[0], (char**) argv);
4688 _exit(EXIT_FAILURE);
4691 j = wait_for_terminate(pid, &status);
4693 log_error("Failed to wait for child: %s", strerror(-r));
4698 if (status.si_code == CLD_EXITED) {
4699 if (streq(verb, "is-enabled")) {
4700 if (status.si_status == 0) {
4709 } else if (status.si_status != 0) {
4720 /* Drop all SysV units */
4721 for (f = 0, t = 0; args[f]; f++) {
4723 if (isempty(args[f]))
4726 args[t++] = args[f];
4735 static int mangle_names(char **original_names, char ***mangled_names) {
4736 char **i, **l, **name;
4738 l = new(char*, strv_length(original_names) + 1);
4743 STRV_FOREACH(name, original_names) {
4745 /* When enabling units qualified path names are OK,
4746 * too, hence allow them explicitly. */
4751 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4767 static int enable_unit(sd_bus *bus, char **args) {
4768 _cleanup_strv_free_ char **names = NULL;
4769 const char *verb = args[0];
4770 UnitFileChange *changes = NULL;
4771 unsigned n_changes = 0;
4772 int carries_install_info = -1;
4778 r = mangle_names(args+1, &names);
4782 r = enable_sysv_units(verb, names);
4786 /* If the operation was fully executed by the SysV compat,
4787 * let's finish early */
4788 if (strv_isempty(names))
4791 if (!bus || avoid_bus()) {
4792 if (streq(verb, "enable")) {
4793 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4794 carries_install_info = r;
4795 } else if (streq(verb, "disable"))
4796 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4797 else if (streq(verb, "reenable")) {
4798 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4799 carries_install_info = r;
4800 } else if (streq(verb, "link"))
4801 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4802 else if (streq(verb, "preset")) {
4803 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4804 carries_install_info = r;
4805 } else if (streq(verb, "mask"))
4806 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4807 else if (streq(verb, "unmask"))
4808 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4810 assert_not_reached("Unknown verb");
4813 log_error("Operation failed: %s", strerror(-r));
4818 dump_unit_file_changes(changes, n_changes);
4822 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4823 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4824 int expect_carries_install_info = false;
4825 bool send_force = true;
4828 if (streq(verb, "enable")) {
4829 method = "EnableUnitFiles";
4830 expect_carries_install_info = true;
4831 } else if (streq(verb, "disable")) {
4832 method = "DisableUnitFiles";
4834 } else if (streq(verb, "reenable")) {
4835 method = "ReenableUnitFiles";
4836 expect_carries_install_info = true;
4837 } else if (streq(verb, "link"))
4838 method = "LinkUnitFiles";
4839 else if (streq(verb, "preset")) {
4840 method = "PresetUnitFiles";
4841 expect_carries_install_info = true;
4842 } else if (streq(verb, "mask"))
4843 method = "MaskUnitFiles";
4844 else if (streq(verb, "unmask")) {
4845 method = "UnmaskUnitFiles";
4848 assert_not_reached("Unknown verb");
4850 r = sd_bus_message_new_method_call(
4852 "org.freedesktop.systemd1",
4853 "/org/freedesktop/systemd1",
4854 "org.freedesktop.systemd1.Manager",
4858 return bus_log_create_error(r);
4860 r = sd_bus_message_append_strv(m, names);
4862 return bus_log_create_error(r);
4864 r = sd_bus_message_append(m, "b", arg_runtime);
4866 return bus_log_create_error(r);
4869 r = sd_bus_message_append(m, "b", arg_force);
4871 return bus_log_create_error(r);
4874 r = sd_bus_call(bus, m, 0, &error, &reply);
4876 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4880 if (expect_carries_install_info) {
4881 r = sd_bus_message_read(reply, "b", &carries_install_info);
4883 return bus_log_parse_error(r);
4886 r = deserialize_and_dump_unit_file_changes(reply);
4890 /* Try to reload if enabeld */
4892 r = daemon_reload(bus, args);
4897 if (carries_install_info == 0)
4898 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4899 "using systemctl.\n"
4900 "Possible reasons for having this kind of units are:\n"
4901 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4902 " .wants/ or .requires/ directory.\n"
4903 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4904 " a requirement dependency on it.\n"
4905 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4906 " D-Bus, udev, scripted systemctl call, ...).\n");
4909 unit_file_changes_free(changes, n_changes);
4914 static int unit_is_enabled(sd_bus *bus, char **args) {
4916 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4917 _cleanup_strv_free_ char **names = NULL;
4922 r = mangle_names(args+1, &names);
4926 r = enable_sysv_units(args[0], names);
4932 if (!bus || avoid_bus()) {
4934 STRV_FOREACH(name, names) {
4935 UnitFileState state;
4937 state = unit_file_get_state(arg_scope, arg_root, *name);
4939 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4943 if (state == UNIT_FILE_ENABLED ||
4944 state == UNIT_FILE_ENABLED_RUNTIME ||
4945 state == UNIT_FILE_STATIC)
4949 puts(unit_file_state_to_string(state));
4953 STRV_FOREACH(name, names) {
4954 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4957 r = sd_bus_call_method(
4959 "org.freedesktop.systemd1",
4960 "/org/freedesktop/systemd1",
4961 "org.freedesktop.systemd1.Manager",
4967 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4971 r = sd_bus_message_read(reply, "s", &s);
4973 return bus_log_parse_error(r);
4975 if (streq(s, "enabled") ||
4976 streq(s, "enabled-runtime") ||
4988 static int systemctl_help(void) {
4990 pager_open_if_enabled();
4992 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4993 "Query or send control commands to the systemd manager.\n\n"
4994 " -h --help Show this help\n"
4995 " --version Show package version\n"
4996 " --system Connect to system manager\n"
4997 " --user Connect to user service manager\n"
4998 " -H --host=[USER@]HOST\n"
4999 " Operate on remote host\n"
5000 " -M --machine=CONTAINER\n"
5001 " Operate on local container\n"
5002 " -t --type=TYPE List only units of a particular type\n"
5003 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5004 " -p --property=NAME Show only properties by this name\n"
5005 " -a --all Show all loaded units/properties, including dead/empty\n"
5006 " ones. To list all units installed on the system, use\n"
5007 " the 'list-unit-files' command instead.\n"
5008 " -l --full Don't ellipsize unit names on output\n"
5009 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5010 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5011 " queueing a new job\n"
5012 " --show-types When showing sockets, explicitly show their type\n"
5013 " -i --ignore-inhibitors\n"
5014 " When shutting down or sleeping, ignore inhibitors\n"
5015 " --kill-who=WHO Who to send signal to\n"
5016 " -s --signal=SIGNAL Which signal to send\n"
5017 " -q --quiet Suppress output\n"
5018 " --no-block Do not wait until operation finished\n"
5019 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5020 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5022 " --no-legend Do not print a legend (column headers and hints)\n"
5023 " --no-pager Do not pipe output into a pager\n"
5024 " --no-ask-password\n"
5025 " Do not ask for system passwords\n"
5026 " --global Enable/disable unit files globally\n"
5027 " --runtime Enable unit files only temporarily until next reboot\n"
5028 " -f --force When enabling unit files, override existing symlinks\n"
5029 " When shutting down, execute action immediately\n"
5030 " --root=PATH Enable unit files in the specified root directory\n"
5031 " -n --lines=INTEGER Number of journal entries to show\n"
5032 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5033 " verbose, export, json, json-pretty, json-sse, cat)\n"
5034 " --plain Print unit dependencies as a list instead of a tree\n\n"
5036 " list-units [PATTERN...] List loaded units\n"
5037 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5038 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5039 " start NAME... Start (activate) one or more units\n"
5040 " stop NAME... Stop (deactivate) one or more units\n"
5041 " reload NAME... Reload one or more units\n"
5042 " restart NAME... Start or restart one or more units\n"
5043 " try-restart NAME... Restart one or more units if active\n"
5044 " reload-or-restart NAME... Reload one or more units if possible,\n"
5045 " otherwise start or restart\n"
5046 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5047 " otherwise restart if active\n"
5048 " isolate NAME Start one unit and stop all others\n"
5049 " kill NAME... Send signal to processes of a unit\n"
5050 " is-active NAME... Check whether units are active\n"
5051 " is-failed NAME... Check whether units are failed\n"
5052 " status [NAME...|PID...] Show runtime status of one or more units\n"
5053 " show [NAME...|JOB...] Show properties of one or more\n"
5054 " units/jobs or the manager\n"
5055 " cat NAME... Show files and drop-ins of one or more units\n"
5056 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5057 " help NAME...|PID... Show manual for one or more units\n"
5058 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
5060 " list-dependencies [NAME] Recursively show units which are required\n"
5061 " or wanted by this unit or by which this\n"
5062 " unit is required or wanted\n\n"
5063 "Unit File Commands:\n"
5064 " list-unit-files [PATTERN...] List installed unit files\n"
5065 " enable NAME... Enable one or more unit files\n"
5066 " disable NAME... Disable one or more unit files\n"
5067 " reenable NAME... Reenable one or more unit files\n"
5068 " preset NAME... Enable/disable one or more unit files\n"
5069 " based on preset configuration\n"
5070 " is-enabled NAME... Check whether unit files are enabled\n\n"
5071 " mask NAME... Mask one or more units\n"
5072 " unmask NAME... Unmask one or more units\n"
5073 " link PATH... Link one or more units files into\n"
5074 " the search path\n"
5075 " get-default Get the name of the default target\n"
5076 " set-default NAME Set the default target\n\n"
5078 " list-jobs [PATTERN...] List jobs\n"
5079 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5080 "Snapshot Commands:\n"
5081 " snapshot [NAME] Create a snapshot\n"
5082 " delete NAME... Remove one or more snapshots\n\n"
5083 "Environment Commands:\n"
5084 " show-environment Dump environment\n"
5085 " set-environment NAME=VALUE... Set one or more environment variables\n"
5086 " unset-environment NAME... Unset one or more environment variables\n"
5087 " import-environment NAME... Import all, one or more environment variables\n\n"
5088 "Manager Lifecycle Commands:\n"
5089 " daemon-reload Reload systemd manager configuration\n"
5090 " daemon-reexec Reexecute systemd manager\n\n"
5091 "System Commands:\n"
5092 " default Enter system default mode\n"
5093 " rescue Enter system rescue mode\n"
5094 " emergency Enter system emergency mode\n"
5095 " halt Shut down and halt the system\n"
5096 " poweroff Shut down and power-off the system\n"
5097 " reboot [ARG] Shut down and reboot the system\n"
5098 " kexec Shut down and reboot the system with kexec\n"
5099 " exit Request user instance exit\n"
5100 " switch-root ROOT [INIT] Change to a different root file system\n"
5101 " suspend Suspend the system\n"
5102 " hibernate Hibernate the system\n"
5103 " hybrid-sleep Hibernate and suspend the system\n",
5104 program_invocation_short_name);
5109 static int halt_help(void) {
5111 printf("%s [OPTIONS...]%s\n\n"
5112 "%s the system.\n\n"
5113 " --help Show this help\n"
5114 " --halt Halt the machine\n"
5115 " -p --poweroff Switch off the machine\n"
5116 " --reboot Reboot the machine\n"
5117 " -f --force Force immediate halt/power-off/reboot\n"
5118 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5119 " -d --no-wtmp Don't write wtmp record\n"
5120 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5121 program_invocation_short_name,
5122 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5123 arg_action == ACTION_REBOOT ? "Reboot" :
5124 arg_action == ACTION_POWEROFF ? "Power off" :
5130 static int shutdown_help(void) {
5132 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5133 "Shut down the system.\n\n"
5134 " --help Show this help\n"
5135 " -H --halt Halt the machine\n"
5136 " -P --poweroff Power-off the machine\n"
5137 " -r --reboot Reboot the machine\n"
5138 " -h Equivalent to --poweroff, overridden by --halt\n"
5139 " -k Don't halt/power-off/reboot, just send warnings\n"
5140 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5141 " -c Cancel a pending shutdown\n",
5142 program_invocation_short_name);
5147 static int telinit_help(void) {
5149 printf("%s [OPTIONS...] {COMMAND}\n\n"
5150 "Send control commands to the init daemon.\n\n"
5151 " --help Show this help\n"
5152 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5154 " 0 Power-off the machine\n"
5155 " 6 Reboot the machine\n"
5156 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5157 " 1, s, S Enter rescue mode\n"
5158 " q, Q Reload init daemon configuration\n"
5159 " u, U Reexecute init daemon\n",
5160 program_invocation_short_name);
5165 static int runlevel_help(void) {
5167 printf("%s [OPTIONS...]\n\n"
5168 "Prints the previous and current runlevel of the init system.\n\n"
5169 " --help Show this help\n",
5170 program_invocation_short_name);
5175 static int help_types(void) {
5179 puts("Available unit types:");
5180 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5181 t = unit_type_to_string(i);
5189 static int systemctl_parse_argv(int argc, char *argv[]) {
5198 ARG_IGNORE_DEPENDENCIES,
5210 ARG_NO_ASK_PASSWORD,
5219 static const struct option options[] = {
5220 { "help", no_argument, NULL, 'h' },
5221 { "version", no_argument, NULL, ARG_VERSION },
5222 { "type", required_argument, NULL, 't' },
5223 { "property", required_argument, NULL, 'p' },
5224 { "all", no_argument, NULL, 'a' },
5225 { "reverse", no_argument, NULL, ARG_REVERSE },
5226 { "after", no_argument, NULL, ARG_AFTER },
5227 { "before", no_argument, NULL, ARG_BEFORE },
5228 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5229 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5230 { "full", no_argument, NULL, 'l' },
5231 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5232 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5233 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5234 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5235 { "ignore-inhibitors", no_argument, NULL, 'i' },
5236 { "user", no_argument, NULL, ARG_USER },
5237 { "system", no_argument, NULL, ARG_SYSTEM },
5238 { "global", no_argument, NULL, ARG_GLOBAL },
5239 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5240 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5241 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5242 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5243 { "quiet", no_argument, NULL, 'q' },
5244 { "root", required_argument, NULL, ARG_ROOT },
5245 { "force", no_argument, NULL, ARG_FORCE },
5246 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5247 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5248 { "signal", required_argument, NULL, 's' },
5249 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5250 { "host", required_argument, NULL, 'H' },
5251 { "machine", required_argument, NULL, 'M' },
5252 { "runtime", no_argument, NULL, ARG_RUNTIME },
5253 { "lines", required_argument, NULL, 'n' },
5254 { "output", required_argument, NULL, 'o' },
5255 { "plain", no_argument, NULL, ARG_PLAIN },
5256 { "state", required_argument, NULL, ARG_STATE },
5265 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5270 return systemctl_help();
5273 puts(PACKAGE_STRING);
5274 puts(SYSTEMD_FEATURES);
5281 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5282 _cleanup_free_ char *type;
5284 type = strndup(word, size);
5288 if (streq(type, "help")) {
5293 if (unit_type_from_string(type) >= 0) {
5294 if (strv_push(&arg_types, type))
5300 /* It's much nicer to use --state= for
5301 * load states, but let's support this
5302 * in --types= too for compatibility
5303 * with old versions */
5304 if (unit_load_state_from_string(optarg) >= 0) {
5305 if (strv_push(&arg_states, type) < 0)
5311 log_error("Unknown unit type or load state '%s'.", type);
5312 log_info("Use -t help to see a list of allowed values.");
5320 /* Make sure that if the empty property list
5321 was specified, we won't show any properties. */
5322 if (isempty(optarg) && !arg_properties) {
5323 arg_properties = new0(char*, 1);
5324 if (!arg_properties)
5330 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5333 prop = strndup(word, size);
5337 if (strv_push(&arg_properties, prop) < 0) {
5344 /* If the user asked for a particular
5345 * property, show it to him, even if it is
5357 arg_dependency = DEPENDENCY_REVERSE;
5361 arg_dependency = DEPENDENCY_AFTER;
5365 arg_dependency = DEPENDENCY_BEFORE;
5368 case ARG_SHOW_TYPES:
5369 arg_show_types = true;
5373 arg_job_mode = optarg;
5377 arg_job_mode = "fail";
5380 case ARG_IRREVERSIBLE:
5381 arg_job_mode = "replace-irreversibly";
5384 case ARG_IGNORE_DEPENDENCIES:
5385 arg_job_mode = "ignore-dependencies";
5389 arg_scope = UNIT_FILE_USER;
5393 arg_scope = UNIT_FILE_SYSTEM;
5397 arg_scope = UNIT_FILE_GLOBAL;
5401 arg_no_block = true;
5405 arg_no_legend = true;
5409 arg_no_pager = true;
5425 if (strv_extend(&arg_states, "failed") < 0)
5443 arg_no_reload = true;
5447 arg_kill_who = optarg;
5451 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5452 log_error("Failed to parse signal string %s.", optarg);
5457 case ARG_NO_ASK_PASSWORD:
5458 arg_ask_password = false;
5462 arg_transport = BUS_TRANSPORT_REMOTE;
5467 arg_transport = BUS_TRANSPORT_CONTAINER;
5476 if (safe_atou(optarg, &arg_lines) < 0) {
5477 log_error("Failed to parse lines '%s'", optarg);
5483 arg_output = output_mode_from_string(optarg);
5484 if (arg_output < 0) {
5485 log_error("Unknown output '%s'.", optarg);
5491 arg_ignore_inhibitors = true;
5502 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5505 s = strndup(word, size);
5509 if (strv_push(&arg_states, s) < 0) {
5521 assert_not_reached("Unhandled option");
5525 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5526 log_error("Cannot access user instance remotely.");
5533 static int halt_parse_argv(int argc, char *argv[]) {
5542 static const struct option options[] = {
5543 { "help", no_argument, NULL, ARG_HELP },
5544 { "halt", no_argument, NULL, ARG_HALT },
5545 { "poweroff", no_argument, NULL, 'p' },
5546 { "reboot", no_argument, NULL, ARG_REBOOT },
5547 { "force", no_argument, NULL, 'f' },
5548 { "wtmp-only", no_argument, NULL, 'w' },
5549 { "no-wtmp", no_argument, NULL, 'd' },
5550 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5559 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5560 if (runlevel == '0' || runlevel == '6')
5563 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5570 arg_action = ACTION_HALT;
5574 if (arg_action != ACTION_REBOOT)
5575 arg_action = ACTION_POWEROFF;
5579 arg_action = ACTION_REBOOT;
5601 /* Compatibility nops */
5608 assert_not_reached("Unhandled option");
5612 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5613 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5615 log_error("Failed to write reboot param to "
5616 REBOOT_PARAM_FILE": %s", strerror(-r));
5619 } else if (optind < argc) {
5620 log_error("Too many arguments.");
5627 static int parse_time_spec(const char *t, usec_t *_u) {
5631 if (streq(t, "now"))
5633 else if (!strchr(t, ':')) {
5636 if (safe_atou64(t, &u) < 0)
5639 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5648 hour = strtol(t, &e, 10);
5649 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5652 minute = strtol(e+1, &e, 10);
5653 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5656 n = now(CLOCK_REALTIME);
5657 s = (time_t) (n / USEC_PER_SEC);
5659 assert_se(localtime_r(&s, &tm));
5661 tm.tm_hour = (int) hour;
5662 tm.tm_min = (int) minute;
5665 assert_se(s = mktime(&tm));
5667 *_u = (usec_t) s * USEC_PER_SEC;
5670 *_u += USEC_PER_DAY;
5676 static int shutdown_parse_argv(int argc, char *argv[]) {
5683 static const struct option options[] = {
5684 { "help", no_argument, NULL, ARG_HELP },
5685 { "halt", no_argument, NULL, 'H' },
5686 { "poweroff", no_argument, NULL, 'P' },
5687 { "reboot", no_argument, NULL, 'r' },
5688 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5689 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5698 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5702 return shutdown_help();
5705 arg_action = ACTION_HALT;
5709 arg_action = ACTION_POWEROFF;
5714 arg_action = ACTION_KEXEC;
5716 arg_action = ACTION_REBOOT;
5720 arg_action = ACTION_KEXEC;
5724 if (arg_action != ACTION_HALT)
5725 arg_action = ACTION_POWEROFF;
5738 /* Compatibility nops */
5742 arg_action = ACTION_CANCEL_SHUTDOWN;
5749 assert_not_reached("Unhandled option");
5753 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5754 r = parse_time_spec(argv[optind], &arg_when);
5756 log_error("Failed to parse time specification: %s", argv[optind]);
5760 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5762 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5763 /* No time argument for shutdown cancel */
5764 arg_wall = argv + optind;
5765 else if (argc > optind + 1)
5766 /* We skip the time argument */
5767 arg_wall = argv + optind + 1;
5774 static int telinit_parse_argv(int argc, char *argv[]) {
5781 static const struct option options[] = {
5782 { "help", no_argument, NULL, ARG_HELP },
5783 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5787 static const struct {
5791 { '0', ACTION_POWEROFF },
5792 { '6', ACTION_REBOOT },
5793 { '1', ACTION_RESCUE },
5794 { '2', ACTION_RUNLEVEL2 },
5795 { '3', ACTION_RUNLEVEL3 },
5796 { '4', ACTION_RUNLEVEL4 },
5797 { '5', ACTION_RUNLEVEL5 },
5798 { 's', ACTION_RESCUE },
5799 { 'S', ACTION_RESCUE },
5800 { 'q', ACTION_RELOAD },
5801 { 'Q', ACTION_RELOAD },
5802 { 'u', ACTION_REEXEC },
5803 { 'U', ACTION_REEXEC }
5812 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5816 return telinit_help();
5826 assert_not_reached("Unhandled option");
5830 if (optind >= argc) {
5835 if (optind + 1 < argc) {
5836 log_error("Too many arguments.");
5840 if (strlen(argv[optind]) != 1) {
5841 log_error("Expected single character argument.");
5845 for (i = 0; i < ELEMENTSOF(table); i++)
5846 if (table[i].from == argv[optind][0])
5849 if (i >= ELEMENTSOF(table)) {
5850 log_error("Unknown command '%s'.", argv[optind]);
5854 arg_action = table[i].to;
5861 static int runlevel_parse_argv(int argc, char *argv[]) {
5867 static const struct option options[] = {
5868 { "help", no_argument, NULL, ARG_HELP },
5877 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5881 return runlevel_help();
5887 assert_not_reached("Unhandled option");
5891 if (optind < argc) {
5892 log_error("Too many arguments.");
5899 static int parse_argv(int argc, char *argv[]) {
5903 if (program_invocation_short_name) {
5905 if (strstr(program_invocation_short_name, "halt")) {
5906 arg_action = ACTION_HALT;
5907 return halt_parse_argv(argc, argv);
5908 } else if (strstr(program_invocation_short_name, "poweroff")) {
5909 arg_action = ACTION_POWEROFF;
5910 return halt_parse_argv(argc, argv);
5911 } else if (strstr(program_invocation_short_name, "reboot")) {
5913 arg_action = ACTION_KEXEC;
5915 arg_action = ACTION_REBOOT;
5916 return halt_parse_argv(argc, argv);
5917 } else if (strstr(program_invocation_short_name, "shutdown")) {
5918 arg_action = ACTION_POWEROFF;
5919 return shutdown_parse_argv(argc, argv);
5920 } else if (strstr(program_invocation_short_name, "init")) {
5922 if (sd_booted() > 0) {
5923 arg_action = _ACTION_INVALID;
5924 return telinit_parse_argv(argc, argv);
5926 /* Hmm, so some other init system is
5927 * running, we need to forward this
5928 * request to it. For now we simply
5929 * guess that it is Upstart. */
5931 execv(TELINIT, argv);
5933 log_error("Couldn't find an alternative telinit implementation to spawn.");
5937 } else if (strstr(program_invocation_short_name, "runlevel")) {
5938 arg_action = ACTION_RUNLEVEL;
5939 return runlevel_parse_argv(argc, argv);
5943 arg_action = ACTION_SYSTEMCTL;
5944 return systemctl_parse_argv(argc, argv);
5947 _pure_ static int action_to_runlevel(void) {
5949 static const char table[_ACTION_MAX] = {
5950 [ACTION_HALT] = '0',
5951 [ACTION_POWEROFF] = '0',
5952 [ACTION_REBOOT] = '6',
5953 [ACTION_RUNLEVEL2] = '2',
5954 [ACTION_RUNLEVEL3] = '3',
5955 [ACTION_RUNLEVEL4] = '4',
5956 [ACTION_RUNLEVEL5] = '5',
5957 [ACTION_RESCUE] = '1'
5960 assert(arg_action < _ACTION_MAX);
5962 return table[arg_action];
5965 static int talk_initctl(void) {
5967 struct init_request request = {
5968 .magic = INIT_MAGIC,
5970 .cmd = INIT_CMD_RUNLVL
5973 _cleanup_close_ int fd = -1;
5977 rl = action_to_runlevel();
5981 request.runlevel = rl;
5983 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5985 if (errno == ENOENT)
5988 log_error("Failed to open "INIT_FIFO": %m");
5993 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5995 log_error("Failed to write to "INIT_FIFO": %m");
5996 return errno > 0 ? -errno : -EIO;
6002 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6004 static const struct {
6012 int (* const dispatch)(sd_bus *bus, char **args);
6018 { "list-units", MORE, 0, list_units },
6019 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6020 { "list-sockets", MORE, 1, list_sockets },
6021 { "list-timers", MORE, 1, list_timers },
6022 { "list-jobs", MORE, 1, list_jobs },
6023 { "clear-jobs", EQUAL, 1, daemon_reload },
6024 { "cancel", MORE, 2, cancel_job },
6025 { "start", MORE, 2, start_unit },
6026 { "stop", MORE, 2, start_unit },
6027 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6028 { "reload", MORE, 2, start_unit },
6029 { "restart", MORE, 2, start_unit },
6030 { "try-restart", MORE, 2, start_unit },
6031 { "reload-or-restart", MORE, 2, start_unit },
6032 { "reload-or-try-restart", MORE, 2, start_unit },
6033 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6034 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6035 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6036 { "isolate", EQUAL, 2, start_unit },
6037 { "kill", MORE, 2, kill_unit },
6038 { "is-active", MORE, 2, check_unit_active },
6039 { "check", MORE, 2, check_unit_active },
6040 { "is-failed", MORE, 2, check_unit_failed },
6041 { "show", MORE, 1, show },
6042 { "cat", MORE, 2, cat },
6043 { "status", MORE, 1, show },
6044 { "help", MORE, 2, show },
6045 { "snapshot", LESS, 2, snapshot },
6046 { "delete", MORE, 2, delete_snapshot },
6047 { "daemon-reload", EQUAL, 1, daemon_reload },
6048 { "daemon-reexec", EQUAL, 1, daemon_reload },
6049 { "show-environment", EQUAL, 1, show_environment },
6050 { "set-environment", MORE, 2, set_environment },
6051 { "unset-environment", MORE, 2, set_environment },
6052 { "import-environment", MORE, 1, import_environment},
6053 { "halt", EQUAL, 1, start_special, FORCE },
6054 { "poweroff", EQUAL, 1, start_special, FORCE },
6055 { "reboot", EQUAL, 1, start_special, FORCE },
6056 { "kexec", EQUAL, 1, start_special },
6057 { "suspend", EQUAL, 1, start_special },
6058 { "hibernate", EQUAL, 1, start_special },
6059 { "hybrid-sleep", EQUAL, 1, start_special },
6060 { "default", EQUAL, 1, start_special },
6061 { "rescue", EQUAL, 1, start_special },
6062 { "emergency", EQUAL, 1, start_special },
6063 { "exit", EQUAL, 1, start_special },
6064 { "reset-failed", MORE, 1, reset_failed },
6065 { "enable", MORE, 2, enable_unit, NOBUS },
6066 { "disable", MORE, 2, enable_unit, NOBUS },
6067 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6068 { "reenable", MORE, 2, enable_unit, NOBUS },
6069 { "preset", MORE, 2, enable_unit, NOBUS },
6070 { "mask", MORE, 2, enable_unit, NOBUS },
6071 { "unmask", MORE, 2, enable_unit, NOBUS },
6072 { "link", MORE, 2, enable_unit, NOBUS },
6073 { "switch-root", MORE, 2, switch_root },
6074 { "list-dependencies", LESS, 2, list_dependencies },
6075 { "set-default", EQUAL, 2, set_default, NOBUS },
6076 { "get-default", EQUAL, 1, get_default, NOBUS },
6077 { "set-property", MORE, 3, set_property },
6086 left = argc - optind;
6088 /* Special rule: no arguments (left == 0) means "list-units" */
6090 if (streq(argv[optind], "help") && !argv[optind+1]) {
6091 log_error("This command expects one or more "
6092 "unit names. Did you mean --help?");
6096 for (; verb->verb; verb++)
6097 if (streq(argv[optind], verb->verb))
6100 log_error("Unknown operation '%s'.", argv[optind]);
6105 switch (verb->argc_cmp) {
6108 if (left != verb->argc) {
6109 log_error("Invalid number of arguments.");
6116 if (left < verb->argc) {
6117 log_error("Too few arguments.");
6124 if (left > verb->argc) {
6125 log_error("Too many arguments.");
6132 assert_not_reached("Unknown comparison operator.");
6135 /* Require a bus connection for all operations but
6137 if (verb->bus == NOBUS) {
6138 if (!bus && !avoid_bus()) {
6139 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6144 if (running_in_chroot() > 0) {
6145 log_info("Running in chroot, ignoring request.");
6149 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6150 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6155 return verb->dispatch(bus, argv + optind);
6158 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6160 struct sd_shutdown_command c = {
6167 union sockaddr_union sockaddr = {
6168 .un.sun_family = AF_UNIX,
6169 .un.sun_path = "/run/systemd/shutdownd",
6172 struct iovec iovec[2] = {{
6173 .iov_base = (char*) &c,
6174 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6177 struct msghdr msghdr = {
6178 .msg_name = &sockaddr,
6179 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6180 + sizeof("/run/systemd/shutdownd") - 1,
6185 _cleanup_close_ int fd;
6187 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6191 if (!isempty(message)) {
6192 iovec[1].iov_base = (char*) message;
6193 iovec[1].iov_len = strlen(message);
6194 msghdr.msg_iovlen++;
6197 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6203 static int reload_with_fallback(sd_bus *bus) {
6206 /* First, try systemd via D-Bus. */
6207 if (daemon_reload(bus, NULL) >= 0)
6211 /* Nothing else worked, so let's try signals */
6212 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6214 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6215 log_error("kill() failed: %m");
6222 static int start_with_fallback(sd_bus *bus) {
6225 /* First, try systemd via D-Bus. */
6226 if (start_unit(bus, NULL) >= 0)
6230 /* Nothing else worked, so let's try
6232 if (talk_initctl() > 0)
6235 log_error("Failed to talk to init daemon.");
6239 warn_wall(arg_action);
6243 static int halt_now(enum action a) {
6245 /* Make sure C-A-D is handled by the kernel from this
6247 reboot(RB_ENABLE_CAD);
6252 log_info("Halting.");
6253 reboot(RB_HALT_SYSTEM);
6256 case ACTION_POWEROFF:
6257 log_info("Powering off.");
6258 reboot(RB_POWER_OFF);
6261 case ACTION_REBOOT: {
6262 _cleanup_free_ char *param = NULL;
6264 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6265 log_info("Rebooting with argument '%s'.", param);
6266 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6267 LINUX_REBOOT_CMD_RESTART2, param);
6270 log_info("Rebooting.");
6271 reboot(RB_AUTOBOOT);
6276 assert_not_reached("Unknown action.");
6280 static int halt_main(sd_bus *bus) {
6283 r = check_inhibitors(bus, arg_action);
6287 if (geteuid() != 0) {
6288 /* Try logind if we are a normal user and no special
6289 * mode applies. Maybe PolicyKit allows us to shutdown
6292 if (arg_when <= 0 &&
6295 (arg_action == ACTION_POWEROFF ||
6296 arg_action == ACTION_REBOOT)) {
6297 r = reboot_with_logind(bus, arg_action);
6302 log_error("Must be root.");
6307 _cleanup_free_ char *m;
6309 m = strv_join(arg_wall, " ");
6313 r = send_shutdownd(arg_when,
6314 arg_action == ACTION_HALT ? 'H' :
6315 arg_action == ACTION_POWEROFF ? 'P' :
6316 arg_action == ACTION_KEXEC ? 'K' :
6323 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6325 char date[FORMAT_TIMESTAMP_MAX];
6327 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6328 format_timestamp(date, sizeof(date), arg_when));
6333 if (!arg_dry && !arg_force)
6334 return start_with_fallback(bus);
6337 if (sd_booted() > 0)
6338 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6340 r = utmp_put_shutdown();
6342 log_warning("Failed to write utmp record: %s", strerror(-r));
6349 r = halt_now(arg_action);
6350 log_error("Failed to reboot: %s", strerror(-r));
6355 static int runlevel_main(void) {
6356 int r, runlevel, previous;
6358 r = utmp_get_runlevel(&runlevel, &previous);
6365 previous <= 0 ? 'N' : previous,
6366 runlevel <= 0 ? 'N' : runlevel);
6371 int main(int argc, char*argv[]) {
6372 _cleanup_bus_unref_ sd_bus *bus = NULL;
6375 setlocale(LC_ALL, "");
6376 log_parse_environment();
6379 /* Explicitly not on_tty() to avoid setting cached value.
6380 * This becomes relevant for piping output which might be
6382 original_stdout_is_tty = isatty(STDOUT_FILENO);
6384 r = parse_argv(argc, argv);
6388 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6389 * let's shortcut this */
6390 if (arg_action == ACTION_RUNLEVEL) {
6391 r = runlevel_main();
6395 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6396 log_info("Running in chroot, ignoring request.");
6402 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6404 /* systemctl_main() will print an error message for the bus
6405 * connection, but only if it needs to */
6407 switch (arg_action) {
6409 case ACTION_SYSTEMCTL:
6410 r = systemctl_main(bus, argc, argv, r);
6414 case ACTION_POWEROFF:
6420 case ACTION_RUNLEVEL2:
6421 case ACTION_RUNLEVEL3:
6422 case ACTION_RUNLEVEL4:
6423 case ACTION_RUNLEVEL5:
6425 case ACTION_EMERGENCY:
6426 case ACTION_DEFAULT:
6427 r = start_with_fallback(bus);
6432 r = reload_with_fallback(bus);
6435 case ACTION_CANCEL_SHUTDOWN: {
6436 _cleanup_free_ char *m = NULL;
6439 m = strv_join(arg_wall, " ");
6446 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6448 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6452 case ACTION_RUNLEVEL:
6453 case _ACTION_INVALID:
6455 assert_not_reached("Unknown action");
6460 ask_password_agent_close();
6461 polkit_agent_close();
6463 strv_free(arg_types);
6464 strv_free(arg_states);
6465 strv_free(arg_properties);
6467 return r < 0 ? EXIT_FAILURE : r;