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_push(&globs, t);
2172 r = strv_push(&mangled, t);
2179 /* Query the manager only if any of the names are a glob, since
2180 * this is fairly expensive */
2181 if (!strv_isempty(globs)) {
2182 _cleanup_free_ UnitInfo *unit_infos = NULL;
2184 r = get_unit_list(bus, &reply, &unit_infos, globs);
2188 for (i = 0; i < r; i++)
2189 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2194 mangled = NULL; /* do not free */
2198 static const struct {
2202 } action_table[_ACTION_MAX] = {
2203 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2204 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2205 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2206 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2207 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2208 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2209 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2210 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2211 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2212 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2213 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2214 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2215 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2216 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2217 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2220 static enum action verb_to_action(const char *verb) {
2223 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2224 if (streq_ptr(action_table[i].verb, verb))
2227 return _ACTION_INVALID;
2230 static int start_unit(sd_bus *bus, char **args) {
2231 _cleanup_set_free_free_ Set *s = NULL;
2232 _cleanup_strv_free_ char **names = NULL;
2233 const char *method, *mode, *one_name;
2239 ask_password_agent_open_if_enabled();
2241 if (arg_action == ACTION_SYSTEMCTL) {
2243 method = verb_to_method(args[0]);
2244 action = verb_to_action(args[0]);
2246 mode = streq(args[0], "isolate") ? "isolate" :
2247 action_table[action].mode ?: arg_job_mode;
2249 one_name = action_table[action].target;
2251 assert(arg_action < ELEMENTSOF(action_table));
2252 assert(action_table[arg_action].target);
2254 method = "StartUnit";
2256 mode = action_table[arg_action].mode;
2257 one_name = action_table[arg_action].target;
2261 names = strv_new(one_name, NULL);
2263 r = expand_names(bus, args + 1, NULL, &names);
2265 log_error("Failed to expand names: %s", strerror(-r));
2268 if (!arg_no_block) {
2269 r = enable_wait_for_jobs(bus);
2271 log_error("Could not watch jobs: %s", strerror(-r));
2275 s = set_new(string_hash_func, string_compare_func);
2280 STRV_FOREACH(name, names) {
2281 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2284 q = start_unit_one(bus, method, *name, mode, &error, s);
2285 if (r >= 0 && q < 0)
2286 r = translate_bus_error_to_exit_status(q, &error);
2289 if (!arg_no_block) {
2292 q = wait_for_jobs(bus, s);
2296 /* When stopping units, warn if they can still be triggered by
2297 * another active unit (socket, path, timer) */
2298 if (!arg_quiet && streq(method, "StopUnit"))
2299 STRV_FOREACH(name, names)
2300 check_triggering_units(bus, *name);
2306 /* Ask systemd-logind, which might grant access to unprivileged users
2307 * through PolicyKit */
2308 static int reboot_with_logind(sd_bus *bus, enum action a) {
2310 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2317 polkit_agent_open_if_enabled();
2325 case ACTION_POWEROFF:
2326 method = "PowerOff";
2329 case ACTION_SUSPEND:
2333 case ACTION_HIBERNATE:
2334 method = "Hibernate";
2337 case ACTION_HYBRID_SLEEP:
2338 method = "HybridSleep";
2345 r = sd_bus_call_method(
2347 "org.freedesktop.login1",
2348 "/org/freedesktop/login1",
2349 "org.freedesktop.login1.Manager",
2355 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2363 static int check_inhibitors(sd_bus *bus, enum action a) {
2365 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2366 _cleanup_strv_free_ char **sessions = NULL;
2367 const char *what, *who, *why, *mode;
2376 if (arg_ignore_inhibitors || arg_force > 0)
2388 r = sd_bus_call_method(
2390 "org.freedesktop.login1",
2391 "/org/freedesktop/login1",
2392 "org.freedesktop.login1.Manager",
2398 /* If logind is not around, then there are no inhibitors... */
2401 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2403 return bus_log_parse_error(r);
2405 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2406 _cleanup_free_ char *comm = NULL, *user = NULL;
2407 _cleanup_strv_free_ char **sv = NULL;
2409 if (!streq(mode, "block"))
2412 sv = strv_split(what, ":");
2416 if (!strv_contains(sv,
2418 a == ACTION_POWEROFF ||
2419 a == ACTION_REBOOT ||
2420 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2423 get_process_comm(pid, &comm);
2424 user = uid_to_name(uid);
2426 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2427 who, (unsigned long) pid, strna(comm), strna(user), why);
2432 return bus_log_parse_error(r);
2434 r = sd_bus_message_exit_container(reply);
2436 return bus_log_parse_error(r);
2438 /* Check for current sessions */
2439 sd_get_sessions(&sessions);
2440 STRV_FOREACH(s, sessions) {
2441 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2443 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2446 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2449 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2452 sd_session_get_tty(*s, &tty);
2453 sd_session_get_seat(*s, &seat);
2454 sd_session_get_service(*s, &service);
2455 user = uid_to_name(uid);
2457 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2464 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2465 action_table[a].verb);
2473 static int start_special(sd_bus *bus, char **args) {
2479 a = verb_to_action(args[0]);
2481 r = check_inhibitors(bus, a);
2485 if (arg_force >= 2 && geteuid() != 0) {
2486 log_error("Must be root.");
2490 if (arg_force >= 2 &&
2491 (a == ACTION_HALT ||
2492 a == ACTION_POWEROFF ||
2493 a == ACTION_REBOOT))
2496 if (arg_force >= 1 &&
2497 (a == ACTION_HALT ||
2498 a == ACTION_POWEROFF ||
2499 a == ACTION_REBOOT ||
2500 a == ACTION_KEXEC ||
2502 return daemon_reload(bus, args);
2504 /* first try logind, to allow authentication with polkit */
2505 if (geteuid() != 0 &&
2506 (a == ACTION_POWEROFF ||
2507 a == ACTION_REBOOT ||
2508 a == ACTION_SUSPEND ||
2509 a == ACTION_HIBERNATE ||
2510 a == ACTION_HYBRID_SLEEP)) {
2511 r = reboot_with_logind(bus, a);
2516 r = start_unit(bus, args);
2517 if (r == EXIT_SUCCESS)
2523 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2524 _cleanup_strv_free_ char **names = NULL;
2531 r = expand_names(bus, args, NULL, &names);
2533 log_error("Failed to expand names: %s", strerror(-r));
2537 STRV_FOREACH(name, names) {
2540 state = check_one_unit(bus, *name, good_states, arg_quiet);
2550 static int check_unit_active(sd_bus *bus, char **args) {
2551 /* According to LSB: 3, "program is not running" */
2552 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2555 static int check_unit_failed(sd_bus *bus, char **args) {
2556 return check_unit_generic(bus, 1, "failed\0", args + 1);
2559 static int kill_unit(sd_bus *bus, char **args) {
2560 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2561 _cleanup_strv_free_ char **names = NULL;
2569 arg_kill_who = "all";
2571 r = expand_names(bus, args + 1, NULL, &names);
2573 log_error("Failed to expand names: %s", strerror(-r));
2575 STRV_FOREACH(name, names) {
2576 q = sd_bus_call_method(
2578 "org.freedesktop.systemd1",
2579 "/org/freedesktop/systemd1",
2580 "org.freedesktop.systemd1.Manager",
2584 "ssi", *names, arg_kill_who, arg_signal);
2586 log_error("Failed to kill unit %s: %s",
2587 *names, bus_error_message(&error, r));
2596 typedef struct ExecStatusInfo {
2604 usec_t start_timestamp;
2605 usec_t exit_timestamp;
2610 LIST_FIELDS(struct ExecStatusInfo, exec);
2613 static void exec_status_info_free(ExecStatusInfo *i) {
2622 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2623 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2626 int32_t code, status;
2632 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2634 return bus_log_parse_error(r);
2638 r = sd_bus_message_read(m, "s", &path);
2640 return bus_log_parse_error(r);
2642 i->path = strdup(path);
2646 r = sd_bus_message_read_strv(m, &i->argv);
2648 return bus_log_parse_error(r);
2650 r = sd_bus_message_read(m,
2653 &start_timestamp, &start_timestamp_monotonic,
2654 &exit_timestamp, &exit_timestamp_monotonic,
2658 return bus_log_parse_error(r);
2661 i->start_timestamp = (usec_t) start_timestamp;
2662 i->exit_timestamp = (usec_t) exit_timestamp;
2663 i->pid = (pid_t) pid;
2667 r = sd_bus_message_exit_container(m);
2669 return bus_log_parse_error(r);
2674 typedef struct UnitStatusInfo {
2676 const char *load_state;
2677 const char *active_state;
2678 const char *sub_state;
2679 const char *unit_file_state;
2681 const char *description;
2682 const char *following;
2684 char **documentation;
2686 const char *fragment_path;
2687 const char *source_path;
2688 const char *control_group;
2690 char **dropin_paths;
2692 const char *load_error;
2695 usec_t inactive_exit_timestamp;
2696 usec_t inactive_exit_timestamp_monotonic;
2697 usec_t active_enter_timestamp;
2698 usec_t active_exit_timestamp;
2699 usec_t inactive_enter_timestamp;
2701 bool need_daemon_reload;
2706 const char *status_text;
2707 const char *pid_file;
2710 usec_t start_timestamp;
2711 usec_t exit_timestamp;
2713 int exit_code, exit_status;
2715 usec_t condition_timestamp;
2716 bool condition_result;
2717 bool failed_condition_trigger;
2718 bool failed_condition_negate;
2719 const char *failed_condition;
2720 const char *failed_condition_param;
2723 unsigned n_accepted;
2724 unsigned n_connections;
2727 /* Pairs of type, path */
2731 const char *sysfs_path;
2733 /* Mount, Automount */
2739 LIST_HEAD(ExecStatusInfo, exec);
2742 static void print_status_info(
2747 const char *on, *off, *ss;
2749 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2750 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2753 arg_all * OUTPUT_SHOW_ALL |
2754 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2755 on_tty() * OUTPUT_COLOR |
2756 !arg_quiet * OUTPUT_WARN_CUTOFF |
2757 arg_full * OUTPUT_FULL_WIDTH;
2762 /* This shows pretty information about a unit. See
2763 * print_property() for a low-level property printer */
2765 printf("%s", strna(i->id));
2767 if (i->description && !streq_ptr(i->id, i->description))
2768 printf(" - %s", i->description);
2773 printf(" Follow: unit currently follows state of %s\n", i->following);
2775 if (streq_ptr(i->load_state, "error")) {
2776 on = ansi_highlight_red();
2777 off = ansi_highlight_off();
2781 path = i->source_path ? i->source_path : i->fragment_path;
2784 printf(" Loaded: %s%s%s (Reason: %s)\n",
2785 on, strna(i->load_state), off, i->load_error);
2786 else if (path && i->unit_file_state)
2787 printf(" Loaded: %s%s%s (%s; %s)\n",
2788 on, strna(i->load_state), off, path, i->unit_file_state);
2790 printf(" Loaded: %s%s%s (%s)\n",
2791 on, strna(i->load_state), off, path);
2793 printf(" Loaded: %s%s%s\n",
2794 on, strna(i->load_state), off);
2796 if (!strv_isempty(i->dropin_paths)) {
2797 _cleanup_free_ char *dir = NULL;
2801 STRV_FOREACH(dropin, i->dropin_paths) {
2802 if (! dir || last) {
2803 printf(dir ? " " : " Drop-In: ");
2808 if (path_get_parent(*dropin, &dir) < 0) {
2813 printf("%s\n %s", dir,
2814 draw_special_char(DRAW_TREE_RIGHT));
2817 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2819 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2823 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2825 if (streq_ptr(i->active_state, "failed")) {
2826 on = ansi_highlight_red();
2827 off = ansi_highlight_off();
2828 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2829 on = ansi_highlight_green();
2830 off = ansi_highlight_off();
2835 printf(" Active: %s%s (%s)%s",
2836 on, strna(i->active_state), ss, off);
2838 printf(" Active: %s%s%s",
2839 on, strna(i->active_state), off);
2841 if (!isempty(i->result) && !streq(i->result, "success"))
2842 printf(" (Result: %s)", i->result);
2844 timestamp = (streq_ptr(i->active_state, "active") ||
2845 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2846 (streq_ptr(i->active_state, "inactive") ||
2847 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2848 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2849 i->active_exit_timestamp;
2851 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2852 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2855 printf(" since %s; %s\n", s2, s1);
2857 printf(" since %s\n", s2);
2861 if (!i->condition_result && i->condition_timestamp > 0) {
2862 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2863 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2865 printf(" start condition failed at %s%s%s\n",
2866 s2, s1 ? "; " : "", s1 ? s1 : "");
2867 if (i->failed_condition_trigger)
2868 printf(" none of the trigger conditions were met\n");
2869 else if (i->failed_condition)
2870 printf(" %s=%s%s was not met\n",
2871 i->failed_condition,
2872 i->failed_condition_negate ? "!" : "",
2873 i->failed_condition_param);
2877 printf(" Device: %s\n", i->sysfs_path);
2879 printf(" Where: %s\n", i->where);
2881 printf(" What: %s\n", i->what);
2883 STRV_FOREACH(t, i->documentation)
2884 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2886 STRV_FOREACH_PAIR(t, t2, i->listen)
2887 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2890 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2892 LIST_FOREACH(exec, p, i->exec) {
2893 _cleanup_free_ char *argv = NULL;
2896 /* Only show exited processes here */
2900 argv = strv_join(p->argv, " ");
2901 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2903 good = is_clean_exit_lsb(p->code, p->status, NULL);
2905 on = ansi_highlight_red();
2906 off = ansi_highlight_off();
2910 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2912 if (p->code == CLD_EXITED) {
2915 printf("status=%i", p->status);
2917 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2922 printf("signal=%s", signal_to_string(p->status));
2924 printf(")%s\n", off);
2926 if (i->main_pid == p->pid &&
2927 i->start_timestamp == p->start_timestamp &&
2928 i->exit_timestamp == p->start_timestamp)
2929 /* Let's not show this twice */
2932 if (p->pid == i->control_pid)
2936 if (i->main_pid > 0 || i->control_pid > 0) {
2937 if (i->main_pid > 0) {
2938 printf(" Main PID: %u", (unsigned) i->main_pid);
2941 _cleanup_free_ char *comm = NULL;
2942 get_process_comm(i->main_pid, &comm);
2944 printf(" (%s)", comm);
2945 } else if (i->exit_code > 0) {
2946 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2948 if (i->exit_code == CLD_EXITED) {
2951 printf("status=%i", i->exit_status);
2953 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2958 printf("signal=%s", signal_to_string(i->exit_status));
2962 if (i->control_pid > 0)
2966 if (i->control_pid > 0) {
2967 _cleanup_free_ char *c = NULL;
2969 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2971 get_process_comm(i->control_pid, &c);
2980 printf(" Status: \"%s\"\n", i->status_text);
2982 if (i->control_group &&
2983 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2986 printf(" CGroup: %s\n", i->control_group);
2988 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2991 char prefix[] = " ";
2994 if (c > sizeof(prefix) - 1)
2995 c -= sizeof(prefix) - 1;
2999 if (i->main_pid > 0)
3000 extra[k++] = i->main_pid;
3002 if (i->control_pid > 0)
3003 extra[k++] = i->control_pid;
3005 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
3006 c, false, extra, k, flags);
3010 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3012 show_journal_by_unit(stdout,
3016 i->inactive_exit_timestamp_monotonic,
3020 arg_scope == UNIT_FILE_SYSTEM,
3024 if (i->need_daemon_reload)
3025 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3026 ansi_highlight_red(),
3027 ansi_highlight_off(),
3028 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3031 static void show_unit_help(UnitStatusInfo *i) {
3036 if (!i->documentation) {
3037 log_info("Documentation for %s not known.", i->id);
3041 STRV_FOREACH(p, i->documentation) {
3043 if (startswith(*p, "man:")) {
3044 const char *args[4] = { "man", NULL, NULL, NULL };
3045 _cleanup_free_ char *page = NULL, *section = NULL;
3052 if ((*p)[k-1] == ')')
3053 e = strrchr(*p, '(');
3056 page = strndup((*p) + 4, e - *p - 4);
3057 section = strndup(e + 1, *p + k - e - 2);
3058 if (!page || !section) {
3070 log_error("Failed to fork: %m");
3076 execvp(args[0], (char**) args);
3077 log_error("Failed to execute man: %m");
3078 _exit(EXIT_FAILURE);
3081 wait_for_terminate(pid, NULL);
3083 log_info("Can't show: %s", *p);
3087 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3094 switch (contents[0]) {
3096 case SD_BUS_TYPE_STRING: {
3099 r = sd_bus_message_read(m, "s", &s);
3101 return bus_log_parse_error(r);
3104 if (streq(name, "Id"))
3106 else if (streq(name, "LoadState"))
3108 else if (streq(name, "ActiveState"))
3109 i->active_state = s;
3110 else if (streq(name, "SubState"))
3112 else if (streq(name, "Description"))
3114 else if (streq(name, "FragmentPath"))
3115 i->fragment_path = s;
3116 else if (streq(name, "SourcePath"))
3119 else if (streq(name, "DefaultControlGroup")) {
3121 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3123 i->control_group = e;
3126 else if (streq(name, "ControlGroup"))
3127 i->control_group = s;
3128 else if (streq(name, "StatusText"))
3130 else if (streq(name, "PIDFile"))
3132 else if (streq(name, "SysFSPath"))
3134 else if (streq(name, "Where"))
3136 else if (streq(name, "What"))
3138 else if (streq(name, "Following"))
3140 else if (streq(name, "UnitFileState"))
3141 i->unit_file_state = s;
3142 else if (streq(name, "Result"))
3149 case SD_BUS_TYPE_BOOLEAN: {
3152 r = sd_bus_message_read(m, "b", &b);
3154 return bus_log_parse_error(r);
3156 if (streq(name, "Accept"))
3158 else if (streq(name, "NeedDaemonReload"))
3159 i->need_daemon_reload = b;
3160 else if (streq(name, "ConditionResult"))
3161 i->condition_result = b;
3166 case SD_BUS_TYPE_UINT32: {
3169 r = sd_bus_message_read(m, "u", &u);
3171 return bus_log_parse_error(r);
3173 if (streq(name, "MainPID")) {
3175 i->main_pid = (pid_t) u;
3178 } else if (streq(name, "ControlPID"))
3179 i->control_pid = (pid_t) u;
3180 else if (streq(name, "ExecMainPID")) {
3182 i->main_pid = (pid_t) u;
3183 } else if (streq(name, "NAccepted"))
3185 else if (streq(name, "NConnections"))
3186 i->n_connections = u;
3191 case SD_BUS_TYPE_INT32: {
3194 r = sd_bus_message_read(m, "i", &j);
3196 return bus_log_parse_error(r);
3198 if (streq(name, "ExecMainCode"))
3199 i->exit_code = (int) j;
3200 else if (streq(name, "ExecMainStatus"))
3201 i->exit_status = (int) j;
3206 case SD_BUS_TYPE_UINT64: {
3209 r = sd_bus_message_read(m, "t", &u);
3211 return bus_log_parse_error(r);
3213 if (streq(name, "ExecMainStartTimestamp"))
3214 i->start_timestamp = (usec_t) u;
3215 else if (streq(name, "ExecMainExitTimestamp"))
3216 i->exit_timestamp = (usec_t) u;
3217 else if (streq(name, "ActiveEnterTimestamp"))
3218 i->active_enter_timestamp = (usec_t) u;
3219 else if (streq(name, "InactiveEnterTimestamp"))
3220 i->inactive_enter_timestamp = (usec_t) u;
3221 else if (streq(name, "InactiveExitTimestamp"))
3222 i->inactive_exit_timestamp = (usec_t) u;
3223 else if (streq(name, "InactiveExitTimestampMonotonic"))
3224 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3225 else if (streq(name, "ActiveExitTimestamp"))
3226 i->active_exit_timestamp = (usec_t) u;
3227 else if (streq(name, "ConditionTimestamp"))
3228 i->condition_timestamp = (usec_t) u;
3233 case SD_BUS_TYPE_ARRAY:
3235 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3236 _cleanup_free_ ExecStatusInfo *info = NULL;
3238 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3240 return bus_log_parse_error(r);
3242 info = new0(ExecStatusInfo, 1);
3246 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3248 info->name = strdup(name);
3252 LIST_PREPEND(exec, i->exec, info);
3254 info = new0(ExecStatusInfo, 1);
3260 return bus_log_parse_error(r);
3262 r = sd_bus_message_exit_container(m);
3264 return bus_log_parse_error(r);
3268 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3269 const char *type, *path;
3271 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3273 return bus_log_parse_error(r);
3275 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3277 r = strv_extend(&i->listen, type);
3281 r = strv_extend(&i->listen, path);
3286 return bus_log_parse_error(r);
3288 r = sd_bus_message_exit_container(m);
3290 return bus_log_parse_error(r);
3294 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3296 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3298 return bus_log_parse_error(r);
3300 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3302 r = sd_bus_message_read_strv(m, &i->documentation);
3304 return bus_log_parse_error(r);
3306 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3307 const char *cond, *param;
3308 int trigger, negate;
3311 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3313 return bus_log_parse_error(r);
3315 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3316 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3317 if (state < 0 && (!trigger || !i->failed_condition)) {
3318 i->failed_condition = cond;
3319 i->failed_condition_trigger = trigger;
3320 i->failed_condition_negate = negate;
3321 i->failed_condition_param = param;
3325 return bus_log_parse_error(r);
3327 r = sd_bus_message_exit_container(m);
3329 return bus_log_parse_error(r);
3336 case SD_BUS_TYPE_STRUCT_BEGIN:
3338 if (streq(name, "LoadError")) {
3339 const char *n, *message;
3341 r = sd_bus_message_read(m, "(ss)", &n, &message);
3343 return bus_log_parse_error(r);
3345 if (!isempty(message))
3346 i->load_error = message;
3359 r = sd_bus_message_skip(m, contents);
3361 return bus_log_parse_error(r);
3366 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3372 /* This is a low-level property printer, see
3373 * print_status_info() for the nicer output */
3375 if (arg_properties && !strv_find(arg_properties, name)) {
3376 /* skip what we didn't read */
3377 r = sd_bus_message_skip(m, contents);
3381 switch (contents[0]) {
3383 case SD_BUS_TYPE_STRUCT_BEGIN:
3385 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3388 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3390 return bus_log_parse_error(r);
3393 printf("%s=%u\n", name, (unsigned) u);
3395 printf("%s=\n", name);
3399 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3402 r = sd_bus_message_read(m, "(so)", &s, NULL);
3404 return bus_log_parse_error(r);
3406 if (arg_all || !isempty(s))
3407 printf("%s=%s\n", name, s);
3411 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3412 const char *a = NULL, *b = NULL;
3414 r = sd_bus_message_read(m, "(ss)", &a, &b);
3416 return bus_log_parse_error(r);
3418 if (arg_all || !isempty(a) || !isempty(b))
3419 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3422 } else if (streq_ptr(name, "SystemCallFilter")) {
3423 _cleanup_strv_free_ char **l = NULL;
3426 r = sd_bus_message_enter_container(m, 'r', "bas");
3428 return bus_log_parse_error(r);
3430 r = sd_bus_message_read(m, "b", &whitelist);
3432 return bus_log_parse_error(r);
3434 r = sd_bus_message_read_strv(m, &l);
3436 return bus_log_parse_error(r);
3438 r = sd_bus_message_exit_container(m);
3440 return bus_log_parse_error(r);
3442 if (arg_all || whitelist || !strv_isempty(l)) {
3446 fputs(name, stdout);
3452 STRV_FOREACH(i, l) {
3460 fputc('\n', stdout);
3468 case SD_BUS_TYPE_ARRAY:
3470 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3474 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3476 return bus_log_parse_error(r);
3478 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3479 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3482 return bus_log_parse_error(r);
3484 r = sd_bus_message_exit_container(m);
3486 return bus_log_parse_error(r);
3490 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3491 const char *type, *path;
3493 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3495 return bus_log_parse_error(r);
3497 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3498 printf("%s=%s\n", type, path);
3500 return bus_log_parse_error(r);
3502 r = sd_bus_message_exit_container(m);
3504 return bus_log_parse_error(r);
3508 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3509 const char *type, *path;
3511 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3513 return bus_log_parse_error(r);
3515 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3516 printf("Listen%s=%s\n", type, path);
3518 return bus_log_parse_error(r);
3520 r = sd_bus_message_exit_container(m);
3522 return bus_log_parse_error(r);
3526 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3528 uint64_t value, next_elapse;
3530 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3532 return bus_log_parse_error(r);
3534 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3535 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3537 printf("%s={ value=%s ; next_elapse=%s }\n",
3539 format_timespan(timespan1, sizeof(timespan1), value, 0),
3540 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3543 return bus_log_parse_error(r);
3545 r = sd_bus_message_exit_container(m);
3547 return bus_log_parse_error(r);
3551 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3552 ExecStatusInfo info = {};
3554 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3556 return bus_log_parse_error(r);
3558 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3559 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3560 _cleanup_free_ char *tt;
3562 tt = strv_join(info.argv, " ");
3564 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3568 yes_no(info.ignore),
3569 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3570 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3571 (unsigned) info. pid,
3572 sigchld_code_to_string(info.code),
3574 info.code == CLD_EXITED ? "" : "/",
3575 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3578 strv_free(info.argv);
3582 r = sd_bus_message_exit_container(m);
3584 return bus_log_parse_error(r);
3588 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3589 const char *path, *rwm;
3591 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3593 return bus_log_parse_error(r);
3595 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3596 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3598 return bus_log_parse_error(r);
3600 r = sd_bus_message_exit_container(m);
3602 return bus_log_parse_error(r);
3606 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3610 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3612 return bus_log_parse_error(r);
3614 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3615 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3617 return bus_log_parse_error(r);
3619 r = sd_bus_message_exit_container(m);
3621 return bus_log_parse_error(r);
3625 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3629 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3631 return bus_log_parse_error(r);
3633 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3634 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3636 return bus_log_parse_error(r);
3638 r = sd_bus_message_exit_container(m);
3640 return bus_log_parse_error(r);
3648 r = bus_print_property(name, m, arg_all);
3650 return bus_log_parse_error(r);
3653 r = sd_bus_message_skip(m, contents);
3655 return bus_log_parse_error(r);
3658 printf("%s=[unprintable]\n", name);
3664 static int show_one(
3668 bool show_properties,
3672 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3673 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3674 UnitStatusInfo info = {};
3681 log_debug("Showing one %s", path);
3683 r = sd_bus_call_method(
3685 "org.freedesktop.systemd1",
3687 "org.freedesktop.DBus.Properties",
3693 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3697 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3699 return bus_log_parse_error(r);
3706 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3707 const char *name, *contents;
3709 r = sd_bus_message_read(reply, "s", &name);
3711 return bus_log_parse_error(r);
3713 r = sd_bus_message_peek_type(reply, NULL, &contents);
3715 return bus_log_parse_error(r);
3717 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3719 return bus_log_parse_error(r);
3721 if (show_properties)
3722 r = print_property(name, reply, contents);
3724 r = status_property(name, reply, &info, contents);
3728 r = sd_bus_message_exit_container(reply);
3730 return bus_log_parse_error(r);
3732 r = sd_bus_message_exit_container(reply);
3734 return bus_log_parse_error(r);
3737 return bus_log_parse_error(r);
3739 r = sd_bus_message_exit_container(reply);
3741 return bus_log_parse_error(r);
3745 if (!show_properties) {
3746 if (streq(verb, "help"))
3747 show_unit_help(&info);
3749 print_status_info(&info, ellipsized);
3752 strv_free(info.documentation);
3753 strv_free(info.dropin_paths);
3754 strv_free(info.listen);
3756 if (!streq_ptr(info.active_state, "active") &&
3757 !streq_ptr(info.active_state, "reloading") &&
3758 streq(verb, "status")) {
3759 /* According to LSB: "program not running" */
3760 /* 0: program is running or service is OK
3761 * 1: program is dead and /run PID file exists
3762 * 2: program is dead and /run/lock lock file exists
3763 * 3: program is not running
3764 * 4: program or service status is unknown
3766 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3772 while ((p = info.exec)) {
3773 LIST_REMOVE(exec, info.exec, p);
3774 exec_status_info_free(p);
3780 static int get_unit_dbus_path_by_pid(
3785 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3786 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3790 r = sd_bus_call_method(
3792 "org.freedesktop.systemd1",
3793 "/org/freedesktop/systemd1",
3794 "org.freedesktop.systemd1.Manager",
3800 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3804 r = sd_bus_message_read(reply, "o", &u);
3806 return bus_log_parse_error(r);
3816 static int show_all(
3819 bool show_properties,
3823 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3824 _cleanup_free_ UnitInfo *unit_infos = NULL;
3829 r = get_unit_list(bus, &reply, &unit_infos, NULL);
3833 pager_open_if_enabled();
3837 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3839 for (u = unit_infos; u < unit_infos + c; u++) {
3840 _cleanup_free_ char *p = NULL;
3842 p = unit_dbus_path_from_name(u->id);
3846 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3854 static int cat(sd_bus *bus, char **args) {
3855 _cleanup_free_ char *unit = NULL;
3856 _cleanup_strv_free_ char **names = NULL;
3864 r = expand_names(bus, args + 1, NULL, &names);
3866 log_error("Failed to expand names: %s", strerror(-r));
3868 pager_open_if_enabled();
3870 STRV_FOREACH(name, names) {
3871 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3872 _cleanup_strv_free_ char **dropin_paths = NULL;
3873 _cleanup_free_ char *fragment_path = NULL;
3876 unit = unit_dbus_path_from_name(*name);
3880 if (need_daemon_reload(bus, *name) > 0)
3881 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3882 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3884 r = sd_bus_get_property_string(
3886 "org.freedesktop.systemd1",
3888 "org.freedesktop.systemd1.Unit",
3893 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3897 r = sd_bus_get_property_strv(
3899 "org.freedesktop.systemd1",
3901 "org.freedesktop.systemd1.Unit",
3906 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3915 if (!isempty(fragment_path)) {
3916 printf("%s# %s%s\n",
3917 ansi_highlight_blue(),
3919 ansi_highlight_off());
3922 r = sendfile_full(STDOUT_FILENO, fragment_path);
3924 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3929 STRV_FOREACH(path, dropin_paths) {
3930 printf("%s%s# %s%s\n",
3931 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3932 ansi_highlight_blue(),
3934 ansi_highlight_off());
3937 r = sendfile_full(STDOUT_FILENO, *path);
3939 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3945 return r < 0 ? r : 0;
3948 static int show(sd_bus *bus, char **args) {
3949 bool show_properties, show_status, new_line = false;
3950 bool ellipsized = false;
3956 show_properties = streq(args[0], "show");
3957 show_status = streq(args[0], "status");
3959 if (show_properties)
3960 pager_open_if_enabled();
3962 /* If no argument is specified inspect the manager itself */
3964 if (show_properties && strv_length(args) <= 1)
3965 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3967 if (show_status && strv_length(args) <= 1)
3968 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3970 _cleanup_free_ char **patterns = NULL;
3973 STRV_FOREACH(name, args + 1) {
3974 _cleanup_free_ char *unit = NULL;
3977 if (safe_atou32(*name, &id) < 0) {
3978 if (strv_push(&patterns, *name) < 0)
3982 } else if (show_properties) {
3983 /* Interpret as job id */
3984 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3988 /* Interpret as PID */
3989 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3996 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3999 if (!strv_isempty(patterns)) {
4000 _cleanup_strv_free_ char **names = NULL;
4002 r = expand_names(bus, patterns, NULL, &names);
4004 log_error("Failed to expand names: %s", strerror(-r));
4006 STRV_FOREACH(name, names) {
4007 _cleanup_free_ char *unit;
4009 unit = unit_dbus_path_from_name(*name);
4013 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4018 if (ellipsized && !arg_quiet)
4019 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4024 static int append_assignment(sd_bus_message *m, const char *assignment) {
4032 eq = strchr(assignment, '=');
4034 log_error("Not an assignment: %s", assignment);
4038 field = strndupa(assignment, eq - assignment);
4041 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
4043 return bus_log_create_error(r);
4045 if (streq(field, "CPUAccounting") ||
4046 streq(field, "MemoryAccounting") ||
4047 streq(field, "BlockIOAccounting")) {
4049 r = parse_boolean(eq);
4051 log_error("Failed to parse boolean assignment %s.", assignment);
4055 r = sd_bus_message_append(m, "v", "b", r);
4057 } else if (streq(field, "MemoryLimit")) {
4060 r = parse_size(eq, 1024, &bytes);
4062 log_error("Failed to parse bytes specification %s", assignment);
4066 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
4068 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
4071 r = safe_atou64(eq, &u);
4073 log_error("Failed to parse %s value %s.", field, eq);
4077 r = sd_bus_message_append(m, "v", "t", u);
4079 } else if (streq(field, "DevicePolicy"))
4080 r = sd_bus_message_append(m, "v", "s", eq);
4082 else if (streq(field, "DeviceAllow")) {
4085 r = sd_bus_message_append(m, "v", "a(ss)", 0);
4087 const char *path, *rwm;
4090 e = strchr(eq, ' ');
4092 path = strndupa(eq, e - eq);
4099 if (!path_startswith(path, "/dev")) {
4100 log_error("%s is not a device file in /dev.", path);
4104 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
4107 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
4110 r = sd_bus_message_append(m, "v", "a(st)", 0);
4112 const char *path, *bandwidth;
4116 e = strchr(eq, ' ');
4118 path = strndupa(eq, e - eq);
4121 log_error("Failed to parse %s value %s.", field, eq);
4125 if (!path_startswith(path, "/dev")) {
4126 log_error("%s is not a device file in /dev.", path);
4130 r = parse_size(bandwidth, 1000, &bytes);
4132 log_error("Failed to parse byte value %s.", bandwidth);
4136 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4139 } else if (streq(field, "BlockIODeviceWeight")) {
4142 r = sd_bus_message_append(m, "v", "a(st)", 0);
4144 const char *path, *weight;
4148 e = strchr(eq, ' ');
4150 path = strndupa(eq, e - eq);
4153 log_error("Failed to parse %s value %s.", field, eq);
4157 if (!path_startswith(path, "/dev")) {
4158 log_error("%s is not a device file in /dev.", path);
4162 r = safe_atou64(weight, &u);
4164 log_error("Failed to parse %s value %s.", field, weight);
4167 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4171 log_error("Unknown assignment %s.", assignment);
4176 return bus_log_create_error(r);
4181 static int set_property(sd_bus *bus, char **args) {
4182 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4183 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4184 _cleanup_free_ char *n = NULL;
4188 r = sd_bus_message_new_method_call(
4191 "org.freedesktop.systemd1",
4192 "/org/freedesktop/systemd1",
4193 "org.freedesktop.systemd1.Manager",
4194 "SetUnitProperties");
4196 return bus_log_create_error(r);
4198 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4202 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4204 return bus_log_create_error(r);
4206 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4208 return bus_log_create_error(r);
4210 STRV_FOREACH(i, args + 2) {
4211 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4213 return bus_log_create_error(r);
4215 r = append_assignment(m, *i);
4219 r = sd_bus_message_close_container(m);
4221 return bus_log_create_error(r);
4224 r = sd_bus_message_close_container(m);
4226 return bus_log_create_error(r);
4228 r = sd_bus_call(bus, m, 0, &error, NULL);
4230 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4237 static int snapshot(sd_bus *bus, char **args) {
4238 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4239 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4240 _cleanup_free_ char *n = NULL, *id = NULL;
4244 if (strv_length(args) > 1)
4245 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4251 r = sd_bus_call_method(
4253 "org.freedesktop.systemd1",
4254 "/org/freedesktop/systemd1",
4255 "org.freedesktop.systemd1.Manager",
4261 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4265 r = sd_bus_message_read(reply, "o", &path);
4267 return bus_log_parse_error(r);
4269 r = sd_bus_get_property_string(
4271 "org.freedesktop.systemd1",
4273 "org.freedesktop.systemd1.Unit",
4278 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4288 static int delete_snapshot(sd_bus *bus, char **args) {
4289 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4290 _cleanup_strv_free_ char **names = NULL;
4296 r = expand_names(bus, args + 1, ".snapshot", &names);
4298 log_error("Failed to expand names: %s", strerror(-r));
4300 STRV_FOREACH(name, names) {
4301 q = sd_bus_call_method(
4303 "org.freedesktop.systemd1",
4304 "/org/freedesktop/systemd1",
4305 "org.freedesktop.systemd1.Manager",
4311 log_error("Failed to remove snapshot %s: %s",
4312 *name, bus_error_message(&error, r));
4321 static int daemon_reload(sd_bus *bus, char **args) {
4322 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4326 if (arg_action == ACTION_RELOAD)
4328 else if (arg_action == ACTION_REEXEC)
4329 method = "Reexecute";
4331 assert(arg_action == ACTION_SYSTEMCTL);
4334 streq(args[0], "clear-jobs") ||
4335 streq(args[0], "cancel") ? "ClearJobs" :
4336 streq(args[0], "daemon-reexec") ? "Reexecute" :
4337 streq(args[0], "reset-failed") ? "ResetFailed" :
4338 streq(args[0], "halt") ? "Halt" :
4339 streq(args[0], "poweroff") ? "PowerOff" :
4340 streq(args[0], "reboot") ? "Reboot" :
4341 streq(args[0], "kexec") ? "KExec" :
4342 streq(args[0], "exit") ? "Exit" :
4343 /* "daemon-reload" */ "Reload";
4346 r = sd_bus_call_method(
4348 "org.freedesktop.systemd1",
4349 "/org/freedesktop/systemd1",
4350 "org.freedesktop.systemd1.Manager",
4356 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4357 /* There's always a fallback possible for
4358 * legacy actions. */
4360 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4361 /* On reexecution, we expect a disconnect, not a
4365 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4367 return r < 0 ? r : 0;
4370 static int reset_failed(sd_bus *bus, char **args) {
4371 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4372 _cleanup_strv_free_ char **names = NULL;
4376 if (strv_length(args) <= 1)
4377 return daemon_reload(bus, args);
4379 r = expand_names(bus, args + 1, NULL, &names);
4381 log_error("Failed to expand names: %s", strerror(-r));
4383 STRV_FOREACH(name, names) {
4384 q = sd_bus_call_method(
4386 "org.freedesktop.systemd1",
4387 "/org/freedesktop/systemd1",
4388 "org.freedesktop.systemd1.Manager",
4394 log_error("Failed to reset failed state of unit %s: %s",
4395 *name, bus_error_message(&error, r));
4404 static int show_environment(sd_bus *bus, char **args) {
4405 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4406 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4410 pager_open_if_enabled();
4412 r = sd_bus_get_property(
4414 "org.freedesktop.systemd1",
4415 "/org/freedesktop/systemd1",
4416 "org.freedesktop.systemd1.Manager",
4422 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4426 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4428 return bus_log_parse_error(r);
4430 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4433 return bus_log_parse_error(r);
4435 r = sd_bus_message_exit_container(reply);
4437 return bus_log_parse_error(r);
4442 static int switch_root(sd_bus *bus, char **args) {
4443 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4444 _cleanup_free_ char *init = NULL;
4449 l = strv_length(args);
4450 if (l < 2 || l > 3) {
4451 log_error("Wrong number of arguments.");
4458 init = strdup(args[2]);
4460 parse_env_file("/proc/cmdline", WHITESPACE,
4471 log_debug("switching root - root: %s; init: %s", root, init);
4473 r = sd_bus_call_method(
4475 "org.freedesktop.systemd1",
4476 "/org/freedesktop/systemd1",
4477 "org.freedesktop.systemd1.Manager",
4483 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4490 static int set_environment(sd_bus *bus, char **args) {
4491 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4492 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4499 method = streq(args[0], "set-environment")
4501 : "UnsetEnvironment";
4503 r = sd_bus_message_new_method_call(
4506 "org.freedesktop.systemd1",
4507 "/org/freedesktop/systemd1",
4508 "org.freedesktop.systemd1.Manager",
4511 return bus_log_create_error(r);
4513 r = sd_bus_message_append_strv(m, args + 1);
4515 return bus_log_create_error(r);
4517 r = sd_bus_call(bus, m, 0, &error, NULL);
4519 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4526 static int import_environment(sd_bus *bus, char **args) {
4527 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4528 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4534 r = sd_bus_message_new_method_call(
4537 "org.freedesktop.systemd1",
4538 "/org/freedesktop/systemd1",
4539 "org.freedesktop.systemd1.Manager",
4542 return bus_log_create_error(r);
4544 if (strv_isempty(args + 1))
4545 r = sd_bus_message_append_strv(m, environ);
4549 r = sd_bus_message_open_container(m, 'a', "s");
4551 return bus_log_create_error(r);
4553 STRV_FOREACH(a, args + 1) {
4555 if (!env_name_is_valid(*a)) {
4556 log_error("Not a valid environment variable name: %s", *a);
4560 STRV_FOREACH(b, environ) {
4563 eq = startswith(*b, *a);
4564 if (eq && *eq == '=') {
4566 r = sd_bus_message_append(m, "s", *b);
4568 return bus_log_create_error(r);
4575 r = sd_bus_message_close_container(m);
4578 return bus_log_create_error(r);
4580 r = sd_bus_call(bus, m, 0, &error, NULL);
4582 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4589 static int enable_sysv_units(const char *verb, char **args) {
4592 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4593 unsigned f = 1, t = 1;
4594 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4596 if (arg_scope != UNIT_FILE_SYSTEM)
4599 if (!streq(verb, "enable") &&
4600 !streq(verb, "disable") &&
4601 !streq(verb, "is-enabled"))
4604 /* Processes all SysV units, and reshuffles the array so that
4605 * afterwards only the native units remain */
4607 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4612 for (f = 0; args[f]; f++) {
4614 _cleanup_free_ char *p = NULL, *q = NULL;
4615 bool found_native = false, found_sysv;
4617 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4625 if (!endswith(name, ".service"))
4628 if (path_is_absolute(name))
4631 STRV_FOREACH(k, paths.unit_path) {
4632 if (!isempty(arg_root))
4633 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4635 asprintf(&p, "%s/%s", *k, name);
4642 found_native = access(p, F_OK) >= 0;
4653 if (!isempty(arg_root))
4654 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4656 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4662 p[strlen(p) - sizeof(".service") + 1] = 0;
4663 found_sysv = access(p, F_OK) >= 0;
4668 /* Mark this entry, so that we don't try enabling it as native unit */
4669 args[f] = (char*) "";
4671 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4673 if (!isempty(arg_root))
4674 argv[c++] = q = strappend("--root=", arg_root);
4676 argv[c++] = basename(p);
4678 streq(verb, "enable") ? "on" :
4679 streq(verb, "disable") ? "off" : "--level=5";
4682 l = strv_join((char**)argv, " ");
4688 log_info("Executing %s", l);
4693 log_error("Failed to fork: %m");
4696 } else if (pid == 0) {
4699 execv(argv[0], (char**) argv);
4700 _exit(EXIT_FAILURE);
4703 j = wait_for_terminate(pid, &status);
4705 log_error("Failed to wait for child: %s", strerror(-r));
4710 if (status.si_code == CLD_EXITED) {
4711 if (streq(verb, "is-enabled")) {
4712 if (status.si_status == 0) {
4721 } else if (status.si_status != 0) {
4732 /* Drop all SysV units */
4733 for (f = 0, t = 0; args[f]; f++) {
4735 if (isempty(args[f]))
4738 args[t++] = args[f];
4747 static int mangle_names(char **original_names, char ***mangled_names) {
4748 char **i, **l, **name;
4750 l = new(char*, strv_length(original_names) + 1);
4755 STRV_FOREACH(name, original_names) {
4757 /* When enabling units qualified path names are OK,
4758 * too, hence allow them explicitly. */
4763 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4779 static int enable_unit(sd_bus *bus, char **args) {
4780 _cleanup_strv_free_ char **names = NULL;
4781 const char *verb = args[0];
4782 UnitFileChange *changes = NULL;
4783 unsigned n_changes = 0;
4784 int carries_install_info = -1;
4790 r = mangle_names(args+1, &names);
4794 r = enable_sysv_units(verb, names);
4798 /* If the operation was fully executed by the SysV compat,
4799 * let's finish early */
4800 if (strv_isempty(names))
4803 if (!bus || avoid_bus()) {
4804 if (streq(verb, "enable")) {
4805 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4806 carries_install_info = r;
4807 } else if (streq(verb, "disable"))
4808 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4809 else if (streq(verb, "reenable")) {
4810 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4811 carries_install_info = r;
4812 } else if (streq(verb, "link"))
4813 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4814 else if (streq(verb, "preset")) {
4815 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4816 carries_install_info = r;
4817 } else if (streq(verb, "mask"))
4818 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4819 else if (streq(verb, "unmask"))
4820 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4822 assert_not_reached("Unknown verb");
4825 log_error("Operation failed: %s", strerror(-r));
4830 dump_unit_file_changes(changes, n_changes);
4834 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4835 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4836 int expect_carries_install_info = false;
4837 bool send_force = true;
4840 if (streq(verb, "enable")) {
4841 method = "EnableUnitFiles";
4842 expect_carries_install_info = true;
4843 } else if (streq(verb, "disable")) {
4844 method = "DisableUnitFiles";
4846 } else if (streq(verb, "reenable")) {
4847 method = "ReenableUnitFiles";
4848 expect_carries_install_info = true;
4849 } else if (streq(verb, "link"))
4850 method = "LinkUnitFiles";
4851 else if (streq(verb, "preset")) {
4852 method = "PresetUnitFiles";
4853 expect_carries_install_info = true;
4854 } else if (streq(verb, "mask"))
4855 method = "MaskUnitFiles";
4856 else if (streq(verb, "unmask")) {
4857 method = "UnmaskUnitFiles";
4860 assert_not_reached("Unknown verb");
4862 r = sd_bus_message_new_method_call(
4865 "org.freedesktop.systemd1",
4866 "/org/freedesktop/systemd1",
4867 "org.freedesktop.systemd1.Manager",
4870 return bus_log_create_error(r);
4872 r = sd_bus_message_append_strv(m, names);
4874 return bus_log_create_error(r);
4876 r = sd_bus_message_append(m, "b", arg_runtime);
4878 return bus_log_create_error(r);
4881 r = sd_bus_message_append(m, "b", arg_force);
4883 return bus_log_create_error(r);
4886 r = sd_bus_call(bus, m, 0, &error, &reply);
4888 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4892 if (expect_carries_install_info) {
4893 r = sd_bus_message_read(reply, "b", &carries_install_info);
4895 return bus_log_parse_error(r);
4898 r = deserialize_and_dump_unit_file_changes(reply);
4902 /* Try to reload if enabeld */
4904 r = daemon_reload(bus, args);
4909 if (carries_install_info == 0)
4910 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4911 "using systemctl.\n"
4912 "Possible reasons for having this kind of units are:\n"
4913 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4914 " .wants/ or .requires/ directory.\n"
4915 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4916 " a requirement dependency on it.\n"
4917 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4918 " D-Bus, udev, scripted systemctl call, ...).\n");
4921 unit_file_changes_free(changes, n_changes);
4926 static int unit_is_enabled(sd_bus *bus, char **args) {
4928 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4929 _cleanup_strv_free_ char **names = NULL;
4934 r = mangle_names(args+1, &names);
4938 r = enable_sysv_units(args[0], names);
4944 if (!bus || avoid_bus()) {
4946 STRV_FOREACH(name, names) {
4947 UnitFileState state;
4949 state = unit_file_get_state(arg_scope, arg_root, *name);
4951 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4955 if (state == UNIT_FILE_ENABLED ||
4956 state == UNIT_FILE_ENABLED_RUNTIME ||
4957 state == UNIT_FILE_STATIC)
4961 puts(unit_file_state_to_string(state));
4965 STRV_FOREACH(name, names) {
4966 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4969 r = sd_bus_call_method(
4971 "org.freedesktop.systemd1",
4972 "/org/freedesktop/systemd1",
4973 "org.freedesktop.systemd1.Manager",
4979 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4983 r = sd_bus_message_read(reply, "s", &s);
4985 return bus_log_parse_error(r);
4987 if (streq(s, "enabled") ||
4988 streq(s, "enabled-runtime") ||
5000 static int systemctl_help(void) {
5002 pager_open_if_enabled();
5004 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5005 "Query or send control commands to the systemd manager.\n\n"
5006 " -h --help Show this help\n"
5007 " --version Show package version\n"
5008 " --system Connect to system manager\n"
5009 " --user Connect to user service manager\n"
5010 " -H --host=[USER@]HOST\n"
5011 " Operate on remote host\n"
5012 " -M --machine=CONTAINER\n"
5013 " Operate on local container\n"
5014 " -t --type=TYPE List only units of a particular type\n"
5015 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5016 " -p --property=NAME Show only properties by this name\n"
5017 " -a --all Show all loaded units/properties, including dead/empty\n"
5018 " ones. To list all units installed on the system, use\n"
5019 " the 'list-unit-files' command instead.\n"
5020 " -l --full Don't ellipsize unit names on output\n"
5021 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5022 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5023 " queueing a new job\n"
5024 " --show-types When showing sockets, explicitly show their type\n"
5025 " -i --ignore-inhibitors\n"
5026 " When shutting down or sleeping, ignore inhibitors\n"
5027 " --kill-who=WHO Who to send signal to\n"
5028 " -s --signal=SIGNAL Which signal to send\n"
5029 " -q --quiet Suppress output\n"
5030 " --no-block Do not wait until operation finished\n"
5031 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5032 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5034 " --no-legend Do not print a legend (column headers and hints)\n"
5035 " --no-pager Do not pipe output into a pager\n"
5036 " --no-ask-password\n"
5037 " Do not ask for system passwords\n"
5038 " --global Enable/disable unit files globally\n"
5039 " --runtime Enable unit files only temporarily until next reboot\n"
5040 " -f --force When enabling unit files, override existing symlinks\n"
5041 " When shutting down, execute action immediately\n"
5042 " --root=PATH Enable unit files in the specified root directory\n"
5043 " -n --lines=INTEGER Number of journal entries to show\n"
5044 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5045 " verbose, export, json, json-pretty, json-sse, cat)\n"
5046 " --plain Print unit dependencies as a list instead of a tree\n\n"
5048 " list-units [PATTERN...] List loaded units\n"
5049 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5050 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5051 " start NAME... Start (activate) one or more units\n"
5052 " stop NAME... Stop (deactivate) one or more units\n"
5053 " reload NAME... Reload one or more units\n"
5054 " restart NAME... Start or restart one or more units\n"
5055 " try-restart NAME... Restart one or more units if active\n"
5056 " reload-or-restart NAME... Reload one or more units if possible,\n"
5057 " otherwise start or restart\n"
5058 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5059 " otherwise restart if active\n"
5060 " isolate NAME Start one unit and stop all others\n"
5061 " kill NAME... Send signal to processes of a unit\n"
5062 " is-active NAME... Check whether units are active\n"
5063 " is-failed NAME... Check whether units are failed\n"
5064 " status [NAME...|PID...] Show runtime status of one or more units\n"
5065 " show [NAME...|JOB...] Show properties of one or more\n"
5066 " units/jobs or the manager\n"
5067 " cat NAME... Show files and drop-ins of one or more units\n"
5068 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5069 " help NAME...|PID... Show manual for one or more units\n"
5070 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
5072 " list-dependencies [NAME] Recursively show units which are required\n"
5073 " or wanted by this unit or by which this\n"
5074 " unit is required or wanted\n\n"
5075 "Unit File Commands:\n"
5076 " list-unit-files [PATTERN...] List installed unit files\n"
5077 " enable NAME... Enable one or more unit files\n"
5078 " disable NAME... Disable one or more unit files\n"
5079 " reenable NAME... Reenable one or more unit files\n"
5080 " preset NAME... Enable/disable one or more unit files\n"
5081 " based on preset configuration\n"
5082 " is-enabled NAME... Check whether unit files are enabled\n\n"
5083 " mask NAME... Mask one or more units\n"
5084 " unmask NAME... Unmask one or more units\n"
5085 " link PATH... Link one or more units files into\n"
5086 " the search path\n"
5087 " get-default Get the name of the default target\n"
5088 " set-default NAME Set the default target\n\n"
5090 " list-jobs [PATTERN...] List jobs\n"
5091 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5092 "Snapshot Commands:\n"
5093 " snapshot [NAME] Create a snapshot\n"
5094 " delete NAME... Remove one or more snapshots\n\n"
5095 "Environment Commands:\n"
5096 " show-environment Dump environment\n"
5097 " set-environment NAME=VALUE... Set one or more environment variables\n"
5098 " unset-environment NAME... Unset one or more environment variables\n"
5099 " import-environment NAME... Import all, one or more environment variables\n\n"
5100 "Manager Lifecycle Commands:\n"
5101 " daemon-reload Reload systemd manager configuration\n"
5102 " daemon-reexec Reexecute systemd manager\n\n"
5103 "System Commands:\n"
5104 " default Enter system default mode\n"
5105 " rescue Enter system rescue mode\n"
5106 " emergency Enter system emergency mode\n"
5107 " halt Shut down and halt the system\n"
5108 " poweroff Shut down and power-off the system\n"
5109 " reboot [ARG] Shut down and reboot the system\n"
5110 " kexec Shut down and reboot the system with kexec\n"
5111 " exit Request user instance exit\n"
5112 " switch-root ROOT [INIT] Change to a different root file system\n"
5113 " suspend Suspend the system\n"
5114 " hibernate Hibernate the system\n"
5115 " hybrid-sleep Hibernate and suspend the system\n",
5116 program_invocation_short_name);
5121 static int halt_help(void) {
5123 printf("%s [OPTIONS...]%s\n\n"
5124 "%s the system.\n\n"
5125 " --help Show this help\n"
5126 " --halt Halt the machine\n"
5127 " -p --poweroff Switch off the machine\n"
5128 " --reboot Reboot the machine\n"
5129 " -f --force Force immediate halt/power-off/reboot\n"
5130 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5131 " -d --no-wtmp Don't write wtmp record\n"
5132 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5133 program_invocation_short_name,
5134 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5135 arg_action == ACTION_REBOOT ? "Reboot" :
5136 arg_action == ACTION_POWEROFF ? "Power off" :
5142 static int shutdown_help(void) {
5144 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5145 "Shut down the system.\n\n"
5146 " --help Show this help\n"
5147 " -H --halt Halt the machine\n"
5148 " -P --poweroff Power-off the machine\n"
5149 " -r --reboot Reboot the machine\n"
5150 " -h Equivalent to --poweroff, overridden by --halt\n"
5151 " -k Don't halt/power-off/reboot, just send warnings\n"
5152 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5153 " -c Cancel a pending shutdown\n",
5154 program_invocation_short_name);
5159 static int telinit_help(void) {
5161 printf("%s [OPTIONS...] {COMMAND}\n\n"
5162 "Send control commands to the init daemon.\n\n"
5163 " --help Show this help\n"
5164 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5166 " 0 Power-off the machine\n"
5167 " 6 Reboot the machine\n"
5168 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5169 " 1, s, S Enter rescue mode\n"
5170 " q, Q Reload init daemon configuration\n"
5171 " u, U Reexecute init daemon\n",
5172 program_invocation_short_name);
5177 static int runlevel_help(void) {
5179 printf("%s [OPTIONS...]\n\n"
5180 "Prints the previous and current runlevel of the init system.\n\n"
5181 " --help Show this help\n",
5182 program_invocation_short_name);
5187 static int help_types(void) {
5191 puts("Available unit types:");
5192 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5193 t = unit_type_to_string(i);
5201 static int systemctl_parse_argv(int argc, char *argv[]) {
5210 ARG_IGNORE_DEPENDENCIES,
5222 ARG_NO_ASK_PASSWORD,
5231 static const struct option options[] = {
5232 { "help", no_argument, NULL, 'h' },
5233 { "version", no_argument, NULL, ARG_VERSION },
5234 { "type", required_argument, NULL, 't' },
5235 { "property", required_argument, NULL, 'p' },
5236 { "all", no_argument, NULL, 'a' },
5237 { "reverse", no_argument, NULL, ARG_REVERSE },
5238 { "after", no_argument, NULL, ARG_AFTER },
5239 { "before", no_argument, NULL, ARG_BEFORE },
5240 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5241 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5242 { "full", no_argument, NULL, 'l' },
5243 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5244 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5245 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5246 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5247 { "ignore-inhibitors", no_argument, NULL, 'i' },
5248 { "user", no_argument, NULL, ARG_USER },
5249 { "system", no_argument, NULL, ARG_SYSTEM },
5250 { "global", no_argument, NULL, ARG_GLOBAL },
5251 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5252 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5253 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5254 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5255 { "quiet", no_argument, NULL, 'q' },
5256 { "root", required_argument, NULL, ARG_ROOT },
5257 { "force", no_argument, NULL, ARG_FORCE },
5258 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5259 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5260 { "signal", required_argument, NULL, 's' },
5261 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5262 { "host", required_argument, NULL, 'H' },
5263 { "machine", required_argument, NULL, 'M' },
5264 { "runtime", no_argument, NULL, ARG_RUNTIME },
5265 { "lines", required_argument, NULL, 'n' },
5266 { "output", required_argument, NULL, 'o' },
5267 { "plain", no_argument, NULL, ARG_PLAIN },
5268 { "state", required_argument, NULL, ARG_STATE },
5277 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5282 return systemctl_help();
5285 puts(PACKAGE_STRING);
5286 puts(SYSTEMD_FEATURES);
5293 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5294 _cleanup_free_ char *type;
5296 type = strndup(word, size);
5300 if (streq(type, "help")) {
5305 if (unit_type_from_string(type) >= 0) {
5306 if (strv_push(&arg_types, type))
5312 /* It's much nicer to use --state= for
5313 * load states, but let's support this
5314 * in --types= too for compatibility
5315 * with old versions */
5316 if (unit_load_state_from_string(optarg) >= 0) {
5317 if (strv_push(&arg_states, type) < 0)
5323 log_error("Unknown unit type or load state '%s'.", type);
5324 log_info("Use -t help to see a list of allowed values.");
5332 /* Make sure that if the empty property list
5333 was specified, we won't show any properties. */
5334 if (isempty(optarg) && !arg_properties) {
5335 arg_properties = new0(char*, 1);
5336 if (!arg_properties)
5342 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5345 prop = strndup(word, size);
5349 if (strv_push(&arg_properties, prop) < 0) {
5356 /* If the user asked for a particular
5357 * property, show it to him, even if it is
5369 arg_dependency = DEPENDENCY_REVERSE;
5373 arg_dependency = DEPENDENCY_AFTER;
5377 arg_dependency = DEPENDENCY_BEFORE;
5380 case ARG_SHOW_TYPES:
5381 arg_show_types = true;
5385 arg_job_mode = optarg;
5389 arg_job_mode = "fail";
5392 case ARG_IRREVERSIBLE:
5393 arg_job_mode = "replace-irreversibly";
5396 case ARG_IGNORE_DEPENDENCIES:
5397 arg_job_mode = "ignore-dependencies";
5401 arg_scope = UNIT_FILE_USER;
5405 arg_scope = UNIT_FILE_SYSTEM;
5409 arg_scope = UNIT_FILE_GLOBAL;
5413 arg_no_block = true;
5417 arg_no_legend = true;
5421 arg_no_pager = true;
5437 if (strv_extend(&arg_states, "failed") < 0)
5455 arg_no_reload = true;
5459 arg_kill_who = optarg;
5463 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5464 log_error("Failed to parse signal string %s.", optarg);
5469 case ARG_NO_ASK_PASSWORD:
5470 arg_ask_password = false;
5474 arg_transport = BUS_TRANSPORT_REMOTE;
5479 arg_transport = BUS_TRANSPORT_CONTAINER;
5488 if (safe_atou(optarg, &arg_lines) < 0) {
5489 log_error("Failed to parse lines '%s'", optarg);
5495 arg_output = output_mode_from_string(optarg);
5496 if (arg_output < 0) {
5497 log_error("Unknown output '%s'.", optarg);
5503 arg_ignore_inhibitors = true;
5514 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5517 s = strndup(word, size);
5521 if (strv_push(&arg_states, s) < 0) {
5533 assert_not_reached("Unhandled option");
5537 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5538 log_error("Cannot access user instance remotely.");
5545 static int halt_parse_argv(int argc, char *argv[]) {
5554 static const struct option options[] = {
5555 { "help", no_argument, NULL, ARG_HELP },
5556 { "halt", no_argument, NULL, ARG_HALT },
5557 { "poweroff", no_argument, NULL, 'p' },
5558 { "reboot", no_argument, NULL, ARG_REBOOT },
5559 { "force", no_argument, NULL, 'f' },
5560 { "wtmp-only", no_argument, NULL, 'w' },
5561 { "no-wtmp", no_argument, NULL, 'd' },
5562 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5571 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5572 if (runlevel == '0' || runlevel == '6')
5575 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5582 arg_action = ACTION_HALT;
5586 if (arg_action != ACTION_REBOOT)
5587 arg_action = ACTION_POWEROFF;
5591 arg_action = ACTION_REBOOT;
5613 /* Compatibility nops */
5620 assert_not_reached("Unhandled option");
5624 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5625 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5627 log_error("Failed to write reboot param to "
5628 REBOOT_PARAM_FILE": %s", strerror(-r));
5631 } else if (optind < argc) {
5632 log_error("Too many arguments.");
5639 static int parse_time_spec(const char *t, usec_t *_u) {
5643 if (streq(t, "now"))
5645 else if (!strchr(t, ':')) {
5648 if (safe_atou64(t, &u) < 0)
5651 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5660 hour = strtol(t, &e, 10);
5661 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5664 minute = strtol(e+1, &e, 10);
5665 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5668 n = now(CLOCK_REALTIME);
5669 s = (time_t) (n / USEC_PER_SEC);
5671 assert_se(localtime_r(&s, &tm));
5673 tm.tm_hour = (int) hour;
5674 tm.tm_min = (int) minute;
5677 assert_se(s = mktime(&tm));
5679 *_u = (usec_t) s * USEC_PER_SEC;
5682 *_u += USEC_PER_DAY;
5688 static int shutdown_parse_argv(int argc, char *argv[]) {
5695 static const struct option options[] = {
5696 { "help", no_argument, NULL, ARG_HELP },
5697 { "halt", no_argument, NULL, 'H' },
5698 { "poweroff", no_argument, NULL, 'P' },
5699 { "reboot", no_argument, NULL, 'r' },
5700 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5701 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5710 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5714 return shutdown_help();
5717 arg_action = ACTION_HALT;
5721 arg_action = ACTION_POWEROFF;
5726 arg_action = ACTION_KEXEC;
5728 arg_action = ACTION_REBOOT;
5732 arg_action = ACTION_KEXEC;
5736 if (arg_action != ACTION_HALT)
5737 arg_action = ACTION_POWEROFF;
5750 /* Compatibility nops */
5754 arg_action = ACTION_CANCEL_SHUTDOWN;
5761 assert_not_reached("Unhandled option");
5765 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5766 r = parse_time_spec(argv[optind], &arg_when);
5768 log_error("Failed to parse time specification: %s", argv[optind]);
5772 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5774 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5775 /* No time argument for shutdown cancel */
5776 arg_wall = argv + optind;
5777 else if (argc > optind + 1)
5778 /* We skip the time argument */
5779 arg_wall = argv + optind + 1;
5786 static int telinit_parse_argv(int argc, char *argv[]) {
5793 static const struct option options[] = {
5794 { "help", no_argument, NULL, ARG_HELP },
5795 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5799 static const struct {
5803 { '0', ACTION_POWEROFF },
5804 { '6', ACTION_REBOOT },
5805 { '1', ACTION_RESCUE },
5806 { '2', ACTION_RUNLEVEL2 },
5807 { '3', ACTION_RUNLEVEL3 },
5808 { '4', ACTION_RUNLEVEL4 },
5809 { '5', ACTION_RUNLEVEL5 },
5810 { 's', ACTION_RESCUE },
5811 { 'S', ACTION_RESCUE },
5812 { 'q', ACTION_RELOAD },
5813 { 'Q', ACTION_RELOAD },
5814 { 'u', ACTION_REEXEC },
5815 { 'U', ACTION_REEXEC }
5824 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5828 return telinit_help();
5838 assert_not_reached("Unhandled option");
5842 if (optind >= argc) {
5847 if (optind + 1 < argc) {
5848 log_error("Too many arguments.");
5852 if (strlen(argv[optind]) != 1) {
5853 log_error("Expected single character argument.");
5857 for (i = 0; i < ELEMENTSOF(table); i++)
5858 if (table[i].from == argv[optind][0])
5861 if (i >= ELEMENTSOF(table)) {
5862 log_error("Unknown command '%s'.", argv[optind]);
5866 arg_action = table[i].to;
5873 static int runlevel_parse_argv(int argc, char *argv[]) {
5879 static const struct option options[] = {
5880 { "help", no_argument, NULL, ARG_HELP },
5889 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5893 return runlevel_help();
5899 assert_not_reached("Unhandled option");
5903 if (optind < argc) {
5904 log_error("Too many arguments.");
5911 static int parse_argv(int argc, char *argv[]) {
5915 if (program_invocation_short_name) {
5917 if (strstr(program_invocation_short_name, "halt")) {
5918 arg_action = ACTION_HALT;
5919 return halt_parse_argv(argc, argv);
5920 } else if (strstr(program_invocation_short_name, "poweroff")) {
5921 arg_action = ACTION_POWEROFF;
5922 return halt_parse_argv(argc, argv);
5923 } else if (strstr(program_invocation_short_name, "reboot")) {
5925 arg_action = ACTION_KEXEC;
5927 arg_action = ACTION_REBOOT;
5928 return halt_parse_argv(argc, argv);
5929 } else if (strstr(program_invocation_short_name, "shutdown")) {
5930 arg_action = ACTION_POWEROFF;
5931 return shutdown_parse_argv(argc, argv);
5932 } else if (strstr(program_invocation_short_name, "init")) {
5934 if (sd_booted() > 0) {
5935 arg_action = _ACTION_INVALID;
5936 return telinit_parse_argv(argc, argv);
5938 /* Hmm, so some other init system is
5939 * running, we need to forward this
5940 * request to it. For now we simply
5941 * guess that it is Upstart. */
5943 execv(TELINIT, argv);
5945 log_error("Couldn't find an alternative telinit implementation to spawn.");
5949 } else if (strstr(program_invocation_short_name, "runlevel")) {
5950 arg_action = ACTION_RUNLEVEL;
5951 return runlevel_parse_argv(argc, argv);
5955 arg_action = ACTION_SYSTEMCTL;
5956 return systemctl_parse_argv(argc, argv);
5959 _pure_ static int action_to_runlevel(void) {
5961 static const char table[_ACTION_MAX] = {
5962 [ACTION_HALT] = '0',
5963 [ACTION_POWEROFF] = '0',
5964 [ACTION_REBOOT] = '6',
5965 [ACTION_RUNLEVEL2] = '2',
5966 [ACTION_RUNLEVEL3] = '3',
5967 [ACTION_RUNLEVEL4] = '4',
5968 [ACTION_RUNLEVEL5] = '5',
5969 [ACTION_RESCUE] = '1'
5972 assert(arg_action < _ACTION_MAX);
5974 return table[arg_action];
5977 static int talk_initctl(void) {
5979 struct init_request request = {
5980 .magic = INIT_MAGIC,
5982 .cmd = INIT_CMD_RUNLVL
5985 _cleanup_close_ int fd = -1;
5989 rl = action_to_runlevel();
5993 request.runlevel = rl;
5995 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5997 if (errno == ENOENT)
6000 log_error("Failed to open "INIT_FIFO": %m");
6005 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6007 log_error("Failed to write to "INIT_FIFO": %m");
6008 return errno > 0 ? -errno : -EIO;
6014 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6016 static const struct {
6024 int (* const dispatch)(sd_bus *bus, char **args);
6030 { "list-units", MORE, 0, list_units },
6031 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6032 { "list-sockets", MORE, 1, list_sockets },
6033 { "list-timers", MORE, 1, list_timers },
6034 { "list-jobs", MORE, 1, list_jobs },
6035 { "clear-jobs", EQUAL, 1, daemon_reload },
6036 { "cancel", MORE, 2, cancel_job },
6037 { "start", MORE, 2, start_unit },
6038 { "stop", MORE, 2, start_unit },
6039 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6040 { "reload", MORE, 2, start_unit },
6041 { "restart", MORE, 2, start_unit },
6042 { "try-restart", MORE, 2, start_unit },
6043 { "reload-or-restart", MORE, 2, start_unit },
6044 { "reload-or-try-restart", MORE, 2, start_unit },
6045 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6046 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6047 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6048 { "isolate", EQUAL, 2, start_unit },
6049 { "kill", MORE, 2, kill_unit },
6050 { "is-active", MORE, 2, check_unit_active },
6051 { "check", MORE, 2, check_unit_active },
6052 { "is-failed", MORE, 2, check_unit_failed },
6053 { "show", MORE, 1, show },
6054 { "cat", MORE, 2, cat },
6055 { "status", MORE, 1, show },
6056 { "help", MORE, 2, show },
6057 { "snapshot", LESS, 2, snapshot },
6058 { "delete", MORE, 2, delete_snapshot },
6059 { "daemon-reload", EQUAL, 1, daemon_reload },
6060 { "daemon-reexec", EQUAL, 1, daemon_reload },
6061 { "show-environment", EQUAL, 1, show_environment },
6062 { "set-environment", MORE, 2, set_environment },
6063 { "unset-environment", MORE, 2, set_environment },
6064 { "import-environment", MORE, 1, import_environment},
6065 { "halt", EQUAL, 1, start_special, FORCE },
6066 { "poweroff", EQUAL, 1, start_special, FORCE },
6067 { "reboot", EQUAL, 1, start_special, FORCE },
6068 { "kexec", EQUAL, 1, start_special },
6069 { "suspend", EQUAL, 1, start_special },
6070 { "hibernate", EQUAL, 1, start_special },
6071 { "hybrid-sleep", EQUAL, 1, start_special },
6072 { "default", EQUAL, 1, start_special },
6073 { "rescue", EQUAL, 1, start_special },
6074 { "emergency", EQUAL, 1, start_special },
6075 { "exit", EQUAL, 1, start_special },
6076 { "reset-failed", MORE, 1, reset_failed },
6077 { "enable", MORE, 2, enable_unit, NOBUS },
6078 { "disable", MORE, 2, enable_unit, NOBUS },
6079 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6080 { "reenable", MORE, 2, enable_unit, NOBUS },
6081 { "preset", MORE, 2, enable_unit, NOBUS },
6082 { "mask", MORE, 2, enable_unit, NOBUS },
6083 { "unmask", MORE, 2, enable_unit, NOBUS },
6084 { "link", MORE, 2, enable_unit, NOBUS },
6085 { "switch-root", MORE, 2, switch_root },
6086 { "list-dependencies", LESS, 2, list_dependencies },
6087 { "set-default", EQUAL, 2, set_default, NOBUS },
6088 { "get-default", EQUAL, 1, get_default, NOBUS },
6089 { "set-property", MORE, 3, set_property },
6098 left = argc - optind;
6100 /* Special rule: no arguments (left == 0) means "list-units" */
6102 if (streq(argv[optind], "help") && !argv[optind+1]) {
6103 log_error("This command expects one or more "
6104 "unit names. Did you mean --help?");
6108 for (; verb->verb; verb++)
6109 if (streq(argv[optind], verb->verb))
6112 log_error("Unknown operation '%s'.", argv[optind]);
6117 switch (verb->argc_cmp) {
6120 if (left != verb->argc) {
6121 log_error("Invalid number of arguments.");
6128 if (left < verb->argc) {
6129 log_error("Too few arguments.");
6136 if (left > verb->argc) {
6137 log_error("Too many arguments.");
6144 assert_not_reached("Unknown comparison operator.");
6147 /* Require a bus connection for all operations but
6149 if (verb->bus == NOBUS) {
6150 if (!bus && !avoid_bus()) {
6151 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6156 if (running_in_chroot() > 0) {
6157 log_info("Running in chroot, ignoring request.");
6161 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6162 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6167 return verb->dispatch(bus, argv + optind);
6170 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6172 struct sd_shutdown_command c = {
6179 union sockaddr_union sockaddr = {
6180 .un.sun_family = AF_UNIX,
6181 .un.sun_path = "/run/systemd/shutdownd",
6184 struct iovec iovec[2] = {{
6185 .iov_base = (char*) &c,
6186 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6189 struct msghdr msghdr = {
6190 .msg_name = &sockaddr,
6191 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6192 + sizeof("/run/systemd/shutdownd") - 1,
6197 _cleanup_close_ int fd;
6199 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6203 if (!isempty(message)) {
6204 iovec[1].iov_base = (char*) message;
6205 iovec[1].iov_len = strlen(message);
6206 msghdr.msg_iovlen++;
6209 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6215 static int reload_with_fallback(sd_bus *bus) {
6218 /* First, try systemd via D-Bus. */
6219 if (daemon_reload(bus, NULL) >= 0)
6223 /* Nothing else worked, so let's try signals */
6224 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6226 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6227 log_error("kill() failed: %m");
6234 static int start_with_fallback(sd_bus *bus) {
6237 /* First, try systemd via D-Bus. */
6238 if (start_unit(bus, NULL) >= 0)
6242 /* Nothing else worked, so let's try
6244 if (talk_initctl() > 0)
6247 log_error("Failed to talk to init daemon.");
6251 warn_wall(arg_action);
6255 static int halt_now(enum action a) {
6257 /* Make sure C-A-D is handled by the kernel from this
6259 reboot(RB_ENABLE_CAD);
6264 log_info("Halting.");
6265 reboot(RB_HALT_SYSTEM);
6268 case ACTION_POWEROFF:
6269 log_info("Powering off.");
6270 reboot(RB_POWER_OFF);
6273 case ACTION_REBOOT: {
6274 _cleanup_free_ char *param = NULL;
6276 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6277 log_info("Rebooting with argument '%s'.", param);
6278 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6279 LINUX_REBOOT_CMD_RESTART2, param);
6282 log_info("Rebooting.");
6283 reboot(RB_AUTOBOOT);
6288 assert_not_reached("Unknown action.");
6292 static int halt_main(sd_bus *bus) {
6295 r = check_inhibitors(bus, arg_action);
6299 if (geteuid() != 0) {
6300 /* Try logind if we are a normal user and no special
6301 * mode applies. Maybe PolicyKit allows us to shutdown
6304 if (arg_when <= 0 &&
6307 (arg_action == ACTION_POWEROFF ||
6308 arg_action == ACTION_REBOOT)) {
6309 r = reboot_with_logind(bus, arg_action);
6314 log_error("Must be root.");
6319 _cleanup_free_ char *m;
6321 m = strv_join(arg_wall, " ");
6325 r = send_shutdownd(arg_when,
6326 arg_action == ACTION_HALT ? 'H' :
6327 arg_action == ACTION_POWEROFF ? 'P' :
6328 arg_action == ACTION_KEXEC ? 'K' :
6335 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6337 char date[FORMAT_TIMESTAMP_MAX];
6339 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6340 format_timestamp(date, sizeof(date), arg_when));
6345 if (!arg_dry && !arg_force)
6346 return start_with_fallback(bus);
6349 if (sd_booted() > 0)
6350 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6352 r = utmp_put_shutdown();
6354 log_warning("Failed to write utmp record: %s", strerror(-r));
6361 r = halt_now(arg_action);
6362 log_error("Failed to reboot: %s", strerror(-r));
6367 static int runlevel_main(void) {
6368 int r, runlevel, previous;
6370 r = utmp_get_runlevel(&runlevel, &previous);
6377 previous <= 0 ? 'N' : previous,
6378 runlevel <= 0 ? 'N' : runlevel);
6383 int main(int argc, char*argv[]) {
6384 _cleanup_bus_unref_ sd_bus *bus = NULL;
6387 setlocale(LC_ALL, "");
6388 log_parse_environment();
6391 /* Explicitly not on_tty() to avoid setting cached value.
6392 * This becomes relevant for piping output which might be
6394 original_stdout_is_tty = isatty(STDOUT_FILENO);
6396 r = parse_argv(argc, argv);
6400 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6401 * let's shortcut this */
6402 if (arg_action == ACTION_RUNLEVEL) {
6403 r = runlevel_main();
6407 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6408 log_info("Running in chroot, ignoring request.");
6414 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6416 /* systemctl_main() will print an error message for the bus
6417 * connection, but only if it needs to */
6419 switch (arg_action) {
6421 case ACTION_SYSTEMCTL:
6422 r = systemctl_main(bus, argc, argv, r);
6426 case ACTION_POWEROFF:
6432 case ACTION_RUNLEVEL2:
6433 case ACTION_RUNLEVEL3:
6434 case ACTION_RUNLEVEL4:
6435 case ACTION_RUNLEVEL5:
6437 case ACTION_EMERGENCY:
6438 case ACTION_DEFAULT:
6439 r = start_with_fallback(bus);
6444 r = reload_with_fallback(bus);
6447 case ACTION_CANCEL_SHUTDOWN: {
6448 _cleanup_free_ char *m = NULL;
6451 m = strv_join(arg_wall, " ");
6458 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6460 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6464 case ACTION_RUNLEVEL:
6465 case _ACTION_INVALID:
6467 assert_not_reached("Unknown action");
6472 ask_password_agent_close();
6473 polkit_agent_close();
6475 strv_free(arg_types);
6476 strv_free(arg_states);
6477 strv_free(arg_properties);
6479 return r < 0 ? EXIT_FAILURE : r;