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 usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
917 if (next->monotonic != (usec_t) -1 && next->monotonic > 0) {
920 if (next->monotonic > nw->monotonic)
921 converted = nw->realtime + (next->monotonic - nw->monotonic);
923 converted = nw->realtime - (nw->monotonic - next->monotonic);
925 if (next->realtime != (usec_t) -1 && next->realtime > 0)
926 next_elapse = MIN(converted, next->realtime);
928 next_elapse = converted;
931 next_elapse = next->realtime;
936 static int list_timers(sd_bus *bus, char **args) {
938 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
939 _cleanup_free_ struct timer_info *timer_infos = NULL;
940 _cleanup_free_ UnitInfo *unit_infos = NULL;
941 struct timer_info *t;
948 pager_open_if_enabled();
950 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
954 dual_timestamp_get(&nw);
956 for (u = unit_infos; u < unit_infos + n; u++) {
957 _cleanup_strv_free_ char **triggered = NULL;
958 dual_timestamp next = {};
961 if (!endswith(u->id, ".timer"))
964 r = get_triggered_units(bus, u->unit_path, &triggered);
968 r = get_next_elapse(bus, u->unit_path, &next);
972 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
977 m = calc_next_elapse(&nw, &next);
979 timer_infos[c++] = (struct timer_info) {
982 .triggered = triggered,
985 triggered = NULL; /* avoid cleanup */
988 qsort_safe(timer_infos, c, sizeof(struct timer_info),
989 (__compar_fn_t) timer_info_compare);
991 output_timers_list(timer_infos, c);
994 for (t = timer_infos; t < timer_infos + c; t++)
995 strv_free(t->triggered);
1000 static int compare_unit_file_list(const void *a, const void *b) {
1001 const char *d1, *d2;
1002 const UnitFileList *u = a, *v = b;
1004 d1 = strrchr(u->path, '.');
1005 d2 = strrchr(v->path, '.');
1010 r = strcasecmp(d1, d2);
1015 return strcasecmp(basename(u->path), basename(v->path));
1018 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1021 if (!strv_isempty(patterns)) {
1024 STRV_FOREACH(pattern, patterns)
1025 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1030 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1033 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1034 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
1035 const UnitFileList *u;
1037 max_id_len = sizeof("UNIT FILE")-1;
1038 state_cols = sizeof("STATE")-1;
1040 for (u = units; u < units + c; u++) {
1041 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1042 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1046 unsigned basic_cols;
1048 id_cols = MIN(max_id_len, 25u);
1049 basic_cols = 1 + id_cols + state_cols;
1050 if (basic_cols < (unsigned) columns())
1051 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1053 id_cols = max_id_len;
1056 printf("%-*s %-*s\n",
1057 id_cols, "UNIT FILE",
1058 state_cols, "STATE");
1060 for (u = units; u < units + c; u++) {
1061 _cleanup_free_ char *e = NULL;
1062 const char *on, *off;
1067 if (u->state == UNIT_FILE_MASKED ||
1068 u->state == UNIT_FILE_MASKED_RUNTIME ||
1069 u->state == UNIT_FILE_DISABLED ||
1070 u->state == UNIT_FILE_INVALID) {
1071 on = ansi_highlight_red();
1072 off = ansi_highlight_off();
1073 } else if (u->state == UNIT_FILE_ENABLED) {
1074 on = ansi_highlight_green();
1075 off = ansi_highlight_off();
1079 id = basename(u->path);
1081 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1083 printf("%-*s %s%-*s%s\n",
1084 id_cols, e ? e : id,
1085 on, state_cols, unit_file_state_to_string(u->state), off);
1089 printf("\n%u unit files listed.\n", n_shown);
1092 static int list_unit_files(sd_bus *bus, char **args) {
1093 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1094 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1095 _cleanup_free_ UnitFileList *units = NULL;
1103 pager_open_if_enabled();
1111 h = hashmap_new(string_hash_func, string_compare_func);
1115 r = unit_file_get_list(arg_scope, arg_root, h);
1117 unit_file_list_free(h);
1118 log_error("Failed to get unit file list: %s", strerror(-r));
1122 n_units = hashmap_size(h);
1123 units = new(UnitFileList, n_units);
1125 unit_file_list_free(h);
1129 HASHMAP_FOREACH(u, h, i) {
1130 if (!output_show_unit_file(u, strv_skip_first(args)))
1137 assert(c <= n_units);
1140 r = sd_bus_call_method(
1142 "org.freedesktop.systemd1",
1143 "/org/freedesktop/systemd1",
1144 "org.freedesktop.systemd1.Manager",
1150 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1154 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1156 return bus_log_parse_error(r);
1158 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1160 if (!GREEDY_REALLOC(units, size, c + 1))
1163 units[c] = (struct UnitFileList) {
1165 unit_file_state_from_string(state)
1168 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1173 return bus_log_parse_error(r);
1175 r = sd_bus_message_exit_container(reply);
1177 return bus_log_parse_error(r);
1181 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1182 output_unit_file_list(units, c);
1186 for (unit = units; unit < units + c; unit++)
1192 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1193 _cleanup_free_ char *n = NULL;
1194 size_t max_len = MAX(columns(),20u);
1200 for (i = level - 1; i >= 0; i--) {
1202 if (len > max_len - 3 && !arg_full) {
1203 printf("%s...\n",max_len % 2 ? "" : " ");
1206 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1210 if (len > max_len - 3 && !arg_full) {
1211 printf("%s...\n",max_len % 2 ? "" : " ");
1215 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1219 printf("%s\n", name);
1223 n = ellipsize(name, max_len-len, 100);
1231 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1233 static const char *dependencies[_DEPENDENCY_MAX] = {
1234 [DEPENDENCY_FORWARD] = "Requires\0"
1235 "RequiresOverridable\0"
1237 "RequisiteOverridable\0"
1239 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1240 "RequiredByOverridable\0"
1243 [DEPENDENCY_AFTER] = "After\0",
1244 [DEPENDENCY_BEFORE] = "Before\0",
1247 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1248 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1249 _cleanup_strv_free_ char **ret = NULL;
1250 _cleanup_free_ char *path = NULL;
1256 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1258 path = unit_dbus_path_from_name(name);
1262 r = sd_bus_call_method(
1264 "org.freedesktop.systemd1",
1266 "org.freedesktop.DBus.Properties",
1270 "s", "org.freedesktop.systemd1.Unit");
1272 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1276 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1278 return bus_log_parse_error(r);
1280 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1283 r = sd_bus_message_read(reply, "s", &prop);
1285 return bus_log_parse_error(r);
1287 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1288 r = sd_bus_message_skip(reply, "v");
1290 return bus_log_parse_error(r);
1293 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1295 return bus_log_parse_error(r);
1297 r = bus_message_read_strv_extend(reply, &ret);
1299 return bus_log_parse_error(r);
1301 r = sd_bus_message_exit_container(reply);
1303 return bus_log_parse_error(r);
1306 r = sd_bus_message_exit_container(reply);
1308 return bus_log_parse_error(r);
1312 return bus_log_parse_error(r);
1314 r = sd_bus_message_exit_container(reply);
1316 return bus_log_parse_error(r);
1324 static int list_dependencies_compare(const void *_a, const void *_b) {
1325 const char **a = (const char**) _a, **b = (const char**) _b;
1327 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1329 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1332 return strcasecmp(*a, *b);
1335 static int list_dependencies_one(
1340 unsigned int branches) {
1342 _cleanup_strv_free_ char **deps = NULL;
1350 r = strv_extend(units, name);
1354 r = list_dependencies_get_dependencies(bus, name, &deps);
1358 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1360 STRV_FOREACH(c, deps) {
1363 if (strv_contains(*units, *c)) {
1365 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1372 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1374 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1376 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1378 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1382 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1383 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1390 strv_remove(*units, name);
1395 static int list_dependencies(sd_bus *bus, char **args) {
1396 _cleanup_strv_free_ char **units = NULL;
1397 _cleanup_free_ char *unit = NULL;
1403 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1408 u = SPECIAL_DEFAULT_TARGET;
1410 pager_open_if_enabled();
1414 return list_dependencies_one(bus, u, 0, &units, 0);
1417 static int get_default(sd_bus *bus, char **args) {
1418 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1419 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1420 _cleanup_free_ char *_path = NULL;
1424 if (!bus || avoid_bus()) {
1425 r = unit_file_get_default(arg_scope, arg_root, &_path);
1427 log_error("Failed to get default target: %s", strerror(-r));
1433 r = sd_bus_call_method(
1435 "org.freedesktop.systemd1",
1436 "/org/freedesktop/systemd1",
1437 "org.freedesktop.systemd1.Manager",
1443 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1447 r = sd_bus_message_read(reply, "s", &path);
1449 return bus_log_parse_error(r);
1453 printf("%s\n", path);
1458 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1461 assert(changes || n_changes == 0);
1463 for (i = 0; i < n_changes; i++) {
1464 if (changes[i].type == UNIT_FILE_SYMLINK)
1465 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1467 log_info("rm '%s'", changes[i].path);
1471 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1472 const char *type, *path, *source;
1475 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1477 return bus_log_parse_error(r);
1479 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1481 if (streq(type, "symlink"))
1482 log_info("ln -s '%s' '%s'", source, path);
1484 log_info("rm '%s'", path);
1488 return bus_log_parse_error(r);
1490 r = sd_bus_message_exit_container(m);
1492 return bus_log_parse_error(r);
1497 static int set_default(sd_bus *bus, char **args) {
1498 _cleanup_free_ char *unit = NULL;
1499 UnitFileChange *changes = NULL;
1500 unsigned n_changes = 0;
1503 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1507 if (!bus || avoid_bus()) {
1508 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1510 log_error("Failed to set default target: %s", strerror(-r));
1515 dump_unit_file_changes(changes, n_changes);
1519 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1520 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1522 r = sd_bus_call_method(
1524 "org.freedesktop.systemd1",
1525 "/org/freedesktop/systemd1",
1526 "org.freedesktop.systemd1.Manager",
1530 "sb", unit, arg_force);
1532 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1536 r = deserialize_and_dump_unit_file_changes(reply);
1540 /* Try to reload if enabeld */
1542 r = daemon_reload(bus, args);
1547 unit_file_changes_free(changes, n_changes);
1554 const char *name, *type, *state;
1557 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1558 unsigned id_len, unit_len, type_len, state_len;
1559 const struct job_info *j;
1560 const char *on, *off;
1561 bool shorten = false;
1563 assert(n == 0 || jobs);
1566 on = ansi_highlight_green();
1567 off = ansi_highlight_off();
1569 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1573 pager_open_if_enabled();
1575 id_len = sizeof("JOB")-1;
1576 unit_len = sizeof("UNIT")-1;
1577 type_len = sizeof("TYPE")-1;
1578 state_len = sizeof("STATE")-1;
1580 for (j = jobs; j < jobs + n; j++) {
1581 uint32_t id = j->id;
1582 assert(j->name && j->type && j->state);
1584 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1585 unit_len = MAX(unit_len, strlen(j->name));
1586 type_len = MAX(type_len, strlen(j->type));
1587 state_len = MAX(state_len, strlen(j->state));
1590 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1591 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1596 printf("%*s %-*s %-*s %-*s\n",
1600 state_len, "STATE");
1602 for (j = jobs; j < jobs + n; j++) {
1603 _cleanup_free_ char *e = NULL;
1605 if (streq(j->state, "running")) {
1606 on = ansi_highlight();
1607 off = ansi_highlight_off();
1611 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1612 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1614 on, unit_len, e ? e : j->name, off,
1616 on, state_len, j->state, off);
1619 if (!arg_no_legend) {
1620 on = ansi_highlight();
1621 off = ansi_highlight_off();
1623 printf("\n%s%u jobs listed%s.\n", on, n, off);
1627 static bool output_show_job(struct job_info *job, char **patterns) {
1628 if (!strv_isempty(patterns)) {
1631 STRV_FOREACH(pattern, patterns)
1632 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1640 static int list_jobs(sd_bus *bus, char **args) {
1641 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1642 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1643 const char *name, *type, *state, *job_path, *unit_path;
1644 _cleanup_free_ struct job_info *jobs = NULL;
1649 bool skipped = false;
1651 r = sd_bus_call_method(
1653 "org.freedesktop.systemd1",
1654 "/org/freedesktop/systemd1",
1655 "org.freedesktop.systemd1.Manager",
1661 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1665 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1667 return bus_log_parse_error(r);
1669 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1670 struct job_info job = { id, name, type, state };
1672 if (!output_show_job(&job, strv_skip_first(args))) {
1677 if (!GREEDY_REALLOC(jobs, size, c + 1))
1683 return bus_log_parse_error(r);
1685 r = sd_bus_message_exit_container(reply);
1687 return bus_log_parse_error(r);
1689 output_jobs_list(jobs, c, skipped);
1693 static int cancel_job(sd_bus *bus, char **args) {
1694 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1699 if (strv_length(args) <= 1)
1700 return daemon_reload(bus, args);
1702 STRV_FOREACH(name, args+1) {
1706 r = safe_atou32(*name, &id);
1708 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1712 r = sd_bus_call_method(
1714 "org.freedesktop.systemd1",
1715 "/org/freedesktop/systemd1",
1716 "org.freedesktop.systemd1.Manager",
1722 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1730 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1731 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1735 /* We ignore all errors here, since this is used to show a
1738 /* We don't use unit_dbus_path_from_name() directly since we
1739 * don't want to load the unit if it isn't loaded. */
1741 r = sd_bus_call_method(
1743 "org.freedesktop.systemd1",
1744 "/org/freedesktop/systemd1",
1745 "org.freedesktop.systemd1.Manager",
1753 r = sd_bus_message_read(reply, "o", &path);
1757 r = sd_bus_get_property_trivial(
1759 "org.freedesktop.systemd1",
1761 "org.freedesktop.systemd1.Unit",
1771 typedef struct WaitData {
1778 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1785 log_debug("Got D-Bus request: %s.%s() on %s",
1786 sd_bus_message_get_interface(m),
1787 sd_bus_message_get_member(m),
1788 sd_bus_message_get_path(m));
1790 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1791 log_error("Warning! D-Bus connection terminated.");
1793 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1795 const char *path, *result, *unit;
1799 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1801 ret = set_remove(d->set, (char*) path);
1807 if (!isempty(result))
1808 d->result = strdup(result);
1811 d->name = strdup(unit);
1816 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1818 ret = set_remove(d->set, (char*) path);
1825 d->result = strdup(result);
1831 bus_log_parse_error(r);
1837 static int enable_wait_for_jobs(sd_bus *bus) {
1842 r = sd_bus_add_match(
1845 "sender='org.freedesktop.systemd1',"
1846 "interface='org.freedesktop.systemd1.Manager',"
1847 "member='JobRemoved',"
1848 "path='/org/freedesktop/systemd1'",
1851 log_error("Failed to add match");
1855 /* This is slightly dirty, since we don't undo the match registrations. */
1859 static int bus_process_wait(sd_bus *bus) {
1863 r = sd_bus_process(bus, NULL);
1868 r = sd_bus_wait(bus, (uint64_t) -1);
1874 static int check_wait_response(WaitData *d) {
1880 if (streq(d->result, "timeout"))
1881 log_error("Job for %s timed out.", strna(d->name));
1882 else if (streq(d->result, "canceled"))
1883 log_error("Job for %s canceled.", strna(d->name));
1884 else if (streq(d->result, "dependency"))
1885 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1886 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1887 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1890 if (streq(d->result, "timeout"))
1892 else if (streq(d->result, "canceled"))
1894 else if (streq(d->result, "dependency"))
1896 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1902 static int wait_for_jobs(sd_bus *bus, Set *s) {
1903 WaitData d = { .set = s };
1909 q = sd_bus_add_filter(bus, wait_filter, &d);
1913 while (!set_isempty(s)) {
1914 q = bus_process_wait(bus);
1916 log_error("Failed to wait for response: %s", strerror(-r));
1921 q = check_wait_response(&d);
1922 /* Return the first error as it is most likely to be
1924 if (q < 0 && r == 0)
1926 log_debug("Got result %s/%s for job %s",
1927 strna(d.result), strerror(-q), strna(d.name));
1937 q = sd_bus_remove_filter(bus, wait_filter, &d);
1938 if (q < 0 && r == 0)
1944 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1945 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1946 _cleanup_free_ char *n = NULL, *state = NULL;
1952 n = unit_name_mangle(name, MANGLE_NOGLOB);
1956 /* We don't use unit_dbus_path_from_name() directly since we
1957 * don't want to load the unit if it isn't loaded. */
1959 r = sd_bus_call_method(
1961 "org.freedesktop.systemd1",
1962 "/org/freedesktop/systemd1",
1963 "org.freedesktop.systemd1.Manager",
1974 r = sd_bus_message_read(reply, "o", &path);
1976 return bus_log_parse_error(r);
1978 r = sd_bus_get_property_string(
1980 "org.freedesktop.systemd1",
1982 "org.freedesktop.systemd1.Unit",
1995 return nulstr_contains(good_states, state);
1998 static int check_triggering_units(
2002 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2003 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2004 _cleanup_strv_free_ char **triggered_by = NULL;
2005 bool print_warning_label = true;
2009 n = unit_name_mangle(name, MANGLE_NOGLOB);
2013 path = unit_dbus_path_from_name(n);
2017 r = sd_bus_get_property_string(
2019 "org.freedesktop.systemd1",
2021 "org.freedesktop.systemd1.Unit",
2026 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2030 if (streq(state, "masked"))
2033 r = sd_bus_get_property_strv(
2035 "org.freedesktop.systemd1",
2037 "org.freedesktop.systemd1.Unit",
2042 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2046 STRV_FOREACH(i, triggered_by) {
2047 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2049 log_error("Failed to check unit: %s", strerror(-r));
2056 if (print_warning_label) {
2057 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2058 print_warning_label = false;
2061 log_warning(" %s", *i);
2067 static const char *verb_to_method(const char *verb) {
2070 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2071 if (streq_ptr(unit_actions[i].verb, verb))
2072 return unit_actions[i].method;
2077 static const char *method_to_verb(const char *method) {
2080 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2081 if (streq_ptr(unit_actions[i].method, method))
2082 return unit_actions[i].verb;
2087 static int start_unit_one(
2092 sd_bus_error *error,
2095 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2104 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2105 r = sd_bus_call_method(
2107 "org.freedesktop.systemd1",
2108 "/org/freedesktop/systemd1",
2109 "org.freedesktop.systemd1.Manager",
2117 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2118 /* There's always a fallback possible for
2119 * legacy actions. */
2120 return -EADDRNOTAVAIL;
2122 verb = method_to_verb(method);
2124 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2128 r = sd_bus_message_read(reply, "o", &path);
2130 return bus_log_parse_error(r);
2132 if (need_daemon_reload(bus, name) > 0)
2133 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2134 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2143 log_debug("Adding %s to the set", p);
2144 r = set_consume(s, p);
2152 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2154 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2155 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2159 STRV_FOREACH(name, names) {
2163 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2165 t = unit_name_mangle(*name, MANGLE_GLOB);
2169 if (string_is_glob(t))
2170 r = strv_consume(&globs, t);
2172 r = strv_consume(&mangled, t);
2177 /* Query the manager only if any of the names are a glob, since
2178 * this is fairly expensive */
2179 if (!strv_isempty(globs)) {
2180 _cleanup_free_ UnitInfo *unit_infos = NULL;
2182 r = get_unit_list(bus, &reply, &unit_infos, globs);
2186 for (i = 0; i < r; i++)
2187 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2192 mangled = NULL; /* do not free */
2196 static const struct {
2200 } action_table[_ACTION_MAX] = {
2201 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2202 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2203 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2204 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2205 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2206 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2207 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2208 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2209 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2210 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2211 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2212 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2213 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2214 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2215 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2218 static enum action verb_to_action(const char *verb) {
2221 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2222 if (streq_ptr(action_table[i].verb, verb))
2225 return _ACTION_INVALID;
2228 static int start_unit(sd_bus *bus, char **args) {
2229 _cleanup_set_free_free_ Set *s = NULL;
2230 _cleanup_strv_free_ char **names = NULL;
2231 const char *method, *mode, *one_name;
2237 ask_password_agent_open_if_enabled();
2239 if (arg_action == ACTION_SYSTEMCTL) {
2241 method = verb_to_method(args[0]);
2242 action = verb_to_action(args[0]);
2244 mode = streq(args[0], "isolate") ? "isolate" :
2245 action_table[action].mode ?: arg_job_mode;
2247 one_name = action_table[action].target;
2249 assert(arg_action < ELEMENTSOF(action_table));
2250 assert(action_table[arg_action].target);
2252 method = "StartUnit";
2254 mode = action_table[arg_action].mode;
2255 one_name = action_table[arg_action].target;
2259 names = strv_new(one_name, NULL);
2261 r = expand_names(bus, args + 1, NULL, &names);
2263 log_error("Failed to expand names: %s", strerror(-r));
2266 if (!arg_no_block) {
2267 r = enable_wait_for_jobs(bus);
2269 log_error("Could not watch jobs: %s", strerror(-r));
2273 s = set_new(string_hash_func, string_compare_func);
2278 STRV_FOREACH(name, names) {
2279 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2282 q = start_unit_one(bus, method, *name, mode, &error, s);
2283 if (r >= 0 && q < 0)
2284 r = translate_bus_error_to_exit_status(q, &error);
2287 if (!arg_no_block) {
2290 q = wait_for_jobs(bus, s);
2294 /* When stopping units, warn if they can still be triggered by
2295 * another active unit (socket, path, timer) */
2296 if (!arg_quiet && streq(method, "StopUnit"))
2297 STRV_FOREACH(name, names)
2298 check_triggering_units(bus, *name);
2304 /* Ask systemd-logind, which might grant access to unprivileged users
2305 * through PolicyKit */
2306 static int reboot_with_logind(sd_bus *bus, enum action a) {
2308 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2315 polkit_agent_open_if_enabled();
2323 case ACTION_POWEROFF:
2324 method = "PowerOff";
2327 case ACTION_SUSPEND:
2331 case ACTION_HIBERNATE:
2332 method = "Hibernate";
2335 case ACTION_HYBRID_SLEEP:
2336 method = "HybridSleep";
2343 r = sd_bus_call_method(
2345 "org.freedesktop.login1",
2346 "/org/freedesktop/login1",
2347 "org.freedesktop.login1.Manager",
2353 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2361 static int check_inhibitors(sd_bus *bus, enum action a) {
2363 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2364 _cleanup_strv_free_ char **sessions = NULL;
2365 const char *what, *who, *why, *mode;
2374 if (arg_ignore_inhibitors || arg_force > 0)
2386 r = sd_bus_call_method(
2388 "org.freedesktop.login1",
2389 "/org/freedesktop/login1",
2390 "org.freedesktop.login1.Manager",
2396 /* If logind is not around, then there are no inhibitors... */
2399 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2401 return bus_log_parse_error(r);
2403 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2404 _cleanup_free_ char *comm = NULL, *user = NULL;
2405 _cleanup_strv_free_ char **sv = NULL;
2407 if (!streq(mode, "block"))
2410 sv = strv_split(what, ":");
2414 if (!strv_contains(sv,
2416 a == ACTION_POWEROFF ||
2417 a == ACTION_REBOOT ||
2418 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2421 get_process_comm(pid, &comm);
2422 user = uid_to_name(uid);
2424 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2425 who, (unsigned long) pid, strna(comm), strna(user), why);
2430 return bus_log_parse_error(r);
2432 r = sd_bus_message_exit_container(reply);
2434 return bus_log_parse_error(r);
2436 /* Check for current sessions */
2437 sd_get_sessions(&sessions);
2438 STRV_FOREACH(s, sessions) {
2439 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2441 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2444 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2447 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2450 sd_session_get_tty(*s, &tty);
2451 sd_session_get_seat(*s, &seat);
2452 sd_session_get_service(*s, &service);
2453 user = uid_to_name(uid);
2455 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2462 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2463 action_table[a].verb);
2471 static int start_special(sd_bus *bus, char **args) {
2477 a = verb_to_action(args[0]);
2479 r = check_inhibitors(bus, a);
2483 if (arg_force >= 2 && geteuid() != 0) {
2484 log_error("Must be root.");
2488 if (arg_force >= 2 &&
2489 (a == ACTION_HALT ||
2490 a == ACTION_POWEROFF ||
2491 a == ACTION_REBOOT))
2494 if (arg_force >= 1 &&
2495 (a == ACTION_HALT ||
2496 a == ACTION_POWEROFF ||
2497 a == ACTION_REBOOT ||
2498 a == ACTION_KEXEC ||
2500 return daemon_reload(bus, args);
2502 /* first try logind, to allow authentication with polkit */
2503 if (geteuid() != 0 &&
2504 (a == ACTION_POWEROFF ||
2505 a == ACTION_REBOOT ||
2506 a == ACTION_SUSPEND ||
2507 a == ACTION_HIBERNATE ||
2508 a == ACTION_HYBRID_SLEEP)) {
2509 r = reboot_with_logind(bus, a);
2514 r = start_unit(bus, args);
2515 if (r == EXIT_SUCCESS)
2521 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2522 _cleanup_strv_free_ char **names = NULL;
2529 r = expand_names(bus, args, NULL, &names);
2531 log_error("Failed to expand names: %s", strerror(-r));
2535 STRV_FOREACH(name, names) {
2538 state = check_one_unit(bus, *name, good_states, arg_quiet);
2548 static int check_unit_active(sd_bus *bus, char **args) {
2549 /* According to LSB: 3, "program is not running" */
2550 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2553 static int check_unit_failed(sd_bus *bus, char **args) {
2554 return check_unit_generic(bus, 1, "failed\0", args + 1);
2557 static int kill_unit(sd_bus *bus, char **args) {
2558 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2559 _cleanup_strv_free_ char **names = NULL;
2567 arg_kill_who = "all";
2569 r = expand_names(bus, args + 1, NULL, &names);
2571 log_error("Failed to expand names: %s", strerror(-r));
2573 STRV_FOREACH(name, names) {
2574 q = sd_bus_call_method(
2576 "org.freedesktop.systemd1",
2577 "/org/freedesktop/systemd1",
2578 "org.freedesktop.systemd1.Manager",
2582 "ssi", *names, arg_kill_who, arg_signal);
2584 log_error("Failed to kill unit %s: %s",
2585 *names, bus_error_message(&error, r));
2594 typedef struct ExecStatusInfo {
2602 usec_t start_timestamp;
2603 usec_t exit_timestamp;
2608 LIST_FIELDS(struct ExecStatusInfo, exec);
2611 static void exec_status_info_free(ExecStatusInfo *i) {
2620 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2621 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2624 int32_t code, status;
2630 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2632 return bus_log_parse_error(r);
2636 r = sd_bus_message_read(m, "s", &path);
2638 return bus_log_parse_error(r);
2640 i->path = strdup(path);
2644 r = sd_bus_message_read_strv(m, &i->argv);
2646 return bus_log_parse_error(r);
2648 r = sd_bus_message_read(m,
2651 &start_timestamp, &start_timestamp_monotonic,
2652 &exit_timestamp, &exit_timestamp_monotonic,
2656 return bus_log_parse_error(r);
2659 i->start_timestamp = (usec_t) start_timestamp;
2660 i->exit_timestamp = (usec_t) exit_timestamp;
2661 i->pid = (pid_t) pid;
2665 r = sd_bus_message_exit_container(m);
2667 return bus_log_parse_error(r);
2672 typedef struct UnitStatusInfo {
2674 const char *load_state;
2675 const char *active_state;
2676 const char *sub_state;
2677 const char *unit_file_state;
2679 const char *description;
2680 const char *following;
2682 char **documentation;
2684 const char *fragment_path;
2685 const char *source_path;
2686 const char *control_group;
2688 char **dropin_paths;
2690 const char *load_error;
2693 usec_t inactive_exit_timestamp;
2694 usec_t inactive_exit_timestamp_monotonic;
2695 usec_t active_enter_timestamp;
2696 usec_t active_exit_timestamp;
2697 usec_t inactive_enter_timestamp;
2699 bool need_daemon_reload;
2704 const char *status_text;
2705 const char *pid_file;
2708 usec_t start_timestamp;
2709 usec_t exit_timestamp;
2711 int exit_code, exit_status;
2713 usec_t condition_timestamp;
2714 bool condition_result;
2715 bool failed_condition_trigger;
2716 bool failed_condition_negate;
2717 const char *failed_condition;
2718 const char *failed_condition_param;
2721 unsigned n_accepted;
2722 unsigned n_connections;
2725 /* Pairs of type, path */
2729 const char *sysfs_path;
2731 /* Mount, Automount */
2737 LIST_HEAD(ExecStatusInfo, exec);
2740 static void print_status_info(
2745 const char *on, *off, *ss;
2747 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2748 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2751 arg_all * OUTPUT_SHOW_ALL |
2752 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2753 on_tty() * OUTPUT_COLOR |
2754 !arg_quiet * OUTPUT_WARN_CUTOFF |
2755 arg_full * OUTPUT_FULL_WIDTH;
2760 /* This shows pretty information about a unit. See
2761 * print_property() for a low-level property printer */
2763 printf("%s", strna(i->id));
2765 if (i->description && !streq_ptr(i->id, i->description))
2766 printf(" - %s", i->description);
2771 printf(" Follow: unit currently follows state of %s\n", i->following);
2773 if (streq_ptr(i->load_state, "error")) {
2774 on = ansi_highlight_red();
2775 off = ansi_highlight_off();
2779 path = i->source_path ? i->source_path : i->fragment_path;
2782 printf(" Loaded: %s%s%s (Reason: %s)\n",
2783 on, strna(i->load_state), off, i->load_error);
2784 else if (path && i->unit_file_state)
2785 printf(" Loaded: %s%s%s (%s; %s)\n",
2786 on, strna(i->load_state), off, path, i->unit_file_state);
2788 printf(" Loaded: %s%s%s (%s)\n",
2789 on, strna(i->load_state), off, path);
2791 printf(" Loaded: %s%s%s\n",
2792 on, strna(i->load_state), off);
2794 if (!strv_isempty(i->dropin_paths)) {
2795 _cleanup_free_ char *dir = NULL;
2799 STRV_FOREACH(dropin, i->dropin_paths) {
2800 if (! dir || last) {
2801 printf(dir ? " " : " Drop-In: ");
2806 if (path_get_parent(*dropin, &dir) < 0) {
2811 printf("%s\n %s", dir,
2812 draw_special_char(DRAW_TREE_RIGHT));
2815 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2817 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2821 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2823 if (streq_ptr(i->active_state, "failed")) {
2824 on = ansi_highlight_red();
2825 off = ansi_highlight_off();
2826 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2827 on = ansi_highlight_green();
2828 off = ansi_highlight_off();
2833 printf(" Active: %s%s (%s)%s",
2834 on, strna(i->active_state), ss, off);
2836 printf(" Active: %s%s%s",
2837 on, strna(i->active_state), off);
2839 if (!isempty(i->result) && !streq(i->result, "success"))
2840 printf(" (Result: %s)", i->result);
2842 timestamp = (streq_ptr(i->active_state, "active") ||
2843 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2844 (streq_ptr(i->active_state, "inactive") ||
2845 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2846 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2847 i->active_exit_timestamp;
2849 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2850 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2853 printf(" since %s; %s\n", s2, s1);
2855 printf(" since %s\n", s2);
2859 if (!i->condition_result && i->condition_timestamp > 0) {
2860 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2861 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2863 printf(" start condition failed at %s%s%s\n",
2864 s2, s1 ? "; " : "", s1 ? s1 : "");
2865 if (i->failed_condition_trigger)
2866 printf(" none of the trigger conditions were met\n");
2867 else if (i->failed_condition)
2868 printf(" %s=%s%s was not met\n",
2869 i->failed_condition,
2870 i->failed_condition_negate ? "!" : "",
2871 i->failed_condition_param);
2875 printf(" Device: %s\n", i->sysfs_path);
2877 printf(" Where: %s\n", i->where);
2879 printf(" What: %s\n", i->what);
2881 STRV_FOREACH(t, i->documentation)
2882 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2884 STRV_FOREACH_PAIR(t, t2, i->listen)
2885 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2888 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2890 LIST_FOREACH(exec, p, i->exec) {
2891 _cleanup_free_ char *argv = NULL;
2894 /* Only show exited processes here */
2898 argv = strv_join(p->argv, " ");
2899 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2901 good = is_clean_exit_lsb(p->code, p->status, NULL);
2903 on = ansi_highlight_red();
2904 off = ansi_highlight_off();
2908 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2910 if (p->code == CLD_EXITED) {
2913 printf("status=%i", p->status);
2915 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2920 printf("signal=%s", signal_to_string(p->status));
2922 printf(")%s\n", off);
2924 if (i->main_pid == p->pid &&
2925 i->start_timestamp == p->start_timestamp &&
2926 i->exit_timestamp == p->start_timestamp)
2927 /* Let's not show this twice */
2930 if (p->pid == i->control_pid)
2934 if (i->main_pid > 0 || i->control_pid > 0) {
2935 if (i->main_pid > 0) {
2936 printf(" Main PID: %u", (unsigned) i->main_pid);
2939 _cleanup_free_ char *comm = NULL;
2940 get_process_comm(i->main_pid, &comm);
2942 printf(" (%s)", comm);
2943 } else if (i->exit_code > 0) {
2944 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2946 if (i->exit_code == CLD_EXITED) {
2949 printf("status=%i", i->exit_status);
2951 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2956 printf("signal=%s", signal_to_string(i->exit_status));
2960 if (i->control_pid > 0)
2964 if (i->control_pid > 0) {
2965 _cleanup_free_ char *c = NULL;
2967 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2969 get_process_comm(i->control_pid, &c);
2978 printf(" Status: \"%s\"\n", i->status_text);
2980 if (i->control_group &&
2981 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2984 printf(" CGroup: %s\n", i->control_group);
2986 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2989 char prefix[] = " ";
2992 if (c > sizeof(prefix) - 1)
2993 c -= sizeof(prefix) - 1;
2997 if (i->main_pid > 0)
2998 extra[k++] = i->main_pid;
3000 if (i->control_pid > 0)
3001 extra[k++] = i->control_pid;
3003 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
3004 c, false, extra, k, flags);
3008 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3010 show_journal_by_unit(stdout,
3014 i->inactive_exit_timestamp_monotonic,
3018 arg_scope == UNIT_FILE_SYSTEM,
3022 if (i->need_daemon_reload)
3023 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3024 ansi_highlight_red(),
3025 ansi_highlight_off(),
3026 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3029 static void show_unit_help(UnitStatusInfo *i) {
3034 if (!i->documentation) {
3035 log_info("Documentation for %s not known.", i->id);
3039 STRV_FOREACH(p, i->documentation) {
3041 if (startswith(*p, "man:")) {
3042 const char *args[4] = { "man", NULL, NULL, NULL };
3043 _cleanup_free_ char *page = NULL, *section = NULL;
3050 if ((*p)[k-1] == ')')
3051 e = strrchr(*p, '(');
3054 page = strndup((*p) + 4, e - *p - 4);
3055 section = strndup(e + 1, *p + k - e - 2);
3056 if (!page || !section) {
3068 log_error("Failed to fork: %m");
3074 execvp(args[0], (char**) args);
3075 log_error("Failed to execute man: %m");
3076 _exit(EXIT_FAILURE);
3079 wait_for_terminate(pid, NULL);
3081 log_info("Can't show: %s", *p);
3085 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3092 switch (contents[0]) {
3094 case SD_BUS_TYPE_STRING: {
3097 r = sd_bus_message_read(m, "s", &s);
3099 return bus_log_parse_error(r);
3102 if (streq(name, "Id"))
3104 else if (streq(name, "LoadState"))
3106 else if (streq(name, "ActiveState"))
3107 i->active_state = s;
3108 else if (streq(name, "SubState"))
3110 else if (streq(name, "Description"))
3112 else if (streq(name, "FragmentPath"))
3113 i->fragment_path = s;
3114 else if (streq(name, "SourcePath"))
3117 else if (streq(name, "DefaultControlGroup")) {
3119 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3121 i->control_group = e;
3124 else if (streq(name, "ControlGroup"))
3125 i->control_group = s;
3126 else if (streq(name, "StatusText"))
3128 else if (streq(name, "PIDFile"))
3130 else if (streq(name, "SysFSPath"))
3132 else if (streq(name, "Where"))
3134 else if (streq(name, "What"))
3136 else if (streq(name, "Following"))
3138 else if (streq(name, "UnitFileState"))
3139 i->unit_file_state = s;
3140 else if (streq(name, "Result"))
3147 case SD_BUS_TYPE_BOOLEAN: {
3150 r = sd_bus_message_read(m, "b", &b);
3152 return bus_log_parse_error(r);
3154 if (streq(name, "Accept"))
3156 else if (streq(name, "NeedDaemonReload"))
3157 i->need_daemon_reload = b;
3158 else if (streq(name, "ConditionResult"))
3159 i->condition_result = b;
3164 case SD_BUS_TYPE_UINT32: {
3167 r = sd_bus_message_read(m, "u", &u);
3169 return bus_log_parse_error(r);
3171 if (streq(name, "MainPID")) {
3173 i->main_pid = (pid_t) u;
3176 } else if (streq(name, "ControlPID"))
3177 i->control_pid = (pid_t) u;
3178 else if (streq(name, "ExecMainPID")) {
3180 i->main_pid = (pid_t) u;
3181 } else if (streq(name, "NAccepted"))
3183 else if (streq(name, "NConnections"))
3184 i->n_connections = u;
3189 case SD_BUS_TYPE_INT32: {
3192 r = sd_bus_message_read(m, "i", &j);
3194 return bus_log_parse_error(r);
3196 if (streq(name, "ExecMainCode"))
3197 i->exit_code = (int) j;
3198 else if (streq(name, "ExecMainStatus"))
3199 i->exit_status = (int) j;
3204 case SD_BUS_TYPE_UINT64: {
3207 r = sd_bus_message_read(m, "t", &u);
3209 return bus_log_parse_error(r);
3211 if (streq(name, "ExecMainStartTimestamp"))
3212 i->start_timestamp = (usec_t) u;
3213 else if (streq(name, "ExecMainExitTimestamp"))
3214 i->exit_timestamp = (usec_t) u;
3215 else if (streq(name, "ActiveEnterTimestamp"))
3216 i->active_enter_timestamp = (usec_t) u;
3217 else if (streq(name, "InactiveEnterTimestamp"))
3218 i->inactive_enter_timestamp = (usec_t) u;
3219 else if (streq(name, "InactiveExitTimestamp"))
3220 i->inactive_exit_timestamp = (usec_t) u;
3221 else if (streq(name, "InactiveExitTimestampMonotonic"))
3222 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3223 else if (streq(name, "ActiveExitTimestamp"))
3224 i->active_exit_timestamp = (usec_t) u;
3225 else if (streq(name, "ConditionTimestamp"))
3226 i->condition_timestamp = (usec_t) u;
3231 case SD_BUS_TYPE_ARRAY:
3233 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3234 _cleanup_free_ ExecStatusInfo *info = NULL;
3236 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3238 return bus_log_parse_error(r);
3240 info = new0(ExecStatusInfo, 1);
3244 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3246 info->name = strdup(name);
3250 LIST_PREPEND(exec, i->exec, info);
3252 info = new0(ExecStatusInfo, 1);
3258 return bus_log_parse_error(r);
3260 r = sd_bus_message_exit_container(m);
3262 return bus_log_parse_error(r);
3266 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3267 const char *type, *path;
3269 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3271 return bus_log_parse_error(r);
3273 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3275 r = strv_extend(&i->listen, type);
3279 r = strv_extend(&i->listen, path);
3284 return bus_log_parse_error(r);
3286 r = sd_bus_message_exit_container(m);
3288 return bus_log_parse_error(r);
3292 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3294 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3296 return bus_log_parse_error(r);
3298 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3300 r = sd_bus_message_read_strv(m, &i->documentation);
3302 return bus_log_parse_error(r);
3304 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3305 const char *cond, *param;
3306 int trigger, negate;
3309 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3311 return bus_log_parse_error(r);
3313 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3314 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3315 if (state < 0 && (!trigger || !i->failed_condition)) {
3316 i->failed_condition = cond;
3317 i->failed_condition_trigger = trigger;
3318 i->failed_condition_negate = negate;
3319 i->failed_condition_param = param;
3323 return bus_log_parse_error(r);
3325 r = sd_bus_message_exit_container(m);
3327 return bus_log_parse_error(r);
3334 case SD_BUS_TYPE_STRUCT_BEGIN:
3336 if (streq(name, "LoadError")) {
3337 const char *n, *message;
3339 r = sd_bus_message_read(m, "(ss)", &n, &message);
3341 return bus_log_parse_error(r);
3343 if (!isempty(message))
3344 i->load_error = message;
3357 r = sd_bus_message_skip(m, contents);
3359 return bus_log_parse_error(r);
3364 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3370 /* This is a low-level property printer, see
3371 * print_status_info() for the nicer output */
3373 if (arg_properties && !strv_find(arg_properties, name)) {
3374 /* skip what we didn't read */
3375 r = sd_bus_message_skip(m, contents);
3379 switch (contents[0]) {
3381 case SD_BUS_TYPE_STRUCT_BEGIN:
3383 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3386 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3388 return bus_log_parse_error(r);
3391 printf("%s=%u\n", name, (unsigned) u);
3393 printf("%s=\n", name);
3397 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3400 r = sd_bus_message_read(m, "(so)", &s, NULL);
3402 return bus_log_parse_error(r);
3404 if (arg_all || !isempty(s))
3405 printf("%s=%s\n", name, s);
3409 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3410 const char *a = NULL, *b = NULL;
3412 r = sd_bus_message_read(m, "(ss)", &a, &b);
3414 return bus_log_parse_error(r);
3416 if (arg_all || !isempty(a) || !isempty(b))
3417 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3420 } else if (streq_ptr(name, "SystemCallFilter")) {
3421 _cleanup_strv_free_ char **l = NULL;
3424 r = sd_bus_message_enter_container(m, 'r', "bas");
3426 return bus_log_parse_error(r);
3428 r = sd_bus_message_read(m, "b", &whitelist);
3430 return bus_log_parse_error(r);
3432 r = sd_bus_message_read_strv(m, &l);
3434 return bus_log_parse_error(r);
3436 r = sd_bus_message_exit_container(m);
3438 return bus_log_parse_error(r);
3440 if (arg_all || whitelist || !strv_isempty(l)) {
3444 fputs(name, stdout);
3450 STRV_FOREACH(i, l) {
3458 fputc('\n', stdout);
3466 case SD_BUS_TYPE_ARRAY:
3468 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3472 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3474 return bus_log_parse_error(r);
3476 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3477 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3480 return bus_log_parse_error(r);
3482 r = sd_bus_message_exit_container(m);
3484 return bus_log_parse_error(r);
3488 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3489 const char *type, *path;
3491 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3493 return bus_log_parse_error(r);
3495 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3496 printf("%s=%s\n", type, path);
3498 return bus_log_parse_error(r);
3500 r = sd_bus_message_exit_container(m);
3502 return bus_log_parse_error(r);
3506 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3507 const char *type, *path;
3509 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3511 return bus_log_parse_error(r);
3513 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3514 printf("Listen%s=%s\n", type, path);
3516 return bus_log_parse_error(r);
3518 r = sd_bus_message_exit_container(m);
3520 return bus_log_parse_error(r);
3524 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3526 uint64_t value, next_elapse;
3528 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3530 return bus_log_parse_error(r);
3532 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3533 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3535 printf("%s={ value=%s ; next_elapse=%s }\n",
3537 format_timespan(timespan1, sizeof(timespan1), value, 0),
3538 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3541 return bus_log_parse_error(r);
3543 r = sd_bus_message_exit_container(m);
3545 return bus_log_parse_error(r);
3549 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3550 ExecStatusInfo info = {};
3552 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3554 return bus_log_parse_error(r);
3556 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3557 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3558 _cleanup_free_ char *tt;
3560 tt = strv_join(info.argv, " ");
3562 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3566 yes_no(info.ignore),
3567 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3568 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3569 (unsigned) info. pid,
3570 sigchld_code_to_string(info.code),
3572 info.code == CLD_EXITED ? "" : "/",
3573 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3576 strv_free(info.argv);
3580 r = sd_bus_message_exit_container(m);
3582 return bus_log_parse_error(r);
3586 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3587 const char *path, *rwm;
3589 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3591 return bus_log_parse_error(r);
3593 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3594 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3596 return bus_log_parse_error(r);
3598 r = sd_bus_message_exit_container(m);
3600 return bus_log_parse_error(r);
3604 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3608 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3610 return bus_log_parse_error(r);
3612 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3613 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3615 return bus_log_parse_error(r);
3617 r = sd_bus_message_exit_container(m);
3619 return bus_log_parse_error(r);
3623 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3627 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3629 return bus_log_parse_error(r);
3631 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3632 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3634 return bus_log_parse_error(r);
3636 r = sd_bus_message_exit_container(m);
3638 return bus_log_parse_error(r);
3646 r = bus_print_property(name, m, arg_all);
3648 return bus_log_parse_error(r);
3651 r = sd_bus_message_skip(m, contents);
3653 return bus_log_parse_error(r);
3656 printf("%s=[unprintable]\n", name);
3662 static int show_one(
3666 bool show_properties,
3670 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3671 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3672 UnitStatusInfo info = {};
3679 log_debug("Showing one %s", path);
3681 r = sd_bus_call_method(
3683 "org.freedesktop.systemd1",
3685 "org.freedesktop.DBus.Properties",
3691 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3695 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3697 return bus_log_parse_error(r);
3704 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3705 const char *name, *contents;
3707 r = sd_bus_message_read(reply, "s", &name);
3709 return bus_log_parse_error(r);
3711 r = sd_bus_message_peek_type(reply, NULL, &contents);
3713 return bus_log_parse_error(r);
3715 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3717 return bus_log_parse_error(r);
3719 if (show_properties)
3720 r = print_property(name, reply, contents);
3722 r = status_property(name, reply, &info, contents);
3726 r = sd_bus_message_exit_container(reply);
3728 return bus_log_parse_error(r);
3730 r = sd_bus_message_exit_container(reply);
3732 return bus_log_parse_error(r);
3735 return bus_log_parse_error(r);
3737 r = sd_bus_message_exit_container(reply);
3739 return bus_log_parse_error(r);
3743 if (!show_properties) {
3744 if (streq(verb, "help"))
3745 show_unit_help(&info);
3747 print_status_info(&info, ellipsized);
3750 strv_free(info.documentation);
3751 strv_free(info.dropin_paths);
3752 strv_free(info.listen);
3754 if (!streq_ptr(info.active_state, "active") &&
3755 !streq_ptr(info.active_state, "reloading") &&
3756 streq(verb, "status")) {
3757 /* According to LSB: "program not running" */
3758 /* 0: program is running or service is OK
3759 * 1: program is dead and /run PID file exists
3760 * 2: program is dead and /run/lock lock file exists
3761 * 3: program is not running
3762 * 4: program or service status is unknown
3764 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3770 while ((p = info.exec)) {
3771 LIST_REMOVE(exec, info.exec, p);
3772 exec_status_info_free(p);
3778 static int get_unit_dbus_path_by_pid(
3783 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3784 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3788 r = sd_bus_call_method(
3790 "org.freedesktop.systemd1",
3791 "/org/freedesktop/systemd1",
3792 "org.freedesktop.systemd1.Manager",
3798 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3802 r = sd_bus_message_read(reply, "o", &u);
3804 return bus_log_parse_error(r);
3814 static int show_all(
3817 bool show_properties,
3821 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3822 _cleanup_free_ UnitInfo *unit_infos = NULL;
3827 r = get_unit_list(bus, &reply, &unit_infos, NULL);
3831 pager_open_if_enabled();
3835 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3837 for (u = unit_infos; u < unit_infos + c; u++) {
3838 _cleanup_free_ char *p = NULL;
3840 p = unit_dbus_path_from_name(u->id);
3844 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3852 static int cat(sd_bus *bus, char **args) {
3853 _cleanup_free_ char *unit = NULL;
3854 _cleanup_strv_free_ char **names = NULL;
3862 r = expand_names(bus, args + 1, NULL, &names);
3864 log_error("Failed to expand names: %s", strerror(-r));
3866 pager_open_if_enabled();
3868 STRV_FOREACH(name, names) {
3869 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3870 _cleanup_strv_free_ char **dropin_paths = NULL;
3871 _cleanup_free_ char *fragment_path = NULL;
3874 unit = unit_dbus_path_from_name(*name);
3878 if (need_daemon_reload(bus, *name) > 0)
3879 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3880 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3882 r = sd_bus_get_property_string(
3884 "org.freedesktop.systemd1",
3886 "org.freedesktop.systemd1.Unit",
3891 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3895 r = sd_bus_get_property_strv(
3897 "org.freedesktop.systemd1",
3899 "org.freedesktop.systemd1.Unit",
3904 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3913 if (!isempty(fragment_path)) {
3914 printf("%s# %s%s\n",
3915 ansi_highlight_blue(),
3917 ansi_highlight_off());
3920 r = sendfile_full(STDOUT_FILENO, fragment_path);
3922 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3927 STRV_FOREACH(path, dropin_paths) {
3928 printf("%s%s# %s%s\n",
3929 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3930 ansi_highlight_blue(),
3932 ansi_highlight_off());
3935 r = sendfile_full(STDOUT_FILENO, *path);
3937 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3943 return r < 0 ? r : 0;
3946 static int show(sd_bus *bus, char **args) {
3947 bool show_properties, show_status, new_line = false;
3948 bool ellipsized = false;
3954 show_properties = streq(args[0], "show");
3955 show_status = streq(args[0], "status");
3957 if (show_properties)
3958 pager_open_if_enabled();
3960 /* If no argument is specified inspect the manager itself */
3962 if (show_properties && strv_length(args) <= 1)
3963 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3965 if (show_status && strv_length(args) <= 1)
3966 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3968 _cleanup_free_ char **patterns = NULL;
3971 STRV_FOREACH(name, args + 1) {
3972 _cleanup_free_ char *unit = NULL;
3975 if (safe_atou32(*name, &id) < 0) {
3976 if (strv_push(&patterns, *name) < 0)
3980 } else if (show_properties) {
3981 /* Interpret as job id */
3982 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3986 /* Interpret as PID */
3987 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3994 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3997 if (!strv_isempty(patterns)) {
3998 _cleanup_strv_free_ char **names = NULL;
4000 r = expand_names(bus, patterns, NULL, &names);
4002 log_error("Failed to expand names: %s", strerror(-r));
4004 STRV_FOREACH(name, names) {
4005 _cleanup_free_ char *unit;
4007 unit = unit_dbus_path_from_name(*name);
4011 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4016 if (ellipsized && !arg_quiet)
4017 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4022 static int append_assignment(sd_bus_message *m, const char *assignment) {
4030 eq = strchr(assignment, '=');
4032 log_error("Not an assignment: %s", assignment);
4036 field = strndupa(assignment, eq - assignment);
4039 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
4041 return bus_log_create_error(r);
4043 if (streq(field, "CPUAccounting") ||
4044 streq(field, "MemoryAccounting") ||
4045 streq(field, "BlockIOAccounting")) {
4047 r = parse_boolean(eq);
4049 log_error("Failed to parse boolean assignment %s.", assignment);
4053 r = sd_bus_message_append(m, "v", "b", r);
4055 } else if (streq(field, "MemoryLimit")) {
4058 r = parse_size(eq, 1024, &bytes);
4060 log_error("Failed to parse bytes specification %s", assignment);
4064 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
4066 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
4069 r = safe_atou64(eq, &u);
4071 log_error("Failed to parse %s value %s.", field, eq);
4075 r = sd_bus_message_append(m, "v", "t", u);
4077 } else if (streq(field, "DevicePolicy"))
4078 r = sd_bus_message_append(m, "v", "s", eq);
4080 else if (streq(field, "DeviceAllow")) {
4083 r = sd_bus_message_append(m, "v", "a(ss)", 0);
4085 const char *path, *rwm;
4088 e = strchr(eq, ' ');
4090 path = strndupa(eq, e - eq);
4097 if (!path_startswith(path, "/dev")) {
4098 log_error("%s is not a device file in /dev.", path);
4102 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
4105 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
4108 r = sd_bus_message_append(m, "v", "a(st)", 0);
4110 const char *path, *bandwidth;
4114 e = strchr(eq, ' ');
4116 path = strndupa(eq, e - eq);
4119 log_error("Failed to parse %s value %s.", field, eq);
4123 if (!path_startswith(path, "/dev")) {
4124 log_error("%s is not a device file in /dev.", path);
4128 r = parse_size(bandwidth, 1000, &bytes);
4130 log_error("Failed to parse byte value %s.", bandwidth);
4134 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4137 } else if (streq(field, "BlockIODeviceWeight")) {
4140 r = sd_bus_message_append(m, "v", "a(st)", 0);
4142 const char *path, *weight;
4146 e = strchr(eq, ' ');
4148 path = strndupa(eq, e - eq);
4151 log_error("Failed to parse %s value %s.", field, eq);
4155 if (!path_startswith(path, "/dev")) {
4156 log_error("%s is not a device file in /dev.", path);
4160 r = safe_atou64(weight, &u);
4162 log_error("Failed to parse %s value %s.", field, weight);
4165 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4169 log_error("Unknown assignment %s.", assignment);
4174 return bus_log_create_error(r);
4179 static int set_property(sd_bus *bus, char **args) {
4180 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4181 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4182 _cleanup_free_ char *n = NULL;
4186 r = sd_bus_message_new_method_call(
4189 "org.freedesktop.systemd1",
4190 "/org/freedesktop/systemd1",
4191 "org.freedesktop.systemd1.Manager",
4192 "SetUnitProperties");
4194 return bus_log_create_error(r);
4196 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4200 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4202 return bus_log_create_error(r);
4204 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4206 return bus_log_create_error(r);
4208 STRV_FOREACH(i, args + 2) {
4209 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4211 return bus_log_create_error(r);
4213 r = append_assignment(m, *i);
4217 r = sd_bus_message_close_container(m);
4219 return bus_log_create_error(r);
4222 r = sd_bus_message_close_container(m);
4224 return bus_log_create_error(r);
4226 r = sd_bus_call(bus, m, 0, &error, NULL);
4228 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4235 static int snapshot(sd_bus *bus, char **args) {
4236 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4237 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4238 _cleanup_free_ char *n = NULL, *id = NULL;
4242 if (strv_length(args) > 1)
4243 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4249 r = sd_bus_call_method(
4251 "org.freedesktop.systemd1",
4252 "/org/freedesktop/systemd1",
4253 "org.freedesktop.systemd1.Manager",
4259 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4263 r = sd_bus_message_read(reply, "o", &path);
4265 return bus_log_parse_error(r);
4267 r = sd_bus_get_property_string(
4269 "org.freedesktop.systemd1",
4271 "org.freedesktop.systemd1.Unit",
4276 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4286 static int delete_snapshot(sd_bus *bus, char **args) {
4287 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4288 _cleanup_strv_free_ char **names = NULL;
4294 r = expand_names(bus, args + 1, ".snapshot", &names);
4296 log_error("Failed to expand names: %s", strerror(-r));
4298 STRV_FOREACH(name, names) {
4299 q = sd_bus_call_method(
4301 "org.freedesktop.systemd1",
4302 "/org/freedesktop/systemd1",
4303 "org.freedesktop.systemd1.Manager",
4309 log_error("Failed to remove snapshot %s: %s",
4310 *name, bus_error_message(&error, r));
4319 static int daemon_reload(sd_bus *bus, char **args) {
4320 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4324 if (arg_action == ACTION_RELOAD)
4326 else if (arg_action == ACTION_REEXEC)
4327 method = "Reexecute";
4329 assert(arg_action == ACTION_SYSTEMCTL);
4332 streq(args[0], "clear-jobs") ||
4333 streq(args[0], "cancel") ? "ClearJobs" :
4334 streq(args[0], "daemon-reexec") ? "Reexecute" :
4335 streq(args[0], "reset-failed") ? "ResetFailed" :
4336 streq(args[0], "halt") ? "Halt" :
4337 streq(args[0], "poweroff") ? "PowerOff" :
4338 streq(args[0], "reboot") ? "Reboot" :
4339 streq(args[0], "kexec") ? "KExec" :
4340 streq(args[0], "exit") ? "Exit" :
4341 /* "daemon-reload" */ "Reload";
4344 r = sd_bus_call_method(
4346 "org.freedesktop.systemd1",
4347 "/org/freedesktop/systemd1",
4348 "org.freedesktop.systemd1.Manager",
4354 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4355 /* There's always a fallback possible for
4356 * legacy actions. */
4358 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4359 /* On reexecution, we expect a disconnect, not a
4363 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4365 return r < 0 ? r : 0;
4368 static int reset_failed(sd_bus *bus, char **args) {
4369 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4370 _cleanup_strv_free_ char **names = NULL;
4374 if (strv_length(args) <= 1)
4375 return daemon_reload(bus, args);
4377 r = expand_names(bus, args + 1, NULL, &names);
4379 log_error("Failed to expand names: %s", strerror(-r));
4381 STRV_FOREACH(name, names) {
4382 q = sd_bus_call_method(
4384 "org.freedesktop.systemd1",
4385 "/org/freedesktop/systemd1",
4386 "org.freedesktop.systemd1.Manager",
4392 log_error("Failed to reset failed state of unit %s: %s",
4393 *name, bus_error_message(&error, r));
4402 static int show_environment(sd_bus *bus, char **args) {
4403 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4404 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4408 pager_open_if_enabled();
4410 r = sd_bus_get_property(
4412 "org.freedesktop.systemd1",
4413 "/org/freedesktop/systemd1",
4414 "org.freedesktop.systemd1.Manager",
4420 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4424 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4426 return bus_log_parse_error(r);
4428 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4431 return bus_log_parse_error(r);
4433 r = sd_bus_message_exit_container(reply);
4435 return bus_log_parse_error(r);
4440 static int switch_root(sd_bus *bus, char **args) {
4441 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4442 _cleanup_free_ char *init = NULL;
4447 l = strv_length(args);
4448 if (l < 2 || l > 3) {
4449 log_error("Wrong number of arguments.");
4456 init = strdup(args[2]);
4458 parse_env_file("/proc/cmdline", WHITESPACE,
4469 log_debug("switching root - root: %s; init: %s", root, init);
4471 r = sd_bus_call_method(
4473 "org.freedesktop.systemd1",
4474 "/org/freedesktop/systemd1",
4475 "org.freedesktop.systemd1.Manager",
4481 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4488 static int set_environment(sd_bus *bus, char **args) {
4489 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4490 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4497 method = streq(args[0], "set-environment")
4499 : "UnsetEnvironment";
4501 r = sd_bus_message_new_method_call(
4504 "org.freedesktop.systemd1",
4505 "/org/freedesktop/systemd1",
4506 "org.freedesktop.systemd1.Manager",
4509 return bus_log_create_error(r);
4511 r = sd_bus_message_append_strv(m, args + 1);
4513 return bus_log_create_error(r);
4515 r = sd_bus_call(bus, m, 0, &error, NULL);
4517 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4524 static int import_environment(sd_bus *bus, char **args) {
4525 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4526 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4532 r = sd_bus_message_new_method_call(
4535 "org.freedesktop.systemd1",
4536 "/org/freedesktop/systemd1",
4537 "org.freedesktop.systemd1.Manager",
4540 return bus_log_create_error(r);
4542 if (strv_isempty(args + 1))
4543 r = sd_bus_message_append_strv(m, environ);
4547 r = sd_bus_message_open_container(m, 'a', "s");
4549 return bus_log_create_error(r);
4551 STRV_FOREACH(a, args + 1) {
4553 if (!env_name_is_valid(*a)) {
4554 log_error("Not a valid environment variable name: %s", *a);
4558 STRV_FOREACH(b, environ) {
4561 eq = startswith(*b, *a);
4562 if (eq && *eq == '=') {
4564 r = sd_bus_message_append(m, "s", *b);
4566 return bus_log_create_error(r);
4573 r = sd_bus_message_close_container(m);
4576 return bus_log_create_error(r);
4578 r = sd_bus_call(bus, m, 0, &error, NULL);
4580 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4587 static int enable_sysv_units(const char *verb, char **args) {
4590 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4591 unsigned f = 1, t = 1;
4592 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4594 if (arg_scope != UNIT_FILE_SYSTEM)
4597 if (!streq(verb, "enable") &&
4598 !streq(verb, "disable") &&
4599 !streq(verb, "is-enabled"))
4602 /* Processes all SysV units, and reshuffles the array so that
4603 * afterwards only the native units remain */
4605 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4610 for (f = 0; args[f]; f++) {
4612 _cleanup_free_ char *p = NULL, *q = NULL;
4613 bool found_native = false, found_sysv;
4615 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4623 if (!endswith(name, ".service"))
4626 if (path_is_absolute(name))
4629 STRV_FOREACH(k, paths.unit_path) {
4630 if (!isempty(arg_root))
4631 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4633 asprintf(&p, "%s/%s", *k, name);
4640 found_native = access(p, F_OK) >= 0;
4651 if (!isempty(arg_root))
4652 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4654 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4660 p[strlen(p) - sizeof(".service") + 1] = 0;
4661 found_sysv = access(p, F_OK) >= 0;
4666 /* Mark this entry, so that we don't try enabling it as native unit */
4667 args[f] = (char*) "";
4669 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4671 if (!isempty(arg_root))
4672 argv[c++] = q = strappend("--root=", arg_root);
4674 argv[c++] = basename(p);
4676 streq(verb, "enable") ? "on" :
4677 streq(verb, "disable") ? "off" : "--level=5";
4680 l = strv_join((char**)argv, " ");
4686 log_info("Executing %s", l);
4691 log_error("Failed to fork: %m");
4694 } else if (pid == 0) {
4697 execv(argv[0], (char**) argv);
4698 _exit(EXIT_FAILURE);
4701 j = wait_for_terminate(pid, &status);
4703 log_error("Failed to wait for child: %s", strerror(-r));
4708 if (status.si_code == CLD_EXITED) {
4709 if (streq(verb, "is-enabled")) {
4710 if (status.si_status == 0) {
4719 } else if (status.si_status != 0) {
4730 /* Drop all SysV units */
4731 for (f = 0, t = 0; args[f]; f++) {
4733 if (isempty(args[f]))
4736 args[t++] = args[f];
4745 static int mangle_names(char **original_names, char ***mangled_names) {
4746 char **i, **l, **name;
4748 l = new(char*, strv_length(original_names) + 1);
4753 STRV_FOREACH(name, original_names) {
4755 /* When enabling units qualified path names are OK,
4756 * too, hence allow them explicitly. */
4761 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4777 static int enable_unit(sd_bus *bus, char **args) {
4778 _cleanup_strv_free_ char **names = NULL;
4779 const char *verb = args[0];
4780 UnitFileChange *changes = NULL;
4781 unsigned n_changes = 0;
4782 int carries_install_info = -1;
4788 r = mangle_names(args+1, &names);
4792 r = enable_sysv_units(verb, names);
4796 /* If the operation was fully executed by the SysV compat,
4797 * let's finish early */
4798 if (strv_isempty(names))
4801 if (!bus || avoid_bus()) {
4802 if (streq(verb, "enable")) {
4803 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4804 carries_install_info = r;
4805 } else if (streq(verb, "disable"))
4806 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4807 else if (streq(verb, "reenable")) {
4808 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4809 carries_install_info = r;
4810 } else if (streq(verb, "link"))
4811 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4812 else if (streq(verb, "preset")) {
4813 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4814 carries_install_info = r;
4815 } else if (streq(verb, "mask"))
4816 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4817 else if (streq(verb, "unmask"))
4818 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4820 assert_not_reached("Unknown verb");
4823 log_error("Operation failed: %s", strerror(-r));
4828 dump_unit_file_changes(changes, n_changes);
4832 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4833 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4834 int expect_carries_install_info = false;
4835 bool send_force = true;
4838 if (streq(verb, "enable")) {
4839 method = "EnableUnitFiles";
4840 expect_carries_install_info = true;
4841 } else if (streq(verb, "disable")) {
4842 method = "DisableUnitFiles";
4844 } else if (streq(verb, "reenable")) {
4845 method = "ReenableUnitFiles";
4846 expect_carries_install_info = true;
4847 } else if (streq(verb, "link"))
4848 method = "LinkUnitFiles";
4849 else if (streq(verb, "preset")) {
4850 method = "PresetUnitFiles";
4851 expect_carries_install_info = true;
4852 } else if (streq(verb, "mask"))
4853 method = "MaskUnitFiles";
4854 else if (streq(verb, "unmask")) {
4855 method = "UnmaskUnitFiles";
4858 assert_not_reached("Unknown verb");
4860 r = sd_bus_message_new_method_call(
4863 "org.freedesktop.systemd1",
4864 "/org/freedesktop/systemd1",
4865 "org.freedesktop.systemd1.Manager",
4868 return bus_log_create_error(r);
4870 r = sd_bus_message_append_strv(m, names);
4872 return bus_log_create_error(r);
4874 r = sd_bus_message_append(m, "b", arg_runtime);
4876 return bus_log_create_error(r);
4879 r = sd_bus_message_append(m, "b", arg_force);
4881 return bus_log_create_error(r);
4884 r = sd_bus_call(bus, m, 0, &error, &reply);
4886 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4890 if (expect_carries_install_info) {
4891 r = sd_bus_message_read(reply, "b", &carries_install_info);
4893 return bus_log_parse_error(r);
4896 r = deserialize_and_dump_unit_file_changes(reply);
4900 /* Try to reload if enabeld */
4902 r = daemon_reload(bus, args);
4907 if (carries_install_info == 0)
4908 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4909 "using systemctl.\n"
4910 "Possible reasons for having this kind of units are:\n"
4911 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4912 " .wants/ or .requires/ directory.\n"
4913 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4914 " a requirement dependency on it.\n"
4915 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4916 " D-Bus, udev, scripted systemctl call, ...).\n");
4919 unit_file_changes_free(changes, n_changes);
4924 static int unit_is_enabled(sd_bus *bus, char **args) {
4926 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4927 _cleanup_strv_free_ char **names = NULL;
4932 r = mangle_names(args+1, &names);
4936 r = enable_sysv_units(args[0], names);
4942 if (!bus || avoid_bus()) {
4944 STRV_FOREACH(name, names) {
4945 UnitFileState state;
4947 state = unit_file_get_state(arg_scope, arg_root, *name);
4949 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4953 if (state == UNIT_FILE_ENABLED ||
4954 state == UNIT_FILE_ENABLED_RUNTIME ||
4955 state == UNIT_FILE_STATIC)
4959 puts(unit_file_state_to_string(state));
4963 STRV_FOREACH(name, names) {
4964 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4967 r = sd_bus_call_method(
4969 "org.freedesktop.systemd1",
4970 "/org/freedesktop/systemd1",
4971 "org.freedesktop.systemd1.Manager",
4977 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4981 r = sd_bus_message_read(reply, "s", &s);
4983 return bus_log_parse_error(r);
4985 if (streq(s, "enabled") ||
4986 streq(s, "enabled-runtime") ||
4998 static int systemctl_help(void) {
5000 pager_open_if_enabled();
5002 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5003 "Query or send control commands to the systemd manager.\n\n"
5004 " -h --help Show this help\n"
5005 " --version Show package version\n"
5006 " --system Connect to system manager\n"
5007 " --user Connect to user service manager\n"
5008 " -H --host=[USER@]HOST\n"
5009 " Operate on remote host\n"
5010 " -M --machine=CONTAINER\n"
5011 " Operate on local container\n"
5012 " -t --type=TYPE List only units of a particular type\n"
5013 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5014 " -p --property=NAME Show only properties by this name\n"
5015 " -a --all Show all loaded units/properties, including dead/empty\n"
5016 " ones. To list all units installed on the system, use\n"
5017 " the 'list-unit-files' command instead.\n"
5018 " -l --full Don't ellipsize unit names on output\n"
5019 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5020 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5021 " queueing a new job\n"
5022 " --show-types When showing sockets, explicitly show their type\n"
5023 " -i --ignore-inhibitors\n"
5024 " When shutting down or sleeping, ignore inhibitors\n"
5025 " --kill-who=WHO Who to send signal to\n"
5026 " -s --signal=SIGNAL Which signal to send\n"
5027 " -q --quiet Suppress output\n"
5028 " --no-block Do not wait until operation finished\n"
5029 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5030 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5032 " --no-legend Do not print a legend (column headers and hints)\n"
5033 " --no-pager Do not pipe output into a pager\n"
5034 " --no-ask-password\n"
5035 " Do not ask for system passwords\n"
5036 " --global Enable/disable unit files globally\n"
5037 " --runtime Enable unit files only temporarily until next reboot\n"
5038 " -f --force When enabling unit files, override existing symlinks\n"
5039 " When shutting down, execute action immediately\n"
5040 " --root=PATH Enable unit files in the specified root directory\n"
5041 " -n --lines=INTEGER Number of journal entries to show\n"
5042 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5043 " verbose, export, json, json-pretty, json-sse, cat)\n"
5044 " --plain Print unit dependencies as a list instead of a tree\n\n"
5046 " list-units [PATTERN...] List loaded units\n"
5047 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5048 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5049 " start NAME... Start (activate) one or more units\n"
5050 " stop NAME... Stop (deactivate) one or more units\n"
5051 " reload NAME... Reload one or more units\n"
5052 " restart NAME... Start or restart one or more units\n"
5053 " try-restart NAME... Restart one or more units if active\n"
5054 " reload-or-restart NAME... Reload one or more units if possible,\n"
5055 " otherwise start or restart\n"
5056 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5057 " otherwise restart if active\n"
5058 " isolate NAME Start one unit and stop all others\n"
5059 " kill NAME... Send signal to processes of a unit\n"
5060 " is-active NAME... Check whether units are active\n"
5061 " is-failed NAME... Check whether units are failed\n"
5062 " status [NAME...|PID...] Show runtime status of one or more units\n"
5063 " show [NAME...|JOB...] Show properties of one or more\n"
5064 " units/jobs or the manager\n"
5065 " cat NAME... Show files and drop-ins of one or more units\n"
5066 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5067 " help NAME...|PID... Show manual for one or more units\n"
5068 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
5070 " list-dependencies [NAME] Recursively show units which are required\n"
5071 " or wanted by this unit or by which this\n"
5072 " unit is required or wanted\n\n"
5073 "Unit File Commands:\n"
5074 " list-unit-files [PATTERN...] List installed unit files\n"
5075 " enable NAME... Enable one or more unit files\n"
5076 " disable NAME... Disable one or more unit files\n"
5077 " reenable NAME... Reenable one or more unit files\n"
5078 " preset NAME... Enable/disable one or more unit files\n"
5079 " based on preset configuration\n"
5080 " is-enabled NAME... Check whether unit files are enabled\n\n"
5081 " mask NAME... Mask one or more units\n"
5082 " unmask NAME... Unmask one or more units\n"
5083 " link PATH... Link one or more units files into\n"
5084 " the search path\n"
5085 " get-default Get the name of the default target\n"
5086 " set-default NAME Set the default target\n\n"
5088 " list-jobs [PATTERN...] List jobs\n"
5089 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5090 "Snapshot Commands:\n"
5091 " snapshot [NAME] Create a snapshot\n"
5092 " delete NAME... Remove one or more snapshots\n\n"
5093 "Environment Commands:\n"
5094 " show-environment Dump environment\n"
5095 " set-environment NAME=VALUE... Set one or more environment variables\n"
5096 " unset-environment NAME... Unset one or more environment variables\n"
5097 " import-environment NAME... Import all, one or more environment variables\n\n"
5098 "Manager Lifecycle Commands:\n"
5099 " daemon-reload Reload systemd manager configuration\n"
5100 " daemon-reexec Reexecute systemd manager\n\n"
5101 "System Commands:\n"
5102 " default Enter system default mode\n"
5103 " rescue Enter system rescue mode\n"
5104 " emergency Enter system emergency mode\n"
5105 " halt Shut down and halt the system\n"
5106 " poweroff Shut down and power-off the system\n"
5107 " reboot [ARG] Shut down and reboot the system\n"
5108 " kexec Shut down and reboot the system with kexec\n"
5109 " exit Request user instance exit\n"
5110 " switch-root ROOT [INIT] Change to a different root file system\n"
5111 " suspend Suspend the system\n"
5112 " hibernate Hibernate the system\n"
5113 " hybrid-sleep Hibernate and suspend the system\n",
5114 program_invocation_short_name);
5119 static int halt_help(void) {
5121 printf("%s [OPTIONS...]%s\n\n"
5122 "%s the system.\n\n"
5123 " --help Show this help\n"
5124 " --halt Halt the machine\n"
5125 " -p --poweroff Switch off the machine\n"
5126 " --reboot Reboot the machine\n"
5127 " -f --force Force immediate halt/power-off/reboot\n"
5128 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5129 " -d --no-wtmp Don't write wtmp record\n"
5130 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5131 program_invocation_short_name,
5132 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5133 arg_action == ACTION_REBOOT ? "Reboot" :
5134 arg_action == ACTION_POWEROFF ? "Power off" :
5140 static int shutdown_help(void) {
5142 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5143 "Shut down the system.\n\n"
5144 " --help Show this help\n"
5145 " -H --halt Halt the machine\n"
5146 " -P --poweroff Power-off the machine\n"
5147 " -r --reboot Reboot the machine\n"
5148 " -h Equivalent to --poweroff, overridden by --halt\n"
5149 " -k Don't halt/power-off/reboot, just send warnings\n"
5150 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5151 " -c Cancel a pending shutdown\n",
5152 program_invocation_short_name);
5157 static int telinit_help(void) {
5159 printf("%s [OPTIONS...] {COMMAND}\n\n"
5160 "Send control commands to the init daemon.\n\n"
5161 " --help Show this help\n"
5162 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5164 " 0 Power-off the machine\n"
5165 " 6 Reboot the machine\n"
5166 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5167 " 1, s, S Enter rescue mode\n"
5168 " q, Q Reload init daemon configuration\n"
5169 " u, U Reexecute init daemon\n",
5170 program_invocation_short_name);
5175 static int runlevel_help(void) {
5177 printf("%s [OPTIONS...]\n\n"
5178 "Prints the previous and current runlevel of the init system.\n\n"
5179 " --help Show this help\n",
5180 program_invocation_short_name);
5185 static int help_types(void) {
5189 puts("Available unit types:");
5190 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5191 t = unit_type_to_string(i);
5199 static int systemctl_parse_argv(int argc, char *argv[]) {
5208 ARG_IGNORE_DEPENDENCIES,
5220 ARG_NO_ASK_PASSWORD,
5229 static const struct option options[] = {
5230 { "help", no_argument, NULL, 'h' },
5231 { "version", no_argument, NULL, ARG_VERSION },
5232 { "type", required_argument, NULL, 't' },
5233 { "property", required_argument, NULL, 'p' },
5234 { "all", no_argument, NULL, 'a' },
5235 { "reverse", no_argument, NULL, ARG_REVERSE },
5236 { "after", no_argument, NULL, ARG_AFTER },
5237 { "before", no_argument, NULL, ARG_BEFORE },
5238 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5239 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5240 { "full", no_argument, NULL, 'l' },
5241 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5242 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5243 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5244 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5245 { "ignore-inhibitors", no_argument, NULL, 'i' },
5246 { "user", no_argument, NULL, ARG_USER },
5247 { "system", no_argument, NULL, ARG_SYSTEM },
5248 { "global", no_argument, NULL, ARG_GLOBAL },
5249 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5250 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5251 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5252 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5253 { "quiet", no_argument, NULL, 'q' },
5254 { "root", required_argument, NULL, ARG_ROOT },
5255 { "force", no_argument, NULL, ARG_FORCE },
5256 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5257 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5258 { "signal", required_argument, NULL, 's' },
5259 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5260 { "host", required_argument, NULL, 'H' },
5261 { "machine", required_argument, NULL, 'M' },
5262 { "runtime", no_argument, NULL, ARG_RUNTIME },
5263 { "lines", required_argument, NULL, 'n' },
5264 { "output", required_argument, NULL, 'o' },
5265 { "plain", no_argument, NULL, ARG_PLAIN },
5266 { "state", required_argument, NULL, ARG_STATE },
5275 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5280 return systemctl_help();
5283 puts(PACKAGE_STRING);
5284 puts(SYSTEMD_FEATURES);
5291 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5292 _cleanup_free_ char *type;
5294 type = strndup(word, size);
5298 if (streq(type, "help")) {
5303 if (unit_type_from_string(type) >= 0) {
5304 if (strv_push(&arg_types, type))
5310 /* It's much nicer to use --state= for
5311 * load states, but let's support this
5312 * in --types= too for compatibility
5313 * with old versions */
5314 if (unit_load_state_from_string(optarg) >= 0) {
5315 if (strv_push(&arg_states, type) < 0)
5321 log_error("Unknown unit type or load state '%s'.", type);
5322 log_info("Use -t help to see a list of allowed values.");
5330 /* Make sure that if the empty property list
5331 was specified, we won't show any properties. */
5332 if (isempty(optarg) && !arg_properties) {
5333 arg_properties = new0(char*, 1);
5334 if (!arg_properties)
5340 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5343 prop = strndup(word, size);
5347 if (strv_consume(&arg_properties, prop) < 0)
5352 /* If the user asked for a particular
5353 * property, show it to him, even if it is
5365 arg_dependency = DEPENDENCY_REVERSE;
5369 arg_dependency = DEPENDENCY_AFTER;
5373 arg_dependency = DEPENDENCY_BEFORE;
5376 case ARG_SHOW_TYPES:
5377 arg_show_types = true;
5381 arg_job_mode = optarg;
5385 arg_job_mode = "fail";
5388 case ARG_IRREVERSIBLE:
5389 arg_job_mode = "replace-irreversibly";
5392 case ARG_IGNORE_DEPENDENCIES:
5393 arg_job_mode = "ignore-dependencies";
5397 arg_scope = UNIT_FILE_USER;
5401 arg_scope = UNIT_FILE_SYSTEM;
5405 arg_scope = UNIT_FILE_GLOBAL;
5409 arg_no_block = true;
5413 arg_no_legend = true;
5417 arg_no_pager = true;
5433 if (strv_extend(&arg_states, "failed") < 0)
5451 arg_no_reload = true;
5455 arg_kill_who = optarg;
5459 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5460 log_error("Failed to parse signal string %s.", optarg);
5465 case ARG_NO_ASK_PASSWORD:
5466 arg_ask_password = false;
5470 arg_transport = BUS_TRANSPORT_REMOTE;
5475 arg_transport = BUS_TRANSPORT_CONTAINER;
5484 if (safe_atou(optarg, &arg_lines) < 0) {
5485 log_error("Failed to parse lines '%s'", optarg);
5491 arg_output = output_mode_from_string(optarg);
5492 if (arg_output < 0) {
5493 log_error("Unknown output '%s'.", optarg);
5499 arg_ignore_inhibitors = true;
5510 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5513 s = strndup(word, size);
5517 if (strv_consume(&arg_states, s) < 0)
5527 assert_not_reached("Unhandled option");
5531 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5532 log_error("Cannot access user instance remotely.");
5539 static int halt_parse_argv(int argc, char *argv[]) {
5548 static const struct option options[] = {
5549 { "help", no_argument, NULL, ARG_HELP },
5550 { "halt", no_argument, NULL, ARG_HALT },
5551 { "poweroff", no_argument, NULL, 'p' },
5552 { "reboot", no_argument, NULL, ARG_REBOOT },
5553 { "force", no_argument, NULL, 'f' },
5554 { "wtmp-only", no_argument, NULL, 'w' },
5555 { "no-wtmp", no_argument, NULL, 'd' },
5556 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5565 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5566 if (runlevel == '0' || runlevel == '6')
5569 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5576 arg_action = ACTION_HALT;
5580 if (arg_action != ACTION_REBOOT)
5581 arg_action = ACTION_POWEROFF;
5585 arg_action = ACTION_REBOOT;
5607 /* Compatibility nops */
5614 assert_not_reached("Unhandled option");
5618 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5619 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5621 log_error("Failed to write reboot param to "
5622 REBOOT_PARAM_FILE": %s", strerror(-r));
5625 } else if (optind < argc) {
5626 log_error("Too many arguments.");
5633 static int parse_time_spec(const char *t, usec_t *_u) {
5637 if (streq(t, "now"))
5639 else if (!strchr(t, ':')) {
5642 if (safe_atou64(t, &u) < 0)
5645 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5654 hour = strtol(t, &e, 10);
5655 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5658 minute = strtol(e+1, &e, 10);
5659 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5662 n = now(CLOCK_REALTIME);
5663 s = (time_t) (n / USEC_PER_SEC);
5665 assert_se(localtime_r(&s, &tm));
5667 tm.tm_hour = (int) hour;
5668 tm.tm_min = (int) minute;
5671 assert_se(s = mktime(&tm));
5673 *_u = (usec_t) s * USEC_PER_SEC;
5676 *_u += USEC_PER_DAY;
5682 static int shutdown_parse_argv(int argc, char *argv[]) {
5689 static const struct option options[] = {
5690 { "help", no_argument, NULL, ARG_HELP },
5691 { "halt", no_argument, NULL, 'H' },
5692 { "poweroff", no_argument, NULL, 'P' },
5693 { "reboot", no_argument, NULL, 'r' },
5694 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5695 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5704 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5708 return shutdown_help();
5711 arg_action = ACTION_HALT;
5715 arg_action = ACTION_POWEROFF;
5720 arg_action = ACTION_KEXEC;
5722 arg_action = ACTION_REBOOT;
5726 arg_action = ACTION_KEXEC;
5730 if (arg_action != ACTION_HALT)
5731 arg_action = ACTION_POWEROFF;
5744 /* Compatibility nops */
5748 arg_action = ACTION_CANCEL_SHUTDOWN;
5755 assert_not_reached("Unhandled option");
5759 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5760 r = parse_time_spec(argv[optind], &arg_when);
5762 log_error("Failed to parse time specification: %s", argv[optind]);
5766 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5768 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5769 /* No time argument for shutdown cancel */
5770 arg_wall = argv + optind;
5771 else if (argc > optind + 1)
5772 /* We skip the time argument */
5773 arg_wall = argv + optind + 1;
5780 static int telinit_parse_argv(int argc, char *argv[]) {
5787 static const struct option options[] = {
5788 { "help", no_argument, NULL, ARG_HELP },
5789 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5793 static const struct {
5797 { '0', ACTION_POWEROFF },
5798 { '6', ACTION_REBOOT },
5799 { '1', ACTION_RESCUE },
5800 { '2', ACTION_RUNLEVEL2 },
5801 { '3', ACTION_RUNLEVEL3 },
5802 { '4', ACTION_RUNLEVEL4 },
5803 { '5', ACTION_RUNLEVEL5 },
5804 { 's', ACTION_RESCUE },
5805 { 'S', ACTION_RESCUE },
5806 { 'q', ACTION_RELOAD },
5807 { 'Q', ACTION_RELOAD },
5808 { 'u', ACTION_REEXEC },
5809 { 'U', ACTION_REEXEC }
5818 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5822 return telinit_help();
5832 assert_not_reached("Unhandled option");
5836 if (optind >= argc) {
5841 if (optind + 1 < argc) {
5842 log_error("Too many arguments.");
5846 if (strlen(argv[optind]) != 1) {
5847 log_error("Expected single character argument.");
5851 for (i = 0; i < ELEMENTSOF(table); i++)
5852 if (table[i].from == argv[optind][0])
5855 if (i >= ELEMENTSOF(table)) {
5856 log_error("Unknown command '%s'.", argv[optind]);
5860 arg_action = table[i].to;
5867 static int runlevel_parse_argv(int argc, char *argv[]) {
5873 static const struct option options[] = {
5874 { "help", no_argument, NULL, ARG_HELP },
5883 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5887 return runlevel_help();
5893 assert_not_reached("Unhandled option");
5897 if (optind < argc) {
5898 log_error("Too many arguments.");
5905 static int parse_argv(int argc, char *argv[]) {
5909 if (program_invocation_short_name) {
5911 if (strstr(program_invocation_short_name, "halt")) {
5912 arg_action = ACTION_HALT;
5913 return halt_parse_argv(argc, argv);
5914 } else if (strstr(program_invocation_short_name, "poweroff")) {
5915 arg_action = ACTION_POWEROFF;
5916 return halt_parse_argv(argc, argv);
5917 } else if (strstr(program_invocation_short_name, "reboot")) {
5919 arg_action = ACTION_KEXEC;
5921 arg_action = ACTION_REBOOT;
5922 return halt_parse_argv(argc, argv);
5923 } else if (strstr(program_invocation_short_name, "shutdown")) {
5924 arg_action = ACTION_POWEROFF;
5925 return shutdown_parse_argv(argc, argv);
5926 } else if (strstr(program_invocation_short_name, "init")) {
5928 if (sd_booted() > 0) {
5929 arg_action = _ACTION_INVALID;
5930 return telinit_parse_argv(argc, argv);
5932 /* Hmm, so some other init system is
5933 * running, we need to forward this
5934 * request to it. For now we simply
5935 * guess that it is Upstart. */
5937 execv(TELINIT, argv);
5939 log_error("Couldn't find an alternative telinit implementation to spawn.");
5943 } else if (strstr(program_invocation_short_name, "runlevel")) {
5944 arg_action = ACTION_RUNLEVEL;
5945 return runlevel_parse_argv(argc, argv);
5949 arg_action = ACTION_SYSTEMCTL;
5950 return systemctl_parse_argv(argc, argv);
5953 _pure_ static int action_to_runlevel(void) {
5955 static const char table[_ACTION_MAX] = {
5956 [ACTION_HALT] = '0',
5957 [ACTION_POWEROFF] = '0',
5958 [ACTION_REBOOT] = '6',
5959 [ACTION_RUNLEVEL2] = '2',
5960 [ACTION_RUNLEVEL3] = '3',
5961 [ACTION_RUNLEVEL4] = '4',
5962 [ACTION_RUNLEVEL5] = '5',
5963 [ACTION_RESCUE] = '1'
5966 assert(arg_action < _ACTION_MAX);
5968 return table[arg_action];
5971 static int talk_initctl(void) {
5973 struct init_request request = {
5974 .magic = INIT_MAGIC,
5976 .cmd = INIT_CMD_RUNLVL
5979 _cleanup_close_ int fd = -1;
5983 rl = action_to_runlevel();
5987 request.runlevel = rl;
5989 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5991 if (errno == ENOENT)
5994 log_error("Failed to open "INIT_FIFO": %m");
5999 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6001 log_error("Failed to write to "INIT_FIFO": %m");
6002 return errno > 0 ? -errno : -EIO;
6008 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6010 static const struct {
6018 int (* const dispatch)(sd_bus *bus, char **args);
6024 { "list-units", MORE, 0, list_units },
6025 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6026 { "list-sockets", MORE, 1, list_sockets },
6027 { "list-timers", MORE, 1, list_timers },
6028 { "list-jobs", MORE, 1, list_jobs },
6029 { "clear-jobs", EQUAL, 1, daemon_reload },
6030 { "cancel", MORE, 2, cancel_job },
6031 { "start", MORE, 2, start_unit },
6032 { "stop", MORE, 2, start_unit },
6033 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6034 { "reload", MORE, 2, start_unit },
6035 { "restart", MORE, 2, start_unit },
6036 { "try-restart", MORE, 2, start_unit },
6037 { "reload-or-restart", MORE, 2, start_unit },
6038 { "reload-or-try-restart", MORE, 2, start_unit },
6039 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6040 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6041 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6042 { "isolate", EQUAL, 2, start_unit },
6043 { "kill", MORE, 2, kill_unit },
6044 { "is-active", MORE, 2, check_unit_active },
6045 { "check", MORE, 2, check_unit_active },
6046 { "is-failed", MORE, 2, check_unit_failed },
6047 { "show", MORE, 1, show },
6048 { "cat", MORE, 2, cat },
6049 { "status", MORE, 1, show },
6050 { "help", MORE, 2, show },
6051 { "snapshot", LESS, 2, snapshot },
6052 { "delete", MORE, 2, delete_snapshot },
6053 { "daemon-reload", EQUAL, 1, daemon_reload },
6054 { "daemon-reexec", EQUAL, 1, daemon_reload },
6055 { "show-environment", EQUAL, 1, show_environment },
6056 { "set-environment", MORE, 2, set_environment },
6057 { "unset-environment", MORE, 2, set_environment },
6058 { "import-environment", MORE, 1, import_environment},
6059 { "halt", EQUAL, 1, start_special, FORCE },
6060 { "poweroff", EQUAL, 1, start_special, FORCE },
6061 { "reboot", EQUAL, 1, start_special, FORCE },
6062 { "kexec", EQUAL, 1, start_special },
6063 { "suspend", EQUAL, 1, start_special },
6064 { "hibernate", EQUAL, 1, start_special },
6065 { "hybrid-sleep", EQUAL, 1, start_special },
6066 { "default", EQUAL, 1, start_special },
6067 { "rescue", EQUAL, 1, start_special },
6068 { "emergency", EQUAL, 1, start_special },
6069 { "exit", EQUAL, 1, start_special },
6070 { "reset-failed", MORE, 1, reset_failed },
6071 { "enable", MORE, 2, enable_unit, NOBUS },
6072 { "disable", MORE, 2, enable_unit, NOBUS },
6073 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6074 { "reenable", MORE, 2, enable_unit, NOBUS },
6075 { "preset", MORE, 2, enable_unit, NOBUS },
6076 { "mask", MORE, 2, enable_unit, NOBUS },
6077 { "unmask", MORE, 2, enable_unit, NOBUS },
6078 { "link", MORE, 2, enable_unit, NOBUS },
6079 { "switch-root", MORE, 2, switch_root },
6080 { "list-dependencies", LESS, 2, list_dependencies },
6081 { "set-default", EQUAL, 2, set_default, NOBUS },
6082 { "get-default", EQUAL, 1, get_default, NOBUS },
6083 { "set-property", MORE, 3, set_property },
6092 left = argc - optind;
6094 /* Special rule: no arguments (left == 0) means "list-units" */
6096 if (streq(argv[optind], "help") && !argv[optind+1]) {
6097 log_error("This command expects one or more "
6098 "unit names. Did you mean --help?");
6102 for (; verb->verb; verb++)
6103 if (streq(argv[optind], verb->verb))
6106 log_error("Unknown operation '%s'.", argv[optind]);
6111 switch (verb->argc_cmp) {
6114 if (left != verb->argc) {
6115 log_error("Invalid number of arguments.");
6122 if (left < verb->argc) {
6123 log_error("Too few arguments.");
6130 if (left > verb->argc) {
6131 log_error("Too many arguments.");
6138 assert_not_reached("Unknown comparison operator.");
6141 /* Require a bus connection for all operations but
6143 if (verb->bus == NOBUS) {
6144 if (!bus && !avoid_bus()) {
6145 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6150 if (running_in_chroot() > 0) {
6151 log_info("Running in chroot, ignoring request.");
6155 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6156 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6161 return verb->dispatch(bus, argv + optind);
6164 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6166 struct sd_shutdown_command c = {
6173 union sockaddr_union sockaddr = {
6174 .un.sun_family = AF_UNIX,
6175 .un.sun_path = "/run/systemd/shutdownd",
6178 struct iovec iovec[2] = {{
6179 .iov_base = (char*) &c,
6180 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6183 struct msghdr msghdr = {
6184 .msg_name = &sockaddr,
6185 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6186 + sizeof("/run/systemd/shutdownd") - 1,
6191 _cleanup_close_ int fd;
6193 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6197 if (!isempty(message)) {
6198 iovec[1].iov_base = (char*) message;
6199 iovec[1].iov_len = strlen(message);
6200 msghdr.msg_iovlen++;
6203 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6209 static int reload_with_fallback(sd_bus *bus) {
6212 /* First, try systemd via D-Bus. */
6213 if (daemon_reload(bus, NULL) >= 0)
6217 /* Nothing else worked, so let's try signals */
6218 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6220 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6221 log_error("kill() failed: %m");
6228 static int start_with_fallback(sd_bus *bus) {
6231 /* First, try systemd via D-Bus. */
6232 if (start_unit(bus, NULL) >= 0)
6236 /* Nothing else worked, so let's try
6238 if (talk_initctl() > 0)
6241 log_error("Failed to talk to init daemon.");
6245 warn_wall(arg_action);
6249 static int halt_now(enum action a) {
6251 /* Make sure C-A-D is handled by the kernel from this
6253 reboot(RB_ENABLE_CAD);
6258 log_info("Halting.");
6259 reboot(RB_HALT_SYSTEM);
6262 case ACTION_POWEROFF:
6263 log_info("Powering off.");
6264 reboot(RB_POWER_OFF);
6267 case ACTION_REBOOT: {
6268 _cleanup_free_ char *param = NULL;
6270 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6271 log_info("Rebooting with argument '%s'.", param);
6272 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6273 LINUX_REBOOT_CMD_RESTART2, param);
6276 log_info("Rebooting.");
6277 reboot(RB_AUTOBOOT);
6282 assert_not_reached("Unknown action.");
6286 static int halt_main(sd_bus *bus) {
6289 r = check_inhibitors(bus, arg_action);
6293 if (geteuid() != 0) {
6294 /* Try logind if we are a normal user and no special
6295 * mode applies. Maybe PolicyKit allows us to shutdown
6298 if (arg_when <= 0 &&
6301 (arg_action == ACTION_POWEROFF ||
6302 arg_action == ACTION_REBOOT)) {
6303 r = reboot_with_logind(bus, arg_action);
6308 log_error("Must be root.");
6313 _cleanup_free_ char *m;
6315 m = strv_join(arg_wall, " ");
6319 r = send_shutdownd(arg_when,
6320 arg_action == ACTION_HALT ? 'H' :
6321 arg_action == ACTION_POWEROFF ? 'P' :
6322 arg_action == ACTION_KEXEC ? 'K' :
6329 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6331 char date[FORMAT_TIMESTAMP_MAX];
6333 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6334 format_timestamp(date, sizeof(date), arg_when));
6339 if (!arg_dry && !arg_force)
6340 return start_with_fallback(bus);
6343 if (sd_booted() > 0)
6344 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6346 r = utmp_put_shutdown();
6348 log_warning("Failed to write utmp record: %s", strerror(-r));
6355 r = halt_now(arg_action);
6356 log_error("Failed to reboot: %s", strerror(-r));
6361 static int runlevel_main(void) {
6362 int r, runlevel, previous;
6364 r = utmp_get_runlevel(&runlevel, &previous);
6371 previous <= 0 ? 'N' : previous,
6372 runlevel <= 0 ? 'N' : runlevel);
6377 int main(int argc, char*argv[]) {
6378 _cleanup_bus_unref_ sd_bus *bus = NULL;
6381 setlocale(LC_ALL, "");
6382 log_parse_environment();
6385 /* Explicitly not on_tty() to avoid setting cached value.
6386 * This becomes relevant for piping output which might be
6388 original_stdout_is_tty = isatty(STDOUT_FILENO);
6390 r = parse_argv(argc, argv);
6394 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6395 * let's shortcut this */
6396 if (arg_action == ACTION_RUNLEVEL) {
6397 r = runlevel_main();
6401 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6402 log_info("Running in chroot, ignoring request.");
6408 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6410 /* systemctl_main() will print an error message for the bus
6411 * connection, but only if it needs to */
6413 switch (arg_action) {
6415 case ACTION_SYSTEMCTL:
6416 r = systemctl_main(bus, argc, argv, r);
6420 case ACTION_POWEROFF:
6426 case ACTION_RUNLEVEL2:
6427 case ACTION_RUNLEVEL3:
6428 case ACTION_RUNLEVEL4:
6429 case ACTION_RUNLEVEL5:
6431 case ACTION_EMERGENCY:
6432 case ACTION_DEFAULT:
6433 r = start_with_fallback(bus);
6438 r = reload_with_fallback(bus);
6441 case ACTION_CANCEL_SHUTDOWN: {
6442 _cleanup_free_ char *m = NULL;
6445 m = strv_join(arg_wall, " ");
6452 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6454 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6458 case ACTION_RUNLEVEL:
6459 case _ACTION_INVALID:
6461 assert_not_reached("Unknown action");
6466 ask_password_agent_close();
6467 polkit_agent_close();
6469 strv_free(arg_types);
6470 strv_free(arg_states);
6471 strv_free(arg_properties);
6473 return r < 0 ? EXIT_FAILURE : r;