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;
2152 char **names, *strv[] = {NULL, NULL}; /* at most one name */
2156 ask_password_agent_open_if_enabled();
2158 if (arg_action == ACTION_SYSTEMCTL) {
2161 streq(args[0], "stop") ||
2162 streq(args[0], "condstop") ? "StopUnit" :
2163 streq(args[0], "reload") ? "ReloadUnit" :
2164 streq(args[0], "restart") ? "RestartUnit" :
2166 streq(args[0], "try-restart") ||
2167 streq(args[0], "condrestart") ? "TryRestartUnit" :
2169 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2171 streq(args[0], "reload-or-try-restart") ||
2172 streq(args[0], "condreload") ||
2173 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2175 action = verb_to_action(args[0]);
2177 mode = streq(args[0], "isolate") ? "isolate" :
2178 action_table[action].mode ?: arg_job_mode;
2180 strv[0] = (char*) action_table[action].target;
2182 assert(arg_action < ELEMENTSOF(action_table));
2183 assert(action_table[arg_action].target);
2185 method = "StartUnit";
2187 mode = action_table[arg_action].mode;
2188 strv[0] = (char*) action_table[arg_action].target;
2196 if (!arg_no_block) {
2197 r = enable_wait_for_jobs(bus);
2199 log_error("Could not watch jobs: %s", strerror(-r));
2203 s = set_new(string_hash_func, string_compare_func);
2208 STRV_FOREACH(name, names) {
2211 q = start_unit_one(bus, method, *name, mode, &error, s);
2212 if (r == 0 && q < 0) {
2213 r = translate_bus_error_to_exit_status(q, &error);
2214 sd_bus_error_free(&error);
2218 if (!arg_no_block) {
2221 q = wait_for_jobs(bus, s);
2225 /* When stopping units, warn if they can still be triggered by
2226 * another active unit (socket, path, timer) */
2227 if (!arg_quiet && streq(method, "StopUnit"))
2228 STRV_FOREACH(name, names)
2229 check_triggering_units(bus, *name);
2235 /* Ask systemd-logind, which might grant access to unprivileged users
2236 * through PolicyKit */
2237 static int reboot_with_logind(sd_bus *bus, enum action a) {
2239 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2246 polkit_agent_open_if_enabled();
2254 case ACTION_POWEROFF:
2255 method = "PowerOff";
2258 case ACTION_SUSPEND:
2262 case ACTION_HIBERNATE:
2263 method = "Hibernate";
2266 case ACTION_HYBRID_SLEEP:
2267 method = "HybridSleep";
2274 r = sd_bus_call_method(
2276 "org.freedesktop.login1",
2277 "/org/freedesktop/login1",
2278 "org.freedesktop.login1.Manager",
2284 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2292 static int check_inhibitors(sd_bus *bus, enum action a) {
2294 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2295 _cleanup_strv_free_ char **sessions = NULL;
2296 const char *what, *who, *why, *mode;
2305 if (arg_ignore_inhibitors || arg_force > 0)
2317 r = sd_bus_call_method(
2319 "org.freedesktop.login1",
2320 "/org/freedesktop/login1",
2321 "org.freedesktop.login1.Manager",
2327 /* If logind is not around, then there are no inhibitors... */
2330 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2332 return bus_log_parse_error(r);
2334 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2335 _cleanup_free_ char *comm = NULL, *user = NULL;
2336 _cleanup_strv_free_ char **sv = NULL;
2338 if (!streq(mode, "block"))
2341 sv = strv_split(what, ":");
2345 if (!strv_contains(sv,
2347 a == ACTION_POWEROFF ||
2348 a == ACTION_REBOOT ||
2349 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2352 get_process_comm(pid, &comm);
2353 user = uid_to_name(uid);
2355 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2356 who, (unsigned long) pid, strna(comm), strna(user), why);
2361 return bus_log_parse_error(r);
2363 r = sd_bus_message_exit_container(reply);
2365 return bus_log_parse_error(r);
2367 /* Check for current sessions */
2368 sd_get_sessions(&sessions);
2369 STRV_FOREACH(s, sessions) {
2370 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2372 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2375 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2378 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2381 sd_session_get_tty(*s, &tty);
2382 sd_session_get_seat(*s, &seat);
2383 sd_session_get_service(*s, &service);
2384 user = uid_to_name(uid);
2386 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2393 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2394 action_table[a].verb);
2402 static int start_special(sd_bus *bus, char **args) {
2408 a = verb_to_action(args[0]);
2410 r = check_inhibitors(bus, a);
2414 if (arg_force >= 2 && geteuid() != 0) {
2415 log_error("Must be root.");
2419 if (arg_force >= 2 &&
2420 (a == ACTION_HALT ||
2421 a == ACTION_POWEROFF ||
2422 a == ACTION_REBOOT))
2425 if (arg_force >= 1 &&
2426 (a == ACTION_HALT ||
2427 a == ACTION_POWEROFF ||
2428 a == ACTION_REBOOT ||
2429 a == ACTION_KEXEC ||
2431 return daemon_reload(bus, args);
2433 /* first try logind, to allow authentication with polkit */
2434 if (geteuid() != 0 &&
2435 (a == ACTION_POWEROFF ||
2436 a == ACTION_REBOOT ||
2437 a == ACTION_SUSPEND ||
2438 a == ACTION_HIBERNATE ||
2439 a == ACTION_HYBRID_SLEEP)) {
2440 r = reboot_with_logind(bus, a);
2445 r = start_unit(bus, args);
2446 if (r == EXIT_SUCCESS)
2452 static int check_unit_active(sd_bus *bus, char **args) {
2454 int r = 3; /* According to LSB: "program is not running" */
2459 STRV_FOREACH(name, args+1) {
2462 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2472 static int check_unit_failed(sd_bus *bus, char **args) {
2479 STRV_FOREACH(name, args+1) {
2482 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2492 static int kill_unit(sd_bus *bus, char **args) {
2493 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2501 arg_kill_who = "all";
2503 STRV_FOREACH(name, args+1) {
2504 _cleanup_free_ char *n = NULL;
2506 n = unit_name_mangle(*name);
2510 r = sd_bus_call_method(
2512 "org.freedesktop.systemd1",
2513 "/org/freedesktop/systemd1",
2514 "org.freedesktop.systemd1.Manager",
2518 "ssi", n, arg_kill_who, arg_signal);
2520 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2528 typedef struct ExecStatusInfo {
2536 usec_t start_timestamp;
2537 usec_t exit_timestamp;
2542 LIST_FIELDS(struct ExecStatusInfo, exec);
2545 static void exec_status_info_free(ExecStatusInfo *i) {
2554 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2555 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2558 int32_t code, status;
2564 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2566 return bus_log_parse_error(r);
2570 r = sd_bus_message_read(m, "s", &path);
2572 return bus_log_parse_error(r);
2574 i->path = strdup(path);
2578 r = sd_bus_message_read_strv(m, &i->argv);
2580 return bus_log_parse_error(r);
2582 r = sd_bus_message_read(m,
2585 &start_timestamp, &start_timestamp_monotonic,
2586 &exit_timestamp, &exit_timestamp_monotonic,
2590 return bus_log_parse_error(r);
2593 i->start_timestamp = (usec_t) start_timestamp;
2594 i->exit_timestamp = (usec_t) exit_timestamp;
2595 i->pid = (pid_t) pid;
2599 r = sd_bus_message_exit_container(m);
2601 return bus_log_parse_error(r);
2606 typedef struct UnitStatusInfo {
2608 const char *load_state;
2609 const char *active_state;
2610 const char *sub_state;
2611 const char *unit_file_state;
2613 const char *description;
2614 const char *following;
2616 char **documentation;
2618 const char *fragment_path;
2619 const char *source_path;
2620 const char *control_group;
2622 char **dropin_paths;
2624 const char *load_error;
2627 usec_t inactive_exit_timestamp;
2628 usec_t inactive_exit_timestamp_monotonic;
2629 usec_t active_enter_timestamp;
2630 usec_t active_exit_timestamp;
2631 usec_t inactive_enter_timestamp;
2633 bool need_daemon_reload;
2638 const char *status_text;
2639 const char *pid_file;
2642 usec_t start_timestamp;
2643 usec_t exit_timestamp;
2645 int exit_code, exit_status;
2647 usec_t condition_timestamp;
2648 bool condition_result;
2649 bool failed_condition_trigger;
2650 bool failed_condition_negate;
2651 const char *failed_condition;
2652 const char *failed_condition_param;
2655 unsigned n_accepted;
2656 unsigned n_connections;
2659 /* Pairs of type, path */
2663 const char *sysfs_path;
2665 /* Mount, Automount */
2671 LIST_HEAD(ExecStatusInfo, exec);
2674 static void print_status_info(
2679 const char *on, *off, *ss;
2681 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2682 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2685 arg_all * OUTPUT_SHOW_ALL |
2686 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2687 on_tty() * OUTPUT_COLOR |
2688 !arg_quiet * OUTPUT_WARN_CUTOFF |
2689 arg_full * OUTPUT_FULL_WIDTH;
2694 /* This shows pretty information about a unit. See
2695 * print_property() for a low-level property printer */
2697 printf("%s", strna(i->id));
2699 if (i->description && !streq_ptr(i->id, i->description))
2700 printf(" - %s", i->description);
2705 printf(" Follow: unit currently follows state of %s\n", i->following);
2707 if (streq_ptr(i->load_state, "error")) {
2708 on = ansi_highlight_red();
2709 off = ansi_highlight_off();
2713 path = i->source_path ? i->source_path : i->fragment_path;
2716 printf(" Loaded: %s%s%s (Reason: %s)\n",
2717 on, strna(i->load_state), off, i->load_error);
2718 else if (path && i->unit_file_state)
2719 printf(" Loaded: %s%s%s (%s; %s)\n",
2720 on, strna(i->load_state), off, path, i->unit_file_state);
2722 printf(" Loaded: %s%s%s (%s)\n",
2723 on, strna(i->load_state), off, path);
2725 printf(" Loaded: %s%s%s\n",
2726 on, strna(i->load_state), off);
2728 if (!strv_isempty(i->dropin_paths)) {
2729 _cleanup_free_ char *dir = NULL;
2733 STRV_FOREACH(dropin, i->dropin_paths) {
2734 if (! dir || last) {
2735 printf(dir ? " " : " Drop-In: ");
2740 if (path_get_parent(*dropin, &dir) < 0) {
2745 printf("%s\n %s", dir,
2746 draw_special_char(DRAW_TREE_RIGHT));
2749 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2751 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2755 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2757 if (streq_ptr(i->active_state, "failed")) {
2758 on = ansi_highlight_red();
2759 off = ansi_highlight_off();
2760 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2761 on = ansi_highlight_green();
2762 off = ansi_highlight_off();
2767 printf(" Active: %s%s (%s)%s",
2768 on, strna(i->active_state), ss, off);
2770 printf(" Active: %s%s%s",
2771 on, strna(i->active_state), off);
2773 if (!isempty(i->result) && !streq(i->result, "success"))
2774 printf(" (Result: %s)", i->result);
2776 timestamp = (streq_ptr(i->active_state, "active") ||
2777 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2778 (streq_ptr(i->active_state, "inactive") ||
2779 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2780 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2781 i->active_exit_timestamp;
2783 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2784 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2787 printf(" since %s; %s\n", s2, s1);
2789 printf(" since %s\n", s2);
2793 if (!i->condition_result && i->condition_timestamp > 0) {
2794 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2795 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2797 printf(" start condition failed at %s%s%s\n",
2798 s2, s1 ? "; " : "", s1 ? s1 : "");
2799 if (i->failed_condition_trigger)
2800 printf(" none of the trigger conditions were met\n");
2801 else if (i->failed_condition)
2802 printf(" %s=%s%s was not met\n",
2803 i->failed_condition,
2804 i->failed_condition_negate ? "!" : "",
2805 i->failed_condition_param);
2809 printf(" Device: %s\n", i->sysfs_path);
2811 printf(" Where: %s\n", i->where);
2813 printf(" What: %s\n", i->what);
2815 STRV_FOREACH(t, i->documentation)
2816 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2818 STRV_FOREACH_PAIR(t, t2, i->listen)
2819 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2822 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2824 LIST_FOREACH(exec, p, i->exec) {
2825 _cleanup_free_ char *argv = NULL;
2828 /* Only show exited processes here */
2832 argv = strv_join(p->argv, " ");
2833 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2835 good = is_clean_exit_lsb(p->code, p->status, NULL);
2837 on = ansi_highlight_red();
2838 off = ansi_highlight_off();
2842 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2844 if (p->code == CLD_EXITED) {
2847 printf("status=%i", p->status);
2849 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2854 printf("signal=%s", signal_to_string(p->status));
2856 printf(")%s\n", off);
2858 if (i->main_pid == p->pid &&
2859 i->start_timestamp == p->start_timestamp &&
2860 i->exit_timestamp == p->start_timestamp)
2861 /* Let's not show this twice */
2864 if (p->pid == i->control_pid)
2868 if (i->main_pid > 0 || i->control_pid > 0) {
2869 if (i->main_pid > 0) {
2870 printf(" Main PID: %u", (unsigned) i->main_pid);
2873 _cleanup_free_ char *comm = NULL;
2874 get_process_comm(i->main_pid, &comm);
2876 printf(" (%s)", comm);
2877 } else if (i->exit_code > 0) {
2878 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2880 if (i->exit_code == CLD_EXITED) {
2883 printf("status=%i", i->exit_status);
2885 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2890 printf("signal=%s", signal_to_string(i->exit_status));
2894 if (i->control_pid > 0)
2898 if (i->control_pid > 0) {
2899 _cleanup_free_ char *c = NULL;
2901 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2903 get_process_comm(i->control_pid, &c);
2912 printf(" Status: \"%s\"\n", i->status_text);
2914 if (i->control_group &&
2915 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2918 printf(" CGroup: %s\n", i->control_group);
2920 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2923 char prefix[] = " ";
2926 if (c > sizeof(prefix) - 1)
2927 c -= sizeof(prefix) - 1;
2931 if (i->main_pid > 0)
2932 extra[k++] = i->main_pid;
2934 if (i->control_pid > 0)
2935 extra[k++] = i->control_pid;
2937 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2938 c, false, extra, k, flags);
2942 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2944 show_journal_by_unit(stdout,
2948 i->inactive_exit_timestamp_monotonic,
2952 arg_scope == UNIT_FILE_SYSTEM,
2956 if (i->need_daemon_reload)
2957 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2958 ansi_highlight_red(),
2959 ansi_highlight_off(),
2960 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2963 static void show_unit_help(UnitStatusInfo *i) {
2968 if (!i->documentation) {
2969 log_info("Documentation for %s not known.", i->id);
2973 STRV_FOREACH(p, i->documentation) {
2975 if (startswith(*p, "man:")) {
2976 const char *args[4] = { "man", NULL, NULL, NULL };
2977 _cleanup_free_ char *page = NULL, *section = NULL;
2984 if ((*p)[k-1] == ')')
2985 e = strrchr(*p, '(');
2988 page = strndup((*p) + 4, e - *p - 4);
2989 section = strndup(e + 1, *p + k - e - 2);
2990 if (!page || !section) {
3002 log_error("Failed to fork: %m");
3008 execvp(args[0], (char**) args);
3009 log_error("Failed to execute man: %m");
3010 _exit(EXIT_FAILURE);
3013 wait_for_terminate(pid, NULL);
3015 log_info("Can't show: %s", *p);
3019 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3026 switch (contents[0]) {
3028 case SD_BUS_TYPE_STRING: {
3031 r = sd_bus_message_read(m, "s", &s);
3033 return bus_log_parse_error(r);
3036 if (streq(name, "Id"))
3038 else if (streq(name, "LoadState"))
3040 else if (streq(name, "ActiveState"))
3041 i->active_state = s;
3042 else if (streq(name, "SubState"))
3044 else if (streq(name, "Description"))
3046 else if (streq(name, "FragmentPath"))
3047 i->fragment_path = s;
3048 else if (streq(name, "SourcePath"))
3051 else if (streq(name, "DefaultControlGroup")) {
3053 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3055 i->control_group = e;
3058 else if (streq(name, "ControlGroup"))
3059 i->control_group = s;
3060 else if (streq(name, "StatusText"))
3062 else if (streq(name, "PIDFile"))
3064 else if (streq(name, "SysFSPath"))
3066 else if (streq(name, "Where"))
3068 else if (streq(name, "What"))
3070 else if (streq(name, "Following"))
3072 else if (streq(name, "UnitFileState"))
3073 i->unit_file_state = s;
3074 else if (streq(name, "Result"))
3081 case SD_BUS_TYPE_BOOLEAN: {
3084 r = sd_bus_message_read(m, "b", &b);
3086 return bus_log_parse_error(r);
3088 if (streq(name, "Accept"))
3090 else if (streq(name, "NeedDaemonReload"))
3091 i->need_daemon_reload = b;
3092 else if (streq(name, "ConditionResult"))
3093 i->condition_result = b;
3098 case SD_BUS_TYPE_UINT32: {
3101 r = sd_bus_message_read(m, "u", &u);
3103 return bus_log_parse_error(r);
3105 if (streq(name, "MainPID")) {
3107 i->main_pid = (pid_t) u;
3110 } else if (streq(name, "ControlPID"))
3111 i->control_pid = (pid_t) u;
3112 else if (streq(name, "ExecMainPID")) {
3114 i->main_pid = (pid_t) u;
3115 } else if (streq(name, "NAccepted"))
3117 else if (streq(name, "NConnections"))
3118 i->n_connections = u;
3123 case SD_BUS_TYPE_INT32: {
3126 r = sd_bus_message_read(m, "i", &j);
3128 return bus_log_parse_error(r);
3130 if (streq(name, "ExecMainCode"))
3131 i->exit_code = (int) j;
3132 else if (streq(name, "ExecMainStatus"))
3133 i->exit_status = (int) j;
3138 case SD_BUS_TYPE_UINT64: {
3141 r = sd_bus_message_read(m, "t", &u);
3143 return bus_log_parse_error(r);
3145 if (streq(name, "ExecMainStartTimestamp"))
3146 i->start_timestamp = (usec_t) u;
3147 else if (streq(name, "ExecMainExitTimestamp"))
3148 i->exit_timestamp = (usec_t) u;
3149 else if (streq(name, "ActiveEnterTimestamp"))
3150 i->active_enter_timestamp = (usec_t) u;
3151 else if (streq(name, "InactiveEnterTimestamp"))
3152 i->inactive_enter_timestamp = (usec_t) u;
3153 else if (streq(name, "InactiveExitTimestamp"))
3154 i->inactive_exit_timestamp = (usec_t) u;
3155 else if (streq(name, "InactiveExitTimestampMonotonic"))
3156 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3157 else if (streq(name, "ActiveExitTimestamp"))
3158 i->active_exit_timestamp = (usec_t) u;
3159 else if (streq(name, "ConditionTimestamp"))
3160 i->condition_timestamp = (usec_t) u;
3165 case SD_BUS_TYPE_ARRAY:
3167 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3168 _cleanup_free_ ExecStatusInfo *info = NULL;
3170 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3172 return bus_log_parse_error(r);
3174 info = new0(ExecStatusInfo, 1);
3178 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3180 info->name = strdup(name);
3184 LIST_PREPEND(exec, i->exec, info);
3186 info = new0(ExecStatusInfo, 1);
3192 return bus_log_parse_error(r);
3194 r = sd_bus_message_exit_container(m);
3196 return bus_log_parse_error(r);
3200 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3201 const char *type, *path;
3203 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3205 return bus_log_parse_error(r);
3207 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3209 r = strv_extend(&i->listen, type);
3213 r = strv_extend(&i->listen, path);
3218 return bus_log_parse_error(r);
3220 r = sd_bus_message_exit_container(m);
3222 return bus_log_parse_error(r);
3226 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3228 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3230 return bus_log_parse_error(r);
3232 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3234 r = sd_bus_message_read_strv(m, &i->documentation);
3236 return bus_log_parse_error(r);
3238 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3239 const char *cond, *param;
3240 int trigger, negate;
3243 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3245 return bus_log_parse_error(r);
3247 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3248 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3249 if (state < 0 && (!trigger || !i->failed_condition)) {
3250 i->failed_condition = cond;
3251 i->failed_condition_trigger = trigger;
3252 i->failed_condition_negate = negate;
3253 i->failed_condition_param = param;
3257 return bus_log_parse_error(r);
3259 r = sd_bus_message_exit_container(m);
3261 return bus_log_parse_error(r);
3268 case SD_BUS_TYPE_STRUCT_BEGIN:
3270 if (streq(name, "LoadError")) {
3271 const char *n, *message;
3273 r = sd_bus_message_read(m, "(ss)", &n, &message);
3275 return bus_log_parse_error(r);
3277 if (!isempty(message))
3278 i->load_error = message;
3291 r = sd_bus_message_skip(m, contents);
3293 return bus_log_parse_error(r);
3298 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3304 /* This is a low-level property printer, see
3305 * print_status_info() for the nicer output */
3307 if (arg_properties && !strv_find(arg_properties, name)) {
3308 /* skip what we didn't read */
3309 r = sd_bus_message_skip(m, contents);
3313 switch (contents[0]) {
3315 case SD_BUS_TYPE_STRUCT_BEGIN:
3317 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3320 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3322 return bus_log_parse_error(r);
3325 printf("%s=%u\n", name, (unsigned) u);
3327 printf("%s=\n", name);
3331 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3334 r = sd_bus_message_read(m, "(so)", &s, NULL);
3336 return bus_log_parse_error(r);
3338 if (arg_all || !isempty(s))
3339 printf("%s=%s\n", name, s);
3343 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3344 const char *a = NULL, *b = NULL;
3346 r = sd_bus_message_read(m, "(ss)", &a, &b);
3348 return bus_log_parse_error(r);
3350 if (arg_all || !isempty(a) || !isempty(b))
3351 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3358 case SD_BUS_TYPE_ARRAY:
3360 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3364 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3366 return bus_log_parse_error(r);
3368 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3369 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3372 return bus_log_parse_error(r);
3374 r = sd_bus_message_exit_container(m);
3376 return bus_log_parse_error(r);
3380 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3381 const char *type, *path;
3383 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3385 return bus_log_parse_error(r);
3387 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3388 printf("%s=%s\n", type, path);
3390 return bus_log_parse_error(r);
3392 r = sd_bus_message_exit_container(m);
3394 return bus_log_parse_error(r);
3398 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3399 const char *type, *path;
3401 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3403 return bus_log_parse_error(r);
3405 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3406 printf("Listen%s=%s\n", type, path);
3408 return bus_log_parse_error(r);
3410 r = sd_bus_message_exit_container(m);
3412 return bus_log_parse_error(r);
3416 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3418 uint64_t value, next_elapse;
3420 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3422 return bus_log_parse_error(r);
3424 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3425 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3427 printf("%s={ value=%s ; next_elapse=%s }\n",
3429 format_timespan(timespan1, sizeof(timespan1), value, 0),
3430 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3433 return bus_log_parse_error(r);
3435 r = sd_bus_message_exit_container(m);
3437 return bus_log_parse_error(r);
3441 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3442 ExecStatusInfo info = {};
3444 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3446 return bus_log_parse_error(r);
3448 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3449 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3450 _cleanup_free_ char *tt;
3452 tt = strv_join(info.argv, " ");
3454 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3458 yes_no(info.ignore),
3459 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3460 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3461 (unsigned) info. pid,
3462 sigchld_code_to_string(info.code),
3464 info.code == CLD_EXITED ? "" : "/",
3465 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3468 strv_free(info.argv);
3472 r = sd_bus_message_exit_container(m);
3474 return bus_log_parse_error(r);
3478 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3479 const char *path, *rwm;
3481 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3483 return bus_log_parse_error(r);
3485 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3486 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3488 return bus_log_parse_error(r);
3490 r = sd_bus_message_exit_container(m);
3492 return bus_log_parse_error(r);
3496 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3500 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3502 return bus_log_parse_error(r);
3504 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3505 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3507 return bus_log_parse_error(r);
3509 r = sd_bus_message_exit_container(m);
3511 return bus_log_parse_error(r);
3515 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3519 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3521 return bus_log_parse_error(r);
3523 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3524 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3526 return bus_log_parse_error(r);
3528 r = sd_bus_message_exit_container(m);
3530 return bus_log_parse_error(r);
3538 r = bus_print_property(name, m, arg_all);
3540 return bus_log_parse_error(r);
3543 r = sd_bus_message_skip(m, contents);
3545 return bus_log_parse_error(r);
3548 printf("%s=[unprintable]\n", name);
3554 static int show_one(
3558 bool show_properties,
3562 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3563 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3564 UnitStatusInfo info = {};
3571 r = sd_bus_call_method(
3573 "org.freedesktop.systemd1",
3575 "org.freedesktop.DBus.Properties",
3581 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3585 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3587 return bus_log_parse_error(r);
3594 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3595 const char *name, *contents;
3597 r = sd_bus_message_read(reply, "s", &name);
3599 return bus_log_parse_error(r);
3601 r = sd_bus_message_peek_type(reply, NULL, &contents);
3603 return bus_log_parse_error(r);
3605 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3607 return bus_log_parse_error(r);
3609 if (show_properties)
3610 r = print_property(name, reply, contents);
3612 r = status_property(name, reply, &info, contents);
3616 r = sd_bus_message_exit_container(reply);
3618 return bus_log_parse_error(r);
3620 r = sd_bus_message_exit_container(reply);
3622 return bus_log_parse_error(r);
3625 return bus_log_parse_error(r);
3627 r = sd_bus_message_exit_container(reply);
3629 return bus_log_parse_error(r);
3633 if (!show_properties) {
3634 if (streq(verb, "help"))
3635 show_unit_help(&info);
3637 print_status_info(&info, ellipsized);
3640 strv_free(info.documentation);
3641 strv_free(info.dropin_paths);
3642 strv_free(info.listen);
3644 if (!streq_ptr(info.active_state, "active") &&
3645 !streq_ptr(info.active_state, "reloading") &&
3646 streq(verb, "status")) {
3647 /* According to LSB: "program not running" */
3648 /* 0: program is running or service is OK
3649 * 1: program is dead and /var/run pid file exists
3650 * 2: program is dead and /var/lock lock file exists
3651 * 3: program is not running
3652 * 4: program or service status is unknown
3654 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3660 while ((p = info.exec)) {
3661 LIST_REMOVE(exec, info.exec, p);
3662 exec_status_info_free(p);
3668 static int get_unit_dbus_path_by_pid(
3673 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3674 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3678 r = sd_bus_call_method(
3680 "org.freedesktop.systemd1",
3681 "/org/freedesktop/systemd1",
3682 "org.freedesktop.systemd1.Manager",
3688 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3692 r = sd_bus_message_read(reply, "o", &u);
3694 return bus_log_parse_error(r);
3704 static int show_all(
3707 bool show_properties,
3711 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3712 _cleanup_free_ UnitInfo *unit_infos = NULL;
3717 r = get_unit_list(bus, &reply, &unit_infos);
3721 pager_open_if_enabled();
3725 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3727 for (u = unit_infos; u < unit_infos + c; u++) {
3728 _cleanup_free_ char *p = NULL;
3730 if (!output_show_unit(u, NULL))
3733 p = unit_dbus_path_from_name(u->id);
3737 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3745 static int cat(sd_bus *bus, char **args) {
3746 _cleanup_free_ char *unit = NULL, *n = NULL;
3754 pager_open_if_enabled();
3756 STRV_FOREACH(name, args+1) {
3757 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3758 _cleanup_strv_free_ char **dropin_paths = NULL;
3759 _cleanup_free_ char *fragment_path = NULL;
3762 n = unit_name_mangle(*name);
3766 unit = unit_dbus_path_from_name(n);
3770 if (need_daemon_reload(bus, n) > 0)
3771 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3772 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3774 r = sd_bus_get_property_string(
3776 "org.freedesktop.systemd1",
3778 "org.freedesktop.systemd1.Unit",
3783 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3787 r = sd_bus_get_property_strv(
3789 "org.freedesktop.systemd1",
3791 "org.freedesktop.systemd1.Unit",
3796 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3805 if (!isempty(fragment_path)) {
3806 printf("%s# %s%s\n",
3807 ansi_highlight_blue(),
3809 ansi_highlight_off());
3812 r = sendfile_full(STDOUT_FILENO, fragment_path);
3814 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3819 STRV_FOREACH(path, dropin_paths) {
3820 printf("%s%s# %s%s\n",
3821 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3822 ansi_highlight_blue(),
3824 ansi_highlight_off());
3827 r = sendfile_full(STDOUT_FILENO, *path);
3829 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3835 return r < 0 ? r : 0;
3838 static int show(sd_bus *bus, char **args) {
3840 bool show_properties, show_status, new_line = false;
3842 bool ellipsized = false;
3847 show_properties = streq(args[0], "show");
3848 show_status = streq(args[0], "status");
3850 if (show_properties)
3851 pager_open_if_enabled();
3853 /* If no argument is specified inspect the manager itself */
3855 if (show_properties && strv_length(args) <= 1)
3856 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3858 if (show_status && strv_length(args) <= 1)
3859 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3861 STRV_FOREACH(name, args+1) {
3862 _cleanup_free_ char *unit = NULL;
3865 if (safe_atou32(*name, &id) < 0) {
3866 _cleanup_free_ char *n = NULL;
3867 /* Interpret as unit name */
3869 n = unit_name_mangle(*name);
3873 unit = unit_dbus_path_from_name(n);
3877 } else if (show_properties) {
3878 /* Interpret as job id */
3879 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3883 /* Interpret as PID */
3884 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3891 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3894 if (ellipsized && !arg_quiet)
3895 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3900 static int append_assignment(sd_bus_message *m, const char *assignment) {
3908 eq = strchr(assignment, '=');
3910 log_error("Not an assignment: %s", assignment);
3914 field = strndupa(assignment, eq - assignment);
3917 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3919 return bus_log_create_error(r);
3921 if (streq(field, "CPUAccounting") ||
3922 streq(field, "MemoryAccounting") ||
3923 streq(field, "BlockIOAccounting")) {
3925 r = parse_boolean(eq);
3927 log_error("Failed to parse boolean assignment %s.", assignment);
3931 r = sd_bus_message_append(m, "v", "b", r);
3933 } else if (streq(field, "MemoryLimit")) {
3936 r = parse_bytes(eq, &bytes);
3938 log_error("Failed to parse bytes specification %s", assignment);
3942 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3944 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3947 r = safe_atou64(eq, &u);
3949 log_error("Failed to parse %s value %s.", field, eq);
3953 r = sd_bus_message_append(m, "v", "t", u);
3955 } else if (streq(field, "DevicePolicy"))
3956 r = sd_bus_message_append(m, "v", "s", eq);
3958 else if (streq(field, "DeviceAllow")) {
3961 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3963 const char *path, *rwm;
3966 e = strchr(eq, ' ');
3968 path = strndupa(eq, e - eq);
3975 if (!path_startswith(path, "/dev")) {
3976 log_error("%s is not a device file in /dev.", path);
3980 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3983 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3986 r = sd_bus_message_append(m, "v", "a(st)", 0);
3988 const char *path, *bandwidth;
3992 e = strchr(eq, ' ');
3994 path = strndupa(eq, e - eq);
3997 log_error("Failed to parse %s value %s.", field, eq);
4001 if (!path_startswith(path, "/dev")) {
4002 log_error("%s is not a device file in /dev.", path);
4006 r = parse_bytes(bandwidth, &bytes);
4008 log_error("Failed to parse byte value %s.", bandwidth);
4012 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4015 } else if (streq(field, "BlockIODeviceWeight")) {
4018 r = sd_bus_message_append(m, "v", "a(st)", 0);
4020 const char *path, *weight;
4024 e = strchr(eq, ' ');
4026 path = strndupa(eq, e - eq);
4029 log_error("Failed to parse %s value %s.", field, eq);
4033 if (!path_startswith(path, "/dev")) {
4034 log_error("%s is not a device file in /dev.", path);
4038 r = safe_atou64(weight, &u);
4040 log_error("Failed to parse %s value %s.", field, weight);
4043 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4047 log_error("Unknown assignment %s.", assignment);
4052 return bus_log_create_error(r);
4057 static int set_property(sd_bus *bus, char **args) {
4058 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4059 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4060 _cleanup_free_ char *n = NULL;
4064 r = sd_bus_message_new_method_call(
4066 "org.freedesktop.systemd1",
4067 "/org/freedesktop/systemd1",
4068 "org.freedesktop.systemd1.Manager",
4069 "SetUnitProperties",
4072 return bus_log_create_error(r);
4074 n = unit_name_mangle(args[1]);
4078 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4080 return bus_log_create_error(r);
4082 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4084 return bus_log_create_error(r);
4086 STRV_FOREACH(i, args + 2) {
4087 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4089 return bus_log_create_error(r);
4091 r = append_assignment(m, *i);
4095 r = sd_bus_message_close_container(m);
4097 return bus_log_create_error(r);
4100 r = sd_bus_message_close_container(m);
4102 return bus_log_create_error(r);
4104 r = sd_bus_call(bus, m, 0, &error, NULL);
4106 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4113 static int snapshot(sd_bus *bus, char **args) {
4114 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4115 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4116 _cleanup_free_ char *n = NULL, *id = NULL;
4120 if (strv_length(args) > 1)
4121 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
4127 r = sd_bus_call_method(
4129 "org.freedesktop.systemd1",
4130 "/org/freedesktop/systemd1",
4131 "org.freedesktop.systemd1.Manager",
4137 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4141 r = sd_bus_message_read(reply, "o", &path);
4143 return bus_log_parse_error(r);
4145 r = sd_bus_get_property_string(
4147 "org.freedesktop.systemd1",
4149 "org.freedesktop.systemd1.Unit",
4154 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4164 static int delete_snapshot(sd_bus *bus, char **args) {
4165 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4171 STRV_FOREACH(name, args+1) {
4172 _cleanup_free_ char *n = NULL;
4174 n = unit_name_mangle_with_suffix(*name, ".snapshot");
4178 r = sd_bus_call_method(
4180 "org.freedesktop.systemd1",
4181 "/org/freedesktop/systemd1",
4182 "org.freedesktop.systemd1.Manager",
4188 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
4196 static int daemon_reload(sd_bus *bus, char **args) {
4197 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4201 if (arg_action == ACTION_RELOAD)
4203 else if (arg_action == ACTION_REEXEC)
4204 method = "Reexecute";
4206 assert(arg_action == ACTION_SYSTEMCTL);
4209 streq(args[0], "clear-jobs") ||
4210 streq(args[0], "cancel") ? "ClearJobs" :
4211 streq(args[0], "daemon-reexec") ? "Reexecute" :
4212 streq(args[0], "reset-failed") ? "ResetFailed" :
4213 streq(args[0], "halt") ? "Halt" :
4214 streq(args[0], "poweroff") ? "PowerOff" :
4215 streq(args[0], "reboot") ? "Reboot" :
4216 streq(args[0], "kexec") ? "KExec" :
4217 streq(args[0], "exit") ? "Exit" :
4218 /* "daemon-reload" */ "Reload";
4221 r = sd_bus_call_method(
4223 "org.freedesktop.systemd1",
4224 "/org/freedesktop/systemd1",
4225 "org.freedesktop.systemd1.Manager",
4231 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4232 /* There's always a fallback possible for
4233 * legacy actions. */
4235 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4236 /* On reexecution, we expect a disconnect, not a
4240 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4242 return r < 0 ? r : 0;
4245 static int reset_failed(sd_bus *bus, char **args) {
4246 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4250 if (strv_length(args) <= 1)
4251 return daemon_reload(bus, args);
4253 STRV_FOREACH(name, args+1) {
4254 _cleanup_free_ char *n;
4256 n = unit_name_mangle(*name);
4260 r = sd_bus_call_method(
4262 "org.freedesktop.systemd1",
4263 "/org/freedesktop/systemd1",
4264 "org.freedesktop.systemd1.Manager",
4270 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4278 static int show_environment(sd_bus *bus, char **args) {
4279 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4280 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4284 pager_open_if_enabled();
4286 r = sd_bus_get_property(
4288 "org.freedesktop.systemd1",
4289 "/org/freedesktop/systemd1",
4290 "org.freedesktop.systemd1.Manager",
4296 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4300 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4302 return bus_log_parse_error(r);
4304 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4307 return bus_log_parse_error(r);
4309 r = sd_bus_message_exit_container(reply);
4311 return bus_log_parse_error(r);
4316 static int switch_root(sd_bus *bus, char **args) {
4317 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4318 _cleanup_free_ char *init = NULL;
4323 l = strv_length(args);
4324 if (l < 2 || l > 3) {
4325 log_error("Wrong number of arguments.");
4332 init = strdup(args[2]);
4334 parse_env_file("/proc/cmdline", WHITESPACE,
4345 log_debug("switching root - root: %s; init: %s", root, init);
4347 r = sd_bus_call_method(
4349 "org.freedesktop.systemd1",
4350 "/org/freedesktop/systemd1",
4351 "org.freedesktop.systemd1.Manager",
4357 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4364 static int set_environment(sd_bus *bus, char **args) {
4365 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4366 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4373 method = streq(args[0], "set-environment")
4375 : "UnsetEnvironment";
4377 r = sd_bus_message_new_method_call(
4379 "org.freedesktop.systemd1",
4380 "/org/freedesktop/systemd1",
4381 "org.freedesktop.systemd1.Manager",
4385 return bus_log_create_error(r);
4387 r = sd_bus_message_append_strv(m, args + 1);
4389 return bus_log_create_error(r);
4391 r = sd_bus_call(bus, m, 0, &error, NULL);
4393 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4400 static int enable_sysv_units(const char *verb, char **args) {
4403 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4404 unsigned f = 1, t = 1;
4405 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4407 if (arg_scope != UNIT_FILE_SYSTEM)
4410 if (!streq(verb, "enable") &&
4411 !streq(verb, "disable") &&
4412 !streq(verb, "is-enabled"))
4415 /* Processes all SysV units, and reshuffles the array so that
4416 * afterwards only the native units remain */
4418 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4423 for (f = 0; args[f]; f++) {
4425 _cleanup_free_ char *p = NULL, *q = NULL;
4426 bool found_native = false, found_sysv;
4428 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4436 if (!endswith(name, ".service"))
4439 if (path_is_absolute(name))
4442 STRV_FOREACH(k, paths.unit_path) {
4443 if (!isempty(arg_root))
4444 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4446 asprintf(&p, "%s/%s", *k, name);
4453 found_native = access(p, F_OK) >= 0;
4464 if (!isempty(arg_root))
4465 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4467 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4473 p[strlen(p) - sizeof(".service") + 1] = 0;
4474 found_sysv = access(p, F_OK) >= 0;
4479 /* Mark this entry, so that we don't try enabling it as native unit */
4480 args[f] = (char*) "";
4482 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4484 if (!isempty(arg_root))
4485 argv[c++] = q = strappend("--root=", arg_root);
4487 argv[c++] = basename(p);
4489 streq(verb, "enable") ? "on" :
4490 streq(verb, "disable") ? "off" : "--level=5";
4493 l = strv_join((char**)argv, " ");
4499 log_info("Executing %s", l);
4504 log_error("Failed to fork: %m");
4507 } else if (pid == 0) {
4510 execv(argv[0], (char**) argv);
4511 _exit(EXIT_FAILURE);
4514 j = wait_for_terminate(pid, &status);
4516 log_error("Failed to wait for child: %s", strerror(-r));
4521 if (status.si_code == CLD_EXITED) {
4522 if (streq(verb, "is-enabled")) {
4523 if (status.si_status == 0) {
4532 } else if (status.si_status != 0) {
4543 /* Drop all SysV units */
4544 for (f = 0, t = 0; args[f]; f++) {
4546 if (isempty(args[f]))
4549 args[t++] = args[f];
4558 static int mangle_names(char **original_names, char ***mangled_names) {
4559 char **i, **l, **name;
4561 l = new(char*, strv_length(original_names) + 1);
4566 STRV_FOREACH(name, original_names) {
4568 /* When enabling units qualified path names are OK,
4569 * too, hence allow them explicitly. */
4574 *i = unit_name_mangle(*name);
4590 static int enable_unit(sd_bus *bus, char **args) {
4591 _cleanup_strv_free_ char **mangled_names = NULL;
4592 const char *verb = args[0];
4593 UnitFileChange *changes = NULL;
4594 unsigned n_changes = 0;
4595 int carries_install_info = -1;
4601 r = mangle_names(args+1, &mangled_names);
4605 r = enable_sysv_units(verb, mangled_names);
4609 if (!bus || avoid_bus()) {
4610 if (streq(verb, "enable")) {
4611 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4612 carries_install_info = r;
4613 } else if (streq(verb, "disable"))
4614 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4615 else if (streq(verb, "reenable")) {
4616 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4617 carries_install_info = r;
4618 } else if (streq(verb, "link"))
4619 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4620 else if (streq(verb, "preset")) {
4621 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4622 carries_install_info = r;
4623 } else if (streq(verb, "mask"))
4624 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4625 else if (streq(verb, "unmask"))
4626 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4628 assert_not_reached("Unknown verb");
4631 log_error("Operation failed: %s", strerror(-r));
4636 dump_unit_file_changes(changes, n_changes);
4640 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4641 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4642 int expect_carries_install_info = false;
4643 bool send_force = true;
4646 if (streq(verb, "enable")) {
4647 method = "EnableUnitFiles";
4648 expect_carries_install_info = true;
4649 } else if (streq(verb, "disable")) {
4650 method = "DisableUnitFiles";
4652 } else if (streq(verb, "reenable")) {
4653 method = "ReenableUnitFiles";
4654 expect_carries_install_info = true;
4655 } else if (streq(verb, "link"))
4656 method = "LinkUnitFiles";
4657 else if (streq(verb, "preset")) {
4658 method = "PresetUnitFiles";
4659 expect_carries_install_info = true;
4660 } else if (streq(verb, "mask"))
4661 method = "MaskUnitFiles";
4662 else if (streq(verb, "unmask")) {
4663 method = "UnmaskUnitFiles";
4666 assert_not_reached("Unknown verb");
4668 r = sd_bus_message_new_method_call(
4670 "org.freedesktop.systemd1",
4671 "/org/freedesktop/systemd1",
4672 "org.freedesktop.systemd1.Manager",
4676 return bus_log_create_error(r);
4678 r = sd_bus_message_append_strv(m, mangled_names);
4680 return bus_log_create_error(r);
4682 r = sd_bus_message_append(m, "b", arg_runtime);
4684 return bus_log_create_error(r);
4687 r = sd_bus_message_append(m, "b", arg_force);
4689 return bus_log_create_error(r);
4692 r = sd_bus_call(bus, m, 0, &error, &reply);
4694 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4698 if (expect_carries_install_info) {
4699 r = sd_bus_message_read(reply, "b", &carries_install_info);
4701 return bus_log_parse_error(r);
4704 r = deserialize_and_dump_unit_file_changes(reply);
4708 /* Try to reload if enabeld */
4710 r = daemon_reload(bus, args);
4715 if (carries_install_info == 0)
4716 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4717 "using systemctl.\n"
4718 "Possible reasons for having this kind of units are:\n"
4719 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4720 " .wants/ or .requires/ directory.\n"
4721 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4722 " a requirement dependency on it.\n"
4723 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4724 " D-Bus, udev, scripted systemctl call, ...).\n");
4727 unit_file_changes_free(changes, n_changes);
4732 static int unit_is_enabled(sd_bus *bus, char **args) {
4734 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4735 _cleanup_strv_free_ char **mangled_names = NULL;
4740 r = mangle_names(args+1, &mangled_names);
4744 r = enable_sysv_units(args[0], mangled_names);
4750 if (!bus || avoid_bus()) {
4752 STRV_FOREACH(name, mangled_names) {
4753 UnitFileState state;
4755 state = unit_file_get_state(arg_scope, arg_root, *name);
4757 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4761 if (state == UNIT_FILE_ENABLED ||
4762 state == UNIT_FILE_ENABLED_RUNTIME ||
4763 state == UNIT_FILE_STATIC)
4767 puts(unit_file_state_to_string(state));
4771 STRV_FOREACH(name, mangled_names) {
4772 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4775 r = sd_bus_call_method(
4777 "org.freedesktop.systemd1",
4778 "/org/freedesktop/systemd1",
4779 "org.freedesktop.systemd1.Manager",
4785 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4789 r = sd_bus_message_read(reply, "s", &s);
4791 return bus_log_parse_error(r);
4793 if (streq(s, "enabled") ||
4794 streq(s, "enabled-runtime") ||
4806 static int systemctl_help(void) {
4808 pager_open_if_enabled();
4810 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4811 "Query or send control commands to the systemd manager.\n\n"
4812 " -h --help Show this help\n"
4813 " --version Show package version\n"
4814 " --system Connect to system manager\n"
4815 " --user Connect to user service manager\n"
4816 " -H --host=[USER@]HOST\n"
4817 " Operate on remote host\n"
4818 " -M --machine=CONTAINER\n"
4819 " Operate on local container\n"
4820 " -t --type=TYPE List only units of a particular type\n"
4821 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4822 " -p --property=NAME Show only properties by this name\n"
4823 " -a --all Show all loaded units/properties, including dead/empty\n"
4824 " ones. To list all units installed on the system, use\n"
4825 " the 'list-unit-files' command instead.\n"
4826 " -l --full Don't ellipsize unit names on output\n"
4827 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4828 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4829 " queueing a new job\n"
4830 " --show-types When showing sockets, explicitly show their type\n"
4831 " -i --ignore-inhibitors\n"
4832 " When shutting down or sleeping, ignore inhibitors\n"
4833 " --kill-who=WHO Who to send signal to\n"
4834 " -s --signal=SIGNAL Which signal to send\n"
4835 " -q --quiet Suppress output\n"
4836 " --no-block Do not wait until operation finished\n"
4837 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4838 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4840 " --no-legend Do not print a legend (column headers and hints)\n"
4841 " --no-pager Do not pipe output into a pager\n"
4842 " --no-ask-password\n"
4843 " Do not ask for system passwords\n"
4844 " --global Enable/disable unit files globally\n"
4845 " --runtime Enable unit files only temporarily until next reboot\n"
4846 " -f --force When enabling unit files, override existing symlinks\n"
4847 " When shutting down, execute action immediately\n"
4848 " --root=PATH Enable unit files in the specified root directory\n"
4849 " -n --lines=INTEGER Number of journal entries to show\n"
4850 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4851 " verbose, export, json, json-pretty, json-sse, cat)\n"
4852 " --plain Print unit dependencies as a list instead of a tree\n\n"
4854 " list-units [PATTERN...] List loaded units\n"
4855 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4856 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4857 " start NAME... Start (activate) one or more units\n"
4858 " stop NAME... Stop (deactivate) one or more units\n"
4859 " reload NAME... Reload one or more units\n"
4860 " restart NAME... Start or restart one or more units\n"
4861 " try-restart NAME... Restart one or more units if active\n"
4862 " reload-or-restart NAME... Reload one or more units if possible,\n"
4863 " otherwise start or restart\n"
4864 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
4865 " otherwise restart if active\n"
4866 " isolate NAME Start one unit and stop all others\n"
4867 " kill NAME... Send signal to processes of a unit\n"
4868 " is-active NAME... Check whether units are active\n"
4869 " is-failed NAME... Check whether units are failed\n"
4870 " status [NAME...|PID...] Show runtime status of one or more units\n"
4871 " show [NAME...|JOB...] Show properties of one or more\n"
4872 " units/jobs or the manager\n"
4873 " cat NAME... Show files and drop-ins of one or more units\n"
4874 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
4875 " help NAME...|PID... Show manual for one or more units\n"
4876 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4878 " list-dependencies [NAME] Recursively show units which are required\n"
4879 " or wanted by this unit or by which this\n"
4880 " unit is required or wanted\n\n"
4881 "Unit File Commands:\n"
4882 " list-unit-files [PATTERN...] List installed unit files\n"
4883 " enable NAME... Enable one or more unit files\n"
4884 " disable NAME... Disable one or more unit files\n"
4885 " reenable NAME... Reenable one or more unit files\n"
4886 " preset NAME... Enable/disable one or more unit files\n"
4887 " based on preset configuration\n"
4888 " is-enabled NAME... Check whether unit files are enabled\n\n"
4889 " mask NAME... Mask one or more units\n"
4890 " unmask NAME... Unmask one or more units\n"
4891 " link PATH... Link one or more units files into\n"
4892 " the search path\n"
4893 " get-default Get the name of the default target\n"
4894 " set-default NAME Set the default target\n\n"
4896 " list-jobs [PATTERN...] List jobs\n"
4897 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4898 "Snapshot Commands:\n"
4899 " snapshot [NAME] Create a snapshot\n"
4900 " delete NAME... Remove one or more snapshots\n\n"
4901 "Environment Commands:\n"
4902 " show-environment Dump environment\n"
4903 " set-environment NAME=VALUE... Set one or more environment variables\n"
4904 " unset-environment NAME... Unset one or more environment variables\n\n"
4905 "Manager Lifecycle Commands:\n"
4906 " daemon-reload Reload systemd manager configuration\n"
4907 " daemon-reexec Reexecute systemd manager\n\n"
4908 "System Commands:\n"
4909 " default Enter system default mode\n"
4910 " rescue Enter system rescue mode\n"
4911 " emergency Enter system emergency mode\n"
4912 " halt Shut down and halt the system\n"
4913 " poweroff Shut down and power-off the system\n"
4914 " reboot [ARG] Shut down and reboot the system\n"
4915 " kexec Shut down and reboot the system with kexec\n"
4916 " exit Request user instance exit\n"
4917 " switch-root ROOT [INIT] Change to a different root file system\n"
4918 " suspend Suspend the system\n"
4919 " hibernate Hibernate the system\n"
4920 " hybrid-sleep Hibernate and suspend the system\n",
4921 program_invocation_short_name);
4926 static int halt_help(void) {
4928 printf("%s [OPTIONS...]%s\n\n"
4929 "%s the system.\n\n"
4930 " --help Show this help\n"
4931 " --halt Halt the machine\n"
4932 " -p --poweroff Switch off the machine\n"
4933 " --reboot Reboot the machine\n"
4934 " -f --force Force immediate halt/power-off/reboot\n"
4935 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4936 " -d --no-wtmp Don't write wtmp record\n"
4937 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4938 program_invocation_short_name,
4939 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4940 arg_action == ACTION_REBOOT ? "Reboot" :
4941 arg_action == ACTION_POWEROFF ? "Power off" :
4947 static int shutdown_help(void) {
4949 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4950 "Shut down the system.\n\n"
4951 " --help Show this help\n"
4952 " -H --halt Halt the machine\n"
4953 " -P --poweroff Power-off the machine\n"
4954 " -r --reboot Reboot the machine\n"
4955 " -h Equivalent to --poweroff, overridden by --halt\n"
4956 " -k Don't halt/power-off/reboot, just send warnings\n"
4957 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4958 " -c Cancel a pending shutdown\n",
4959 program_invocation_short_name);
4964 static int telinit_help(void) {
4966 printf("%s [OPTIONS...] {COMMAND}\n\n"
4967 "Send control commands to the init daemon.\n\n"
4968 " --help Show this help\n"
4969 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4971 " 0 Power-off the machine\n"
4972 " 6 Reboot the machine\n"
4973 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4974 " 1, s, S Enter rescue mode\n"
4975 " q, Q Reload init daemon configuration\n"
4976 " u, U Reexecute init daemon\n",
4977 program_invocation_short_name);
4982 static int runlevel_help(void) {
4984 printf("%s [OPTIONS...]\n\n"
4985 "Prints the previous and current runlevel of the init system.\n\n"
4986 " --help Show this help\n",
4987 program_invocation_short_name);
4992 static int help_types(void) {
4996 puts("Available unit types:");
4997 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
4998 t = unit_type_to_string(i);
5006 static int systemctl_parse_argv(int argc, char *argv[]) {
5015 ARG_IGNORE_DEPENDENCIES,
5027 ARG_NO_ASK_PASSWORD,
5036 static const struct option options[] = {
5037 { "help", no_argument, NULL, 'h' },
5038 { "version", no_argument, NULL, ARG_VERSION },
5039 { "type", required_argument, NULL, 't' },
5040 { "property", required_argument, NULL, 'p' },
5041 { "all", no_argument, NULL, 'a' },
5042 { "reverse", no_argument, NULL, ARG_REVERSE },
5043 { "after", no_argument, NULL, ARG_AFTER },
5044 { "before", no_argument, NULL, ARG_BEFORE },
5045 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5046 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5047 { "full", no_argument, NULL, 'l' },
5048 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5049 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5050 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5051 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5052 { "ignore-inhibitors", no_argument, NULL, 'i' },
5053 { "user", no_argument, NULL, ARG_USER },
5054 { "system", no_argument, NULL, ARG_SYSTEM },
5055 { "global", no_argument, NULL, ARG_GLOBAL },
5056 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5057 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5058 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5059 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5060 { "quiet", no_argument, NULL, 'q' },
5061 { "root", required_argument, NULL, ARG_ROOT },
5062 { "force", no_argument, NULL, ARG_FORCE },
5063 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5064 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5065 { "signal", required_argument, NULL, 's' },
5066 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5067 { "host", required_argument, NULL, 'H' },
5068 { "machine", required_argument, NULL, 'M' },
5069 { "runtime", no_argument, NULL, ARG_RUNTIME },
5070 { "lines", required_argument, NULL, 'n' },
5071 { "output", required_argument, NULL, 'o' },
5072 { "plain", no_argument, NULL, ARG_PLAIN },
5073 { "state", required_argument, NULL, ARG_STATE },
5082 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5087 return systemctl_help();
5090 puts(PACKAGE_STRING);
5091 puts(SYSTEMD_FEATURES);
5098 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5099 _cleanup_free_ char *type;
5101 type = strndup(word, size);
5105 if (streq(type, "help")) {
5110 if (unit_type_from_string(type) >= 0) {
5111 if (strv_push(&arg_types, type))
5117 /* It's much nicer to use --state= for
5118 * load states, but let's support this
5119 * in --types= too for compatibility
5120 * with old versions */
5121 if (unit_load_state_from_string(optarg) >= 0) {
5122 if (strv_push(&arg_states, type) < 0)
5128 log_error("Unknown unit type or load state '%s'.", type);
5129 log_info("Use -t help to see a list of allowed values.");
5137 /* Make sure that if the empty property list
5138 was specified, we won't show any properties. */
5139 if (isempty(optarg) && !arg_properties) {
5140 arg_properties = new0(char*, 1);
5141 if (!arg_properties)
5147 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5150 prop = strndup(word, size);
5154 if (strv_push(&arg_properties, prop) < 0) {
5161 /* If the user asked for a particular
5162 * property, show it to him, even if it is
5174 arg_dependency = DEPENDENCY_REVERSE;
5178 arg_dependency = DEPENDENCY_AFTER;
5182 arg_dependency = DEPENDENCY_BEFORE;
5185 case ARG_SHOW_TYPES:
5186 arg_show_types = true;
5190 arg_job_mode = optarg;
5194 arg_job_mode = "fail";
5197 case ARG_IRREVERSIBLE:
5198 arg_job_mode = "replace-irreversibly";
5201 case ARG_IGNORE_DEPENDENCIES:
5202 arg_job_mode = "ignore-dependencies";
5206 arg_scope = UNIT_FILE_USER;
5210 arg_scope = UNIT_FILE_SYSTEM;
5214 arg_scope = UNIT_FILE_GLOBAL;
5218 arg_no_block = true;
5222 arg_no_legend = true;
5226 arg_no_pager = true;
5242 if (strv_extend(&arg_states, "failed") < 0)
5260 arg_no_reload = true;
5264 arg_kill_who = optarg;
5268 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5269 log_error("Failed to parse signal string %s.", optarg);
5274 case ARG_NO_ASK_PASSWORD:
5275 arg_ask_password = false;
5279 arg_transport = BUS_TRANSPORT_REMOTE;
5284 arg_transport = BUS_TRANSPORT_CONTAINER;
5293 if (safe_atou(optarg, &arg_lines) < 0) {
5294 log_error("Failed to parse lines '%s'", optarg);
5300 arg_output = output_mode_from_string(optarg);
5301 if (arg_output < 0) {
5302 log_error("Unknown output '%s'.", optarg);
5308 arg_ignore_inhibitors = true;
5319 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5322 s = strndup(word, size);
5326 if (strv_push(&arg_states, s) < 0) {
5338 assert_not_reached("Unhandled option");
5342 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5343 log_error("Cannot access user instance remotely.");
5350 static int halt_parse_argv(int argc, char *argv[]) {
5359 static const struct option options[] = {
5360 { "help", no_argument, NULL, ARG_HELP },
5361 { "halt", no_argument, NULL, ARG_HALT },
5362 { "poweroff", no_argument, NULL, 'p' },
5363 { "reboot", no_argument, NULL, ARG_REBOOT },
5364 { "force", no_argument, NULL, 'f' },
5365 { "wtmp-only", no_argument, NULL, 'w' },
5366 { "no-wtmp", no_argument, NULL, 'd' },
5367 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5376 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5377 if (runlevel == '0' || runlevel == '6')
5380 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5387 arg_action = ACTION_HALT;
5391 if (arg_action != ACTION_REBOOT)
5392 arg_action = ACTION_POWEROFF;
5396 arg_action = ACTION_REBOOT;
5418 /* Compatibility nops */
5425 assert_not_reached("Unhandled option");
5429 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5430 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5432 log_error("Failed to write reboot param to "
5433 REBOOT_PARAM_FILE": %s", strerror(-r));
5436 } else if (optind < argc) {
5437 log_error("Too many arguments.");
5444 static int parse_time_spec(const char *t, usec_t *_u) {
5448 if (streq(t, "now"))
5450 else if (!strchr(t, ':')) {
5453 if (safe_atou64(t, &u) < 0)
5456 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5465 hour = strtol(t, &e, 10);
5466 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5469 minute = strtol(e+1, &e, 10);
5470 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5473 n = now(CLOCK_REALTIME);
5474 s = (time_t) (n / USEC_PER_SEC);
5476 assert_se(localtime_r(&s, &tm));
5478 tm.tm_hour = (int) hour;
5479 tm.tm_min = (int) minute;
5482 assert_se(s = mktime(&tm));
5484 *_u = (usec_t) s * USEC_PER_SEC;
5487 *_u += USEC_PER_DAY;
5493 static int shutdown_parse_argv(int argc, char *argv[]) {
5500 static const struct option options[] = {
5501 { "help", no_argument, NULL, ARG_HELP },
5502 { "halt", no_argument, NULL, 'H' },
5503 { "poweroff", no_argument, NULL, 'P' },
5504 { "reboot", no_argument, NULL, 'r' },
5505 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5506 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5515 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5519 return shutdown_help();
5522 arg_action = ACTION_HALT;
5526 arg_action = ACTION_POWEROFF;
5531 arg_action = ACTION_KEXEC;
5533 arg_action = ACTION_REBOOT;
5537 arg_action = ACTION_KEXEC;
5541 if (arg_action != ACTION_HALT)
5542 arg_action = ACTION_POWEROFF;
5555 /* Compatibility nops */
5559 arg_action = ACTION_CANCEL_SHUTDOWN;
5566 assert_not_reached("Unhandled option");
5570 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5571 r = parse_time_spec(argv[optind], &arg_when);
5573 log_error("Failed to parse time specification: %s", argv[optind]);
5577 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5579 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5580 /* No time argument for shutdown cancel */
5581 arg_wall = argv + optind;
5582 else if (argc > optind + 1)
5583 /* We skip the time argument */
5584 arg_wall = argv + optind + 1;
5591 static int telinit_parse_argv(int argc, char *argv[]) {
5598 static const struct option options[] = {
5599 { "help", no_argument, NULL, ARG_HELP },
5600 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5604 static const struct {
5608 { '0', ACTION_POWEROFF },
5609 { '6', ACTION_REBOOT },
5610 { '1', ACTION_RESCUE },
5611 { '2', ACTION_RUNLEVEL2 },
5612 { '3', ACTION_RUNLEVEL3 },
5613 { '4', ACTION_RUNLEVEL4 },
5614 { '5', ACTION_RUNLEVEL5 },
5615 { 's', ACTION_RESCUE },
5616 { 'S', ACTION_RESCUE },
5617 { 'q', ACTION_RELOAD },
5618 { 'Q', ACTION_RELOAD },
5619 { 'u', ACTION_REEXEC },
5620 { 'U', ACTION_REEXEC }
5629 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5633 return telinit_help();
5643 assert_not_reached("Unhandled option");
5647 if (optind >= argc) {
5652 if (optind + 1 < argc) {
5653 log_error("Too many arguments.");
5657 if (strlen(argv[optind]) != 1) {
5658 log_error("Expected single character argument.");
5662 for (i = 0; i < ELEMENTSOF(table); i++)
5663 if (table[i].from == argv[optind][0])
5666 if (i >= ELEMENTSOF(table)) {
5667 log_error("Unknown command '%s'.", argv[optind]);
5671 arg_action = table[i].to;
5678 static int runlevel_parse_argv(int argc, char *argv[]) {
5684 static const struct option options[] = {
5685 { "help", no_argument, NULL, ARG_HELP },
5694 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5698 return runlevel_help();
5705 assert_not_reached("Unhandled option");
5709 if (optind < argc) {
5710 log_error("Too many arguments.");
5717 static int parse_argv(int argc, char *argv[]) {
5721 if (program_invocation_short_name) {
5723 if (strstr(program_invocation_short_name, "halt")) {
5724 arg_action = ACTION_HALT;
5725 return halt_parse_argv(argc, argv);
5726 } else if (strstr(program_invocation_short_name, "poweroff")) {
5727 arg_action = ACTION_POWEROFF;
5728 return halt_parse_argv(argc, argv);
5729 } else if (strstr(program_invocation_short_name, "reboot")) {
5731 arg_action = ACTION_KEXEC;
5733 arg_action = ACTION_REBOOT;
5734 return halt_parse_argv(argc, argv);
5735 } else if (strstr(program_invocation_short_name, "shutdown")) {
5736 arg_action = ACTION_POWEROFF;
5737 return shutdown_parse_argv(argc, argv);
5738 } else if (strstr(program_invocation_short_name, "init")) {
5740 if (sd_booted() > 0) {
5741 arg_action = _ACTION_INVALID;
5742 return telinit_parse_argv(argc, argv);
5744 /* Hmm, so some other init system is
5745 * running, we need to forward this
5746 * request to it. For now we simply
5747 * guess that it is Upstart. */
5749 execv(TELINIT, argv);
5751 log_error("Couldn't find an alternative telinit implementation to spawn.");
5755 } else if (strstr(program_invocation_short_name, "runlevel")) {
5756 arg_action = ACTION_RUNLEVEL;
5757 return runlevel_parse_argv(argc, argv);
5761 arg_action = ACTION_SYSTEMCTL;
5762 return systemctl_parse_argv(argc, argv);
5765 _pure_ static int action_to_runlevel(void) {
5767 static const char table[_ACTION_MAX] = {
5768 [ACTION_HALT] = '0',
5769 [ACTION_POWEROFF] = '0',
5770 [ACTION_REBOOT] = '6',
5771 [ACTION_RUNLEVEL2] = '2',
5772 [ACTION_RUNLEVEL3] = '3',
5773 [ACTION_RUNLEVEL4] = '4',
5774 [ACTION_RUNLEVEL5] = '5',
5775 [ACTION_RESCUE] = '1'
5778 assert(arg_action < _ACTION_MAX);
5780 return table[arg_action];
5783 static int talk_initctl(void) {
5785 struct init_request request = {
5786 .magic = INIT_MAGIC,
5788 .cmd = INIT_CMD_RUNLVL
5791 _cleanup_close_ int fd = -1;
5795 rl = action_to_runlevel();
5799 request.runlevel = rl;
5801 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5803 if (errno == ENOENT)
5806 log_error("Failed to open "INIT_FIFO": %m");
5811 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5813 log_error("Failed to write to "INIT_FIFO": %m");
5814 return errno > 0 ? -errno : -EIO;
5820 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5822 static const struct {
5830 int (* const dispatch)(sd_bus *bus, char **args);
5836 { "list-units", MORE, 0, list_units },
5837 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
5838 { "list-sockets", MORE, 1, list_sockets },
5839 { "list-timers", MORE, 1, list_timers },
5840 { "list-jobs", MORE, 1, list_jobs },
5841 { "clear-jobs", EQUAL, 1, daemon_reload },
5842 { "cancel", MORE, 2, cancel_job },
5843 { "start", MORE, 2, start_unit },
5844 { "stop", MORE, 2, start_unit },
5845 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5846 { "reload", MORE, 2, start_unit },
5847 { "restart", MORE, 2, start_unit },
5848 { "try-restart", MORE, 2, start_unit },
5849 { "reload-or-restart", MORE, 2, start_unit },
5850 { "reload-or-try-restart", MORE, 2, start_unit },
5851 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5852 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5853 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5854 { "isolate", EQUAL, 2, start_unit },
5855 { "kill", MORE, 2, kill_unit },
5856 { "is-active", MORE, 2, check_unit_active },
5857 { "check", MORE, 2, check_unit_active },
5858 { "is-failed", MORE, 2, check_unit_failed },
5859 { "show", MORE, 1, show },
5860 { "cat", MORE, 2, cat },
5861 { "status", MORE, 1, show },
5862 { "help", MORE, 2, show },
5863 { "snapshot", LESS, 2, snapshot },
5864 { "delete", MORE, 2, delete_snapshot },
5865 { "daemon-reload", EQUAL, 1, daemon_reload },
5866 { "daemon-reexec", EQUAL, 1, daemon_reload },
5867 { "show-environment", EQUAL, 1, show_environment },
5868 { "set-environment", MORE, 2, set_environment },
5869 { "unset-environment", MORE, 2, set_environment },
5870 { "halt", EQUAL, 1, start_special, FORCE },
5871 { "poweroff", EQUAL, 1, start_special, FORCE },
5872 { "reboot", EQUAL, 1, start_special, FORCE },
5873 { "kexec", EQUAL, 1, start_special },
5874 { "suspend", EQUAL, 1, start_special },
5875 { "hibernate", EQUAL, 1, start_special },
5876 { "hybrid-sleep", EQUAL, 1, start_special },
5877 { "default", EQUAL, 1, start_special },
5878 { "rescue", EQUAL, 1, start_special },
5879 { "emergency", EQUAL, 1, start_special },
5880 { "exit", EQUAL, 1, start_special },
5881 { "reset-failed", MORE, 1, reset_failed },
5882 { "enable", MORE, 2, enable_unit, NOBUS },
5883 { "disable", MORE, 2, enable_unit, NOBUS },
5884 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
5885 { "reenable", MORE, 2, enable_unit, NOBUS },
5886 { "preset", MORE, 2, enable_unit, NOBUS },
5887 { "mask", MORE, 2, enable_unit, NOBUS },
5888 { "unmask", MORE, 2, enable_unit, NOBUS },
5889 { "link", MORE, 2, enable_unit, NOBUS },
5890 { "switch-root", MORE, 2, switch_root },
5891 { "list-dependencies", LESS, 2, list_dependencies },
5892 { "set-default", EQUAL, 2, set_default, NOBUS },
5893 { "get-default", EQUAL, 1, get_default, NOBUS },
5894 { "set-property", MORE, 3, set_property },
5903 left = argc - optind;
5905 /* Special rule: no arguments (left == 0) means "list-units" */
5907 if (streq(argv[optind], "help") && !argv[optind+1]) {
5908 log_error("This command expects one or more "
5909 "unit names. Did you mean --help?");
5913 for (; verb->verb; verb++)
5914 if (streq(argv[optind], verb->verb))
5917 log_error("Unknown operation '%s'.", argv[optind]);
5922 switch (verb->argc_cmp) {
5925 if (left != verb->argc) {
5926 log_error("Invalid number of arguments.");
5933 if (left < verb->argc) {
5934 log_error("Too few arguments.");
5941 if (left > verb->argc) {
5942 log_error("Too many arguments.");
5949 assert_not_reached("Unknown comparison operator.");
5952 /* Require a bus connection for all operations but
5954 if (verb->bus == NOBUS) {
5955 if (!bus && !avoid_bus()) {
5956 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5961 if (running_in_chroot() > 0) {
5962 log_info("Running in chroot, ignoring request.");
5966 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
5967 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5972 return verb->dispatch(bus, argv + optind);
5975 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5977 struct sd_shutdown_command c = {
5984 union sockaddr_union sockaddr = {
5985 .un.sun_family = AF_UNIX,
5986 .un.sun_path = "/run/systemd/shutdownd",
5989 struct iovec iovec[2] = {{
5990 .iov_base = (char*) &c,
5991 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5994 struct msghdr msghdr = {
5995 .msg_name = &sockaddr,
5996 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5997 + sizeof("/run/systemd/shutdownd") - 1,
6002 _cleanup_close_ int fd;
6004 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6008 if (!isempty(message)) {
6009 iovec[1].iov_base = (char*) message;
6010 iovec[1].iov_len = strlen(message);
6011 msghdr.msg_iovlen++;
6014 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6020 static int reload_with_fallback(sd_bus *bus) {
6023 /* First, try systemd via D-Bus. */
6024 if (daemon_reload(bus, NULL) >= 0)
6028 /* Nothing else worked, so let's try signals */
6029 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6031 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6032 log_error("kill() failed: %m");
6039 static int start_with_fallback(sd_bus *bus) {
6042 /* First, try systemd via D-Bus. */
6043 if (start_unit(bus, NULL) >= 0)
6047 /* Nothing else worked, so let's try
6049 if (talk_initctl() > 0)
6052 log_error("Failed to talk to init daemon.");
6056 warn_wall(arg_action);
6060 static int halt_now(enum action a) {
6062 /* Make sure C-A-D is handled by the kernel from this
6064 reboot(RB_ENABLE_CAD);
6069 log_info("Halting.");
6070 reboot(RB_HALT_SYSTEM);
6073 case ACTION_POWEROFF:
6074 log_info("Powering off.");
6075 reboot(RB_POWER_OFF);
6078 case ACTION_REBOOT: {
6079 _cleanup_free_ char *param = NULL;
6081 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6082 log_info("Rebooting with argument '%s'.", param);
6083 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6084 LINUX_REBOOT_CMD_RESTART2, param);
6087 log_info("Rebooting.");
6088 reboot(RB_AUTOBOOT);
6093 assert_not_reached("Unknown action.");
6097 static int halt_main(sd_bus *bus) {
6100 r = check_inhibitors(bus, arg_action);
6104 if (geteuid() != 0) {
6105 /* Try logind if we are a normal user and no special
6106 * mode applies. Maybe PolicyKit allows us to shutdown
6109 if (arg_when <= 0 &&
6112 (arg_action == ACTION_POWEROFF ||
6113 arg_action == ACTION_REBOOT)) {
6114 r = reboot_with_logind(bus, arg_action);
6119 log_error("Must be root.");
6124 _cleanup_free_ char *m;
6126 m = strv_join(arg_wall, " ");
6130 r = send_shutdownd(arg_when,
6131 arg_action == ACTION_HALT ? 'H' :
6132 arg_action == ACTION_POWEROFF ? 'P' :
6133 arg_action == ACTION_KEXEC ? 'K' :
6140 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6142 char date[FORMAT_TIMESTAMP_MAX];
6144 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6145 format_timestamp(date, sizeof(date), arg_when));
6150 if (!arg_dry && !arg_force)
6151 return start_with_fallback(bus);
6154 if (sd_booted() > 0)
6155 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6157 r = utmp_put_shutdown();
6159 log_warning("Failed to write utmp record: %s", strerror(-r));
6166 r = halt_now(arg_action);
6167 log_error("Failed to reboot: %s", strerror(-r));
6172 static int runlevel_main(void) {
6173 int r, runlevel, previous;
6175 r = utmp_get_runlevel(&runlevel, &previous);
6182 previous <= 0 ? 'N' : previous,
6183 runlevel <= 0 ? 'N' : runlevel);
6188 int main(int argc, char*argv[]) {
6189 _cleanup_bus_unref_ sd_bus *bus = NULL;
6192 setlocale(LC_ALL, "");
6193 log_parse_environment();
6196 /* Explicitly not on_tty() to avoid setting cached value.
6197 * This becomes relevant for piping output which might be
6199 original_stdout_is_tty = isatty(STDOUT_FILENO);
6201 r = parse_argv(argc, argv);
6205 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6206 * let's shortcut this */
6207 if (arg_action == ACTION_RUNLEVEL) {
6208 r = runlevel_main();
6212 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6213 log_info("Running in chroot, ignoring request.");
6219 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6221 /* systemctl_main() will print an error message for the bus
6222 * connection, but only if it needs to */
6224 switch (arg_action) {
6226 case ACTION_SYSTEMCTL:
6227 r = systemctl_main(bus, argc, argv, r);
6231 case ACTION_POWEROFF:
6237 case ACTION_RUNLEVEL2:
6238 case ACTION_RUNLEVEL3:
6239 case ACTION_RUNLEVEL4:
6240 case ACTION_RUNLEVEL5:
6242 case ACTION_EMERGENCY:
6243 case ACTION_DEFAULT:
6244 r = start_with_fallback(bus);
6249 r = reload_with_fallback(bus);
6252 case ACTION_CANCEL_SHUTDOWN: {
6253 _cleanup_free_ char *m = NULL;
6256 m = strv_join(arg_wall, " ");
6263 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6265 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6269 case ACTION_RUNLEVEL:
6270 case _ACTION_INVALID:
6272 assert_not_reached("Unknown action");
6277 ask_password_agent_close();
6278 polkit_agent_close();
6280 strv_free(arg_types);
6281 strv_free(arg_states);
6282 strv_free(arg_properties);
6284 return r < 0 ? EXIT_FAILURE : r;