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, " ");
260 utmp_wall(p, NULL, NULL);
268 utmp_wall(table[a], NULL, 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 = strlen("UNIT");
337 load_len = strlen("LOAD");
338 active_len = strlen("ACTIVE");
339 sub_len = strlen("SUB");
340 job_len = strlen("JOB");
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 = strlen("LISTEN"),
643 typelen = strlen("TYPE") * arg_show_types,
644 socklen = strlen("UNIT"),
645 servlen = strlen("ACTIVATES");
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 = strlen("NEXT"),
840 leftlen = strlen("LEFT"),
841 unitlen = strlen("UNIT"),
842 activatelen = strlen("ACTIVATES");
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;
1035 const UnitFileList *u;
1037 max_id_len = strlen("UNIT FILE");
1038 state_cols = strlen("STATE");
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;
1065 if (u->state == UNIT_FILE_MASKED ||
1066 u->state == UNIT_FILE_MASKED_RUNTIME ||
1067 u->state == UNIT_FILE_DISABLED ||
1068 u->state == UNIT_FILE_INVALID) {
1069 on = ansi_highlight_red();
1070 off = ansi_highlight_off();
1071 } else if (u->state == UNIT_FILE_ENABLED) {
1072 on = ansi_highlight_green();
1073 off = ansi_highlight_off();
1077 id = basename(u->path);
1079 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1081 printf("%-*s %s%-*s%s\n",
1082 id_cols, e ? e : id,
1083 on, state_cols, unit_file_state_to_string(u->state), off);
1087 printf("\n%u unit files listed.\n", c);
1090 static int list_unit_files(sd_bus *bus, char **args) {
1091 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1092 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1093 _cleanup_free_ UnitFileList *units = NULL;
1101 pager_open_if_enabled();
1109 h = hashmap_new(string_hash_func, string_compare_func);
1113 r = unit_file_get_list(arg_scope, arg_root, h);
1115 unit_file_list_free(h);
1116 log_error("Failed to get unit file list: %s", strerror(-r));
1120 n_units = hashmap_size(h);
1121 units = new(UnitFileList, n_units);
1123 unit_file_list_free(h);
1127 HASHMAP_FOREACH(u, h, i) {
1128 if (!output_show_unit_file(u, strv_skip_first(args)))
1135 assert(c <= n_units);
1138 r = sd_bus_call_method(
1140 "org.freedesktop.systemd1",
1141 "/org/freedesktop/systemd1",
1142 "org.freedesktop.systemd1.Manager",
1148 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1152 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1154 return bus_log_parse_error(r);
1156 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1158 if (!GREEDY_REALLOC(units, size, c + 1))
1161 units[c] = (struct UnitFileList) {
1163 unit_file_state_from_string(state)
1166 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1171 return bus_log_parse_error(r);
1173 r = sd_bus_message_exit_container(reply);
1175 return bus_log_parse_error(r);
1179 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1180 output_unit_file_list(units, c);
1184 for (unit = units; unit < units + c; unit++)
1190 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1191 _cleanup_free_ char *n = NULL;
1192 size_t max_len = MAX(columns(),20u);
1198 for (i = level - 1; i >= 0; i--) {
1200 if (len > max_len - 3 && !arg_full) {
1201 printf("%s...\n",max_len % 2 ? "" : " ");
1204 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1208 if (len > max_len - 3 && !arg_full) {
1209 printf("%s...\n",max_len % 2 ? "" : " ");
1213 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1217 printf("%s\n", name);
1221 n = ellipsize(name, max_len-len, 100);
1229 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1231 static const char *dependencies[_DEPENDENCY_MAX] = {
1232 [DEPENDENCY_FORWARD] = "Requires\0"
1233 "RequiresOverridable\0"
1235 "RequisiteOverridable\0"
1237 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1238 "RequiredByOverridable\0"
1241 [DEPENDENCY_AFTER] = "After\0",
1242 [DEPENDENCY_BEFORE] = "Before\0",
1245 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1246 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1247 _cleanup_strv_free_ char **ret = NULL;
1248 _cleanup_free_ char *path = NULL;
1254 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1256 path = unit_dbus_path_from_name(name);
1260 r = sd_bus_call_method(
1262 "org.freedesktop.systemd1",
1264 "org.freedesktop.DBus.Properties",
1268 "s", "org.freedesktop.systemd1.Unit");
1270 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1274 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1276 return bus_log_parse_error(r);
1278 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1281 r = sd_bus_message_read(reply, "s", &prop);
1283 return bus_log_parse_error(r);
1285 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1286 r = sd_bus_message_skip(reply, "v");
1288 return bus_log_parse_error(r);
1291 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1293 return bus_log_parse_error(r);
1295 r = bus_message_read_strv_extend(reply, &ret);
1297 return bus_log_parse_error(r);
1299 r = sd_bus_message_exit_container(reply);
1301 return bus_log_parse_error(r);
1304 r = sd_bus_message_exit_container(reply);
1306 return bus_log_parse_error(r);
1310 return bus_log_parse_error(r);
1312 r = sd_bus_message_exit_container(reply);
1314 return bus_log_parse_error(r);
1322 static int list_dependencies_compare(const void *_a, const void *_b) {
1323 const char **a = (const char**) _a, **b = (const char**) _b;
1325 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1327 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1330 return strcasecmp(*a, *b);
1333 static int list_dependencies_one(
1338 unsigned int branches) {
1340 _cleanup_strv_free_ char **deps = NULL;
1348 r = strv_extend(units, name);
1352 r = list_dependencies_get_dependencies(bus, name, &deps);
1356 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1358 STRV_FOREACH(c, deps) {
1361 if (strv_contains(*units, *c)) {
1363 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1370 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1372 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1374 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1376 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1380 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1381 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1388 strv_remove(*units, name);
1393 static int list_dependencies(sd_bus *bus, char **args) {
1394 _cleanup_strv_free_ char **units = NULL;
1395 _cleanup_free_ char *unit = NULL;
1401 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1406 u = SPECIAL_DEFAULT_TARGET;
1408 pager_open_if_enabled();
1412 return list_dependencies_one(bus, u, 0, &units, 0);
1415 struct machine_info {
1419 char *control_group;
1420 uint32_t n_failed_units;
1425 static const struct bus_properties_map machine_info_property_map[] = {
1426 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1427 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1428 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1429 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1430 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1434 static void free_machines_list(struct machine_info *machine_infos, int n) {
1440 for (i = 0; i < n; i++) {
1441 free(machine_infos[i].name);
1442 free(machine_infos[i].state);
1443 free(machine_infos[i].control_group);
1446 free(machine_infos);
1449 static int compare_machine_info(const void *a, const void *b) {
1450 const struct machine_info *u = a, *v = b;
1452 if (u->is_host != v->is_host)
1453 return u->is_host > v->is_host ? 1 : -1;
1455 return strcasecmp(u->name, v->name);
1458 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1459 _cleanup_bus_unref_ sd_bus *container = NULL;
1465 r = sd_bus_open_system_container(&container, mi->name);
1472 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1479 static bool output_show_machine(const char *name, char **patterns) {
1484 if (strv_isempty(patterns))
1487 STRV_FOREACH(i, patterns)
1488 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1494 static int get_machine_list(
1496 struct machine_info **_machine_infos,
1499 struct machine_info *machine_infos = NULL;
1500 _cleanup_strv_free_ char **m = NULL;
1501 _cleanup_free_ char *hn = NULL;
1506 hn = gethostname_malloc();
1510 if (output_show_machine(hn, patterns)) {
1511 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1514 machine_infos[c].is_host = true;
1515 machine_infos[c].name = hn;
1518 get_machine_properties(bus, &machine_infos[c]);
1522 sd_get_machine_names(&m);
1523 STRV_FOREACH(i, m) {
1524 _cleanup_free_ char *class = NULL;
1526 if (!output_show_machine(*i, patterns))
1529 sd_machine_get_class(*i, &class);
1530 if (!streq_ptr(class, "container"))
1533 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1534 free_machines_list(machine_infos, c);
1538 machine_infos[c].is_host = false;
1539 machine_infos[c].name = strdup(*i);
1540 if (!machine_infos[c].name) {
1541 free_machines_list(machine_infos, c);
1545 get_machine_properties(NULL, &machine_infos[c]);
1549 *_machine_infos = machine_infos;
1553 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1554 struct machine_info *m;
1556 namelen = sizeof("NAME") - 1,
1557 statelen = sizeof("STATE") - 1,
1558 failedlen = sizeof("FAILED") - 1,
1559 jobslen = sizeof("JOBS") - 1;
1561 assert(machine_infos || n == 0);
1563 for (m = machine_infos; m < machine_infos + n; m++) {
1564 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1565 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1566 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1567 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1571 printf("%-*s %-*s %-*s %-*s\n",
1574 failedlen, "FAILED",
1577 for (m = machine_infos; m < machine_infos + n; m++) {
1578 const char *on_state, *off_state, *on_failed, *off_failed;
1580 if (streq_ptr(m->state, "degraded")) {
1581 on_state = ansi_highlight_red();
1582 off_state = ansi_highlight_off();
1583 } else if (!streq_ptr(m->state, "running")) {
1584 on_state = ansi_highlight_yellow();
1585 off_state = ansi_highlight_off();
1587 on_state = off_state = "";
1589 if (m->n_failed_units > 0) {
1590 on_failed = ansi_highlight_red();
1591 off_failed = ansi_highlight_off();
1593 on_failed = off_failed = "";
1596 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1597 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1598 on_state, statelen, strna(m->state), off_state,
1599 on_failed, failedlen, m->n_failed_units, off_failed,
1600 jobslen, m->n_jobs);
1602 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1603 namelen, strna(m->name),
1604 on_state, statelen, strna(m->state), off_state,
1605 on_failed, failedlen, m->n_failed_units, off_failed,
1606 jobslen, m->n_jobs);
1610 printf("\n%u machines listed.\n", n);
1613 static int list_machines(sd_bus *bus, char **args) {
1614 struct machine_info *machine_infos = NULL;
1619 if (geteuid() != 0) {
1620 log_error("Must be root.");
1624 pager_open_if_enabled();
1626 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1630 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1631 output_machines_list(machine_infos, r);
1632 free_machines_list(machine_infos, r);
1637 static int get_default(sd_bus *bus, char **args) {
1638 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1639 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1640 _cleanup_free_ char *_path = NULL;
1644 if (!bus || avoid_bus()) {
1645 r = unit_file_get_default(arg_scope, arg_root, &_path);
1647 log_error("Failed to get default target: %s", strerror(-r));
1653 r = sd_bus_call_method(
1655 "org.freedesktop.systemd1",
1656 "/org/freedesktop/systemd1",
1657 "org.freedesktop.systemd1.Manager",
1663 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1667 r = sd_bus_message_read(reply, "s", &path);
1669 return bus_log_parse_error(r);
1673 printf("%s\n", path);
1678 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1681 assert(changes || n_changes == 0);
1683 for (i = 0; i < n_changes; i++) {
1684 if (changes[i].type == UNIT_FILE_SYMLINK)
1685 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1687 log_info("rm '%s'", changes[i].path);
1691 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1692 const char *type, *path, *source;
1695 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1697 return bus_log_parse_error(r);
1699 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1701 if (streq(type, "symlink"))
1702 log_info("ln -s '%s' '%s'", source, path);
1704 log_info("rm '%s'", path);
1708 return bus_log_parse_error(r);
1710 r = sd_bus_message_exit_container(m);
1712 return bus_log_parse_error(r);
1717 static int set_default(sd_bus *bus, char **args) {
1718 _cleanup_free_ char *unit = NULL;
1719 UnitFileChange *changes = NULL;
1720 unsigned n_changes = 0;
1723 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1727 if (!bus || avoid_bus()) {
1728 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1730 log_error("Failed to set default target: %s", strerror(-r));
1735 dump_unit_file_changes(changes, n_changes);
1739 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1740 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1742 r = sd_bus_call_method(
1744 "org.freedesktop.systemd1",
1745 "/org/freedesktop/systemd1",
1746 "org.freedesktop.systemd1.Manager",
1750 "sb", unit, arg_force);
1752 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1756 r = deserialize_and_dump_unit_file_changes(reply);
1760 /* Try to reload if enabeld */
1762 r = daemon_reload(bus, args);
1767 unit_file_changes_free(changes, n_changes);
1774 const char *name, *type, *state;
1777 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1778 unsigned id_len, unit_len, type_len, state_len;
1779 const struct job_info *j;
1780 const char *on, *off;
1781 bool shorten = false;
1783 assert(n == 0 || jobs);
1786 on = ansi_highlight_green();
1787 off = ansi_highlight_off();
1789 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1793 pager_open_if_enabled();
1795 id_len = strlen("JOB");
1796 unit_len = strlen("UNIT");
1797 type_len = strlen("TYPE");
1798 state_len = strlen("STATE");
1800 for (j = jobs; j < jobs + n; j++) {
1801 uint32_t id = j->id;
1802 assert(j->name && j->type && j->state);
1804 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1805 unit_len = MAX(unit_len, strlen(j->name));
1806 type_len = MAX(type_len, strlen(j->type));
1807 state_len = MAX(state_len, strlen(j->state));
1810 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1811 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1816 printf("%*s %-*s %-*s %-*s\n",
1820 state_len, "STATE");
1822 for (j = jobs; j < jobs + n; j++) {
1823 _cleanup_free_ char *e = NULL;
1825 if (streq(j->state, "running")) {
1826 on = ansi_highlight();
1827 off = ansi_highlight_off();
1831 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1832 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1834 on, unit_len, e ? e : j->name, off,
1836 on, state_len, j->state, off);
1839 if (!arg_no_legend) {
1840 on = ansi_highlight();
1841 off = ansi_highlight_off();
1843 printf("\n%s%u jobs listed%s.\n", on, n, off);
1847 static bool output_show_job(struct job_info *job, char **patterns) {
1852 if (strv_isempty(patterns))
1855 STRV_FOREACH(pattern, patterns)
1856 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1861 static int list_jobs(sd_bus *bus, char **args) {
1862 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1863 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1864 const char *name, *type, *state, *job_path, *unit_path;
1865 _cleanup_free_ struct job_info *jobs = NULL;
1870 bool skipped = false;
1872 r = sd_bus_call_method(
1874 "org.freedesktop.systemd1",
1875 "/org/freedesktop/systemd1",
1876 "org.freedesktop.systemd1.Manager",
1882 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1886 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1888 return bus_log_parse_error(r);
1890 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1891 struct job_info job = { id, name, type, state };
1893 if (!output_show_job(&job, strv_skip_first(args))) {
1898 if (!GREEDY_REALLOC(jobs, size, c + 1))
1904 return bus_log_parse_error(r);
1906 r = sd_bus_message_exit_container(reply);
1908 return bus_log_parse_error(r);
1910 output_jobs_list(jobs, c, skipped);
1914 static int cancel_job(sd_bus *bus, char **args) {
1915 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1920 if (strv_length(args) <= 1)
1921 return daemon_reload(bus, args);
1923 STRV_FOREACH(name, args+1) {
1927 r = safe_atou32(*name, &id);
1929 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1933 r = sd_bus_call_method(
1935 "org.freedesktop.systemd1",
1936 "/org/freedesktop/systemd1",
1937 "org.freedesktop.systemd1.Manager",
1943 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1951 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1952 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1956 /* We ignore all errors here, since this is used to show a
1959 /* We don't use unit_dbus_path_from_name() directly since we
1960 * don't want to load the unit if it isn't loaded. */
1962 r = sd_bus_call_method(
1964 "org.freedesktop.systemd1",
1965 "/org/freedesktop/systemd1",
1966 "org.freedesktop.systemd1.Manager",
1974 r = sd_bus_message_read(reply, "o", &path);
1978 r = sd_bus_get_property_trivial(
1980 "org.freedesktop.systemd1",
1982 "org.freedesktop.systemd1.Unit",
1992 typedef struct WaitData {
1999 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2006 log_debug("Got D-Bus request: %s.%s() on %s",
2007 sd_bus_message_get_interface(m),
2008 sd_bus_message_get_member(m),
2009 sd_bus_message_get_path(m));
2011 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2012 log_error("Warning! D-Bus connection terminated.");
2014 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2016 const char *path, *result, *unit;
2020 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2022 ret = set_remove(d->set, (char*) path);
2028 if (!isempty(result))
2029 d->result = strdup(result);
2032 d->name = strdup(unit);
2037 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2039 ret = set_remove(d->set, (char*) path);
2046 d->result = strdup(result);
2052 bus_log_parse_error(r);
2058 static int enable_wait_for_jobs(sd_bus *bus) {
2063 r = sd_bus_add_match(
2066 "sender='org.freedesktop.systemd1',"
2067 "interface='org.freedesktop.systemd1.Manager',"
2068 "member='JobRemoved',"
2069 "path='/org/freedesktop/systemd1'",
2072 log_error("Failed to add match");
2076 /* This is slightly dirty, since we don't undo the match registrations. */
2080 static int bus_process_wait(sd_bus *bus) {
2084 r = sd_bus_process(bus, NULL);
2089 r = sd_bus_wait(bus, (uint64_t) -1);
2095 static int check_wait_response(WaitData *d) {
2101 if (streq(d->result, "timeout"))
2102 log_error("Job for %s timed out.", strna(d->name));
2103 else if (streq(d->result, "canceled"))
2104 log_error("Job for %s canceled.", strna(d->name));
2105 else if (streq(d->result, "dependency"))
2106 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2107 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2108 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2111 if (streq(d->result, "timeout"))
2113 else if (streq(d->result, "canceled"))
2115 else if (streq(d->result, "dependency"))
2117 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2123 static int wait_for_jobs(sd_bus *bus, Set *s) {
2124 WaitData d = { .set = s };
2130 q = sd_bus_add_filter(bus, wait_filter, &d);
2134 while (!set_isempty(s)) {
2135 q = bus_process_wait(bus);
2137 log_error("Failed to wait for response: %s", strerror(-r));
2142 q = check_wait_response(&d);
2143 /* Return the first error as it is most likely to be
2145 if (q < 0 && r == 0)
2147 log_debug("Got result %s/%s for job %s",
2148 strna(d.result), strerror(-q), strna(d.name));
2158 q = sd_bus_remove_filter(bus, wait_filter, &d);
2159 if (q < 0 && r == 0)
2165 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2166 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2167 _cleanup_free_ char *n = NULL, *state = NULL;
2173 n = unit_name_mangle(name, MANGLE_NOGLOB);
2177 /* We don't use unit_dbus_path_from_name() directly since we
2178 * don't want to load the unit if it isn't loaded. */
2180 r = sd_bus_call_method(
2182 "org.freedesktop.systemd1",
2183 "/org/freedesktop/systemd1",
2184 "org.freedesktop.systemd1.Manager",
2195 r = sd_bus_message_read(reply, "o", &path);
2197 return bus_log_parse_error(r);
2199 r = sd_bus_get_property_string(
2201 "org.freedesktop.systemd1",
2203 "org.freedesktop.systemd1.Unit",
2216 return nulstr_contains(good_states, state);
2219 static int check_triggering_units(
2223 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2224 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2225 _cleanup_strv_free_ char **triggered_by = NULL;
2226 bool print_warning_label = true;
2230 n = unit_name_mangle(name, MANGLE_NOGLOB);
2234 path = unit_dbus_path_from_name(n);
2238 r = sd_bus_get_property_string(
2240 "org.freedesktop.systemd1",
2242 "org.freedesktop.systemd1.Unit",
2247 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2251 if (streq(state, "masked"))
2254 r = sd_bus_get_property_strv(
2256 "org.freedesktop.systemd1",
2258 "org.freedesktop.systemd1.Unit",
2263 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2267 STRV_FOREACH(i, triggered_by) {
2268 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2270 log_error("Failed to check unit: %s", strerror(-r));
2277 if (print_warning_label) {
2278 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2279 print_warning_label = false;
2282 log_warning(" %s", *i);
2288 static const char *verb_to_method(const char *verb) {
2291 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2292 if (streq_ptr(unit_actions[i].verb, verb))
2293 return unit_actions[i].method;
2298 static const char *method_to_verb(const char *method) {
2301 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2302 if (streq_ptr(unit_actions[i].method, method))
2303 return unit_actions[i].verb;
2308 static int start_unit_one(
2313 sd_bus_error *error,
2316 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2325 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2326 r = sd_bus_call_method(
2328 "org.freedesktop.systemd1",
2329 "/org/freedesktop/systemd1",
2330 "org.freedesktop.systemd1.Manager",
2338 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2339 /* There's always a fallback possible for
2340 * legacy actions. */
2341 return -EADDRNOTAVAIL;
2343 verb = method_to_verb(method);
2345 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2349 r = sd_bus_message_read(reply, "o", &path);
2351 return bus_log_parse_error(r);
2353 if (need_daemon_reload(bus, name) > 0)
2354 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2355 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2364 log_debug("Adding %s to the set", p);
2365 r = set_consume(s, p);
2373 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2375 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2376 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2380 STRV_FOREACH(name, names) {
2384 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2386 t = unit_name_mangle(*name, MANGLE_GLOB);
2390 if (string_is_glob(t))
2391 r = strv_consume(&globs, t);
2393 r = strv_consume(&mangled, t);
2398 /* Query the manager only if any of the names are a glob, since
2399 * this is fairly expensive */
2400 if (!strv_isempty(globs)) {
2401 _cleanup_free_ UnitInfo *unit_infos = NULL;
2403 r = get_unit_list(bus, &reply, &unit_infos, globs);
2407 for (i = 0; i < r; i++)
2408 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2413 mangled = NULL; /* do not free */
2417 static const struct {
2421 } action_table[_ACTION_MAX] = {
2422 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2423 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2424 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2425 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2426 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2427 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2428 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2429 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2430 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2431 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2432 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2433 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2434 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2435 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2436 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2439 static enum action verb_to_action(const char *verb) {
2442 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2443 if (streq_ptr(action_table[i].verb, verb))
2446 return _ACTION_INVALID;
2449 static int start_unit(sd_bus *bus, char **args) {
2450 _cleanup_set_free_free_ Set *s = NULL;
2451 _cleanup_strv_free_ char **names = NULL;
2452 const char *method, *mode, *one_name;
2458 ask_password_agent_open_if_enabled();
2460 if (arg_action == ACTION_SYSTEMCTL) {
2462 method = verb_to_method(args[0]);
2463 action = verb_to_action(args[0]);
2465 mode = streq(args[0], "isolate") ? "isolate" :
2466 action_table[action].mode ?: arg_job_mode;
2468 one_name = action_table[action].target;
2470 assert(arg_action < ELEMENTSOF(action_table));
2471 assert(action_table[arg_action].target);
2473 method = "StartUnit";
2475 mode = action_table[arg_action].mode;
2476 one_name = action_table[arg_action].target;
2480 names = strv_new(one_name, NULL);
2482 r = expand_names(bus, args + 1, NULL, &names);
2484 log_error("Failed to expand names: %s", strerror(-r));
2487 if (!arg_no_block) {
2488 r = enable_wait_for_jobs(bus);
2490 log_error("Could not watch jobs: %s", strerror(-r));
2494 s = set_new(string_hash_func, string_compare_func);
2499 STRV_FOREACH(name, names) {
2500 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2503 q = start_unit_one(bus, method, *name, mode, &error, s);
2504 if (r >= 0 && q < 0)
2505 r = translate_bus_error_to_exit_status(q, &error);
2508 if (!arg_no_block) {
2511 q = wait_for_jobs(bus, s);
2515 /* When stopping units, warn if they can still be triggered by
2516 * another active unit (socket, path, timer) */
2517 if (!arg_quiet && streq(method, "StopUnit"))
2518 STRV_FOREACH(name, names)
2519 check_triggering_units(bus, *name);
2525 /* Ask systemd-logind, which might grant access to unprivileged users
2526 * through PolicyKit */
2527 static int reboot_with_logind(sd_bus *bus, enum action a) {
2529 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2536 polkit_agent_open_if_enabled();
2544 case ACTION_POWEROFF:
2545 method = "PowerOff";
2548 case ACTION_SUSPEND:
2552 case ACTION_HIBERNATE:
2553 method = "Hibernate";
2556 case ACTION_HYBRID_SLEEP:
2557 method = "HybridSleep";
2564 r = sd_bus_call_method(
2566 "org.freedesktop.login1",
2567 "/org/freedesktop/login1",
2568 "org.freedesktop.login1.Manager",
2574 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2582 static int check_inhibitors(sd_bus *bus, enum action a) {
2584 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2585 _cleanup_strv_free_ char **sessions = NULL;
2586 const char *what, *who, *why, *mode;
2595 if (arg_ignore_inhibitors || arg_force > 0)
2607 r = sd_bus_call_method(
2609 "org.freedesktop.login1",
2610 "/org/freedesktop/login1",
2611 "org.freedesktop.login1.Manager",
2617 /* If logind is not around, then there are no inhibitors... */
2620 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2622 return bus_log_parse_error(r);
2624 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2625 _cleanup_free_ char *comm = NULL, *user = NULL;
2626 _cleanup_strv_free_ char **sv = NULL;
2628 if (!streq(mode, "block"))
2631 sv = strv_split(what, ":");
2635 if (!strv_contains(sv,
2637 a == ACTION_POWEROFF ||
2638 a == ACTION_REBOOT ||
2639 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2642 get_process_comm(pid, &comm);
2643 user = uid_to_name(uid);
2645 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2646 who, (unsigned long) pid, strna(comm), strna(user), why);
2651 return bus_log_parse_error(r);
2653 r = sd_bus_message_exit_container(reply);
2655 return bus_log_parse_error(r);
2657 /* Check for current sessions */
2658 sd_get_sessions(&sessions);
2659 STRV_FOREACH(s, sessions) {
2660 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2662 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2665 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2668 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2671 sd_session_get_tty(*s, &tty);
2672 sd_session_get_seat(*s, &seat);
2673 sd_session_get_service(*s, &service);
2674 user = uid_to_name(uid);
2676 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2683 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2684 action_table[a].verb);
2692 static int start_special(sd_bus *bus, char **args) {
2698 a = verb_to_action(args[0]);
2700 r = check_inhibitors(bus, a);
2704 if (arg_force >= 2 && geteuid() != 0) {
2705 log_error("Must be root.");
2709 if (arg_force >= 2 &&
2710 (a == ACTION_HALT ||
2711 a == ACTION_POWEROFF ||
2712 a == ACTION_REBOOT))
2715 if (arg_force >= 1 &&
2716 (a == ACTION_HALT ||
2717 a == ACTION_POWEROFF ||
2718 a == ACTION_REBOOT ||
2719 a == ACTION_KEXEC ||
2721 return daemon_reload(bus, args);
2723 /* first try logind, to allow authentication with polkit */
2724 if (geteuid() != 0 &&
2725 (a == ACTION_POWEROFF ||
2726 a == ACTION_REBOOT ||
2727 a == ACTION_SUSPEND ||
2728 a == ACTION_HIBERNATE ||
2729 a == ACTION_HYBRID_SLEEP)) {
2730 r = reboot_with_logind(bus, a);
2735 r = start_unit(bus, args);
2736 if (r == EXIT_SUCCESS)
2742 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2743 _cleanup_strv_free_ char **names = NULL;
2750 r = expand_names(bus, args, NULL, &names);
2752 log_error("Failed to expand names: %s", strerror(-r));
2756 STRV_FOREACH(name, names) {
2759 state = check_one_unit(bus, *name, good_states, arg_quiet);
2769 static int check_unit_active(sd_bus *bus, char **args) {
2770 /* According to LSB: 3, "program is not running" */
2771 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2774 static int check_unit_failed(sd_bus *bus, char **args) {
2775 return check_unit_generic(bus, 1, "failed\0", args + 1);
2778 static int kill_unit(sd_bus *bus, char **args) {
2779 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2780 _cleanup_strv_free_ char **names = NULL;
2788 arg_kill_who = "all";
2790 r = expand_names(bus, args + 1, NULL, &names);
2792 log_error("Failed to expand names: %s", strerror(-r));
2794 STRV_FOREACH(name, names) {
2795 q = sd_bus_call_method(
2797 "org.freedesktop.systemd1",
2798 "/org/freedesktop/systemd1",
2799 "org.freedesktop.systemd1.Manager",
2803 "ssi", *names, arg_kill_who, arg_signal);
2805 log_error("Failed to kill unit %s: %s",
2806 *names, bus_error_message(&error, r));
2815 typedef struct ExecStatusInfo {
2823 usec_t start_timestamp;
2824 usec_t exit_timestamp;
2829 LIST_FIELDS(struct ExecStatusInfo, exec);
2832 static void exec_status_info_free(ExecStatusInfo *i) {
2841 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2842 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2845 int32_t code, status;
2851 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2853 return bus_log_parse_error(r);
2857 r = sd_bus_message_read(m, "s", &path);
2859 return bus_log_parse_error(r);
2861 i->path = strdup(path);
2865 r = sd_bus_message_read_strv(m, &i->argv);
2867 return bus_log_parse_error(r);
2869 r = sd_bus_message_read(m,
2872 &start_timestamp, &start_timestamp_monotonic,
2873 &exit_timestamp, &exit_timestamp_monotonic,
2877 return bus_log_parse_error(r);
2880 i->start_timestamp = (usec_t) start_timestamp;
2881 i->exit_timestamp = (usec_t) exit_timestamp;
2882 i->pid = (pid_t) pid;
2886 r = sd_bus_message_exit_container(m);
2888 return bus_log_parse_error(r);
2893 typedef struct UnitStatusInfo {
2895 const char *load_state;
2896 const char *active_state;
2897 const char *sub_state;
2898 const char *unit_file_state;
2900 const char *description;
2901 const char *following;
2903 char **documentation;
2905 const char *fragment_path;
2906 const char *source_path;
2907 const char *control_group;
2909 char **dropin_paths;
2911 const char *load_error;
2914 usec_t inactive_exit_timestamp;
2915 usec_t inactive_exit_timestamp_monotonic;
2916 usec_t active_enter_timestamp;
2917 usec_t active_exit_timestamp;
2918 usec_t inactive_enter_timestamp;
2920 bool need_daemon_reload;
2925 const char *status_text;
2926 const char *pid_file;
2929 usec_t start_timestamp;
2930 usec_t exit_timestamp;
2932 int exit_code, exit_status;
2934 usec_t condition_timestamp;
2935 bool condition_result;
2936 bool failed_condition_trigger;
2937 bool failed_condition_negate;
2938 const char *failed_condition;
2939 const char *failed_condition_param;
2942 unsigned n_accepted;
2943 unsigned n_connections;
2946 /* Pairs of type, path */
2950 const char *sysfs_path;
2952 /* Mount, Automount */
2958 LIST_HEAD(ExecStatusInfo, exec);
2961 static void print_status_info(
2966 const char *active_on, *active_off, *on, *off, *ss;
2968 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2969 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2972 arg_all * OUTPUT_SHOW_ALL |
2973 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2974 on_tty() * OUTPUT_COLOR |
2975 !arg_quiet * OUTPUT_WARN_CUTOFF |
2976 arg_full * OUTPUT_FULL_WIDTH;
2981 /* This shows pretty information about a unit. See
2982 * print_property() for a low-level property printer */
2984 if (streq_ptr(i->active_state, "failed")) {
2985 active_on = ansi_highlight_red();
2986 active_off = ansi_highlight_off();
2987 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2988 active_on = ansi_highlight_green();
2989 active_off = ansi_highlight_off();
2991 active_on = active_off = "";
2993 printf("%s%s%s%s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
2995 if (i->description && !streq_ptr(i->id, i->description))
2996 printf(" - %s", i->description);
3001 printf(" Follow: unit currently follows state of %s\n", i->following);
3003 if (streq_ptr(i->load_state, "error")) {
3004 on = ansi_highlight_red();
3005 off = ansi_highlight_off();
3009 path = i->source_path ? i->source_path : i->fragment_path;
3012 printf(" Loaded: %s%s%s (Reason: %s)\n",
3013 on, strna(i->load_state), off, i->load_error);
3014 else if (path && i->unit_file_state)
3015 printf(" Loaded: %s%s%s (%s; %s)\n",
3016 on, strna(i->load_state), off, path, i->unit_file_state);
3018 printf(" Loaded: %s%s%s (%s)\n",
3019 on, strna(i->load_state), off, path);
3021 printf(" Loaded: %s%s%s\n",
3022 on, strna(i->load_state), off);
3024 if (!strv_isempty(i->dropin_paths)) {
3025 _cleanup_free_ char *dir = NULL;
3029 STRV_FOREACH(dropin, i->dropin_paths) {
3030 if (! dir || last) {
3031 printf(dir ? " " : " Drop-In: ");
3036 if (path_get_parent(*dropin, &dir) < 0) {
3041 printf("%s\n %s", dir,
3042 draw_special_char(DRAW_TREE_RIGHT));
3045 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3047 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3051 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3053 printf(" Active: %s%s (%s)%s",
3054 active_on, strna(i->active_state), ss, active_off);
3056 printf(" Active: %s%s%s",
3057 active_on, strna(i->active_state), active_off);
3059 if (!isempty(i->result) && !streq(i->result, "success"))
3060 printf(" (Result: %s)", i->result);
3062 timestamp = (streq_ptr(i->active_state, "active") ||
3063 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3064 (streq_ptr(i->active_state, "inactive") ||
3065 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3066 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3067 i->active_exit_timestamp;
3069 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3070 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3073 printf(" since %s; %s\n", s2, s1);
3075 printf(" since %s\n", s2);
3079 if (!i->condition_result && i->condition_timestamp > 0) {
3080 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3081 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3083 printf(" start condition failed at %s%s%s\n",
3084 s2, s1 ? "; " : "", s1 ? s1 : "");
3085 if (i->failed_condition_trigger)
3086 printf(" none of the trigger conditions were met\n");
3087 else if (i->failed_condition)
3088 printf(" %s=%s%s was not met\n",
3089 i->failed_condition,
3090 i->failed_condition_negate ? "!" : "",
3091 i->failed_condition_param);
3095 printf(" Device: %s\n", i->sysfs_path);
3097 printf(" Where: %s\n", i->where);
3099 printf(" What: %s\n", i->what);
3101 STRV_FOREACH(t, i->documentation)
3102 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3104 STRV_FOREACH_PAIR(t, t2, i->listen)
3105 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3108 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3110 LIST_FOREACH(exec, p, i->exec) {
3111 _cleanup_free_ char *argv = NULL;
3114 /* Only show exited processes here */
3118 argv = strv_join(p->argv, " ");
3119 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3121 good = is_clean_exit_lsb(p->code, p->status, NULL);
3123 on = ansi_highlight_red();
3124 off = ansi_highlight_off();
3128 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3130 if (p->code == CLD_EXITED) {
3133 printf("status=%i", p->status);
3135 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3140 printf("signal=%s", signal_to_string(p->status));
3142 printf(")%s\n", off);
3144 if (i->main_pid == p->pid &&
3145 i->start_timestamp == p->start_timestamp &&
3146 i->exit_timestamp == p->start_timestamp)
3147 /* Let's not show this twice */
3150 if (p->pid == i->control_pid)
3154 if (i->main_pid > 0 || i->control_pid > 0) {
3155 if (i->main_pid > 0) {
3156 printf(" Main PID: %u", (unsigned) i->main_pid);
3159 _cleanup_free_ char *comm = NULL;
3160 get_process_comm(i->main_pid, &comm);
3162 printf(" (%s)", comm);
3163 } else if (i->exit_code > 0) {
3164 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3166 if (i->exit_code == CLD_EXITED) {
3169 printf("status=%i", i->exit_status);
3171 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3176 printf("signal=%s", signal_to_string(i->exit_status));
3180 if (i->control_pid > 0)
3184 if (i->control_pid > 0) {
3185 _cleanup_free_ char *c = NULL;
3187 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3189 get_process_comm(i->control_pid, &c);
3198 printf(" Status: \"%s\"\n", i->status_text);
3200 if (i->control_group &&
3201 (i->main_pid > 0 || i->control_pid > 0 ||
3202 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3205 printf(" CGroup: %s\n", i->control_group);
3207 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3210 static const char prefix[] = " ";
3213 if (c > sizeof(prefix) - 1)
3214 c -= sizeof(prefix) - 1;
3218 if (i->main_pid > 0)
3219 extra[k++] = i->main_pid;
3221 if (i->control_pid > 0)
3222 extra[k++] = i->control_pid;
3224 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3228 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3229 show_journal_by_unit(stdout,
3233 i->inactive_exit_timestamp_monotonic,
3236 flags | OUTPUT_BEGIN_NEWLINE,
3237 arg_scope == UNIT_FILE_SYSTEM,
3241 if (i->need_daemon_reload)
3242 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3243 ansi_highlight_red(),
3244 ansi_highlight_off(),
3245 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3248 static void show_unit_help(UnitStatusInfo *i) {
3253 if (!i->documentation) {
3254 log_info("Documentation for %s not known.", i->id);
3258 STRV_FOREACH(p, i->documentation) {
3260 if (startswith(*p, "man:")) {
3261 const char *args[4] = { "man", NULL, NULL, NULL };
3262 _cleanup_free_ char *page = NULL, *section = NULL;
3269 if ((*p)[k-1] == ')')
3270 e = strrchr(*p, '(');
3273 page = strndup((*p) + 4, e - *p - 4);
3274 section = strndup(e + 1, *p + k - e - 2);
3275 if (!page || !section) {
3287 log_error("Failed to fork: %m");
3293 execvp(args[0], (char**) args);
3294 log_error("Failed to execute man: %m");
3295 _exit(EXIT_FAILURE);
3298 wait_for_terminate(pid, NULL);
3300 log_info("Can't show: %s", *p);
3304 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3311 switch (contents[0]) {
3313 case SD_BUS_TYPE_STRING: {
3316 r = sd_bus_message_read(m, "s", &s);
3318 return bus_log_parse_error(r);
3321 if (streq(name, "Id"))
3323 else if (streq(name, "LoadState"))
3325 else if (streq(name, "ActiveState"))
3326 i->active_state = s;
3327 else if (streq(name, "SubState"))
3329 else if (streq(name, "Description"))
3331 else if (streq(name, "FragmentPath"))
3332 i->fragment_path = s;
3333 else if (streq(name, "SourcePath"))
3336 else if (streq(name, "DefaultControlGroup")) {
3338 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3340 i->control_group = e;
3343 else if (streq(name, "ControlGroup"))
3344 i->control_group = s;
3345 else if (streq(name, "StatusText"))
3347 else if (streq(name, "PIDFile"))
3349 else if (streq(name, "SysFSPath"))
3351 else if (streq(name, "Where"))
3353 else if (streq(name, "What"))
3355 else if (streq(name, "Following"))
3357 else if (streq(name, "UnitFileState"))
3358 i->unit_file_state = s;
3359 else if (streq(name, "Result"))
3366 case SD_BUS_TYPE_BOOLEAN: {
3369 r = sd_bus_message_read(m, "b", &b);
3371 return bus_log_parse_error(r);
3373 if (streq(name, "Accept"))
3375 else if (streq(name, "NeedDaemonReload"))
3376 i->need_daemon_reload = b;
3377 else if (streq(name, "ConditionResult"))
3378 i->condition_result = b;
3383 case SD_BUS_TYPE_UINT32: {
3386 r = sd_bus_message_read(m, "u", &u);
3388 return bus_log_parse_error(r);
3390 if (streq(name, "MainPID")) {
3392 i->main_pid = (pid_t) u;
3395 } else if (streq(name, "ControlPID"))
3396 i->control_pid = (pid_t) u;
3397 else if (streq(name, "ExecMainPID")) {
3399 i->main_pid = (pid_t) u;
3400 } else if (streq(name, "NAccepted"))
3402 else if (streq(name, "NConnections"))
3403 i->n_connections = u;
3408 case SD_BUS_TYPE_INT32: {
3411 r = sd_bus_message_read(m, "i", &j);
3413 return bus_log_parse_error(r);
3415 if (streq(name, "ExecMainCode"))
3416 i->exit_code = (int) j;
3417 else if (streq(name, "ExecMainStatus"))
3418 i->exit_status = (int) j;
3423 case SD_BUS_TYPE_UINT64: {
3426 r = sd_bus_message_read(m, "t", &u);
3428 return bus_log_parse_error(r);
3430 if (streq(name, "ExecMainStartTimestamp"))
3431 i->start_timestamp = (usec_t) u;
3432 else if (streq(name, "ExecMainExitTimestamp"))
3433 i->exit_timestamp = (usec_t) u;
3434 else if (streq(name, "ActiveEnterTimestamp"))
3435 i->active_enter_timestamp = (usec_t) u;
3436 else if (streq(name, "InactiveEnterTimestamp"))
3437 i->inactive_enter_timestamp = (usec_t) u;
3438 else if (streq(name, "InactiveExitTimestamp"))
3439 i->inactive_exit_timestamp = (usec_t) u;
3440 else if (streq(name, "InactiveExitTimestampMonotonic"))
3441 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3442 else if (streq(name, "ActiveExitTimestamp"))
3443 i->active_exit_timestamp = (usec_t) u;
3444 else if (streq(name, "ConditionTimestamp"))
3445 i->condition_timestamp = (usec_t) u;
3450 case SD_BUS_TYPE_ARRAY:
3452 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3453 _cleanup_free_ ExecStatusInfo *info = NULL;
3455 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3457 return bus_log_parse_error(r);
3459 info = new0(ExecStatusInfo, 1);
3463 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3465 info->name = strdup(name);
3469 LIST_PREPEND(exec, i->exec, info);
3471 info = new0(ExecStatusInfo, 1);
3477 return bus_log_parse_error(r);
3479 r = sd_bus_message_exit_container(m);
3481 return bus_log_parse_error(r);
3485 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3486 const char *type, *path;
3488 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3490 return bus_log_parse_error(r);
3492 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3494 r = strv_extend(&i->listen, type);
3498 r = strv_extend(&i->listen, path);
3503 return bus_log_parse_error(r);
3505 r = sd_bus_message_exit_container(m);
3507 return bus_log_parse_error(r);
3511 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3513 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3515 return bus_log_parse_error(r);
3517 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3519 r = sd_bus_message_read_strv(m, &i->documentation);
3521 return bus_log_parse_error(r);
3523 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3524 const char *cond, *param;
3525 int trigger, negate;
3528 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3530 return bus_log_parse_error(r);
3532 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3533 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3534 if (state < 0 && (!trigger || !i->failed_condition)) {
3535 i->failed_condition = cond;
3536 i->failed_condition_trigger = trigger;
3537 i->failed_condition_negate = negate;
3538 i->failed_condition_param = param;
3542 return bus_log_parse_error(r);
3544 r = sd_bus_message_exit_container(m);
3546 return bus_log_parse_error(r);
3553 case SD_BUS_TYPE_STRUCT_BEGIN:
3555 if (streq(name, "LoadError")) {
3556 const char *n, *message;
3558 r = sd_bus_message_read(m, "(ss)", &n, &message);
3560 return bus_log_parse_error(r);
3562 if (!isempty(message))
3563 i->load_error = message;
3576 r = sd_bus_message_skip(m, contents);
3578 return bus_log_parse_error(r);
3583 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3589 /* This is a low-level property printer, see
3590 * print_status_info() for the nicer output */
3592 if (arg_properties && !strv_find(arg_properties, name)) {
3593 /* skip what we didn't read */
3594 r = sd_bus_message_skip(m, contents);
3598 switch (contents[0]) {
3600 case SD_BUS_TYPE_STRUCT_BEGIN:
3602 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3605 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3607 return bus_log_parse_error(r);
3610 printf("%s=%u\n", name, (unsigned) u);
3612 printf("%s=\n", name);
3616 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3619 r = sd_bus_message_read(m, "(so)", &s, NULL);
3621 return bus_log_parse_error(r);
3623 if (arg_all || !isempty(s))
3624 printf("%s=%s\n", name, s);
3628 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3629 const char *a = NULL, *b = NULL;
3631 r = sd_bus_message_read(m, "(ss)", &a, &b);
3633 return bus_log_parse_error(r);
3635 if (arg_all || !isempty(a) || !isempty(b))
3636 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3639 } else if (streq_ptr(name, "SystemCallFilter")) {
3640 _cleanup_strv_free_ char **l = NULL;
3643 r = sd_bus_message_enter_container(m, 'r', "bas");
3645 return bus_log_parse_error(r);
3647 r = sd_bus_message_read(m, "b", &whitelist);
3649 return bus_log_parse_error(r);
3651 r = sd_bus_message_read_strv(m, &l);
3653 return bus_log_parse_error(r);
3655 r = sd_bus_message_exit_container(m);
3657 return bus_log_parse_error(r);
3659 if (arg_all || whitelist || !strv_isempty(l)) {
3663 fputs(name, stdout);
3669 STRV_FOREACH(i, l) {
3677 fputc('\n', stdout);
3685 case SD_BUS_TYPE_ARRAY:
3687 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3691 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3693 return bus_log_parse_error(r);
3695 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3696 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3699 return bus_log_parse_error(r);
3701 r = sd_bus_message_exit_container(m);
3703 return bus_log_parse_error(r);
3707 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3708 const char *type, *path;
3710 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3712 return bus_log_parse_error(r);
3714 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3715 printf("%s=%s\n", type, path);
3717 return bus_log_parse_error(r);
3719 r = sd_bus_message_exit_container(m);
3721 return bus_log_parse_error(r);
3725 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3726 const char *type, *path;
3728 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3730 return bus_log_parse_error(r);
3732 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3733 printf("Listen%s=%s\n", type, path);
3735 return bus_log_parse_error(r);
3737 r = sd_bus_message_exit_container(m);
3739 return bus_log_parse_error(r);
3743 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3745 uint64_t value, next_elapse;
3747 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3749 return bus_log_parse_error(r);
3751 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3752 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3754 printf("%s={ value=%s ; next_elapse=%s }\n",
3756 format_timespan(timespan1, sizeof(timespan1), value, 0),
3757 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3760 return bus_log_parse_error(r);
3762 r = sd_bus_message_exit_container(m);
3764 return bus_log_parse_error(r);
3768 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3769 ExecStatusInfo info = {};
3771 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3773 return bus_log_parse_error(r);
3775 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3776 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3777 _cleanup_free_ char *tt;
3779 tt = strv_join(info.argv, " ");
3781 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3785 yes_no(info.ignore),
3786 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3787 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3788 (unsigned) info. pid,
3789 sigchld_code_to_string(info.code),
3791 info.code == CLD_EXITED ? "" : "/",
3792 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3795 strv_free(info.argv);
3799 r = sd_bus_message_exit_container(m);
3801 return bus_log_parse_error(r);
3805 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3806 const char *path, *rwm;
3808 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3810 return bus_log_parse_error(r);
3812 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3813 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3815 return bus_log_parse_error(r);
3817 r = sd_bus_message_exit_container(m);
3819 return bus_log_parse_error(r);
3823 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3827 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3829 return bus_log_parse_error(r);
3831 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3832 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3834 return bus_log_parse_error(r);
3836 r = sd_bus_message_exit_container(m);
3838 return bus_log_parse_error(r);
3842 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3846 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3848 return bus_log_parse_error(r);
3850 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3851 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3853 return bus_log_parse_error(r);
3855 r = sd_bus_message_exit_container(m);
3857 return bus_log_parse_error(r);
3865 r = bus_print_property(name, m, arg_all);
3867 return bus_log_parse_error(r);
3870 r = sd_bus_message_skip(m, contents);
3872 return bus_log_parse_error(r);
3875 printf("%s=[unprintable]\n", name);
3881 static int show_one(
3885 bool show_properties,
3889 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3890 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3891 UnitStatusInfo info = {};
3898 log_debug("Showing one %s", path);
3900 r = sd_bus_call_method(
3902 "org.freedesktop.systemd1",
3904 "org.freedesktop.DBus.Properties",
3910 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3914 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3916 return bus_log_parse_error(r);
3923 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3924 const char *name, *contents;
3926 r = sd_bus_message_read(reply, "s", &name);
3928 return bus_log_parse_error(r);
3930 r = sd_bus_message_peek_type(reply, NULL, &contents);
3932 return bus_log_parse_error(r);
3934 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3936 return bus_log_parse_error(r);
3938 if (show_properties)
3939 r = print_property(name, reply, contents);
3941 r = status_property(name, reply, &info, contents);
3945 r = sd_bus_message_exit_container(reply);
3947 return bus_log_parse_error(r);
3949 r = sd_bus_message_exit_container(reply);
3951 return bus_log_parse_error(r);
3954 return bus_log_parse_error(r);
3956 r = sd_bus_message_exit_container(reply);
3958 return bus_log_parse_error(r);
3962 if (!show_properties) {
3963 if (streq(verb, "help"))
3964 show_unit_help(&info);
3966 print_status_info(&info, ellipsized);
3969 strv_free(info.documentation);
3970 strv_free(info.dropin_paths);
3971 strv_free(info.listen);
3973 if (!streq_ptr(info.active_state, "active") &&
3974 !streq_ptr(info.active_state, "reloading") &&
3975 streq(verb, "status")) {
3976 /* According to LSB: "program not running" */
3977 /* 0: program is running or service is OK
3978 * 1: program is dead and /run PID file exists
3979 * 2: program is dead and /run/lock lock file exists
3980 * 3: program is not running
3981 * 4: program or service status is unknown
3983 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3989 while ((p = info.exec)) {
3990 LIST_REMOVE(exec, info.exec, p);
3991 exec_status_info_free(p);
3997 static int get_unit_dbus_path_by_pid(
4002 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4003 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4007 r = sd_bus_call_method(
4009 "org.freedesktop.systemd1",
4010 "/org/freedesktop/systemd1",
4011 "org.freedesktop.systemd1.Manager",
4017 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
4021 r = sd_bus_message_read(reply, "o", &u);
4023 return bus_log_parse_error(r);
4033 static int show_all(
4036 bool show_properties,
4040 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4041 _cleanup_free_ UnitInfo *unit_infos = NULL;
4046 r = get_unit_list(bus, &reply, &unit_infos, NULL);
4050 pager_open_if_enabled();
4054 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4056 for (u = unit_infos; u < unit_infos + c; u++) {
4057 _cleanup_free_ char *p = NULL;
4059 p = unit_dbus_path_from_name(u->id);
4063 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4071 static int show_system_status(sd_bus *bus) {
4072 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4073 _cleanup_free_ char *hn = NULL;
4074 struct machine_info mi = {};
4075 const char *on, *off;
4078 hn = gethostname_malloc();
4082 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4084 log_error("Failed to read server status: %s", strerror(-r));
4088 if (streq_ptr(mi.state, "degraded")) {
4089 on = ansi_highlight_red();
4090 off = ansi_highlight_off();
4091 } else if (!streq_ptr(mi.state, "running")) {
4092 on = ansi_highlight_yellow();
4093 off = ansi_highlight_off();
4097 printf("%s%s%s%s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4099 printf(" State: %s%s%s\n",
4100 on, strna(mi.state), off);
4102 printf(" Jobs: %u queued\n", mi.n_jobs);
4103 printf(" Failed: %u units\n", mi.n_failed_units);
4105 printf(" Since: %s; %s\n",
4106 format_timestamp(since2, sizeof(since2), mi.timestamp),
4107 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4109 printf(" CGroup: %s\n", mi.control_group ?: "/");
4110 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4112 arg_all * OUTPUT_SHOW_ALL |
4113 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4114 on_tty() * OUTPUT_COLOR |
4115 !arg_quiet * OUTPUT_WARN_CUTOFF |
4116 arg_full * OUTPUT_FULL_WIDTH;
4118 static const char prefix[] = " ";
4122 if (c > sizeof(prefix) - 1)
4123 c -= sizeof(prefix) - 1;
4127 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4131 free(mi.control_group);
4136 static int show(sd_bus *bus, char **args) {
4137 bool show_properties, show_status, new_line = false;
4138 bool ellipsized = false;
4144 show_properties = streq(args[0], "show");
4145 show_status = streq(args[0], "status");
4147 if (show_properties)
4148 pager_open_if_enabled();
4150 /* If no argument is specified inspect the manager itself */
4152 if (show_properties && strv_length(args) <= 1)
4153 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4155 if (show_status && strv_length(args) <= 1) {
4157 pager_open_if_enabled();
4158 show_system_status(bus);
4162 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4164 _cleanup_free_ char **patterns = NULL;
4167 STRV_FOREACH(name, args + 1) {
4168 _cleanup_free_ char *unit = NULL;
4171 if (safe_atou32(*name, &id) < 0) {
4172 if (strv_push(&patterns, *name) < 0)
4176 } else if (show_properties) {
4177 /* Interpret as job id */
4178 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4182 /* Interpret as PID */
4183 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4190 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4193 if (!strv_isempty(patterns)) {
4194 _cleanup_strv_free_ char **names = NULL;
4196 r = expand_names(bus, patterns, NULL, &names);
4198 log_error("Failed to expand names: %s", strerror(-r));
4200 STRV_FOREACH(name, names) {
4201 _cleanup_free_ char *unit;
4203 unit = unit_dbus_path_from_name(*name);
4207 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4212 if (ellipsized && !arg_quiet)
4213 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4218 static int cat(sd_bus *bus, char **args) {
4219 _cleanup_free_ char *unit = NULL;
4220 _cleanup_strv_free_ char **names = NULL;
4228 r = expand_names(bus, args + 1, NULL, &names);
4230 log_error("Failed to expand names: %s", strerror(-r));
4232 pager_open_if_enabled();
4234 STRV_FOREACH(name, names) {
4235 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4236 _cleanup_strv_free_ char **dropin_paths = NULL;
4237 _cleanup_free_ char *fragment_path = NULL;
4240 unit = unit_dbus_path_from_name(*name);
4244 if (need_daemon_reload(bus, *name) > 0)
4245 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4246 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4248 r = sd_bus_get_property_string(
4250 "org.freedesktop.systemd1",
4252 "org.freedesktop.systemd1.Unit",
4257 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4261 r = sd_bus_get_property_strv(
4263 "org.freedesktop.systemd1",
4265 "org.freedesktop.systemd1.Unit",
4270 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4279 if (!isempty(fragment_path)) {
4280 printf("%s# %s%s\n",
4281 ansi_highlight_blue(),
4283 ansi_highlight_off());
4286 r = sendfile_full(STDOUT_FILENO, fragment_path);
4288 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4293 STRV_FOREACH(path, dropin_paths) {
4294 printf("%s%s# %s%s\n",
4295 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4296 ansi_highlight_blue(),
4298 ansi_highlight_off());
4301 r = sendfile_full(STDOUT_FILENO, *path);
4303 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4309 return r < 0 ? r : 0;
4312 static int set_property(sd_bus *bus, char **args) {
4313 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4314 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4315 _cleanup_free_ char *n = NULL;
4319 r = sd_bus_message_new_method_call(
4322 "org.freedesktop.systemd1",
4323 "/org/freedesktop/systemd1",
4324 "org.freedesktop.systemd1.Manager",
4325 "SetUnitProperties");
4327 return bus_log_create_error(r);
4329 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4333 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4335 return bus_log_create_error(r);
4337 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4339 return bus_log_create_error(r);
4341 STRV_FOREACH(i, args + 2) {
4342 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4344 return bus_log_create_error(r);
4346 r = bus_append_unit_property_assignment(m, *i);
4350 r = sd_bus_message_close_container(m);
4352 return bus_log_create_error(r);
4355 r = sd_bus_message_close_container(m);
4357 return bus_log_create_error(r);
4359 r = sd_bus_call(bus, m, 0, &error, NULL);
4361 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4368 static int snapshot(sd_bus *bus, char **args) {
4369 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4370 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4371 _cleanup_free_ char *n = NULL, *id = NULL;
4375 if (strv_length(args) > 1)
4376 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4382 r = sd_bus_call_method(
4384 "org.freedesktop.systemd1",
4385 "/org/freedesktop/systemd1",
4386 "org.freedesktop.systemd1.Manager",
4392 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4396 r = sd_bus_message_read(reply, "o", &path);
4398 return bus_log_parse_error(r);
4400 r = sd_bus_get_property_string(
4402 "org.freedesktop.systemd1",
4404 "org.freedesktop.systemd1.Unit",
4409 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4419 static int delete_snapshot(sd_bus *bus, char **args) {
4420 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4421 _cleanup_strv_free_ char **names = NULL;
4427 r = expand_names(bus, args + 1, ".snapshot", &names);
4429 log_error("Failed to expand names: %s", strerror(-r));
4431 STRV_FOREACH(name, names) {
4432 q = sd_bus_call_method(
4434 "org.freedesktop.systemd1",
4435 "/org/freedesktop/systemd1",
4436 "org.freedesktop.systemd1.Manager",
4442 log_error("Failed to remove snapshot %s: %s",
4443 *name, bus_error_message(&error, r));
4452 static int daemon_reload(sd_bus *bus, char **args) {
4453 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4457 if (arg_action == ACTION_RELOAD)
4459 else if (arg_action == ACTION_REEXEC)
4460 method = "Reexecute";
4462 assert(arg_action == ACTION_SYSTEMCTL);
4465 streq(args[0], "clear-jobs") ||
4466 streq(args[0], "cancel") ? "ClearJobs" :
4467 streq(args[0], "daemon-reexec") ? "Reexecute" :
4468 streq(args[0], "reset-failed") ? "ResetFailed" :
4469 streq(args[0], "halt") ? "Halt" :
4470 streq(args[0], "poweroff") ? "PowerOff" :
4471 streq(args[0], "reboot") ? "Reboot" :
4472 streq(args[0], "kexec") ? "KExec" :
4473 streq(args[0], "exit") ? "Exit" :
4474 /* "daemon-reload" */ "Reload";
4477 r = sd_bus_call_method(
4479 "org.freedesktop.systemd1",
4480 "/org/freedesktop/systemd1",
4481 "org.freedesktop.systemd1.Manager",
4487 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4488 /* There's always a fallback possible for
4489 * legacy actions. */
4491 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4492 /* On reexecution, we expect a disconnect, not a
4496 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4498 return r < 0 ? r : 0;
4501 static int reset_failed(sd_bus *bus, char **args) {
4502 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4503 _cleanup_strv_free_ char **names = NULL;
4507 if (strv_length(args) <= 1)
4508 return daemon_reload(bus, args);
4510 r = expand_names(bus, args + 1, NULL, &names);
4512 log_error("Failed to expand names: %s", strerror(-r));
4514 STRV_FOREACH(name, names) {
4515 q = sd_bus_call_method(
4517 "org.freedesktop.systemd1",
4518 "/org/freedesktop/systemd1",
4519 "org.freedesktop.systemd1.Manager",
4525 log_error("Failed to reset failed state of unit %s: %s",
4526 *name, bus_error_message(&error, r));
4535 static int show_environment(sd_bus *bus, char **args) {
4536 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4537 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4541 pager_open_if_enabled();
4543 r = sd_bus_get_property(
4545 "org.freedesktop.systemd1",
4546 "/org/freedesktop/systemd1",
4547 "org.freedesktop.systemd1.Manager",
4553 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4557 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4559 return bus_log_parse_error(r);
4561 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4564 return bus_log_parse_error(r);
4566 r = sd_bus_message_exit_container(reply);
4568 return bus_log_parse_error(r);
4573 static int switch_root(sd_bus *bus, char **args) {
4574 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4575 _cleanup_free_ char *cmdline_init = NULL;
4576 const char *root, *init;
4580 l = strv_length(args);
4581 if (l < 2 || l > 3) {
4582 log_error("Wrong number of arguments.");
4591 r = parse_env_file("/proc/cmdline", WHITESPACE,
4592 "init", &cmdline_init,
4595 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4597 init = cmdline_init;
4604 const char *root_systemd_path = NULL, *root_init_path = NULL;
4606 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4607 root_init_path = strappenda3(root, "/", init);
4609 /* If the passed init is actually the same as the
4610 * systemd binary, then let's suppress it. */
4611 if (files_same(root_init_path, root_systemd_path) > 0)
4615 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4617 r = sd_bus_call_method(
4619 "org.freedesktop.systemd1",
4620 "/org/freedesktop/systemd1",
4621 "org.freedesktop.systemd1.Manager",
4627 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4634 static int set_environment(sd_bus *bus, char **args) {
4635 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4636 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4643 method = streq(args[0], "set-environment")
4645 : "UnsetEnvironment";
4647 r = sd_bus_message_new_method_call(
4650 "org.freedesktop.systemd1",
4651 "/org/freedesktop/systemd1",
4652 "org.freedesktop.systemd1.Manager",
4655 return bus_log_create_error(r);
4657 r = sd_bus_message_append_strv(m, args + 1);
4659 return bus_log_create_error(r);
4661 r = sd_bus_call(bus, m, 0, &error, NULL);
4663 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4670 static int import_environment(sd_bus *bus, char **args) {
4671 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4672 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4678 r = sd_bus_message_new_method_call(
4681 "org.freedesktop.systemd1",
4682 "/org/freedesktop/systemd1",
4683 "org.freedesktop.systemd1.Manager",
4686 return bus_log_create_error(r);
4688 if (strv_isempty(args + 1))
4689 r = sd_bus_message_append_strv(m, environ);
4693 r = sd_bus_message_open_container(m, 'a', "s");
4695 return bus_log_create_error(r);
4697 STRV_FOREACH(a, args + 1) {
4699 if (!env_name_is_valid(*a)) {
4700 log_error("Not a valid environment variable name: %s", *a);
4704 STRV_FOREACH(b, environ) {
4707 eq = startswith(*b, *a);
4708 if (eq && *eq == '=') {
4710 r = sd_bus_message_append(m, "s", *b);
4712 return bus_log_create_error(r);
4719 r = sd_bus_message_close_container(m);
4722 return bus_log_create_error(r);
4724 r = sd_bus_call(bus, m, 0, &error, NULL);
4726 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4733 static int enable_sysv_units(const char *verb, char **args) {
4736 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4737 unsigned f = 1, t = 1;
4738 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4740 if (arg_scope != UNIT_FILE_SYSTEM)
4743 if (!streq(verb, "enable") &&
4744 !streq(verb, "disable") &&
4745 !streq(verb, "is-enabled"))
4748 /* Processes all SysV units, and reshuffles the array so that
4749 * afterwards only the native units remain */
4751 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4756 for (f = 0; args[f]; f++) {
4758 _cleanup_free_ char *p = NULL, *q = NULL;
4759 bool found_native = false, found_sysv;
4761 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4769 if (!endswith(name, ".service"))
4772 if (path_is_absolute(name))
4775 STRV_FOREACH(k, paths.unit_path) {
4776 if (!isempty(arg_root))
4777 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4779 asprintf(&p, "%s/%s", *k, name);
4786 found_native = access(p, F_OK) >= 0;
4797 if (!isempty(arg_root))
4798 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4800 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4806 p[strlen(p) - sizeof(".service") + 1] = 0;
4807 found_sysv = access(p, F_OK) >= 0;
4812 /* Mark this entry, so that we don't try enabling it as native unit */
4813 args[f] = (char*) "";
4815 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4817 if (!isempty(arg_root))
4818 argv[c++] = q = strappend("--root=", arg_root);
4820 argv[c++] = basename(p);
4822 streq(verb, "enable") ? "on" :
4823 streq(verb, "disable") ? "off" : "--level=5";
4826 l = strv_join((char**)argv, " ");
4832 log_info("Executing %s", l);
4837 log_error("Failed to fork: %m");
4840 } else if (pid == 0) {
4843 execv(argv[0], (char**) argv);
4844 _exit(EXIT_FAILURE);
4847 j = wait_for_terminate(pid, &status);
4849 log_error("Failed to wait for child: %s", strerror(-r));
4854 if (status.si_code == CLD_EXITED) {
4855 if (streq(verb, "is-enabled")) {
4856 if (status.si_status == 0) {
4865 } else if (status.si_status != 0) {
4876 /* Drop all SysV units */
4877 for (f = 0, t = 0; args[f]; f++) {
4879 if (isempty(args[f]))
4882 args[t++] = args[f];
4891 static int mangle_names(char **original_names, char ***mangled_names) {
4892 char **i, **l, **name;
4894 l = new(char*, strv_length(original_names) + 1);
4899 STRV_FOREACH(name, original_names) {
4901 /* When enabling units qualified path names are OK,
4902 * too, hence allow them explicitly. */
4907 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4923 static int enable_unit(sd_bus *bus, char **args) {
4924 _cleanup_strv_free_ char **names = NULL;
4925 const char *verb = args[0];
4926 UnitFileChange *changes = NULL;
4927 unsigned n_changes = 0;
4928 int carries_install_info = -1;
4934 r = mangle_names(args+1, &names);
4938 r = enable_sysv_units(verb, names);
4942 /* If the operation was fully executed by the SysV compat,
4943 * let's finish early */
4944 if (strv_isempty(names))
4947 if (!bus || avoid_bus()) {
4948 if (streq(verb, "enable")) {
4949 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4950 carries_install_info = r;
4951 } else if (streq(verb, "disable"))
4952 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4953 else if (streq(verb, "reenable")) {
4954 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4955 carries_install_info = r;
4956 } else if (streq(verb, "link"))
4957 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4958 else if (streq(verb, "preset")) {
4959 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4960 carries_install_info = r;
4961 } else if (streq(verb, "mask"))
4962 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4963 else if (streq(verb, "unmask"))
4964 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4966 assert_not_reached("Unknown verb");
4969 log_error("Operation failed: %s", strerror(-r));
4974 dump_unit_file_changes(changes, n_changes);
4978 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4979 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4980 int expect_carries_install_info = false;
4981 bool send_force = true;
4984 if (streq(verb, "enable")) {
4985 method = "EnableUnitFiles";
4986 expect_carries_install_info = true;
4987 } else if (streq(verb, "disable")) {
4988 method = "DisableUnitFiles";
4990 } else if (streq(verb, "reenable")) {
4991 method = "ReenableUnitFiles";
4992 expect_carries_install_info = true;
4993 } else if (streq(verb, "link"))
4994 method = "LinkUnitFiles";
4995 else if (streq(verb, "preset")) {
4996 method = "PresetUnitFiles";
4997 expect_carries_install_info = true;
4998 } else if (streq(verb, "mask"))
4999 method = "MaskUnitFiles";
5000 else if (streq(verb, "unmask")) {
5001 method = "UnmaskUnitFiles";
5004 assert_not_reached("Unknown verb");
5006 r = sd_bus_message_new_method_call(
5009 "org.freedesktop.systemd1",
5010 "/org/freedesktop/systemd1",
5011 "org.freedesktop.systemd1.Manager",
5014 return bus_log_create_error(r);
5016 r = sd_bus_message_append_strv(m, names);
5018 return bus_log_create_error(r);
5020 r = sd_bus_message_append(m, "b", arg_runtime);
5022 return bus_log_create_error(r);
5025 r = sd_bus_message_append(m, "b", arg_force);
5027 return bus_log_create_error(r);
5030 r = sd_bus_call(bus, m, 0, &error, &reply);
5032 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5036 if (expect_carries_install_info) {
5037 r = sd_bus_message_read(reply, "b", &carries_install_info);
5039 return bus_log_parse_error(r);
5042 r = deserialize_and_dump_unit_file_changes(reply);
5046 /* Try to reload if enabeld */
5048 r = daemon_reload(bus, args);
5053 if (carries_install_info == 0)
5054 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5055 "using systemctl.\n"
5056 "Possible reasons for having this kind of units are:\n"
5057 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5058 " .wants/ or .requires/ directory.\n"
5059 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5060 " a requirement dependency on it.\n"
5061 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5062 " D-Bus, udev, scripted systemctl call, ...).\n");
5065 unit_file_changes_free(changes, n_changes);
5070 static int unit_is_enabled(sd_bus *bus, char **args) {
5072 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5073 _cleanup_strv_free_ char **names = NULL;
5078 r = mangle_names(args+1, &names);
5082 r = enable_sysv_units(args[0], names);
5088 if (!bus || avoid_bus()) {
5090 STRV_FOREACH(name, names) {
5091 UnitFileState state;
5093 state = unit_file_get_state(arg_scope, arg_root, *name);
5095 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5099 if (state == UNIT_FILE_ENABLED ||
5100 state == UNIT_FILE_ENABLED_RUNTIME ||
5101 state == UNIT_FILE_STATIC)
5105 puts(unit_file_state_to_string(state));
5109 STRV_FOREACH(name, names) {
5110 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5113 r = sd_bus_call_method(
5115 "org.freedesktop.systemd1",
5116 "/org/freedesktop/systemd1",
5117 "org.freedesktop.systemd1.Manager",
5123 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5127 r = sd_bus_message_read(reply, "s", &s);
5129 return bus_log_parse_error(r);
5131 if (streq(s, "enabled") ||
5132 streq(s, "enabled-runtime") ||
5144 static int systemctl_help(void) {
5146 pager_open_if_enabled();
5148 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5149 "Query or send control commands to the systemd manager.\n\n"
5150 " -h --help Show this help\n"
5151 " --version Show package version\n"
5152 " --system Connect to system manager\n"
5153 " --user Connect to user service manager\n"
5154 " -H --host=[USER@]HOST\n"
5155 " Operate on remote host\n"
5156 " -M --machine=CONTAINER\n"
5157 " Operate on local container\n"
5158 " -t --type=TYPE List only units of a particular type\n"
5159 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5160 " -p --property=NAME Show only properties by this name\n"
5161 " -a --all Show all loaded units/properties, including dead/empty\n"
5162 " ones. To list all units installed on the system, use\n"
5163 " the 'list-unit-files' command instead.\n"
5164 " -l --full Don't ellipsize unit names on output\n"
5165 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5166 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5167 " queueing a new job\n"
5168 " --show-types When showing sockets, explicitly show their type\n"
5169 " -i --ignore-inhibitors\n"
5170 " When shutting down or sleeping, ignore inhibitors\n"
5171 " --kill-who=WHO Who to send signal to\n"
5172 " -s --signal=SIGNAL Which signal to send\n"
5173 " -q --quiet Suppress output\n"
5174 " --no-block Do not wait until operation finished\n"
5175 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5176 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5178 " --no-legend Do not print a legend (column headers and hints)\n"
5179 " --no-pager Do not pipe output into a pager\n"
5180 " --no-ask-password\n"
5181 " Do not ask for system passwords\n"
5182 " --global Enable/disable unit files globally\n"
5183 " --runtime Enable unit files only temporarily until next reboot\n"
5184 " -f --force When enabling unit files, override existing symlinks\n"
5185 " When shutting down, execute action immediately\n"
5186 " --root=PATH Enable unit files in the specified root directory\n"
5187 " -n --lines=INTEGER Number of journal entries to show\n"
5188 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5189 " verbose, export, json, json-pretty, json-sse, cat)\n"
5190 " --plain Print unit dependencies as a list instead of a tree\n\n"
5192 " list-units [PATTERN...] List loaded units\n"
5193 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5194 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5195 " start NAME... Start (activate) one or more units\n"
5196 " stop NAME... Stop (deactivate) one or more units\n"
5197 " reload NAME... Reload one or more units\n"
5198 " restart NAME... Start or restart one or more units\n"
5199 " try-restart NAME... Restart one or more units if active\n"
5200 " reload-or-restart NAME... Reload one or more units if possible,\n"
5201 " otherwise start or restart\n"
5202 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5203 " otherwise restart if active\n"
5204 " isolate NAME Start one unit and stop all others\n"
5205 " kill NAME... Send signal to processes of a unit\n"
5206 " is-active NAME... Check whether units are active\n"
5207 " is-failed NAME... Check whether units are failed\n"
5208 " status [NAME...|PID...] Show runtime status of one or more units\n"
5209 " show [NAME...|JOB...] Show properties of one or more\n"
5210 " units/jobs or the manager\n"
5211 " cat NAME... Show files and drop-ins of one or more units\n"
5212 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5213 " help NAME...|PID... Show manual for one or more units\n"
5214 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
5216 " list-dependencies [NAME] Recursively show units which are required\n"
5217 " or wanted by this unit or by which this\n"
5218 " unit is required or wanted\n\n"
5219 "Unit File Commands:\n"
5220 " list-unit-files [PATTERN...] List installed unit files\n"
5221 " enable NAME... Enable one or more unit files\n"
5222 " disable NAME... Disable one or more unit files\n"
5223 " reenable NAME... Reenable one or more unit files\n"
5224 " preset NAME... Enable/disable one or more unit files\n"
5225 " based on preset configuration\n"
5226 " is-enabled NAME... Check whether unit files are enabled\n\n"
5227 " mask NAME... Mask one or more units\n"
5228 " unmask NAME... Unmask one or more units\n"
5229 " link PATH... Link one or more units files into\n"
5230 " the search path\n"
5231 " get-default Get the name of the default target\n"
5232 " set-default NAME Set the default target\n\n"
5233 "Machine Commands:\n"
5234 " list-machines [PATTERN...] List local containers and host\n\n"
5236 " list-jobs [PATTERN...] List jobs\n"
5237 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5238 "Snapshot Commands:\n"
5239 " snapshot [NAME] Create a snapshot\n"
5240 " delete NAME... Remove one or more snapshots\n\n"
5241 "Environment Commands:\n"
5242 " show-environment Dump environment\n"
5243 " set-environment NAME=VALUE... Set one or more environment variables\n"
5244 " unset-environment NAME... Unset one or more environment variables\n"
5245 " import-environment NAME... Import all, one or more environment variables\n\n"
5246 "Manager Lifecycle Commands:\n"
5247 " daemon-reload Reload systemd manager configuration\n"
5248 " daemon-reexec Reexecute systemd manager\n\n"
5249 "System Commands:\n"
5250 " default Enter system default mode\n"
5251 " rescue Enter system rescue mode\n"
5252 " emergency Enter system emergency mode\n"
5253 " halt Shut down and halt the system\n"
5254 " poweroff Shut down and power-off the system\n"
5255 " reboot [ARG] Shut down and reboot the system\n"
5256 " kexec Shut down and reboot the system with kexec\n"
5257 " exit Request user instance exit\n"
5258 " switch-root ROOT [INIT] Change to a different root file system\n"
5259 " suspend Suspend the system\n"
5260 " hibernate Hibernate the system\n"
5261 " hybrid-sleep Hibernate and suspend the system\n",
5262 program_invocation_short_name);
5267 static int halt_help(void) {
5269 printf("%s [OPTIONS...]%s\n\n"
5270 "%s the system.\n\n"
5271 " --help Show this help\n"
5272 " --halt Halt the machine\n"
5273 " -p --poweroff Switch off the machine\n"
5274 " --reboot Reboot the machine\n"
5275 " -f --force Force immediate halt/power-off/reboot\n"
5276 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5277 " -d --no-wtmp Don't write wtmp record\n"
5278 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5279 program_invocation_short_name,
5280 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5281 arg_action == ACTION_REBOOT ? "Reboot" :
5282 arg_action == ACTION_POWEROFF ? "Power off" :
5288 static int shutdown_help(void) {
5290 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5291 "Shut down the system.\n\n"
5292 " --help Show this help\n"
5293 " -H --halt Halt the machine\n"
5294 " -P --poweroff Power-off the machine\n"
5295 " -r --reboot Reboot the machine\n"
5296 " -h Equivalent to --poweroff, overridden by --halt\n"
5297 " -k Don't halt/power-off/reboot, just send warnings\n"
5298 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5299 " -c Cancel a pending shutdown\n",
5300 program_invocation_short_name);
5305 static int telinit_help(void) {
5307 printf("%s [OPTIONS...] {COMMAND}\n\n"
5308 "Send control commands to the init daemon.\n\n"
5309 " --help Show this help\n"
5310 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5312 " 0 Power-off the machine\n"
5313 " 6 Reboot the machine\n"
5314 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5315 " 1, s, S Enter rescue mode\n"
5316 " q, Q Reload init daemon configuration\n"
5317 " u, U Reexecute init daemon\n",
5318 program_invocation_short_name);
5323 static int runlevel_help(void) {
5325 printf("%s [OPTIONS...]\n\n"
5326 "Prints the previous and current runlevel of the init system.\n\n"
5327 " --help Show this help\n",
5328 program_invocation_short_name);
5333 static int help_types(void) {
5337 puts("Available unit types:");
5338 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5339 t = unit_type_to_string(i);
5347 static int systemctl_parse_argv(int argc, char *argv[]) {
5356 ARG_IGNORE_DEPENDENCIES,
5368 ARG_NO_ASK_PASSWORD,
5377 static const struct option options[] = {
5378 { "help", no_argument, NULL, 'h' },
5379 { "version", no_argument, NULL, ARG_VERSION },
5380 { "type", required_argument, NULL, 't' },
5381 { "property", required_argument, NULL, 'p' },
5382 { "all", no_argument, NULL, 'a' },
5383 { "reverse", no_argument, NULL, ARG_REVERSE },
5384 { "after", no_argument, NULL, ARG_AFTER },
5385 { "before", no_argument, NULL, ARG_BEFORE },
5386 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5387 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5388 { "full", no_argument, NULL, 'l' },
5389 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5390 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5391 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5392 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5393 { "ignore-inhibitors", no_argument, NULL, 'i' },
5394 { "user", no_argument, NULL, ARG_USER },
5395 { "system", no_argument, NULL, ARG_SYSTEM },
5396 { "global", no_argument, NULL, ARG_GLOBAL },
5397 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5398 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5399 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5400 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5401 { "quiet", no_argument, NULL, 'q' },
5402 { "root", required_argument, NULL, ARG_ROOT },
5403 { "force", no_argument, NULL, ARG_FORCE },
5404 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5405 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5406 { "signal", required_argument, NULL, 's' },
5407 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5408 { "host", required_argument, NULL, 'H' },
5409 { "machine", required_argument, NULL, 'M' },
5410 { "runtime", no_argument, NULL, ARG_RUNTIME },
5411 { "lines", required_argument, NULL, 'n' },
5412 { "output", required_argument, NULL, 'o' },
5413 { "plain", no_argument, NULL, ARG_PLAIN },
5414 { "state", required_argument, NULL, ARG_STATE },
5423 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5428 return systemctl_help();
5431 puts(PACKAGE_STRING);
5432 puts(SYSTEMD_FEATURES);
5439 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5440 _cleanup_free_ char *type;
5442 type = strndup(word, size);
5446 if (streq(type, "help")) {
5451 if (unit_type_from_string(type) >= 0) {
5452 if (strv_push(&arg_types, type))
5458 /* It's much nicer to use --state= for
5459 * load states, but let's support this
5460 * in --types= too for compatibility
5461 * with old versions */
5462 if (unit_load_state_from_string(optarg) >= 0) {
5463 if (strv_push(&arg_states, type) < 0)
5469 log_error("Unknown unit type or load state '%s'.", type);
5470 log_info("Use -t help to see a list of allowed values.");
5478 /* Make sure that if the empty property list
5479 was specified, we won't show any properties. */
5480 if (isempty(optarg) && !arg_properties) {
5481 arg_properties = new0(char*, 1);
5482 if (!arg_properties)
5488 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5491 prop = strndup(word, size);
5495 if (strv_consume(&arg_properties, prop) < 0)
5500 /* If the user asked for a particular
5501 * property, show it to him, even if it is
5513 arg_dependency = DEPENDENCY_REVERSE;
5517 arg_dependency = DEPENDENCY_AFTER;
5521 arg_dependency = DEPENDENCY_BEFORE;
5524 case ARG_SHOW_TYPES:
5525 arg_show_types = true;
5529 arg_job_mode = optarg;
5533 arg_job_mode = "fail";
5536 case ARG_IRREVERSIBLE:
5537 arg_job_mode = "replace-irreversibly";
5540 case ARG_IGNORE_DEPENDENCIES:
5541 arg_job_mode = "ignore-dependencies";
5545 arg_scope = UNIT_FILE_USER;
5549 arg_scope = UNIT_FILE_SYSTEM;
5553 arg_scope = UNIT_FILE_GLOBAL;
5557 arg_no_block = true;
5561 arg_no_legend = true;
5565 arg_no_pager = true;
5581 if (strv_extend(&arg_states, "failed") < 0)
5599 arg_no_reload = true;
5603 arg_kill_who = optarg;
5607 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5608 log_error("Failed to parse signal string %s.", optarg);
5613 case ARG_NO_ASK_PASSWORD:
5614 arg_ask_password = false;
5618 arg_transport = BUS_TRANSPORT_REMOTE;
5623 arg_transport = BUS_TRANSPORT_CONTAINER;
5632 if (safe_atou(optarg, &arg_lines) < 0) {
5633 log_error("Failed to parse lines '%s'", optarg);
5639 arg_output = output_mode_from_string(optarg);
5640 if (arg_output < 0) {
5641 log_error("Unknown output '%s'.", optarg);
5647 arg_ignore_inhibitors = true;
5658 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5661 s = strndup(word, size);
5665 if (strv_consume(&arg_states, s) < 0)
5675 assert_not_reached("Unhandled option");
5679 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5680 log_error("Cannot access user instance remotely.");
5687 static int halt_parse_argv(int argc, char *argv[]) {
5696 static const struct option options[] = {
5697 { "help", no_argument, NULL, ARG_HELP },
5698 { "halt", no_argument, NULL, ARG_HALT },
5699 { "poweroff", no_argument, NULL, 'p' },
5700 { "reboot", no_argument, NULL, ARG_REBOOT },
5701 { "force", no_argument, NULL, 'f' },
5702 { "wtmp-only", no_argument, NULL, 'w' },
5703 { "no-wtmp", no_argument, NULL, 'd' },
5704 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5713 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5714 if (runlevel == '0' || runlevel == '6')
5717 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5724 arg_action = ACTION_HALT;
5728 if (arg_action != ACTION_REBOOT)
5729 arg_action = ACTION_POWEROFF;
5733 arg_action = ACTION_REBOOT;
5755 /* Compatibility nops */
5762 assert_not_reached("Unhandled option");
5766 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5767 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5769 log_error("Failed to write reboot param to "
5770 REBOOT_PARAM_FILE": %s", strerror(-r));
5773 } else if (optind < argc) {
5774 log_error("Too many arguments.");
5781 static int parse_time_spec(const char *t, usec_t *_u) {
5785 if (streq(t, "now"))
5787 else if (!strchr(t, ':')) {
5790 if (safe_atou64(t, &u) < 0)
5793 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5802 hour = strtol(t, &e, 10);
5803 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5806 minute = strtol(e+1, &e, 10);
5807 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5810 n = now(CLOCK_REALTIME);
5811 s = (time_t) (n / USEC_PER_SEC);
5813 assert_se(localtime_r(&s, &tm));
5815 tm.tm_hour = (int) hour;
5816 tm.tm_min = (int) minute;
5819 assert_se(s = mktime(&tm));
5821 *_u = (usec_t) s * USEC_PER_SEC;
5824 *_u += USEC_PER_DAY;
5830 static int shutdown_parse_argv(int argc, char *argv[]) {
5837 static const struct option options[] = {
5838 { "help", no_argument, NULL, ARG_HELP },
5839 { "halt", no_argument, NULL, 'H' },
5840 { "poweroff", no_argument, NULL, 'P' },
5841 { "reboot", no_argument, NULL, 'r' },
5842 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5843 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5852 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5856 return shutdown_help();
5859 arg_action = ACTION_HALT;
5863 arg_action = ACTION_POWEROFF;
5868 arg_action = ACTION_KEXEC;
5870 arg_action = ACTION_REBOOT;
5874 arg_action = ACTION_KEXEC;
5878 if (arg_action != ACTION_HALT)
5879 arg_action = ACTION_POWEROFF;
5892 /* Compatibility nops */
5896 arg_action = ACTION_CANCEL_SHUTDOWN;
5903 assert_not_reached("Unhandled option");
5907 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5908 r = parse_time_spec(argv[optind], &arg_when);
5910 log_error("Failed to parse time specification: %s", argv[optind]);
5914 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5916 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5917 /* No time argument for shutdown cancel */
5918 arg_wall = argv + optind;
5919 else if (argc > optind + 1)
5920 /* We skip the time argument */
5921 arg_wall = argv + optind + 1;
5928 static int telinit_parse_argv(int argc, char *argv[]) {
5935 static const struct option options[] = {
5936 { "help", no_argument, NULL, ARG_HELP },
5937 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5941 static const struct {
5945 { '0', ACTION_POWEROFF },
5946 { '6', ACTION_REBOOT },
5947 { '1', ACTION_RESCUE },
5948 { '2', ACTION_RUNLEVEL2 },
5949 { '3', ACTION_RUNLEVEL3 },
5950 { '4', ACTION_RUNLEVEL4 },
5951 { '5', ACTION_RUNLEVEL5 },
5952 { 's', ACTION_RESCUE },
5953 { 'S', ACTION_RESCUE },
5954 { 'q', ACTION_RELOAD },
5955 { 'Q', ACTION_RELOAD },
5956 { 'u', ACTION_REEXEC },
5957 { 'U', ACTION_REEXEC }
5966 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5970 return telinit_help();
5980 assert_not_reached("Unhandled option");
5984 if (optind >= argc) {
5989 if (optind + 1 < argc) {
5990 log_error("Too many arguments.");
5994 if (strlen(argv[optind]) != 1) {
5995 log_error("Expected single character argument.");
5999 for (i = 0; i < ELEMENTSOF(table); i++)
6000 if (table[i].from == argv[optind][0])
6003 if (i >= ELEMENTSOF(table)) {
6004 log_error("Unknown command '%s'.", argv[optind]);
6008 arg_action = table[i].to;
6015 static int runlevel_parse_argv(int argc, char *argv[]) {
6021 static const struct option options[] = {
6022 { "help", no_argument, NULL, ARG_HELP },
6031 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6035 return runlevel_help();
6041 assert_not_reached("Unhandled option");
6045 if (optind < argc) {
6046 log_error("Too many arguments.");
6053 static int parse_argv(int argc, char *argv[]) {
6057 if (program_invocation_short_name) {
6059 if (strstr(program_invocation_short_name, "halt")) {
6060 arg_action = ACTION_HALT;
6061 return halt_parse_argv(argc, argv);
6062 } else if (strstr(program_invocation_short_name, "poweroff")) {
6063 arg_action = ACTION_POWEROFF;
6064 return halt_parse_argv(argc, argv);
6065 } else if (strstr(program_invocation_short_name, "reboot")) {
6067 arg_action = ACTION_KEXEC;
6069 arg_action = ACTION_REBOOT;
6070 return halt_parse_argv(argc, argv);
6071 } else if (strstr(program_invocation_short_name, "shutdown")) {
6072 arg_action = ACTION_POWEROFF;
6073 return shutdown_parse_argv(argc, argv);
6074 } else if (strstr(program_invocation_short_name, "init")) {
6076 if (sd_booted() > 0) {
6077 arg_action = _ACTION_INVALID;
6078 return telinit_parse_argv(argc, argv);
6080 /* Hmm, so some other init system is
6081 * running, we need to forward this
6082 * request to it. For now we simply
6083 * guess that it is Upstart. */
6085 execv(TELINIT, argv);
6087 log_error("Couldn't find an alternative telinit implementation to spawn.");
6091 } else if (strstr(program_invocation_short_name, "runlevel")) {
6092 arg_action = ACTION_RUNLEVEL;
6093 return runlevel_parse_argv(argc, argv);
6097 arg_action = ACTION_SYSTEMCTL;
6098 return systemctl_parse_argv(argc, argv);
6101 _pure_ static int action_to_runlevel(void) {
6103 static const char table[_ACTION_MAX] = {
6104 [ACTION_HALT] = '0',
6105 [ACTION_POWEROFF] = '0',
6106 [ACTION_REBOOT] = '6',
6107 [ACTION_RUNLEVEL2] = '2',
6108 [ACTION_RUNLEVEL3] = '3',
6109 [ACTION_RUNLEVEL4] = '4',
6110 [ACTION_RUNLEVEL5] = '5',
6111 [ACTION_RESCUE] = '1'
6114 assert(arg_action < _ACTION_MAX);
6116 return table[arg_action];
6119 static int talk_initctl(void) {
6121 struct init_request request = {
6122 .magic = INIT_MAGIC,
6124 .cmd = INIT_CMD_RUNLVL
6127 _cleanup_close_ int fd = -1;
6131 rl = action_to_runlevel();
6135 request.runlevel = rl;
6137 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6139 if (errno == ENOENT)
6142 log_error("Failed to open "INIT_FIFO": %m");
6147 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6149 log_error("Failed to write to "INIT_FIFO": %m");
6150 return errno > 0 ? -errno : -EIO;
6156 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6158 static const struct {
6166 int (* const dispatch)(sd_bus *bus, char **args);
6172 { "list-units", MORE, 0, list_units },
6173 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6174 { "list-sockets", MORE, 1, list_sockets },
6175 { "list-timers", MORE, 1, list_timers },
6176 { "list-jobs", MORE, 1, list_jobs },
6177 { "list-machines", MORE, 1, list_machines },
6178 { "clear-jobs", EQUAL, 1, daemon_reload },
6179 { "cancel", MORE, 2, cancel_job },
6180 { "start", MORE, 2, start_unit },
6181 { "stop", MORE, 2, start_unit },
6182 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6183 { "reload", MORE, 2, start_unit },
6184 { "restart", MORE, 2, start_unit },
6185 { "try-restart", MORE, 2, start_unit },
6186 { "reload-or-restart", MORE, 2, start_unit },
6187 { "reload-or-try-restart", MORE, 2, start_unit },
6188 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6189 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6190 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6191 { "isolate", EQUAL, 2, start_unit },
6192 { "kill", MORE, 2, kill_unit },
6193 { "is-active", MORE, 2, check_unit_active },
6194 { "check", MORE, 2, check_unit_active },
6195 { "is-failed", MORE, 2, check_unit_failed },
6196 { "show", MORE, 1, show },
6197 { "cat", MORE, 2, cat },
6198 { "status", MORE, 1, show },
6199 { "help", MORE, 2, show },
6200 { "snapshot", LESS, 2, snapshot },
6201 { "delete", MORE, 2, delete_snapshot },
6202 { "daemon-reload", EQUAL, 1, daemon_reload },
6203 { "daemon-reexec", EQUAL, 1, daemon_reload },
6204 { "show-environment", EQUAL, 1, show_environment },
6205 { "set-environment", MORE, 2, set_environment },
6206 { "unset-environment", MORE, 2, set_environment },
6207 { "import-environment", MORE, 1, import_environment},
6208 { "halt", EQUAL, 1, start_special, FORCE },
6209 { "poweroff", EQUAL, 1, start_special, FORCE },
6210 { "reboot", EQUAL, 1, start_special, FORCE },
6211 { "kexec", EQUAL, 1, start_special },
6212 { "suspend", EQUAL, 1, start_special },
6213 { "hibernate", EQUAL, 1, start_special },
6214 { "hybrid-sleep", EQUAL, 1, start_special },
6215 { "default", EQUAL, 1, start_special },
6216 { "rescue", EQUAL, 1, start_special },
6217 { "emergency", EQUAL, 1, start_special },
6218 { "exit", EQUAL, 1, start_special },
6219 { "reset-failed", MORE, 1, reset_failed },
6220 { "enable", MORE, 2, enable_unit, NOBUS },
6221 { "disable", MORE, 2, enable_unit, NOBUS },
6222 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6223 { "reenable", MORE, 2, enable_unit, NOBUS },
6224 { "preset", MORE, 2, enable_unit, NOBUS },
6225 { "mask", MORE, 2, enable_unit, NOBUS },
6226 { "unmask", MORE, 2, enable_unit, NOBUS },
6227 { "link", MORE, 2, enable_unit, NOBUS },
6228 { "switch-root", MORE, 2, switch_root },
6229 { "list-dependencies", LESS, 2, list_dependencies },
6230 { "set-default", EQUAL, 2, set_default, NOBUS },
6231 { "get-default", EQUAL, 1, get_default, NOBUS },
6232 { "set-property", MORE, 3, set_property },
6241 left = argc - optind;
6243 /* Special rule: no arguments (left == 0) means "list-units" */
6245 if (streq(argv[optind], "help") && !argv[optind+1]) {
6246 log_error("This command expects one or more "
6247 "unit names. Did you mean --help?");
6251 for (; verb->verb; verb++)
6252 if (streq(argv[optind], verb->verb))
6255 log_error("Unknown operation '%s'.", argv[optind]);
6260 switch (verb->argc_cmp) {
6263 if (left != verb->argc) {
6264 log_error("Invalid number of arguments.");
6271 if (left < verb->argc) {
6272 log_error("Too few arguments.");
6279 if (left > verb->argc) {
6280 log_error("Too many arguments.");
6287 assert_not_reached("Unknown comparison operator.");
6290 /* Require a bus connection for all operations but
6292 if (verb->bus == NOBUS) {
6293 if (!bus && !avoid_bus()) {
6294 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6299 if (running_in_chroot() > 0) {
6300 log_info("Running in chroot, ignoring request.");
6304 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6305 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6310 return verb->dispatch(bus, argv + optind);
6313 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6315 struct sd_shutdown_command c = {
6322 union sockaddr_union sockaddr = {
6323 .un.sun_family = AF_UNIX,
6324 .un.sun_path = "/run/systemd/shutdownd",
6327 struct iovec iovec[2] = {{
6328 .iov_base = (char*) &c,
6329 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6332 struct msghdr msghdr = {
6333 .msg_name = &sockaddr,
6334 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6335 + strlen("/run/systemd/shutdownd"),
6340 _cleanup_close_ int fd;
6342 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6346 if (!isempty(message)) {
6347 iovec[1].iov_base = (char*) message;
6348 iovec[1].iov_len = strlen(message);
6349 msghdr.msg_iovlen++;
6352 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6358 static int reload_with_fallback(sd_bus *bus) {
6361 /* First, try systemd via D-Bus. */
6362 if (daemon_reload(bus, NULL) >= 0)
6366 /* Nothing else worked, so let's try signals */
6367 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6369 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6370 log_error("kill() failed: %m");
6377 static int start_with_fallback(sd_bus *bus) {
6380 /* First, try systemd via D-Bus. */
6381 if (start_unit(bus, NULL) >= 0)
6385 /* Nothing else worked, so let's try
6387 if (talk_initctl() > 0)
6390 log_error("Failed to talk to init daemon.");
6394 warn_wall(arg_action);
6398 static int halt_now(enum action a) {
6400 /* Make sure C-A-D is handled by the kernel from this
6402 reboot(RB_ENABLE_CAD);
6407 log_info("Halting.");
6408 reboot(RB_HALT_SYSTEM);
6411 case ACTION_POWEROFF:
6412 log_info("Powering off.");
6413 reboot(RB_POWER_OFF);
6416 case ACTION_REBOOT: {
6417 _cleanup_free_ char *param = NULL;
6419 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6420 log_info("Rebooting with argument '%s'.", param);
6421 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6422 LINUX_REBOOT_CMD_RESTART2, param);
6425 log_info("Rebooting.");
6426 reboot(RB_AUTOBOOT);
6431 assert_not_reached("Unknown action.");
6435 static int halt_main(sd_bus *bus) {
6438 r = check_inhibitors(bus, arg_action);
6442 if (geteuid() != 0) {
6443 /* Try logind if we are a normal user and no special
6444 * mode applies. Maybe PolicyKit allows us to shutdown
6447 if (arg_when <= 0 &&
6450 (arg_action == ACTION_POWEROFF ||
6451 arg_action == ACTION_REBOOT)) {
6452 r = reboot_with_logind(bus, arg_action);
6457 log_error("Must be root.");
6462 _cleanup_free_ char *m;
6464 m = strv_join(arg_wall, " ");
6468 r = send_shutdownd(arg_when,
6469 arg_action == ACTION_HALT ? 'H' :
6470 arg_action == ACTION_POWEROFF ? 'P' :
6471 arg_action == ACTION_KEXEC ? 'K' :
6478 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6480 char date[FORMAT_TIMESTAMP_MAX];
6482 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6483 format_timestamp(date, sizeof(date), arg_when));
6488 if (!arg_dry && !arg_force)
6489 return start_with_fallback(bus);
6492 if (sd_booted() > 0)
6493 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6495 r = utmp_put_shutdown();
6497 log_warning("Failed to write utmp record: %s", strerror(-r));
6504 r = halt_now(arg_action);
6505 log_error("Failed to reboot: %s", strerror(-r));
6510 static int runlevel_main(void) {
6511 int r, runlevel, previous;
6513 r = utmp_get_runlevel(&runlevel, &previous);
6520 previous <= 0 ? 'N' : previous,
6521 runlevel <= 0 ? 'N' : runlevel);
6526 int main(int argc, char*argv[]) {
6527 _cleanup_bus_unref_ sd_bus *bus = NULL;
6530 setlocale(LC_ALL, "");
6531 log_parse_environment();
6534 /* Explicitly not on_tty() to avoid setting cached value.
6535 * This becomes relevant for piping output which might be
6537 original_stdout_is_tty = isatty(STDOUT_FILENO);
6539 r = parse_argv(argc, argv);
6543 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6544 * let's shortcut this */
6545 if (arg_action == ACTION_RUNLEVEL) {
6546 r = runlevel_main();
6550 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6551 log_info("Running in chroot, ignoring request.");
6557 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6559 /* systemctl_main() will print an error message for the bus
6560 * connection, but only if it needs to */
6562 switch (arg_action) {
6564 case ACTION_SYSTEMCTL:
6565 r = systemctl_main(bus, argc, argv, r);
6569 case ACTION_POWEROFF:
6575 case ACTION_RUNLEVEL2:
6576 case ACTION_RUNLEVEL3:
6577 case ACTION_RUNLEVEL4:
6578 case ACTION_RUNLEVEL5:
6580 case ACTION_EMERGENCY:
6581 case ACTION_DEFAULT:
6582 r = start_with_fallback(bus);
6587 r = reload_with_fallback(bus);
6590 case ACTION_CANCEL_SHUTDOWN: {
6591 _cleanup_free_ char *m = NULL;
6594 m = strv_join(arg_wall, " ");
6601 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6603 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6607 case ACTION_RUNLEVEL:
6608 case _ACTION_INVALID:
6610 assert_not_reached("Unknown action");
6615 ask_password_agent_close();
6616 polkit_agent_close();
6618 strv_free(arg_types);
6619 strv_free(arg_states);
6620 strv_free(arg_properties);
6622 return r < 0 ? EXIT_FAILURE : r;