1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
50 #include "utmp-wtmp.h"
53 #include "path-util.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
61 #include "bus-errors.h"
63 #include "unit-name.h"
65 #include "spawn-ask-password-agent.h"
66 #include "spawn-polkit-agent.h"
68 #include "logs-show.h"
69 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
76 static char **arg_types = NULL;
77 static char **arg_states = NULL;
78 static char **arg_properties = NULL;
79 static bool arg_all = false;
80 static bool original_stdout_is_tty;
81 static enum dependency {
87 } arg_dependency = DEPENDENCY_FORWARD;
88 static const char *arg_job_mode = "replace";
89 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
90 static bool arg_no_block = false;
91 static bool arg_no_legend = false;
92 static bool arg_no_pager = false;
93 static bool arg_no_wtmp = false;
94 static bool arg_no_wall = false;
95 static bool arg_no_reload = false;
96 static bool arg_show_types = false;
97 static bool arg_ignore_inhibitors = false;
98 static bool arg_dry = false;
99 static bool arg_quiet = false;
100 static bool arg_full = false;
101 static int arg_force = 0;
102 static bool arg_ask_password = true;
103 static bool arg_runtime = false;
104 static char **arg_wall = NULL;
105 static const char *arg_kill_who = NULL;
106 static int arg_signal = SIGTERM;
107 static const char *arg_root = NULL;
108 static usec_t arg_when = 0;
130 ACTION_CANCEL_SHUTDOWN,
132 } arg_action = ACTION_SYSTEMCTL;
133 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
134 static char *arg_host = NULL;
135 static unsigned arg_lines = 10;
136 static OutputMode arg_output = OUTPUT_SHORT;
137 static bool arg_plain = false;
139 static int daemon_reload(sd_bus *bus, char **args);
140 static int halt_now(enum action a);
142 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
144 static char** strv_skip_first(char **strv) {
145 if (strv_length(strv) > 0)
150 static void pager_open_if_enabled(void) {
158 static void ask_password_agent_open_if_enabled(void) {
160 /* Open the password agent as a child process if necessary */
162 if (!arg_ask_password)
165 if (arg_scope != UNIT_FILE_SYSTEM)
168 if (arg_transport != BUS_TRANSPORT_LOCAL)
171 ask_password_agent_open();
175 static void polkit_agent_open_if_enabled(void) {
177 /* Open the polkit agent as a child process if necessary */
179 if (!arg_ask_password)
182 if (arg_scope != UNIT_FILE_SYSTEM)
185 if (arg_transport != BUS_TRANSPORT_LOCAL)
192 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
195 if (!sd_bus_error_is_set(error))
198 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
199 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
200 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
201 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
202 return EXIT_NOPERMISSION;
204 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
205 return EXIT_NOTINSTALLED;
207 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
208 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
209 return EXIT_NOTIMPLEMENTED;
211 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
212 return EXIT_NOTCONFIGURED;
220 static void warn_wall(enum action a) {
221 static const char *table[_ACTION_MAX] = {
222 [ACTION_HALT] = "The system is going down for system halt NOW!",
223 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
224 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
225 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
226 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
227 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
228 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
235 _cleanup_free_ char *p;
237 p = strv_join(arg_wall, " ");
252 utmp_wall(table[a], NULL);
255 static bool avoid_bus(void) {
257 if (running_in_chroot() > 0)
260 if (sd_booted() <= 0)
263 if (!isempty(arg_root))
266 if (arg_scope == UNIT_FILE_GLOBAL)
272 static int compare_unit_info(const void *a, const void *b) {
273 const UnitInfo *u = a, *v = b;
276 d1 = strrchr(u->id, '.');
277 d2 = strrchr(v->id, '.');
282 r = strcasecmp(d1, d2);
287 return strcasecmp(u->id, v->id);
290 static bool output_show_unit(const UnitInfo *u, char **patterns) {
293 if (!strv_isempty(arg_states))
295 strv_contains(arg_states, u->load_state) ||
296 strv_contains(arg_states, u->sub_state) ||
297 strv_contains(arg_states, u->active_state);
299 if (!strv_isempty(patterns)) {
302 STRV_FOREACH(pattern, patterns)
303 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
308 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
309 strv_find(arg_types, dot+1))) &&
310 (arg_all || !(streq(u->active_state, "inactive")
311 || u->following[0]) || u->job_id > 0);
314 static void output_units_list(const UnitInfo *unit_infos, unsigned c, char** patterns) {
315 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
317 unsigned n_shown = 0;
320 max_id_len = sizeof("UNIT")-1;
321 load_len = sizeof("LOAD")-1;
322 active_len = sizeof("ACTIVE")-1;
323 sub_len = sizeof("SUB")-1;
324 job_len = sizeof("JOB")-1;
327 for (u = unit_infos; u < unit_infos + c; u++) {
328 if (!output_show_unit(u, patterns))
331 max_id_len = MAX(max_id_len, strlen(u->id));
332 load_len = MAX(load_len, strlen(u->load_state));
333 active_len = MAX(active_len, strlen(u->active_state));
334 sub_len = MAX(sub_len, strlen(u->sub_state));
336 if (u->job_id != 0) {
337 job_len = MAX(job_len, strlen(u->job_type));
342 if (!arg_full && original_stdout_is_tty) {
345 id_len = MIN(max_id_len, 25u);
346 basic_len = 5 + id_len + 5 + active_len + sub_len;
349 basic_len += job_len + 1;
351 if (basic_len < (unsigned) columns()) {
352 unsigned extra_len, incr;
353 extra_len = columns() - basic_len;
355 /* Either UNIT already got 25, or is fully satisfied.
356 * Grant up to 25 to DESC now. */
357 incr = MIN(extra_len, 25u);
361 /* split the remaining space between UNIT and DESC,
362 * but do not give UNIT more than it needs. */
364 incr = MIN(extra_len / 2, max_id_len - id_len);
366 desc_len += extra_len - incr;
372 for (u = unit_infos; u < unit_infos + c; u++) {
373 _cleanup_free_ char *e = NULL;
374 const char *on_loaded, *off_loaded, *on = "";
375 const char *on_active, *off_active, *off = "";
377 if (!output_show_unit(u, patterns))
380 if (!n_shown && !arg_no_legend) {
381 printf("%-*s %-*s %-*s %-*s ",
384 active_len, "ACTIVE",
388 printf("%-*s ", job_len, "JOB");
390 if (!arg_full && arg_no_pager)
391 printf("%.*s\n", desc_len, "DESCRIPTION");
393 printf("%s\n", "DESCRIPTION");
398 if (streq(u->load_state, "error") ||
399 streq(u->load_state, "not-found")) {
400 on_loaded = on = ansi_highlight_red();
401 off_loaded = off = ansi_highlight_off();
403 on_loaded = off_loaded = "";
405 if (streq(u->active_state, "failed")) {
406 on_active = on = ansi_highlight_red();
407 off_active = off = ansi_highlight_off();
409 on_active = off_active = "";
411 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
413 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
414 on, id_len, e ? e : u->id, off,
415 on_loaded, load_len, u->load_state, off_loaded,
416 on_active, active_len, u->active_state,
417 sub_len, u->sub_state, off_active,
418 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
421 printf("%.*s\n", desc_len, u->description);
423 printf("%s\n", u->description);
426 if (!arg_no_legend) {
427 const char *on, *off;
430 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
431 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
432 "SUB = The low-level unit activation state, values depend on unit type.\n");
434 printf("JOB = Pending job for the unit.\n");
436 on = ansi_highlight();
437 off = ansi_highlight_off();
439 on = ansi_highlight_red();
440 off = ansi_highlight_off();
444 printf("%s%u loaded units listed.%s\n"
445 "To show all installed unit files use 'systemctl list-unit-files'.\n",
448 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
449 "To show all installed unit files use 'systemctl list-unit-files'.\n",
454 static int get_unit_list(
456 sd_bus_message **_reply,
457 UnitInfo **_unit_infos) {
459 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
460 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
461 _cleanup_free_ UnitInfo *unit_infos = NULL;
470 r = sd_bus_call_method(
472 "org.freedesktop.systemd1",
473 "/org/freedesktop/systemd1",
474 "org.freedesktop.systemd1.Manager",
480 log_error("Failed to list units: %s", bus_error_message(&error, r));
484 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
486 return bus_log_parse_error(r);
488 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
490 if (!GREEDY_REALLOC(unit_infos, size, c+1))
496 return bus_log_parse_error(r);
498 r = sd_bus_message_exit_container(reply);
500 return bus_log_parse_error(r);
505 *_unit_infos = unit_infos;
511 static int list_units(sd_bus *bus, char **args) {
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
513 _cleanup_free_ UnitInfo *unit_infos = NULL;
516 pager_open_if_enabled();
518 r = get_unit_list(bus, &reply, &unit_infos);
522 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
523 output_units_list(unit_infos, r, strv_skip_first(args));
528 static int get_triggered_units(
533 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
536 r = sd_bus_get_property_strv(
538 "org.freedesktop.systemd1",
540 "org.freedesktop.systemd1.Unit",
546 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
551 static int get_listening(
553 const char* unit_path,
556 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
557 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
558 const char *type, *path;
561 r = sd_bus_get_property(
563 "org.freedesktop.systemd1",
565 "org.freedesktop.systemd1.Socket",
571 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
575 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
577 return bus_log_parse_error(r);
579 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
581 r = strv_extend(listening, type);
585 r = strv_extend(listening, path);
592 return bus_log_parse_error(r);
594 r = sd_bus_message_exit_container(reply);
596 return bus_log_parse_error(r);
607 /* Note: triggered is a list here, although it almost certainly
608 * will always be one unit. Nevertheless, dbus API allows for multiple
609 * values, so let's follow that.*/
612 /* The strv above is shared. free is set only in the first one. */
616 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
622 o = strcmp(a->path, b->path);
624 o = strcmp(a->type, b->type);
629 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
630 struct socket_info *s;
631 unsigned pathlen = sizeof("LISTEN") - 1,
632 typelen = (sizeof("TYPE") - 1) * arg_show_types,
633 socklen = sizeof("UNIT") - 1,
634 servlen = sizeof("ACTIVATES") - 1;
635 const char *on, *off;
637 for (s = socket_infos; s < socket_infos + cs; s++) {
641 socklen = MAX(socklen, strlen(s->id));
643 typelen = MAX(typelen, strlen(s->type));
644 pathlen = MAX(pathlen, strlen(s->path));
646 STRV_FOREACH(a, s->triggered)
647 tmp += strlen(*a) + 2*(a != s->triggered);
648 servlen = MAX(servlen, tmp);
653 printf("%-*s %-*.*s%-*s %s\n",
655 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
659 for (s = socket_infos; s < socket_infos + cs; s++) {
663 printf("%-*s %-*s %-*s",
664 pathlen, s->path, typelen, s->type, socklen, s->id);
667 pathlen, s->path, socklen, s->id);
668 STRV_FOREACH(a, s->triggered)
670 a == s->triggered ? "" : ",", *a);
674 on = ansi_highlight();
675 off = ansi_highlight_off();
679 on = ansi_highlight_red();
680 off = ansi_highlight_off();
683 if (!arg_no_legend) {
684 printf("%s%u sockets listed.%s\n", on, cs, off);
686 printf("Pass --all to see loaded but inactive sockets, too.\n");
692 static int list_sockets(sd_bus *bus, char **args) {
693 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
694 _cleanup_free_ UnitInfo *unit_infos = NULL;
695 struct socket_info *socket_infos = NULL;
697 struct socket_info *s;
702 pager_open_if_enabled();
704 n = get_unit_list(bus, &reply, &unit_infos);
708 for (u = unit_infos; u < unit_infos + n; u++) {
709 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
712 if (!output_show_unit(u, strv_skip_first(args)))
715 if (!endswith(u->id, ".socket"))
718 r = get_triggered_units(bus, u->unit_path, &triggered);
722 c = get_listening(bus, u->unit_path, &listening);
728 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
733 for (i = 0; i < c; i++)
734 socket_infos[cs + i] = (struct socket_info) {
736 .type = listening[i*2],
737 .path = listening[i*2 + 1],
738 .triggered = triggered,
739 .own_triggered = i==0,
742 /* from this point on we will cleanup those socket_infos */
745 listening = triggered = NULL; /* avoid cleanup */
748 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
749 (__compar_fn_t) socket_info_compare);
751 output_sockets_list(socket_infos, cs);
754 assert(cs == 0 || socket_infos);
755 for (s = socket_infos; s < socket_infos + cs; s++) {
758 if (s->own_triggered)
759 strv_free(s->triggered);
766 static int get_next_elapse(
769 dual_timestamp *next) {
771 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
779 r = sd_bus_get_property_trivial(
781 "org.freedesktop.systemd1",
783 "org.freedesktop.systemd1.Timer",
784 "NextElapseUSecMonotonic",
789 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
793 r = sd_bus_get_property_trivial(
795 "org.freedesktop.systemd1",
797 "org.freedesktop.systemd1.Timer",
798 "NextElapseUSecRealtime",
803 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
817 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
821 if (a->next_elapse < b->next_elapse)
823 if (a->next_elapse > b->next_elapse)
826 return strcmp(a->id, b->id);
829 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
830 struct timer_info *t;
832 nextlen = sizeof("NEXT") - 1,
833 leftlen = sizeof("LEFT") - 1,
834 unitlen = sizeof("UNIT") - 1,
835 activatelen = sizeof("ACTIVATES") - 1;
837 const char *on, *off;
839 assert(timer_infos || n == 0);
841 for (t = timer_infos; t < timer_infos + n; t++) {
845 if (t->next_elapse > 0) {
846 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
848 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
849 nextlen = MAX(nextlen, strlen(tstamp) + 1);
851 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
852 leftlen = MAX(leftlen, strlen(trel));
855 unitlen = MAX(unitlen, strlen(t->id));
857 STRV_FOREACH(a, t->triggered)
858 ul += strlen(*a) + 2*(a != t->triggered);
859 activatelen = MAX(activatelen, ul);
864 printf("%-*s %-*s %-*s %s\n",
870 for (t = timer_infos; t < timer_infos + n; t++) {
871 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
874 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
875 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
877 printf("%-*s %-*s %-*s",
878 nextlen, tstamp, leftlen, trel, unitlen, t->id);
880 STRV_FOREACH(a, t->triggered)
882 a == t->triggered ? "" : ",", *a);
886 on = ansi_highlight();
887 off = ansi_highlight_off();
891 on = ansi_highlight_red();
892 off = ansi_highlight_off();
895 if (!arg_no_legend) {
896 printf("%s%u timers listed.%s\n", on, n, off);
898 printf("Pass --all to see loaded but inactive timers, too.\n");
904 static int list_timers(sd_bus *bus, char **args) {
906 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
907 _cleanup_free_ struct timer_info *timer_infos = NULL;
908 _cleanup_free_ UnitInfo *unit_infos = NULL;
909 struct timer_info *t;
916 pager_open_if_enabled();
918 n = get_unit_list(bus, &reply, &unit_infos);
922 dual_timestamp_get(&nw);
924 for (u = unit_infos; u < unit_infos + n; u++) {
925 _cleanup_strv_free_ char **triggered = NULL;
929 if (!output_show_unit(u, strv_skip_first(args)))
932 if (!endswith(u->id, ".timer"))
935 r = get_triggered_units(bus, u->unit_path, &triggered);
939 r = get_next_elapse(bus, u->unit_path, &next);
943 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
946 if (next.monotonic > nw.monotonic)
947 converted = nw.realtime + (next.monotonic - nw.monotonic);
949 converted = nw.realtime - (nw.monotonic - next.monotonic);
951 if (next.realtime != (usec_t) -1 && next.realtime > 0)
952 m = MIN(converted, next.realtime);
958 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
963 timer_infos[c++] = (struct timer_info) {
966 .triggered = triggered,
969 triggered = NULL; /* avoid cleanup */
972 qsort_safe(timer_infos, c, sizeof(struct timer_info),
973 (__compar_fn_t) timer_info_compare);
975 output_timers_list(timer_infos, c);
978 for (t = timer_infos; t < timer_infos + c; t++)
979 strv_free(t->triggered);
984 static int compare_unit_file_list(const void *a, const void *b) {
986 const UnitFileList *u = a, *v = b;
988 d1 = strrchr(u->path, '.');
989 d2 = strrchr(v->path, '.');
994 r = strcasecmp(d1, d2);
999 return strcasecmp(basename(u->path), basename(v->path));
1002 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1005 if (!strv_isempty(patterns)) {
1008 STRV_FOREACH(pattern, patterns)
1009 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1014 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1017 static void output_unit_file_list(const UnitFileList *units, unsigned c, char **patterns) {
1018 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
1019 const UnitFileList *u;
1021 max_id_len = sizeof("UNIT FILE")-1;
1022 state_cols = sizeof("STATE")-1;
1024 for (u = units; u < units + c; u++) {
1025 if (!output_show_unit_file(u, patterns))
1028 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1029 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1033 unsigned basic_cols;
1035 id_cols = MIN(max_id_len, 25u);
1036 basic_cols = 1 + id_cols + state_cols;
1037 if (basic_cols < (unsigned) columns())
1038 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1040 id_cols = max_id_len;
1043 printf("%-*s %-*s\n",
1044 id_cols, "UNIT FILE",
1045 state_cols, "STATE");
1047 for (u = units; u < units + c; u++) {
1048 _cleanup_free_ char *e = NULL;
1049 const char *on, *off;
1052 if (!output_show_unit_file(u, patterns))
1057 if (u->state == UNIT_FILE_MASKED ||
1058 u->state == UNIT_FILE_MASKED_RUNTIME ||
1059 u->state == UNIT_FILE_DISABLED ||
1060 u->state == UNIT_FILE_INVALID) {
1061 on = ansi_highlight_red();
1062 off = ansi_highlight_off();
1063 } else if (u->state == UNIT_FILE_ENABLED) {
1064 on = ansi_highlight_green();
1065 off = ansi_highlight_off();
1069 id = basename(u->path);
1071 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1073 printf("%-*s %s%-*s%s\n",
1074 id_cols, e ? e : id,
1075 on, state_cols, unit_file_state_to_string(u->state), off);
1079 printf("\n%u unit files listed.\n", n_shown);
1082 static int list_unit_files(sd_bus *bus, char **args) {
1083 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1084 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1085 _cleanup_free_ UnitFileList *units = NULL;
1091 pager_open_if_enabled();
1099 h = hashmap_new(string_hash_func, string_compare_func);
1103 r = unit_file_get_list(arg_scope, arg_root, h);
1105 unit_file_list_free(h);
1106 log_error("Failed to get unit file list: %s", strerror(-r));
1110 n_units = hashmap_size(h);
1111 units = new(UnitFileList, n_units);
1113 unit_file_list_free(h);
1117 HASHMAP_FOREACH(u, h, i) {
1118 memcpy(units + c++, u, sizeof(UnitFileList));
1122 assert(c == n_units);
1127 r = sd_bus_call_method(
1129 "org.freedesktop.systemd1",
1130 "/org/freedesktop/systemd1",
1131 "org.freedesktop.systemd1.Manager",
1137 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1141 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1143 return bus_log_parse_error(r);
1145 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1147 if (!GREEDY_REALLOC(units, size, c + 1))
1150 units[c++] = (struct UnitFileList) {
1152 unit_file_state_from_string(state)
1156 return bus_log_parse_error(r);
1158 r = sd_bus_message_exit_container(reply);
1160 return bus_log_parse_error(r);
1164 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1165 output_unit_file_list(units, c, strv_skip_first(args));
1171 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1172 _cleanup_free_ char *n = NULL;
1173 size_t max_len = MAX(columns(),20u);
1179 for (i = level - 1; i >= 0; i--) {
1181 if (len > max_len - 3 && !arg_full) {
1182 printf("%s...\n",max_len % 2 ? "" : " ");
1185 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1189 if (len > max_len - 3 && !arg_full) {
1190 printf("%s...\n",max_len % 2 ? "" : " ");
1194 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1198 printf("%s\n", name);
1202 n = ellipsize(name, max_len-len, 100);
1210 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1212 static const char *dependencies[_DEPENDENCY_MAX] = {
1213 [DEPENDENCY_FORWARD] = "Requires\0"
1214 "RequiresOverridable\0"
1216 "RequisiteOverridable\0"
1218 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1219 "RequiredByOverridable\0"
1222 [DEPENDENCY_AFTER] = "After\0",
1223 [DEPENDENCY_BEFORE] = "Before\0",
1226 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1227 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1228 _cleanup_strv_free_ char **ret = NULL;
1229 _cleanup_free_ char *path = NULL;
1235 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1237 path = unit_dbus_path_from_name(name);
1241 r = sd_bus_call_method(
1243 "org.freedesktop.systemd1",
1245 "org.freedesktop.DBus.Properties",
1249 "s", "org.freedesktop.systemd1.Unit");
1251 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1255 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1257 return bus_log_parse_error(r);
1259 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1262 r = sd_bus_message_read(reply, "s", &prop);
1264 return bus_log_parse_error(r);
1266 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1267 r = sd_bus_message_skip(reply, "v");
1269 return bus_log_parse_error(r);
1272 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1274 return bus_log_parse_error(r);
1276 r = bus_message_read_strv_extend(reply, &ret);
1278 return bus_log_parse_error(r);
1280 r = sd_bus_message_exit_container(reply);
1282 return bus_log_parse_error(r);
1285 r = sd_bus_message_exit_container(reply);
1287 return bus_log_parse_error(r);
1291 return bus_log_parse_error(r);
1293 r = sd_bus_message_exit_container(reply);
1295 return bus_log_parse_error(r);
1303 static int list_dependencies_compare(const void *_a, const void *_b) {
1304 const char **a = (const char**) _a, **b = (const char**) _b;
1306 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1308 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1311 return strcasecmp(*a, *b);
1314 static int list_dependencies_one(
1319 unsigned int branches) {
1321 _cleanup_strv_free_ char **deps = NULL, **u;
1329 u = strv_append(*units, name);
1333 r = list_dependencies_get_dependencies(bus, name, &deps);
1337 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1339 STRV_FOREACH(c, deps) {
1342 if (strv_contains(u, *c)) {
1344 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1351 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1353 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1355 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1357 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1361 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1362 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1377 static int list_dependencies(sd_bus *bus, char **args) {
1378 _cleanup_strv_free_ char **units = NULL;
1379 _cleanup_free_ char *unit = NULL;
1385 unit = unit_name_mangle(args[1]);
1390 u = SPECIAL_DEFAULT_TARGET;
1392 pager_open_if_enabled();
1396 return list_dependencies_one(bus, u, 0, &units, 0);
1399 static int get_default(sd_bus *bus, char **args) {
1400 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1401 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1402 _cleanup_free_ char *_path = NULL;
1406 if (!bus || avoid_bus()) {
1407 r = unit_file_get_default(arg_scope, arg_root, &_path);
1409 log_error("Failed to get default target: %s", strerror(-r));
1415 r = sd_bus_call_method(
1417 "org.freedesktop.systemd1",
1418 "/org/freedesktop/systemd1",
1419 "org.freedesktop.systemd1.Manager",
1425 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1429 r = sd_bus_message_read(reply, "s", &path);
1431 return bus_log_parse_error(r);
1435 printf("%s\n", path);
1440 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1443 assert(changes || n_changes == 0);
1445 for (i = 0; i < n_changes; i++) {
1446 if (changes[i].type == UNIT_FILE_SYMLINK)
1447 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1449 log_info("rm '%s'", changes[i].path);
1453 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1454 const char *type, *path, *source;
1457 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1459 return bus_log_parse_error(r);
1461 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1463 if (streq(type, "symlink"))
1464 log_info("ln -s '%s' '%s'", source, path);
1466 log_info("rm '%s'", path);
1470 return bus_log_parse_error(r);
1472 r = sd_bus_message_exit_container(m);
1474 return bus_log_parse_error(r);
1479 static int set_default(sd_bus *bus, char **args) {
1480 _cleanup_free_ char *unit = NULL;
1481 UnitFileChange *changes = NULL;
1482 unsigned n_changes = 0;
1485 unit = unit_name_mangle_with_suffix(args[1], ".target");
1489 if (!bus || avoid_bus()) {
1490 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1492 log_error("Failed to set default target: %s", strerror(-r));
1497 dump_unit_file_changes(changes, n_changes);
1501 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1502 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1504 r = sd_bus_call_method(
1506 "org.freedesktop.systemd1",
1507 "/org/freedesktop/systemd1",
1508 "org.freedesktop.systemd1.Manager",
1512 "sb", unit, arg_force);
1514 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1518 r = deserialize_and_dump_unit_file_changes(reply);
1522 /* Try to reload if enabeld */
1524 r = daemon_reload(bus, args);
1529 unit_file_changes_free(changes, n_changes);
1536 const char *name, *type, *state;
1539 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1540 unsigned id_len, unit_len, type_len, state_len;
1541 const struct job_info *j;
1542 const char *on, *off;
1543 bool shorten = false;
1545 assert(n == 0 || jobs);
1548 on = ansi_highlight_green();
1549 off = ansi_highlight_off();
1551 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1555 pager_open_if_enabled();
1557 id_len = sizeof("JOB")-1;
1558 unit_len = sizeof("UNIT")-1;
1559 type_len = sizeof("TYPE")-1;
1560 state_len = sizeof("STATE")-1;
1562 for (j = jobs; j < jobs + n; j++) {
1563 uint32_t id = j->id;
1564 assert(j->name && j->type && j->state);
1566 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1567 unit_len = MAX(unit_len, strlen(j->name));
1568 type_len = MAX(type_len, strlen(j->type));
1569 state_len = MAX(state_len, strlen(j->state));
1572 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1573 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1578 printf("%*s %-*s %-*s %-*s\n",
1582 state_len, "STATE");
1584 for (j = jobs; j < jobs + n; j++) {
1585 _cleanup_free_ char *e = NULL;
1587 if (streq(j->state, "running")) {
1588 on = ansi_highlight();
1589 off = ansi_highlight_off();
1593 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1594 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1596 on, unit_len, e ? e : j->name, off,
1598 on, state_len, j->state, off);
1601 if (!arg_no_legend) {
1602 on = ansi_highlight();
1603 off = ansi_highlight_off();
1605 printf("\n%s%u jobs listed%s.\n", on, n, off);
1609 static bool output_show_job(struct job_info *job, char **patterns) {
1610 if (!strv_isempty(patterns)) {
1613 STRV_FOREACH(pattern, patterns)
1614 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1622 static int list_jobs(sd_bus *bus, char **args) {
1623 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1624 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1625 const char *name, *type, *state, *job_path, *unit_path;
1626 _cleanup_free_ struct job_info *jobs = NULL;
1631 bool skipped = false;
1633 r = sd_bus_call_method(
1635 "org.freedesktop.systemd1",
1636 "/org/freedesktop/systemd1",
1637 "org.freedesktop.systemd1.Manager",
1643 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1647 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1649 return bus_log_parse_error(r);
1651 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1652 struct job_info job = { id, name, type, state };
1654 if (!output_show_job(&job, strv_skip_first(args))) {
1659 if (!GREEDY_REALLOC(jobs, size, c + 1))
1665 return bus_log_parse_error(r);
1667 r = sd_bus_message_exit_container(reply);
1669 return bus_log_parse_error(r);
1671 output_jobs_list(jobs, c, skipped);
1675 static int cancel_job(sd_bus *bus, char **args) {
1676 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1681 if (strv_length(args) <= 1)
1682 return daemon_reload(bus, args);
1684 STRV_FOREACH(name, args+1) {
1688 r = safe_atou32(*name, &id);
1690 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1694 r = sd_bus_call_method(
1696 "org.freedesktop.systemd1",
1697 "/org/freedesktop/systemd1",
1698 "org.freedesktop.systemd1.Manager",
1704 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1712 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1713 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1714 _cleanup_free_ char *n = NULL;
1718 /* We ignore all errors here, since this is used to show a
1721 n = unit_name_mangle(unit);
1725 /* We don't use unit_dbus_path_from_name() directly since we
1726 * don't want to load the unit if it isn't loaded. */
1728 r = sd_bus_call_method(
1730 "org.freedesktop.systemd1",
1731 "/org/freedesktop/systemd1",
1732 "org.freedesktop.systemd1.Manager",
1740 r = sd_bus_message_read(reply, "o", &path);
1744 r = sd_bus_get_property_trivial(
1746 "org.freedesktop.systemd1",
1748 "org.freedesktop.systemd1.Unit",
1758 typedef struct WaitData {
1765 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1772 log_debug("Got D-Bus request: %s.%s() on %s",
1773 sd_bus_message_get_interface(m),
1774 sd_bus_message_get_member(m),
1775 sd_bus_message_get_path(m));
1777 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1778 log_error("Warning! D-Bus connection terminated.");
1780 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1782 const char *path, *result, *unit;
1786 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1788 ret = set_remove(d->set, (char*) path);
1794 if (!isempty(result))
1795 d->result = strdup(result);
1798 d->name = strdup(unit);
1803 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1805 ret = set_remove(d->set, (char*) path);
1812 d->result = strdup(result);
1818 bus_log_parse_error(r);
1824 static int enable_wait_for_jobs(sd_bus *bus) {
1829 r = sd_bus_add_match(
1832 "sender='org.freedesktop.systemd1',"
1833 "interface='org.freedesktop.systemd1.Manager',"
1834 "member='JobRemoved',"
1835 "path='/org/freedesktop/systemd1'",
1838 log_error("Failed to add match");
1842 /* This is slightly dirty, since we don't undo the match registrations. */
1846 static int bus_process_wait(sd_bus *bus) {
1850 r = sd_bus_process(bus, NULL);
1855 r = sd_bus_wait(bus, (uint64_t) -1);
1861 static int check_wait_response(WaitData *d) {
1867 if (streq(d->result, "timeout"))
1868 log_error("Job for %s timed out.", strna(d->name));
1869 else if (streq(d->result, "canceled"))
1870 log_error("Job for %s canceled.", strna(d->name));
1871 else if (streq(d->result, "dependency"))
1872 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1873 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1874 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1877 if (streq(d->result, "timeout"))
1879 else if (streq(d->result, "canceled"))
1881 else if (streq(d->result, "dependency"))
1883 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1889 static int wait_for_jobs(sd_bus *bus, Set *s) {
1890 WaitData d = { .set = s };
1896 q = sd_bus_add_filter(bus, wait_filter, &d);
1900 while (!set_isempty(s)) {
1901 q = bus_process_wait(bus);
1906 q = check_wait_response(&d);
1907 /* Return the first error as it is most likely to be
1909 if (q < 0 && r == 0)
1920 q = sd_bus_remove_filter(bus, wait_filter, &d);
1921 if (q < 0 && r == 0)
1927 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1928 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1929 _cleanup_free_ char *n = NULL, *state = NULL;
1935 n = unit_name_mangle(name);
1939 /* We don't use unit_dbus_path_from_name() directly since we
1940 * don't want to load the unit if it isn't loaded. */
1942 r = sd_bus_call_method(
1944 "org.freedesktop.systemd1",
1945 "/org/freedesktop/systemd1",
1946 "org.freedesktop.systemd1.Manager",
1957 r = sd_bus_message_read(reply, "o", &path);
1959 return bus_log_parse_error(r);
1961 r = sd_bus_get_property_string(
1963 "org.freedesktop.systemd1",
1965 "org.freedesktop.systemd1.Unit",
1978 return nulstr_contains(good_states, state);
1981 static int check_triggering_units(
1985 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1986 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1987 _cleanup_strv_free_ char **triggered_by = NULL;
1988 bool print_warning_label = true;
1992 n = unit_name_mangle(name);
1996 path = unit_dbus_path_from_name(n);
2000 r = sd_bus_get_property_string(
2002 "org.freedesktop.systemd1",
2004 "org.freedesktop.systemd1.Unit",
2009 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2013 if (streq(state, "masked"))
2016 r = sd_bus_get_property_strv(
2018 "org.freedesktop.systemd1",
2020 "org.freedesktop.systemd1.Unit",
2025 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2029 STRV_FOREACH(i, triggered_by) {
2030 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2032 log_error("Failed to check unit: %s", strerror(-r));
2039 if (print_warning_label) {
2040 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2041 print_warning_label = false;
2044 log_warning(" %s", *i);
2050 static int start_unit_one(
2055 sd_bus_error *error,
2058 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2059 _cleanup_free_ char *n;
2068 n = unit_name_mangle(name);
2072 r = sd_bus_call_method(
2074 "org.freedesktop.systemd1",
2075 "/org/freedesktop/systemd1",
2076 "org.freedesktop.systemd1.Manager",
2082 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2083 /* There's always a fallback possible for
2084 * legacy actions. */
2085 return -EADDRNOTAVAIL;
2087 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
2091 r = sd_bus_message_read(reply, "o", &path);
2093 return bus_log_parse_error(r);
2095 if (need_daemon_reload(bus, n) > 0)
2096 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2097 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2106 r = set_consume(s, p);
2114 static const struct {
2118 } action_table[_ACTION_MAX] = {
2119 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2120 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2121 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2122 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2123 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2124 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2125 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2126 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2127 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2128 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2129 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2130 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2131 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2132 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2133 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2136 static enum action verb_to_action(const char *verb) {
2139 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2140 if (streq_ptr(action_table[i].verb, verb))
2143 return _ACTION_INVALID;
2146 static int start_unit(sd_bus *bus, char **args) {
2147 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2148 _cleanup_set_free_free_ Set *s = NULL;
2149 const char *method, *mode, *one_name;
2155 ask_password_agent_open_if_enabled();
2157 if (arg_action == ACTION_SYSTEMCTL) {
2160 streq(args[0], "stop") ||
2161 streq(args[0], "condstop") ? "StopUnit" :
2162 streq(args[0], "reload") ? "ReloadUnit" :
2163 streq(args[0], "restart") ? "RestartUnit" :
2165 streq(args[0], "try-restart") ||
2166 streq(args[0], "condrestart") ? "TryRestartUnit" :
2168 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2170 streq(args[0], "reload-or-try-restart") ||
2171 streq(args[0], "condreload") ||
2172 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2174 action = verb_to_action(args[0]);
2176 mode = streq(args[0], "isolate") ? "isolate" :
2177 action_table[action].mode ?: arg_job_mode;
2179 one_name = action_table[action].target;
2181 assert(arg_action < ELEMENTSOF(action_table));
2182 assert(action_table[arg_action].target);
2184 method = "StartUnit";
2186 mode = action_table[arg_action].mode;
2187 one_name = action_table[arg_action].target;
2190 if (!arg_no_block) {
2191 r = enable_wait_for_jobs(bus);
2193 log_error("Could not watch jobs: %s", strerror(-r));
2197 s = set_new(string_hash_func, string_compare_func);
2203 r = start_unit_one(bus, method, one_name, mode, &error, s);
2205 r = translate_bus_error_to_exit_status(r, &error);
2209 STRV_FOREACH(name, args+1) {
2212 q = start_unit_one(bus, method, *name, mode, &error, s);
2214 r = translate_bus_error_to_exit_status(q, &error);
2215 sd_bus_error_free(&error);
2220 if (!arg_no_block) {
2223 q = wait_for_jobs(bus, s);
2227 /* When stopping units, warn if they can still be triggered by
2228 * another active unit (socket, path, timer) */
2229 if (!arg_quiet && streq(method, "StopUnit")) {
2231 check_triggering_units(bus, one_name);
2233 STRV_FOREACH(name, args+1)
2234 check_triggering_units(bus, *name);
2241 /* Ask systemd-logind, which might grant access to unprivileged users
2242 * through PolicyKit */
2243 static int reboot_with_logind(sd_bus *bus, enum action a) {
2245 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2252 polkit_agent_open_if_enabled();
2260 case ACTION_POWEROFF:
2261 method = "PowerOff";
2264 case ACTION_SUSPEND:
2268 case ACTION_HIBERNATE:
2269 method = "Hibernate";
2272 case ACTION_HYBRID_SLEEP:
2273 method = "HybridSleep";
2280 r = sd_bus_call_method(
2282 "org.freedesktop.login1",
2283 "/org/freedesktop/login1",
2284 "org.freedesktop.login1.Manager",
2290 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2298 static int check_inhibitors(sd_bus *bus, enum action a) {
2300 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2301 _cleanup_strv_free_ char **sessions = NULL;
2302 const char *what, *who, *why, *mode;
2311 if (arg_ignore_inhibitors || arg_force > 0)
2323 r = sd_bus_call_method(
2325 "org.freedesktop.login1",
2326 "/org/freedesktop/login1",
2327 "org.freedesktop.login1.Manager",
2333 /* If logind is not around, then there are no inhibitors... */
2336 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2338 return bus_log_parse_error(r);
2340 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2341 _cleanup_free_ char *comm = NULL, *user = NULL;
2342 _cleanup_strv_free_ char **sv = NULL;
2344 if (!streq(mode, "block"))
2347 sv = strv_split(what, ":");
2351 if (!strv_contains(sv,
2353 a == ACTION_POWEROFF ||
2354 a == ACTION_REBOOT ||
2355 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2358 get_process_comm(pid, &comm);
2359 user = uid_to_name(uid);
2361 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2362 who, (unsigned long) pid, strna(comm), strna(user), why);
2367 return bus_log_parse_error(r);
2369 r = sd_bus_message_exit_container(reply);
2371 return bus_log_parse_error(r);
2373 /* Check for current sessions */
2374 sd_get_sessions(&sessions);
2375 STRV_FOREACH(s, sessions) {
2376 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2378 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2381 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2384 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2387 sd_session_get_tty(*s, &tty);
2388 sd_session_get_seat(*s, &seat);
2389 sd_session_get_service(*s, &service);
2390 user = uid_to_name(uid);
2392 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2399 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2400 action_table[a].verb);
2408 static int start_special(sd_bus *bus, char **args) {
2414 a = verb_to_action(args[0]);
2416 r = check_inhibitors(bus, a);
2420 if (arg_force >= 2 && geteuid() != 0) {
2421 log_error("Must be root.");
2425 if (arg_force >= 2 &&
2426 (a == ACTION_HALT ||
2427 a == ACTION_POWEROFF ||
2428 a == ACTION_REBOOT))
2431 if (arg_force >= 1 &&
2432 (a == ACTION_HALT ||
2433 a == ACTION_POWEROFF ||
2434 a == ACTION_REBOOT ||
2435 a == ACTION_KEXEC ||
2437 return daemon_reload(bus, args);
2439 /* first try logind, to allow authentication with polkit */
2440 if (geteuid() != 0 &&
2441 (a == ACTION_POWEROFF ||
2442 a == ACTION_REBOOT ||
2443 a == ACTION_SUSPEND ||
2444 a == ACTION_HIBERNATE ||
2445 a == ACTION_HYBRID_SLEEP)) {
2446 r = reboot_with_logind(bus, a);
2451 r = start_unit(bus, args);
2452 if (r == EXIT_SUCCESS)
2458 static int check_unit_active(sd_bus *bus, char **args) {
2460 int r = 3; /* According to LSB: "program is not running" */
2465 STRV_FOREACH(name, args+1) {
2468 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2478 static int check_unit_failed(sd_bus *bus, char **args) {
2485 STRV_FOREACH(name, args+1) {
2488 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2498 static int kill_unit(sd_bus *bus, char **args) {
2499 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2507 arg_kill_who = "all";
2509 STRV_FOREACH(name, args+1) {
2510 _cleanup_free_ char *n = NULL;
2512 n = unit_name_mangle(*name);
2516 r = sd_bus_call_method(
2518 "org.freedesktop.systemd1",
2519 "/org/freedesktop/systemd1",
2520 "org.freedesktop.systemd1.Manager",
2524 "ssi", n, arg_kill_who, arg_signal);
2526 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2534 typedef struct ExecStatusInfo {
2542 usec_t start_timestamp;
2543 usec_t exit_timestamp;
2548 LIST_FIELDS(struct ExecStatusInfo, exec);
2551 static void exec_status_info_free(ExecStatusInfo *i) {
2560 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2561 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2564 int32_t code, status;
2570 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2572 return bus_log_parse_error(r);
2576 r = sd_bus_message_read(m, "s", &path);
2578 return bus_log_parse_error(r);
2580 i->path = strdup(path);
2584 r = sd_bus_message_read_strv(m, &i->argv);
2586 return bus_log_parse_error(r);
2588 r = sd_bus_message_read(m,
2591 &start_timestamp, &start_timestamp_monotonic,
2592 &exit_timestamp, &exit_timestamp_monotonic,
2596 return bus_log_parse_error(r);
2599 i->start_timestamp = (usec_t) start_timestamp;
2600 i->exit_timestamp = (usec_t) exit_timestamp;
2601 i->pid = (pid_t) pid;
2605 r = sd_bus_message_exit_container(m);
2607 return bus_log_parse_error(r);
2612 typedef struct UnitStatusInfo {
2614 const char *load_state;
2615 const char *active_state;
2616 const char *sub_state;
2617 const char *unit_file_state;
2619 const char *description;
2620 const char *following;
2622 char **documentation;
2624 const char *fragment_path;
2625 const char *source_path;
2626 const char *control_group;
2628 char **dropin_paths;
2630 const char *load_error;
2633 usec_t inactive_exit_timestamp;
2634 usec_t inactive_exit_timestamp_monotonic;
2635 usec_t active_enter_timestamp;
2636 usec_t active_exit_timestamp;
2637 usec_t inactive_enter_timestamp;
2639 bool need_daemon_reload;
2644 const char *status_text;
2645 const char *pid_file;
2648 usec_t start_timestamp;
2649 usec_t exit_timestamp;
2651 int exit_code, exit_status;
2653 usec_t condition_timestamp;
2654 bool condition_result;
2655 bool failed_condition_trigger;
2656 bool failed_condition_negate;
2657 const char *failed_condition;
2658 const char *failed_condition_param;
2661 unsigned n_accepted;
2662 unsigned n_connections;
2665 /* Pairs of type, path */
2669 const char *sysfs_path;
2671 /* Mount, Automount */
2677 LIST_HEAD(ExecStatusInfo, exec);
2680 static void print_status_info(
2685 const char *on, *off, *ss;
2687 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2688 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2691 arg_all * OUTPUT_SHOW_ALL |
2692 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2693 on_tty() * OUTPUT_COLOR |
2694 !arg_quiet * OUTPUT_WARN_CUTOFF |
2695 arg_full * OUTPUT_FULL_WIDTH;
2700 /* This shows pretty information about a unit. See
2701 * print_property() for a low-level property printer */
2703 printf("%s", strna(i->id));
2705 if (i->description && !streq_ptr(i->id, i->description))
2706 printf(" - %s", i->description);
2711 printf(" Follow: unit currently follows state of %s\n", i->following);
2713 if (streq_ptr(i->load_state, "error")) {
2714 on = ansi_highlight_red();
2715 off = ansi_highlight_off();
2719 path = i->source_path ? i->source_path : i->fragment_path;
2722 printf(" Loaded: %s%s%s (Reason: %s)\n",
2723 on, strna(i->load_state), off, i->load_error);
2724 else if (path && i->unit_file_state)
2725 printf(" Loaded: %s%s%s (%s; %s)\n",
2726 on, strna(i->load_state), off, path, i->unit_file_state);
2728 printf(" Loaded: %s%s%s (%s)\n",
2729 on, strna(i->load_state), off, path);
2731 printf(" Loaded: %s%s%s\n",
2732 on, strna(i->load_state), off);
2734 if (!strv_isempty(i->dropin_paths)) {
2735 _cleanup_free_ char *dir = NULL;
2739 STRV_FOREACH(dropin, i->dropin_paths) {
2740 if (! dir || last) {
2741 printf(dir ? " " : " Drop-In: ");
2746 if (path_get_parent(*dropin, &dir) < 0) {
2751 printf("%s\n %s", dir,
2752 draw_special_char(DRAW_TREE_RIGHT));
2755 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2757 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2761 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2763 if (streq_ptr(i->active_state, "failed")) {
2764 on = ansi_highlight_red();
2765 off = ansi_highlight_off();
2766 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2767 on = ansi_highlight_green();
2768 off = ansi_highlight_off();
2773 printf(" Active: %s%s (%s)%s",
2774 on, strna(i->active_state), ss, off);
2776 printf(" Active: %s%s%s",
2777 on, strna(i->active_state), off);
2779 if (!isempty(i->result) && !streq(i->result, "success"))
2780 printf(" (Result: %s)", i->result);
2782 timestamp = (streq_ptr(i->active_state, "active") ||
2783 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2784 (streq_ptr(i->active_state, "inactive") ||
2785 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2786 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2787 i->active_exit_timestamp;
2789 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2790 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2793 printf(" since %s; %s\n", s2, s1);
2795 printf(" since %s\n", s2);
2799 if (!i->condition_result && i->condition_timestamp > 0) {
2800 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2801 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2803 printf(" start condition failed at %s%s%s\n",
2804 s2, s1 ? "; " : "", s1 ? s1 : "");
2805 if (i->failed_condition_trigger)
2806 printf(" none of the trigger conditions were met\n");
2807 else if (i->failed_condition)
2808 printf(" %s=%s%s was not met\n",
2809 i->failed_condition,
2810 i->failed_condition_negate ? "!" : "",
2811 i->failed_condition_param);
2815 printf(" Device: %s\n", i->sysfs_path);
2817 printf(" Where: %s\n", i->where);
2819 printf(" What: %s\n", i->what);
2821 STRV_FOREACH(t, i->documentation)
2822 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2824 STRV_FOREACH_PAIR(t, t2, i->listen)
2825 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2828 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2830 LIST_FOREACH(exec, p, i->exec) {
2831 _cleanup_free_ char *argv = NULL;
2834 /* Only show exited processes here */
2838 argv = strv_join(p->argv, " ");
2839 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2841 good = is_clean_exit_lsb(p->code, p->status, NULL);
2843 on = ansi_highlight_red();
2844 off = ansi_highlight_off();
2848 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2850 if (p->code == CLD_EXITED) {
2853 printf("status=%i", p->status);
2855 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2860 printf("signal=%s", signal_to_string(p->status));
2862 printf(")%s\n", off);
2864 if (i->main_pid == p->pid &&
2865 i->start_timestamp == p->start_timestamp &&
2866 i->exit_timestamp == p->start_timestamp)
2867 /* Let's not show this twice */
2870 if (p->pid == i->control_pid)
2874 if (i->main_pid > 0 || i->control_pid > 0) {
2875 if (i->main_pid > 0) {
2876 printf(" Main PID: %u", (unsigned) i->main_pid);
2879 _cleanup_free_ char *comm = NULL;
2880 get_process_comm(i->main_pid, &comm);
2882 printf(" (%s)", comm);
2883 } else if (i->exit_code > 0) {
2884 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2886 if (i->exit_code == CLD_EXITED) {
2889 printf("status=%i", i->exit_status);
2891 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2896 printf("signal=%s", signal_to_string(i->exit_status));
2900 if (i->control_pid > 0)
2904 if (i->control_pid > 0) {
2905 _cleanup_free_ char *c = NULL;
2907 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2909 get_process_comm(i->control_pid, &c);
2918 printf(" Status: \"%s\"\n", i->status_text);
2920 if (i->control_group &&
2921 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2924 printf(" CGroup: %s\n", i->control_group);
2926 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2929 char prefix[] = " ";
2932 if (c > sizeof(prefix) - 1)
2933 c -= sizeof(prefix) - 1;
2937 if (i->main_pid > 0)
2938 extra[k++] = i->main_pid;
2940 if (i->control_pid > 0)
2941 extra[k++] = i->control_pid;
2943 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2944 c, false, extra, k, flags);
2948 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2950 show_journal_by_unit(stdout,
2954 i->inactive_exit_timestamp_monotonic,
2958 arg_scope == UNIT_FILE_SYSTEM,
2962 if (i->need_daemon_reload)
2963 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2964 ansi_highlight_red(),
2965 ansi_highlight_off(),
2966 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2969 static void show_unit_help(UnitStatusInfo *i) {
2974 if (!i->documentation) {
2975 log_info("Documentation for %s not known.", i->id);
2979 STRV_FOREACH(p, i->documentation) {
2981 if (startswith(*p, "man:")) {
2982 const char *args[4] = { "man", NULL, NULL, NULL };
2983 _cleanup_free_ char *page = NULL, *section = NULL;
2990 if ((*p)[k-1] == ')')
2991 e = strrchr(*p, '(');
2994 page = strndup((*p) + 4, e - *p - 4);
2995 section = strndup(e + 1, *p + k - e - 2);
2996 if (!page || !section) {
3008 log_error("Failed to fork: %m");
3014 execvp(args[0], (char**) args);
3015 log_error("Failed to execute man: %m");
3016 _exit(EXIT_FAILURE);
3019 wait_for_terminate(pid, NULL);
3021 log_info("Can't show: %s", *p);
3025 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3032 switch (contents[0]) {
3034 case SD_BUS_TYPE_STRING: {
3037 r = sd_bus_message_read(m, "s", &s);
3039 return bus_log_parse_error(r);
3042 if (streq(name, "Id"))
3044 else if (streq(name, "LoadState"))
3046 else if (streq(name, "ActiveState"))
3047 i->active_state = s;
3048 else if (streq(name, "SubState"))
3050 else if (streq(name, "Description"))
3052 else if (streq(name, "FragmentPath"))
3053 i->fragment_path = s;
3054 else if (streq(name, "SourcePath"))
3057 else if (streq(name, "DefaultControlGroup")) {
3059 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3061 i->control_group = e;
3064 else if (streq(name, "ControlGroup"))
3065 i->control_group = s;
3066 else if (streq(name, "StatusText"))
3068 else if (streq(name, "PIDFile"))
3070 else if (streq(name, "SysFSPath"))
3072 else if (streq(name, "Where"))
3074 else if (streq(name, "What"))
3076 else if (streq(name, "Following"))
3078 else if (streq(name, "UnitFileState"))
3079 i->unit_file_state = s;
3080 else if (streq(name, "Result"))
3087 case SD_BUS_TYPE_BOOLEAN: {
3090 r = sd_bus_message_read(m, "b", &b);
3092 return bus_log_parse_error(r);
3094 if (streq(name, "Accept"))
3096 else if (streq(name, "NeedDaemonReload"))
3097 i->need_daemon_reload = b;
3098 else if (streq(name, "ConditionResult"))
3099 i->condition_result = b;
3104 case SD_BUS_TYPE_UINT32: {
3107 r = sd_bus_message_read(m, "u", &u);
3109 return bus_log_parse_error(r);
3111 if (streq(name, "MainPID")) {
3113 i->main_pid = (pid_t) u;
3116 } else if (streq(name, "ControlPID"))
3117 i->control_pid = (pid_t) u;
3118 else if (streq(name, "ExecMainPID")) {
3120 i->main_pid = (pid_t) u;
3121 } else if (streq(name, "NAccepted"))
3123 else if (streq(name, "NConnections"))
3124 i->n_connections = u;