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 wait_for_jobs(sd_bus *bus, Set *s) {
1847 WaitData d = { .set = s };
1853 r = sd_bus_add_filter(bus, wait_filter, &d);
1857 while (!set_isempty(s)) {
1859 r = sd_bus_process(bus, NULL);
1864 r = sd_bus_wait(bus, (uint64_t) -1);
1873 if (streq(d.result, "timeout"))
1874 log_error("Job for %s timed out.", strna(d.name));
1875 else if (streq(d.result, "canceled"))
1876 log_error("Job for %s canceled.", strna(d.name));
1877 else if (streq(d.result, "dependency"))
1878 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1879 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1880 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1883 if (streq_ptr(d.result, "timeout"))
1885 else if (streq_ptr(d.result, "canceled"))
1887 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1898 return sd_bus_remove_filter(bus, wait_filter, &d);
1901 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1902 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1903 _cleanup_free_ char *n = NULL, *state = NULL;
1909 n = unit_name_mangle(name);
1913 /* We don't use unit_dbus_path_from_name() directly since we
1914 * don't want to load the unit if it isn't loaded. */
1916 r = sd_bus_call_method(
1918 "org.freedesktop.systemd1",
1919 "/org/freedesktop/systemd1",
1920 "org.freedesktop.systemd1.Manager",
1931 r = sd_bus_message_read(reply, "o", &path);
1933 return bus_log_parse_error(r);
1935 r = sd_bus_get_property_string(
1937 "org.freedesktop.systemd1",
1939 "org.freedesktop.systemd1.Unit",
1952 return nulstr_contains(good_states, state);
1955 static int check_triggering_units(
1959 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1960 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1961 _cleanup_strv_free_ char **triggered_by = NULL;
1962 bool print_warning_label = true;
1966 n = unit_name_mangle(name);
1970 path = unit_dbus_path_from_name(n);
1974 r = sd_bus_get_property_string(
1976 "org.freedesktop.systemd1",
1978 "org.freedesktop.systemd1.Unit",
1983 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1987 if (streq(state, "masked"))
1990 r = sd_bus_get_property_strv(
1992 "org.freedesktop.systemd1",
1994 "org.freedesktop.systemd1.Unit",
1999 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2003 STRV_FOREACH(i, triggered_by) {
2004 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2006 log_error("Failed to check unit: %s", strerror(-r));
2013 if (print_warning_label) {
2014 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2015 print_warning_label = false;
2018 log_warning(" %s", *i);
2024 static int start_unit_one(
2029 sd_bus_error *error,
2032 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2033 _cleanup_free_ char *n;
2042 n = unit_name_mangle(name);
2046 r = sd_bus_call_method(
2048 "org.freedesktop.systemd1",
2049 "/org/freedesktop/systemd1",
2050 "org.freedesktop.systemd1.Manager",
2056 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2057 /* There's always a fallback possible for
2058 * legacy actions. */
2059 return -EADDRNOTAVAIL;
2061 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
2065 r = sd_bus_message_read(reply, "o", &path);
2067 return bus_log_parse_error(r);
2069 if (need_daemon_reload(bus, n) > 0)
2070 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2071 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2080 r = set_consume(s, p);
2088 static const struct {
2092 } action_table[_ACTION_MAX] = {
2093 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2094 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2095 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2096 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2097 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2098 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2099 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2100 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2101 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2102 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2103 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2104 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2105 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2106 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2107 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2110 static enum action verb_to_action(const char *verb) {
2113 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2114 if (streq_ptr(action_table[i].verb, verb))
2117 return _ACTION_INVALID;
2120 static int start_unit(sd_bus *bus, char **args) {
2121 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2122 _cleanup_set_free_free_ Set *s = NULL;
2123 const char *method, *mode, *one_name;
2129 ask_password_agent_open_if_enabled();
2131 if (arg_action == ACTION_SYSTEMCTL) {
2134 streq(args[0], "stop") ||
2135 streq(args[0], "condstop") ? "StopUnit" :
2136 streq(args[0], "reload") ? "ReloadUnit" :
2137 streq(args[0], "restart") ? "RestartUnit" :
2139 streq(args[0], "try-restart") ||
2140 streq(args[0], "condrestart") ? "TryRestartUnit" :
2142 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2144 streq(args[0], "reload-or-try-restart") ||
2145 streq(args[0], "condreload") ||
2146 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2148 action = verb_to_action(args[0]);
2150 mode = streq(args[0], "isolate") ? "isolate" :
2151 action_table[action].mode ?: arg_job_mode;
2153 one_name = action_table[action].target;
2155 assert(arg_action < ELEMENTSOF(action_table));
2156 assert(action_table[arg_action].target);
2158 method = "StartUnit";
2160 mode = action_table[arg_action].mode;
2161 one_name = action_table[arg_action].target;
2164 if (!arg_no_block) {
2165 r = enable_wait_for_jobs(bus);
2167 log_error("Could not watch jobs: %s", strerror(-r));
2171 s = set_new(string_hash_func, string_compare_func);
2177 r = start_unit_one(bus, method, one_name, mode, &error, s);
2179 r = translate_bus_error_to_exit_status(r, &error);
2183 STRV_FOREACH(name, args+1) {
2186 q = start_unit_one(bus, method, *name, mode, &error, s);
2188 r = translate_bus_error_to_exit_status(q, &error);
2189 sd_bus_error_free(&error);
2194 if (!arg_no_block) {
2197 q = wait_for_jobs(bus, s);
2201 /* When stopping units, warn if they can still be triggered by
2202 * another active unit (socket, path, timer) */
2203 if (!arg_quiet && streq(method, "StopUnit")) {
2205 check_triggering_units(bus, one_name);
2207 STRV_FOREACH(name, args+1)
2208 check_triggering_units(bus, *name);
2215 /* Ask systemd-logind, which might grant access to unprivileged users
2216 * through PolicyKit */
2217 static int reboot_with_logind(sd_bus *bus, enum action a) {
2219 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2226 polkit_agent_open_if_enabled();
2234 case ACTION_POWEROFF:
2235 method = "PowerOff";
2238 case ACTION_SUSPEND:
2242 case ACTION_HIBERNATE:
2243 method = "Hibernate";
2246 case ACTION_HYBRID_SLEEP:
2247 method = "HybridSleep";
2254 r = sd_bus_call_method(
2256 "org.freedesktop.login1",
2257 "/org/freedesktop/login1",
2258 "org.freedesktop.login1.Manager",
2264 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2272 static int check_inhibitors(sd_bus *bus, enum action a) {
2274 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2275 _cleanup_strv_free_ char **sessions = NULL;
2276 const char *what, *who, *why, *mode;
2285 if (arg_ignore_inhibitors || arg_force > 0)
2297 r = sd_bus_call_method(
2299 "org.freedesktop.login1",
2300 "/org/freedesktop/login1",
2301 "org.freedesktop.login1.Manager",
2307 /* If logind is not around, then there are no inhibitors... */
2310 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2312 return bus_log_parse_error(r);
2314 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2315 _cleanup_free_ char *comm = NULL, *user = NULL;
2316 _cleanup_strv_free_ char **sv = NULL;
2318 if (!streq(mode, "block"))
2321 sv = strv_split(what, ":");
2325 if (!strv_contains(sv,
2327 a == ACTION_POWEROFF ||
2328 a == ACTION_REBOOT ||
2329 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2332 get_process_comm(pid, &comm);
2333 user = uid_to_name(uid);
2335 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2336 who, (unsigned long) pid, strna(comm), strna(user), why);
2341 return bus_log_parse_error(r);
2343 r = sd_bus_message_exit_container(reply);
2345 return bus_log_parse_error(r);
2347 /* Check for current sessions */
2348 sd_get_sessions(&sessions);
2349 STRV_FOREACH(s, sessions) {
2350 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2352 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2355 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2358 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2361 sd_session_get_tty(*s, &tty);
2362 sd_session_get_seat(*s, &seat);
2363 sd_session_get_service(*s, &service);
2364 user = uid_to_name(uid);
2366 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2373 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2374 action_table[a].verb);
2382 static int start_special(sd_bus *bus, char **args) {
2388 a = verb_to_action(args[0]);
2390 r = check_inhibitors(bus, a);
2394 if (arg_force >= 2 && geteuid() != 0) {
2395 log_error("Must be root.");
2399 if (arg_force >= 2 &&
2400 (a == ACTION_HALT ||
2401 a == ACTION_POWEROFF ||
2402 a == ACTION_REBOOT))
2405 if (arg_force >= 1 &&
2406 (a == ACTION_HALT ||
2407 a == ACTION_POWEROFF ||
2408 a == ACTION_REBOOT ||
2409 a == ACTION_KEXEC ||
2411 return daemon_reload(bus, args);
2413 /* first try logind, to allow authentication with polkit */
2414 if (geteuid() != 0 &&
2415 (a == ACTION_POWEROFF ||
2416 a == ACTION_REBOOT ||
2417 a == ACTION_SUSPEND ||
2418 a == ACTION_HIBERNATE ||
2419 a == ACTION_HYBRID_SLEEP)) {
2420 r = reboot_with_logind(bus, a);
2425 r = start_unit(bus, args);
2426 if (r == EXIT_SUCCESS)
2432 static int check_unit_active(sd_bus *bus, char **args) {
2434 int r = 3; /* According to LSB: "program is not running" */
2439 STRV_FOREACH(name, args+1) {
2442 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2452 static int check_unit_failed(sd_bus *bus, char **args) {
2459 STRV_FOREACH(name, args+1) {
2462 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2472 static int kill_unit(sd_bus *bus, char **args) {
2473 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2481 arg_kill_who = "all";
2483 STRV_FOREACH(name, args+1) {
2484 _cleanup_free_ char *n = NULL;
2486 n = unit_name_mangle(*name);
2490 r = sd_bus_call_method(
2492 "org.freedesktop.systemd1",
2493 "/org/freedesktop/systemd1",
2494 "org.freedesktop.systemd1.Manager",
2498 "ssi", n, arg_kill_who, arg_signal);
2500 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2508 typedef struct ExecStatusInfo {
2516 usec_t start_timestamp;
2517 usec_t exit_timestamp;
2522 LIST_FIELDS(struct ExecStatusInfo, exec);
2525 static void exec_status_info_free(ExecStatusInfo *i) {
2534 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2535 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2538 int32_t code, status;
2544 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2546 return bus_log_parse_error(r);
2550 r = sd_bus_message_read(m, "s", &path);
2552 return bus_log_parse_error(r);
2554 i->path = strdup(path);
2558 r = sd_bus_message_read_strv(m, &i->argv);
2560 return bus_log_parse_error(r);
2562 r = sd_bus_message_read(m,
2565 &start_timestamp, &start_timestamp_monotonic,
2566 &exit_timestamp, &exit_timestamp_monotonic,
2570 return bus_log_parse_error(r);
2573 i->start_timestamp = (usec_t) start_timestamp;
2574 i->exit_timestamp = (usec_t) exit_timestamp;
2575 i->pid = (pid_t) pid;
2579 r = sd_bus_message_exit_container(m);
2581 return bus_log_parse_error(r);
2586 typedef struct UnitStatusInfo {
2588 const char *load_state;
2589 const char *active_state;
2590 const char *sub_state;
2591 const char *unit_file_state;
2593 const char *description;
2594 const char *following;
2596 char **documentation;
2598 const char *fragment_path;
2599 const char *source_path;
2600 const char *control_group;
2602 char **dropin_paths;
2604 const char *load_error;
2607 usec_t inactive_exit_timestamp;
2608 usec_t inactive_exit_timestamp_monotonic;
2609 usec_t active_enter_timestamp;
2610 usec_t active_exit_timestamp;
2611 usec_t inactive_enter_timestamp;
2613 bool need_daemon_reload;
2618 const char *status_text;
2619 const char *pid_file;
2622 usec_t start_timestamp;
2623 usec_t exit_timestamp;
2625 int exit_code, exit_status;
2627 usec_t condition_timestamp;
2628 bool condition_result;
2629 bool failed_condition_trigger;
2630 bool failed_condition_negate;
2631 const char *failed_condition;
2632 const char *failed_condition_param;
2635 unsigned n_accepted;
2636 unsigned n_connections;
2639 /* Pairs of type, path */
2643 const char *sysfs_path;
2645 /* Mount, Automount */
2651 LIST_HEAD(ExecStatusInfo, exec);
2654 static void print_status_info(
2659 const char *on, *off, *ss;
2661 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2662 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2665 arg_all * OUTPUT_SHOW_ALL |
2666 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2667 on_tty() * OUTPUT_COLOR |
2668 !arg_quiet * OUTPUT_WARN_CUTOFF |
2669 arg_full * OUTPUT_FULL_WIDTH;
2674 /* This shows pretty information about a unit. See
2675 * print_property() for a low-level property printer */
2677 printf("%s", strna(i->id));
2679 if (i->description && !streq_ptr(i->id, i->description))
2680 printf(" - %s", i->description);
2685 printf(" Follow: unit currently follows state of %s\n", i->following);
2687 if (streq_ptr(i->load_state, "error")) {
2688 on = ansi_highlight_red();
2689 off = ansi_highlight_off();
2693 path = i->source_path ? i->source_path : i->fragment_path;
2696 printf(" Loaded: %s%s%s (Reason: %s)\n",
2697 on, strna(i->load_state), off, i->load_error);
2698 else if (path && i->unit_file_state)
2699 printf(" Loaded: %s%s%s (%s; %s)\n",
2700 on, strna(i->load_state), off, path, i->unit_file_state);
2702 printf(" Loaded: %s%s%s (%s)\n",
2703 on, strna(i->load_state), off, path);
2705 printf(" Loaded: %s%s%s\n",
2706 on, strna(i->load_state), off);
2708 if (!strv_isempty(i->dropin_paths)) {
2709 _cleanup_free_ char *dir = NULL;
2713 STRV_FOREACH(dropin, i->dropin_paths) {
2714 if (! dir || last) {
2715 printf(dir ? " " : " Drop-In: ");
2720 if (path_get_parent(*dropin, &dir) < 0) {
2725 printf("%s\n %s", dir,
2726 draw_special_char(DRAW_TREE_RIGHT));
2729 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2731 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2735 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2737 if (streq_ptr(i->active_state, "failed")) {
2738 on = ansi_highlight_red();
2739 off = ansi_highlight_off();
2740 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2741 on = ansi_highlight_green();
2742 off = ansi_highlight_off();
2747 printf(" Active: %s%s (%s)%s",
2748 on, strna(i->active_state), ss, off);
2750 printf(" Active: %s%s%s",
2751 on, strna(i->active_state), off);
2753 if (!isempty(i->result) && !streq(i->result, "success"))
2754 printf(" (Result: %s)", i->result);
2756 timestamp = (streq_ptr(i->active_state, "active") ||
2757 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2758 (streq_ptr(i->active_state, "inactive") ||
2759 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2760 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2761 i->active_exit_timestamp;
2763 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2764 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2767 printf(" since %s; %s\n", s2, s1);
2769 printf(" since %s\n", s2);
2773 if (!i->condition_result && i->condition_timestamp > 0) {
2774 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2775 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2777 printf(" start condition failed at %s%s%s\n",
2778 s2, s1 ? "; " : "", s1 ? s1 : "");
2779 if (i->failed_condition_trigger)
2780 printf(" none of the trigger conditions were met\n");
2781 else if (i->failed_condition)
2782 printf(" %s=%s%s was not met\n",
2783 i->failed_condition,
2784 i->failed_condition_negate ? "!" : "",
2785 i->failed_condition_param);
2789 printf(" Device: %s\n", i->sysfs_path);
2791 printf(" Where: %s\n", i->where);
2793 printf(" What: %s\n", i->what);
2795 STRV_FOREACH(t, i->documentation)
2796 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2798 STRV_FOREACH_PAIR(t, t2, i->listen)
2799 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2802 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2804 LIST_FOREACH(exec, p, i->exec) {
2805 _cleanup_free_ char *argv = NULL;
2808 /* Only show exited processes here */
2812 argv = strv_join(p->argv, " ");
2813 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2815 good = is_clean_exit_lsb(p->code, p->status, NULL);
2817 on = ansi_highlight_red();
2818 off = ansi_highlight_off();
2822 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2824 if (p->code == CLD_EXITED) {
2827 printf("status=%i", p->status);
2829 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2834 printf("signal=%s", signal_to_string(p->status));
2836 printf(")%s\n", off);
2838 if (i->main_pid == p->pid &&
2839 i->start_timestamp == p->start_timestamp &&
2840 i->exit_timestamp == p->start_timestamp)
2841 /* Let's not show this twice */
2844 if (p->pid == i->control_pid)
2848 if (i->main_pid > 0 || i->control_pid > 0) {
2849 if (i->main_pid > 0) {
2850 printf(" Main PID: %u", (unsigned) i->main_pid);
2853 _cleanup_free_ char *comm = NULL;
2854 get_process_comm(i->main_pid, &comm);
2856 printf(" (%s)", comm);
2857 } else if (i->exit_code > 0) {
2858 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2860 if (i->exit_code == CLD_EXITED) {
2863 printf("status=%i", i->exit_status);
2865 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2870 printf("signal=%s", signal_to_string(i->exit_status));
2874 if (i->control_pid > 0)
2878 if (i->control_pid > 0) {
2879 _cleanup_free_ char *c = NULL;
2881 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2883 get_process_comm(i->control_pid, &c);
2892 printf(" Status: \"%s\"\n", i->status_text);
2894 if (i->control_group &&
2895 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2898 printf(" CGroup: %s\n", i->control_group);
2900 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2903 char prefix[] = " ";
2906 if (c > sizeof(prefix) - 1)
2907 c -= sizeof(prefix) - 1;
2911 if (i->main_pid > 0)
2912 extra[k++] = i->main_pid;
2914 if (i->control_pid > 0)
2915 extra[k++] = i->control_pid;
2917 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2918 c, false, extra, k, flags);
2922 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2924 show_journal_by_unit(stdout,
2928 i->inactive_exit_timestamp_monotonic,
2932 arg_scope == UNIT_FILE_SYSTEM,
2936 if (i->need_daemon_reload)
2937 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2938 ansi_highlight_red(),
2939 ansi_highlight_off(),
2940 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2943 static void show_unit_help(UnitStatusInfo *i) {
2948 if (!i->documentation) {
2949 log_info("Documentation for %s not known.", i->id);
2953 STRV_FOREACH(p, i->documentation) {
2955 if (startswith(*p, "man:")) {
2956 const char *args[4] = { "man", NULL, NULL, NULL };
2957 _cleanup_free_ char *page = NULL, *section = NULL;
2964 if ((*p)[k-1] == ')')
2965 e = strrchr(*p, '(');
2968 page = strndup((*p) + 4, e - *p - 4);
2969 section = strndup(e + 1, *p + k - e - 2);
2970 if (!page || !section) {
2982 log_error("Failed to fork: %m");
2988 execvp(args[0], (char**) args);
2989 log_error("Failed to execute man: %m");
2990 _exit(EXIT_FAILURE);
2993 wait_for_terminate(pid, NULL);
2995 log_info("Can't show: %s", *p);
2999 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3006 switch (contents[0]) {
3008 case SD_BUS_TYPE_STRING: {
3011 r = sd_bus_message_read(m, "s", &s);
3013 return bus_log_parse_error(r);
3016 if (streq(name, "Id"))
3018 else if (streq(name, "LoadState"))
3020 else if (streq(name, "ActiveState"))
3021 i->active_state = s;
3022 else if (streq(name, "SubState"))
3024 else if (streq(name, "Description"))
3026 else if (streq(name, "FragmentPath"))
3027 i->fragment_path = s;
3028 else if (streq(name, "SourcePath"))
3031 else if (streq(name, "DefaultControlGroup")) {
3033 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3035 i->control_group = e;
3038 else if (streq(name, "ControlGroup"))
3039 i->control_group = s;
3040 else if (streq(name, "StatusText"))
3042 else if (streq(name, "PIDFile"))
3044 else if (streq(name, "SysFSPath"))
3046 else if (streq(name, "Where"))
3048 else if (streq(name, "What"))
3050 else if (streq(name, "Following"))
3052 else if (streq(name, "UnitFileState"))
3053 i->unit_file_state = s;
3054 else if (streq(name, "Result"))
3061 case SD_BUS_TYPE_BOOLEAN: {
3064 r = sd_bus_message_read(m, "b", &b);
3066 return bus_log_parse_error(r);
3068 if (streq(name, "Accept"))
3070 else if (streq(name, "NeedDaemonReload"))
3071 i->need_daemon_reload = b;
3072 else if (streq(name, "ConditionResult"))
3073 i->condition_result = b;
3078 case SD_BUS_TYPE_UINT32: {
3081 r = sd_bus_message_read(m, "u", &u);
3083 return bus_log_parse_error(r);
3085 if (streq(name, "MainPID")) {
3087 i->main_pid = (pid_t) u;
3090 } else if (streq(name, "ControlPID"))
3091 i->control_pid = (pid_t) u;
3092 else if (streq(name, "ExecMainPID")) {
3094 i->main_pid = (pid_t) u;
3095 } else if (streq(name, "NAccepted"))
3097 else if (streq(name, "NConnections"))
3098 i->n_connections = u;
3103 case SD_BUS_TYPE_INT32: {
3106 r = sd_bus_message_read(m, "i", &j);
3108 return bus_log_parse_error(r);
3110 if (streq(name, "ExecMainCode"))
3111 i->exit_code = (int) j;
3112 else if (streq(name, "ExecMainStatus"))
3113 i->exit_status = (int) j;
3118 case SD_BUS_TYPE_UINT64: {
3121 r = sd_bus_message_read(m, "t", &u);
3123 return bus_log_parse_error(r);
3125 if (streq(name, "ExecMainStartTimestamp"))
3126 i->start_timestamp = (usec_t) u;
3127 else if (streq(name, "ExecMainExitTimestamp"))
3128 i->exit_timestamp = (usec_t) u;
3129 else if (streq(name, "ActiveEnterTimestamp"))
3130 i->active_enter_timestamp = (usec_t) u;
3131 else if (streq(name, "InactiveEnterTimestamp"))
3132 i->inactive_enter_timestamp = (usec_t) u;
3133 else if (streq(name, "InactiveExitTimestamp"))
3134 i->inactive_exit_timestamp = (usec_t) u;
3135 else if (streq(name, "InactiveExitTimestampMonotonic"))
3136 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3137 else if (streq(name, "ActiveExitTimestamp"))
3138 i->active_exit_timestamp = (usec_t) u;
3139 else if (streq(name, "ConditionTimestamp"))
3140 i->condition_timestamp = (usec_t) u;
3145 case SD_BUS_TYPE_ARRAY:
3147 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3148 _cleanup_free_ ExecStatusInfo *info = NULL;
3150 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3152 return bus_log_parse_error(r);
3154 info = new0(ExecStatusInfo, 1);
3158 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3160 info->name = strdup(name);
3164 LIST_PREPEND(exec, i->exec, info);
3166 info = new0(ExecStatusInfo, 1);
3172 return bus_log_parse_error(r);
3174 r = sd_bus_message_exit_container(m);
3176 return bus_log_parse_error(r);
3180 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3181 const char *type, *path;
3183 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3185 return bus_log_parse_error(r);
3187 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3189 r = strv_extend(&i->listen, type);
3193 r = strv_extend(&i->listen, path);
3198 return bus_log_parse_error(r);
3200 r = sd_bus_message_exit_container(m);
3202 return bus_log_parse_error(r);
3206 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3208 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3210 return bus_log_parse_error(r);
3212 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3214 r = sd_bus_message_read_strv(m, &i->documentation);
3216 return bus_log_parse_error(r);
3218 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3219 const char *cond, *param;
3220 int trigger, negate;
3223 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3225 return bus_log_parse_error(r);
3227 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3228 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3229 if (state < 0 && (!trigger || !i->failed_condition)) {
3230 i->failed_condition = cond;
3231 i->failed_condition_trigger = trigger;
3232 i->failed_condition_negate = negate;
3233 i->failed_condition_param = param;
3237 return bus_log_parse_error(r);
3239 r = sd_bus_message_exit_container(m);
3241 return bus_log_parse_error(r);
3248 case SD_BUS_TYPE_STRUCT_BEGIN:
3250 if (streq(name, "LoadError")) {
3251 const char *n, *message;
3253 r = sd_bus_message_read(m, "(ss)", &n, &message);
3255 return bus_log_parse_error(r);
3257 if (!isempty(message))
3258 i->load_error = message;
3271 r = sd_bus_message_skip(m, contents);
3273 return bus_log_parse_error(r);
3278 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3284 /* This is a low-level property printer, see
3285 * print_status_info() for the nicer output */
3287 if (arg_properties && !strv_find(arg_properties, name)) {
3288 /* skip what we didn't read */
3289 r = sd_bus_message_skip(m, contents);
3293 switch (contents[0]) {
3295 case SD_BUS_TYPE_STRUCT_BEGIN:
3297 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3300 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3302 return bus_log_parse_error(r);
3305 printf("%s=%u\n", name, (unsigned) u);
3307 printf("%s=\n", name);
3311 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3314 r = sd_bus_message_read(m, "(so)", &s, NULL);
3316 return bus_log_parse_error(r);
3318 if (arg_all || !isempty(s))
3319 printf("%s=%s\n", name, s);
3323 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3324 const char *a = NULL, *b = NULL;
3326 r = sd_bus_message_read(m, "(ss)", &a, &b);
3328 return bus_log_parse_error(r);
3330 if (arg_all || !isempty(a) || !isempty(b))
3331 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3338 case SD_BUS_TYPE_ARRAY:
3340 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3344 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3346 return bus_log_parse_error(r);
3348 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3349 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3352 return bus_log_parse_error(r);
3354 r = sd_bus_message_exit_container(m);
3356 return bus_log_parse_error(r);
3360 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3361 const char *type, *path;
3363 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3365 return bus_log_parse_error(r);
3367 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3368 printf("%s=%s\n", type, path);
3370 return bus_log_parse_error(r);
3372 r = sd_bus_message_exit_container(m);
3374 return bus_log_parse_error(r);
3378 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3379 const char *type, *path;
3381 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3383 return bus_log_parse_error(r);
3385 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3386 printf("Listen%s=%s\n", type, path);
3388 return bus_log_parse_error(r);
3390 r = sd_bus_message_exit_container(m);
3392 return bus_log_parse_error(r);
3396 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3398 uint64_t value, next_elapse;
3400 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3402 return bus_log_parse_error(r);
3404 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3405 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3407 printf("%s={ value=%s ; next_elapse=%s }\n",
3409 format_timespan(timespan1, sizeof(timespan1), value, 0),
3410 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3413 return bus_log_parse_error(r);
3415 r = sd_bus_message_exit_container(m);
3417 return bus_log_parse_error(r);
3421 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3422 ExecStatusInfo info = {};
3424 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3426 return bus_log_parse_error(r);
3428 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3429 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3430 _cleanup_free_ char *tt;
3432 tt = strv_join(info.argv, " ");
3434 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3438 yes_no(info.ignore),
3439 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3440 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3441 (unsigned) info. pid,
3442 sigchld_code_to_string(info.code),
3444 info.code == CLD_EXITED ? "" : "/",
3445 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3448 strv_free(info.argv);
3452 r = sd_bus_message_exit_container(m);
3454 return bus_log_parse_error(r);
3458 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3459 const char *path, *rwm;
3461 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3463 return bus_log_parse_error(r);
3465 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3466 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3468 return bus_log_parse_error(r);
3470 r = sd_bus_message_exit_container(m);
3472 return bus_log_parse_error(r);
3476 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3480 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3482 return bus_log_parse_error(r);
3484 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3485 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3487 return bus_log_parse_error(r);
3489 r = sd_bus_message_exit_container(m);
3491 return bus_log_parse_error(r);
3495 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3499 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3501 return bus_log_parse_error(r);
3503 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3504 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3506 return bus_log_parse_error(r);
3508 r = sd_bus_message_exit_container(m);
3510 return bus_log_parse_error(r);
3518 r = bus_print_property(name, m, arg_all);
3520 return bus_log_parse_error(r);
3523 r = sd_bus_message_skip(m, contents);
3525 return bus_log_parse_error(r);
3528 printf("%s=[unprintable]\n", name);
3534 static int show_one(
3538 bool show_properties,
3542 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3543 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3544 UnitStatusInfo info = {};
3551 r = sd_bus_call_method(
3553 "org.freedesktop.systemd1",
3555 "org.freedesktop.DBus.Properties",
3561 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3565 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3567 return bus_log_parse_error(r);
3574 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3575 const char *name, *contents;
3577 r = sd_bus_message_read(reply, "s", &name);
3579 return bus_log_parse_error(r);
3581 r = sd_bus_message_peek_type(reply, NULL, &contents);
3583 return bus_log_parse_error(r);
3585 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3587 return bus_log_parse_error(r);
3589 if (show_properties)
3590 r = print_property(name, reply, contents);
3592 r = status_property(name, reply, &info, contents);
3596 r = sd_bus_message_exit_container(reply);
3598 return bus_log_parse_error(r);
3600 r = sd_bus_message_exit_container(reply);
3602 return bus_log_parse_error(r);
3605 return bus_log_parse_error(r);
3607 r = sd_bus_message_exit_container(reply);
3609 return bus_log_parse_error(r);
3613 if (!show_properties) {
3614 if (streq(verb, "help"))
3615 show_unit_help(&info);
3617 print_status_info(&info, ellipsized);
3620 strv_free(info.documentation);
3621 strv_free(info.dropin_paths);
3622 strv_free(info.listen);
3624 if (!streq_ptr(info.active_state, "active") &&
3625 !streq_ptr(info.active_state, "reloading") &&
3626 streq(verb, "status")) {
3627 /* According to LSB: "program not running" */
3628 /* 0: program is running or service is OK
3629 * 1: program is dead and /var/run pid file exists
3630 * 2: program is dead and /var/lock lock file exists
3631 * 3: program is not running
3632 * 4: program or service status is unknown
3634 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3640 while ((p = info.exec)) {
3641 LIST_REMOVE(exec, info.exec, p);
3642 exec_status_info_free(p);
3648 static int get_unit_dbus_path_by_pid(
3653 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3654 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3657 r = sd_bus_call_method(
3659 "org.freedesktop.systemd1",
3660 "/org/freedesktop/systemd1",
3661 "org.freedesktop.systemd1.Manager",
3667 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3671 r = sd_bus_message_read(reply, "o", unit);
3673 return bus_log_parse_error(r);
3678 static int show_all(
3681 bool show_properties,
3685 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3686 _cleanup_free_ UnitInfo *unit_infos = NULL;
3691 r = get_unit_list(bus, &reply, &unit_infos);
3695 pager_open_if_enabled();
3699 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3701 for (u = unit_infos; u < unit_infos + c; u++) {
3702 _cleanup_free_ char *p = NULL;
3704 if (!output_show_unit(u, NULL))
3707 p = unit_dbus_path_from_name(u->id);
3711 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3719 static int cat(sd_bus *bus, char **args) {
3723 _cleanup_free_ char *unit = NULL, *n = NULL;
3728 pager_open_if_enabled();
3730 STRV_FOREACH(name, args+1) {
3731 _cleanup_free_ char *fragment_path = NULL;
3732 _cleanup_strv_free_ char **dropin_paths = NULL;
3736 n = unit_name_mangle(*name);
3740 unit = unit_dbus_path_from_name(n);
3744 if (need_daemon_reload(bus, n) > 0)
3745 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3746 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3748 r = sd_bus_get_property_string(
3750 "org.freedesktop.systemd1",
3752 "org.freedesktop.systemd1.Unit",
3757 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3761 r = sd_bus_get_property_strv(
3763 "org.freedesktop.systemd1",
3765 "org.freedesktop.systemd1.Unit",
3770 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3774 if (!isempty(fragment_path)) {
3775 fprintf(stdout, "# %s\n", fragment_path);
3777 r = sendfile_full(STDOUT_FILENO, fragment_path);
3779 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3784 STRV_FOREACH(path, dropin_paths) {
3785 fprintf(stdout, "%s# %s\n",
3786 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3789 r = sendfile_full(STDOUT_FILENO, *path);
3791 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3800 static int show(sd_bus *bus, char **args) {
3802 bool show_properties, show_status, new_line = false;
3804 bool ellipsized = false;
3809 show_properties = streq(args[0], "show");
3810 show_status = streq(args[0], "status");
3812 if (show_properties)
3813 pager_open_if_enabled();
3815 /* If no argument is specified inspect the manager itself */
3817 if (show_properties && strv_length(args) <= 1)
3818 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3820 if (show_status && strv_length(args) <= 1)
3821 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3823 STRV_FOREACH(name, args+1) {
3824 _cleanup_free_ char *unit = NULL;
3827 if (safe_atou32(*name, &id) < 0) {
3828 _cleanup_free_ char *n = NULL;
3829 /* Interpret as unit name */
3831 n = unit_name_mangle(*name);
3835 unit = unit_dbus_path_from_name(n);
3839 } else if (show_properties) {
3840 /* Interpret as job id */
3841 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3845 /* Interpret as PID */
3846 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3851 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3854 if (ellipsized && !arg_quiet)
3855 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3860 static int append_assignment(sd_bus_message *m, const char *assignment) {
3868 eq = strchr(assignment, '=');
3870 log_error("Not an assignment: %s", assignment);
3874 field = strndupa(assignment, eq - assignment);
3877 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3879 return bus_log_create_error(r);
3881 if (streq(field, "CPUAccounting") ||
3882 streq(field, "MemoryAccounting") ||
3883 streq(field, "BlockIOAccounting")) {
3885 r = parse_boolean(eq);
3887 log_error("Failed to parse boolean assignment %s.", assignment);
3891 r = sd_bus_message_append(m, "v", "b", r);
3893 } else if (streq(field, "MemoryLimit")) {
3896 r = parse_bytes(eq, &bytes);
3898 log_error("Failed to parse bytes specification %s", assignment);
3902 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3904 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3907 r = safe_atou64(eq, &u);
3909 log_error("Failed to parse %s value %s.", field, eq);
3913 r = sd_bus_message_append(m, "v", "t", u);
3915 } else if (streq(field, "DevicePolicy"))
3916 r = sd_bus_message_append(m, "v", "s", eq);
3918 else if (streq(field, "DeviceAllow")) {
3921 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3923 const char *path, *rwm;
3926 e = strchr(eq, ' ');
3928 path = strndupa(eq, e - eq);
3935 if (!path_startswith(path, "/dev")) {
3936 log_error("%s is not a device file in /dev.", path);
3940 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3943 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3946 r = sd_bus_message_append(m, "v", "a(st)", 0);
3948 const char *path, *bandwidth;
3952 e = strchr(eq, ' ');
3954 path = strndupa(eq, e - eq);
3957 log_error("Failed to parse %s value %s.", field, eq);
3961 if (!path_startswith(path, "/dev")) {
3962 log_error("%s is not a device file in /dev.", path);
3966 r = parse_bytes(bandwidth, &bytes);
3968 log_error("Failed to parse byte value %s.", bandwidth);
3972 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3975 } else if (streq(field, "BlockIODeviceWeight")) {
3978 r = sd_bus_message_append(m, "v", "a(st)", 0);
3980 const char *path, *weight;
3984 e = strchr(eq, ' ');
3986 path = strndupa(eq, e - eq);
3989 log_error("Failed to parse %s value %s.", field, eq);
3993 if (!path_startswith(path, "/dev")) {
3994 log_error("%s is not a device file in /dev.", path);
3998 r = safe_atou64(weight, &u);
4000 log_error("Failed to parse %s value %s.", field, weight);
4003 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4007 log_error("Unknown assignment %s.", assignment);
4012 return bus_log_create_error(r);
4017 static int set_property(sd_bus *bus, char **args) {
4018 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4019 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4020 _cleanup_free_ char *n = NULL;
4024 r = sd_bus_message_new_method_call(
4026 "org.freedesktop.systemd1",
4027 "/org/freedesktop/systemd1",
4028 "org.freedesktop.systemd1.Manager",
4029 "SetUnitProperties",
4032 return bus_log_create_error(r);
4034 n = unit_name_mangle(args[1]);
4038 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4040 return bus_log_create_error(r);
4042 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4044 return bus_log_create_error(r);
4046 STRV_FOREACH(i, args + 2) {
4047 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4049 return bus_log_create_error(r);
4051 r = append_assignment(m, *i);
4055 r = sd_bus_message_close_container(m);
4057 return bus_log_create_error(r);
4060 r = sd_bus_message_close_container(m);
4062 return bus_log_create_error(r);
4064 r = sd_bus_call(bus, m, 0, &error, NULL);
4066 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4073 static int snapshot(sd_bus *bus, char **args) {
4074 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4075 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4076 _cleanup_free_ char *n = NULL, *id = NULL;
4080 if (strv_length(args) > 1)
4081 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
4087 r = sd_bus_call_method(
4089 "org.freedesktop.systemd1",
4090 "/org/freedesktop/systemd1",
4091 "org.freedesktop.systemd1.Manager",
4097 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4101 r = sd_bus_message_read(reply, "o", &path);
4103 return bus_log_parse_error(r);
4105 r = sd_bus_get_property_string(
4107 "org.freedesktop.systemd1",
4109 "org.freedesktop.systemd1.Unit",
4114 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4124 static int delete_snapshot(sd_bus *bus, char **args) {
4125 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4131 STRV_FOREACH(name, args+1) {
4132 _cleanup_free_ char *n = NULL;
4134 n = unit_name_mangle_with_suffix(*name, ".snapshot");
4138 r = sd_bus_call_method(
4140 "org.freedesktop.systemd1",
4141 "/org/freedesktop/systemd1",
4142 "org.freedesktop.systemd1.Manager",
4148 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
4156 static int daemon_reload(sd_bus *bus, char **args) {
4157 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4161 if (arg_action == ACTION_RELOAD)
4163 else if (arg_action == ACTION_REEXEC)
4164 method = "Reexecute";
4166 assert(arg_action == ACTION_SYSTEMCTL);
4169 streq(args[0], "clear-jobs") ||
4170 streq(args[0], "cancel") ? "ClearJobs" :
4171 streq(args[0], "daemon-reexec") ? "Reexecute" :
4172 streq(args[0], "reset-failed") ? "ResetFailed" :
4173 streq(args[0], "halt") ? "Halt" :
4174 streq(args[0], "poweroff") ? "PowerOff" :
4175 streq(args[0], "reboot") ? "Reboot" :
4176 streq(args[0], "kexec") ? "KExec" :
4177 streq(args[0], "exit") ? "Exit" :
4178 /* "daemon-reload" */ "Reload";
4181 r = sd_bus_call_method(
4183 "org.freedesktop.systemd1",
4184 "/org/freedesktop/systemd1",
4185 "org.freedesktop.systemd1.Manager",
4191 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4192 /* There's always a fallback possible for
4193 * legacy actions. */
4195 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4196 /* On reexecution, we expect a disconnect, not a
4200 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4202 return r < 0 ? r : 0;
4205 static int reset_failed(sd_bus *bus, char **args) {
4206 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4210 if (strv_length(args) <= 1)
4211 return daemon_reload(bus, args);
4213 STRV_FOREACH(name, args+1) {
4214 _cleanup_free_ char *n;
4216 n = unit_name_mangle(*name);
4220 r = sd_bus_call_method(
4222 "org.freedesktop.systemd1",
4223 "/org/freedesktop/systemd1",
4224 "org.freedesktop.systemd1.Manager",
4230 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4238 static int show_environment(sd_bus *bus, char **args) {
4239 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4240 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4244 pager_open_if_enabled();
4246 r = sd_bus_get_property(
4248 "org.freedesktop.systemd1",
4249 "/org/freedesktop/systemd1",
4250 "org.freedesktop.systemd1.Manager",
4256 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4260 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4262 return bus_log_parse_error(r);
4264 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4267 return bus_log_parse_error(r);
4269 r = sd_bus_message_exit_container(reply);
4271 return bus_log_parse_error(r);
4276 static int switch_root(sd_bus *bus, char **args) {
4277 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4278 _cleanup_free_ char *init = NULL;
4283 l = strv_length(args);
4284 if (l < 2 || l > 3) {
4285 log_error("Wrong number of arguments.");
4292 init = strdup(args[2]);
4294 parse_env_file("/proc/cmdline", WHITESPACE,
4305 log_debug("switching root - root: %s; init: %s", root, init);
4307 r = sd_bus_call_method(
4309 "org.freedesktop.systemd1",
4310 "/org/freedesktop/systemd1",
4311 "org.freedesktop.systemd1.Manager",
4317 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4324 static int set_environment(sd_bus *bus, char **args) {
4325 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4326 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4333 method = streq(args[0], "set-environment")
4335 : "UnsetEnvironment";
4337 r = sd_bus_message_new_method_call(
4339 "org.freedesktop.systemd1",
4340 "/org/freedesktop/systemd1",
4341 "org.freedesktop.systemd1.Manager",
4345 return bus_log_create_error(r);
4347 r = sd_bus_message_append_strv(m, args + 1);
4349 return bus_log_create_error(r);
4351 r = sd_bus_call(bus, m, 0, &error, NULL);
4353 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4360 static int enable_sysv_units(const char *verb, char **args) {
4363 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4364 unsigned f = 1, t = 1;
4365 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4367 if (arg_scope != UNIT_FILE_SYSTEM)
4370 if (!streq(verb, "enable") &&
4371 !streq(verb, "disable") &&
4372 !streq(verb, "is-enabled"))
4375 /* Processes all SysV units, and reshuffles the array so that
4376 * afterwards only the native units remain */
4378 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4383 for (f = 0; args[f]; f++) {
4385 _cleanup_free_ char *p = NULL, *q = NULL;
4386 bool found_native = false, found_sysv;
4388 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4396 if (!endswith(name, ".service"))
4399 if (path_is_absolute(name))
4402 STRV_FOREACH(k, paths.unit_path) {
4403 if (!isempty(arg_root))
4404 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4406 asprintf(&p, "%s/%s", *k, name);
4413 found_native = access(p, F_OK) >= 0;
4424 if (!isempty(arg_root))
4425 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4427 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4433 p[strlen(p) - sizeof(".service") + 1] = 0;
4434 found_sysv = access(p, F_OK) >= 0;
4439 /* Mark this entry, so that we don't try enabling it as native unit */
4440 args[f] = (char*) "";
4442 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4444 if (!isempty(arg_root))
4445 argv[c++] = q = strappend("--root=", arg_root);
4447 argv[c++] = basename(p);
4449 streq(verb, "enable") ? "on" :
4450 streq(verb, "disable") ? "off" : "--level=5";
4453 l = strv_join((char**)argv, " ");
4459 log_info("Executing %s", l);
4464 log_error("Failed to fork: %m");
4467 } else if (pid == 0) {
4470 execv(argv[0], (char**) argv);
4471 _exit(EXIT_FAILURE);
4474 j = wait_for_terminate(pid, &status);
4476 log_error("Failed to wait for child: %s", strerror(-r));
4481 if (status.si_code == CLD_EXITED) {
4482 if (streq(verb, "is-enabled")) {
4483 if (status.si_status == 0) {
4492 } else if (status.si_status != 0) {
4503 /* Drop all SysV units */
4504 for (f = 0, t = 0; args[f]; f++) {
4506 if (isempty(args[f]))
4509 args[t++] = args[f];
4518 static int mangle_names(char **original_names, char ***mangled_names) {
4519 char **i, **l, **name;
4521 l = new(char*, strv_length(original_names) + 1);
4526 STRV_FOREACH(name, original_names) {
4528 /* When enabling units qualified path names are OK,
4529 * too, hence allow them explicitly. */
4534 *i = unit_name_mangle(*name);
4550 static int enable_unit(sd_bus *bus, char **args) {
4551 _cleanup_strv_free_ char **mangled_names = NULL;
4552 const char *verb = args[0];
4553 UnitFileChange *changes = NULL;
4554 unsigned n_changes = 0;
4555 int carries_install_info = -1;
4561 r = mangle_names(args+1, &mangled_names);
4565 r = enable_sysv_units(verb, mangled_names);
4569 if (!bus || avoid_bus()) {
4570 if (streq(verb, "enable")) {
4571 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4572 carries_install_info = r;
4573 } else if (streq(verb, "disable"))
4574 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4575 else if (streq(verb, "reenable")) {
4576 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4577 carries_install_info = r;
4578 } else if (streq(verb, "link"))
4579 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4580 else if (streq(verb, "preset")) {
4581 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4582 carries_install_info = r;
4583 } else if (streq(verb, "mask"))
4584 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4585 else if (streq(verb, "unmask"))
4586 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4588 assert_not_reached("Unknown verb");
4591 log_error("Operation failed: %s", strerror(-r));
4596 dump_unit_file_changes(changes, n_changes);
4600 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4601 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4602 int expect_carries_install_info = false;
4603 bool send_force = true;
4606 if (streq(verb, "enable")) {
4607 method = "EnableUnitFiles";
4608 expect_carries_install_info = true;
4609 } else if (streq(verb, "disable")) {
4610 method = "DisableUnitFiles";
4612 } else if (streq(verb, "reenable")) {
4613 method = "ReenableUnitFiles";
4614 expect_carries_install_info = true;
4615 } else if (streq(verb, "link"))
4616 method = "LinkUnitFiles";
4617 else if (streq(verb, "preset")) {
4618 method = "PresetUnitFiles";
4619 expect_carries_install_info = true;
4620 } else if (streq(verb, "mask"))
4621 method = "MaskUnitFiles";
4622 else if (streq(verb, "unmask")) {
4623 method = "UnmaskUnitFiles";
4626 assert_not_reached("Unknown verb");
4628 r = sd_bus_message_new_method_call(
4630 "org.freedesktop.systemd1",
4631 "/org/freedesktop/systemd1",
4632 "org.freedesktop.systemd1.Manager",
4636 return bus_log_create_error(r);
4638 r = sd_bus_message_append_strv(m, mangled_names);
4640 return bus_log_create_error(r);
4642 r = sd_bus_message_append(m, "b", arg_runtime);
4644 return bus_log_create_error(r);
4647 r = sd_bus_message_append(m, "b", arg_force);
4649 return bus_log_create_error(r);
4652 r = sd_bus_call(bus, m, 0, &error, &reply);
4654 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4658 if (expect_carries_install_info) {
4659 r = sd_bus_message_read(reply, "b", &carries_install_info);
4661 return bus_log_parse_error(r);
4664 r = deserialize_and_dump_unit_file_changes(reply);
4668 /* Try to reload if enabeld */
4670 r = daemon_reload(bus, args);
4675 if (carries_install_info == 0)
4676 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4677 "using systemctl.\n"
4678 "Possible reasons for having this kind of units are:\n"
4679 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4680 " .wants/ or .requires/ directory.\n"
4681 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4682 " a requirement dependency on it.\n"
4683 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4684 " D-Bus, udev, scripted systemctl call, ...).\n");
4687 unit_file_changes_free(changes, n_changes);
4692 static int unit_is_enabled(sd_bus *bus, char **args) {
4694 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4695 _cleanup_strv_free_ char **mangled_names = NULL;
4700 r = mangle_names(args+1, &mangled_names);
4704 r = enable_sysv_units(args[0], mangled_names);
4710 if (!bus || avoid_bus()) {
4712 STRV_FOREACH(name, mangled_names) {
4713 UnitFileState state;
4715 state = unit_file_get_state(arg_scope, arg_root, *name);
4717 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4721 if (state == UNIT_FILE_ENABLED ||
4722 state == UNIT_FILE_ENABLED_RUNTIME ||
4723 state == UNIT_FILE_STATIC)
4727 puts(unit_file_state_to_string(state));
4731 STRV_FOREACH(name, mangled_names) {
4732 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4735 r = sd_bus_call_method(
4737 "org.freedesktop.systemd1",
4738 "/org/freedesktop/systemd1",
4739 "org.freedesktop.systemd1.Manager",
4745 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4749 r = sd_bus_message_read(reply, "s", &s);
4751 return bus_log_parse_error(r);
4753 if (streq(s, "enabled") ||
4754 streq(s, "enabled-runtime") ||
4766 static int systemctl_help(void) {
4768 pager_open_if_enabled();
4770 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4771 "Query or send control commands to the systemd manager.\n\n"
4772 " -h --help Show this help\n"
4773 " --version Show package version\n"
4774 " --system Connect to system manager\n"
4775 " --user Connect to user service manager\n"
4776 " -H --host=[USER@]HOST\n"
4777 " Operate on remote host\n"
4778 " -M --machine=CONTAINER\n"
4779 " Operate on local container\n"
4780 " -t --type=TYPE List only units of a particular type\n"
4781 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4782 " -p --property=NAME Show only properties by this name\n"
4783 " -a --all Show all loaded units/properties, including dead/empty\n"
4784 " ones. To list all units installed on the system, use\n"
4785 " the 'list-unit-files' command instead.\n"
4786 " -l --full Don't ellipsize unit names on output\n"
4787 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4788 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4789 " queueing a new job\n"
4790 " --show-types When showing sockets, explicitly show their type\n"
4791 " -i --ignore-inhibitors\n"
4792 " When shutting down or sleeping, ignore inhibitors\n"
4793 " --kill-who=WHO Who to send signal to\n"
4794 " -s --signal=SIGNAL Which signal to send\n"
4795 " -q --quiet Suppress output\n"
4796 " --no-block Do not wait until operation finished\n"
4797 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4798 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4800 " --no-legend Do not print a legend (column headers and hints)\n"
4801 " --no-pager Do not pipe output into a pager\n"
4802 " --no-ask-password\n"
4803 " Do not ask for system passwords\n"
4804 " --global Enable/disable unit files globally\n"
4805 " --runtime Enable unit files only temporarily until next reboot\n"
4806 " -f --force When enabling unit files, override existing symlinks\n"
4807 " When shutting down, execute action immediately\n"
4808 " --root=PATH Enable unit files in the specified root directory\n"
4809 " -n --lines=INTEGER Number of journal entries to show\n"
4810 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4811 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4813 " list-units [PATTERN...] List loaded units\n"
4814 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4815 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4816 " start [NAME...] Start (activate) one or more units\n"
4817 " stop [NAME...] Stop (deactivate) one or more units\n"
4818 " reload [NAME...] Reload one or more units\n"
4819 " restart [NAME...] Start or restart one or more units\n"
4820 " try-restart [NAME...] Restart one or more units if active\n"
4821 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4822 " otherwise start or restart\n"
4823 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4824 " otherwise restart if active\n"
4825 " isolate [NAME] Start one unit and stop all others\n"
4826 " kill [NAME...] Send signal to processes of a unit\n"
4827 " is-active [NAME...] Check whether units are active\n"
4828 " is-failed [NAME...] Check whether units are failed\n"
4829 " status [NAME...|PID...] Show runtime status of one or more units\n"
4830 " show [NAME...|JOB...] Show properties of one or more\n"
4831 " units/jobs or the manager\n"
4832 " cat [NAME...] Show files and drop-ins of one or more units\n"
4833 " set-property [NAME] [ASSIGNMENT...]\n"
4834 " Sets one or more properties of a unit\n"
4835 " help [NAME...|PID...] Show manual for one or more units\n"
4836 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4838 " list-dependencies [NAME] Recursively show units which are required\n"
4839 " or wanted by this unit or by which this\n"
4840 " unit is required or wanted\n\n"
4841 "Unit File Commands:\n"
4842 " list-unit-files [PATTERN...] List installed unit files\n"
4843 " enable [NAME...] Enable one or more unit files\n"
4844 " disable [NAME...] Disable one or more unit files\n"
4845 " reenable [NAME...] Reenable one or more unit files\n"
4846 " preset [NAME...] Enable/disable one or more unit files\n"
4847 " based on preset configuration\n"
4848 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4849 " mask [NAME...] Mask one or more units\n"
4850 " unmask [NAME...] Unmask one or more units\n"
4851 " link [PATH...] Link one or more units files into\n"
4852 " the search path\n"
4853 " get-default Get the name of the default target\n"
4854 " set-default NAME Set the default target\n\n"
4856 " list-jobs [PATTERN...] List jobs\n"
4857 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4858 "Snapshot Commands:\n"
4859 " snapshot [NAME] Create a snapshot\n"
4860 " delete [NAME...] Remove one or more snapshots\n\n"
4861 "Environment Commands:\n"
4862 " show-environment Dump environment\n"
4863 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4864 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4865 "Manager Lifecycle Commands:\n"
4866 " daemon-reload Reload systemd manager configuration\n"
4867 " daemon-reexec Reexecute systemd manager\n\n"
4868 "System Commands:\n"
4869 " default Enter system default mode\n"
4870 " rescue Enter system rescue mode\n"
4871 " emergency Enter system emergency mode\n"
4872 " halt Shut down and halt the system\n"
4873 " poweroff Shut down and power-off the system\n"
4874 " reboot [ARG] Shut down and reboot the system\n"
4875 " kexec Shut down and reboot the system with kexec\n"
4876 " exit Request user instance exit\n"
4877 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4878 " suspend Suspend the system\n"
4879 " hibernate Hibernate the system\n"
4880 " hybrid-sleep Hibernate and suspend the system\n",
4881 program_invocation_short_name);
4886 static int halt_help(void) {
4888 printf("%s [OPTIONS...]%s\n\n"
4889 "%s the system.\n\n"
4890 " --help Show this help\n"
4891 " --halt Halt the machine\n"
4892 " -p --poweroff Switch off the machine\n"
4893 " --reboot Reboot the machine\n"
4894 " -f --force Force immediate halt/power-off/reboot\n"
4895 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4896 " -d --no-wtmp Don't write wtmp record\n"
4897 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4898 program_invocation_short_name,
4899 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4900 arg_action == ACTION_REBOOT ? "Reboot" :
4901 arg_action == ACTION_POWEROFF ? "Power off" :
4907 static int shutdown_help(void) {
4909 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4910 "Shut down the system.\n\n"
4911 " --help Show this help\n"
4912 " -H --halt Halt the machine\n"
4913 " -P --poweroff Power-off the machine\n"
4914 " -r --reboot Reboot the machine\n"
4915 " -h Equivalent to --poweroff, overridden by --halt\n"
4916 " -k Don't halt/power-off/reboot, just send warnings\n"
4917 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4918 " -c Cancel a pending shutdown\n",
4919 program_invocation_short_name);
4924 static int telinit_help(void) {
4926 printf("%s [OPTIONS...] {COMMAND}\n\n"
4927 "Send control commands to the init daemon.\n\n"
4928 " --help Show this help\n"
4929 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4931 " 0 Power-off the machine\n"
4932 " 6 Reboot the machine\n"
4933 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4934 " 1, s, S Enter rescue mode\n"
4935 " q, Q Reload init daemon configuration\n"
4936 " u, U Reexecute init daemon\n",
4937 program_invocation_short_name);
4942 static int runlevel_help(void) {
4944 printf("%s [OPTIONS...]\n\n"
4945 "Prints the previous and current runlevel of the init system.\n\n"
4946 " --help Show this help\n",
4947 program_invocation_short_name);
4952 static int help_types(void) {
4956 puts("Available unit types:");
4957 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
4958 t = unit_type_to_string(i);
4966 static int systemctl_parse_argv(int argc, char *argv[]) {
4975 ARG_IGNORE_DEPENDENCIES,
4987 ARG_NO_ASK_PASSWORD,
4996 static const struct option options[] = {
4997 { "help", no_argument, NULL, 'h' },
4998 { "version", no_argument, NULL, ARG_VERSION },
4999 { "type", required_argument, NULL, 't' },
5000 { "property", required_argument, NULL, 'p' },
5001 { "all", no_argument, NULL, 'a' },
5002 { "reverse", no_argument, NULL, ARG_REVERSE },
5003 { "after", no_argument, NULL, ARG_AFTER },
5004 { "before", no_argument, NULL, ARG_BEFORE },
5005 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5006 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5007 { "full", no_argument, NULL, 'l' },
5008 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5009 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5010 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5011 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5012 { "ignore-inhibitors", no_argument, NULL, 'i' },
5013 { "user", no_argument, NULL, ARG_USER },
5014 { "system", no_argument, NULL, ARG_SYSTEM },
5015 { "global", no_argument, NULL, ARG_GLOBAL },
5016 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5017 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5018 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5019 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5020 { "quiet", no_argument, NULL, 'q' },
5021 { "root", required_argument, NULL, ARG_ROOT },
5022 { "force", no_argument, NULL, ARG_FORCE },
5023 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5024 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5025 { "signal", required_argument, NULL, 's' },
5026 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5027 { "host", required_argument, NULL, 'H' },
5028 { "machine", required_argument, NULL, 'M' },
5029 { "runtime", no_argument, NULL, ARG_RUNTIME },
5030 { "lines", required_argument, NULL, 'n' },
5031 { "output", required_argument, NULL, 'o' },
5032 { "plain", no_argument, NULL, ARG_PLAIN },
5033 { "state", required_argument, NULL, ARG_STATE },
5042 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5047 return systemctl_help();
5050 puts(PACKAGE_STRING);
5051 puts(SYSTEMD_FEATURES);
5058 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5059 _cleanup_free_ char *type;
5061 type = strndup(word, size);
5065 if (streq(type, "help")) {
5070 if (unit_type_from_string(type) >= 0) {
5071 if (strv_push(&arg_types, type))
5077 /* It's much nicer to use --state= for
5078 * load states, but let's support this
5079 * in --types= too for compatibility
5080 * with old versions */
5081 if (unit_load_state_from_string(optarg) >= 0) {
5082 if (strv_push(&arg_states, type) < 0)
5088 log_error("Unknown unit type or load state '%s'.", type);
5089 log_info("Use -t help to see a list of allowed values.");
5097 /* Make sure that if the empty property list
5098 was specified, we won't show any properties. */
5099 if (isempty(optarg) && !arg_properties) {
5100 arg_properties = new0(char*, 1);
5101 if (!arg_properties)
5107 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5110 prop = strndup(word, size);
5114 if (strv_push(&arg_properties, prop) < 0) {
5121 /* If the user asked for a particular
5122 * property, show it to him, even if it is
5134 arg_dependency = DEPENDENCY_REVERSE;
5138 arg_dependency = DEPENDENCY_AFTER;
5142 arg_dependency = DEPENDENCY_BEFORE;
5145 case ARG_SHOW_TYPES:
5146 arg_show_types = true;
5150 arg_job_mode = optarg;
5154 arg_job_mode = "fail";
5157 case ARG_IRREVERSIBLE:
5158 arg_job_mode = "replace-irreversibly";
5161 case ARG_IGNORE_DEPENDENCIES:
5162 arg_job_mode = "ignore-dependencies";
5166 arg_scope = UNIT_FILE_USER;
5170 arg_scope = UNIT_FILE_SYSTEM;
5174 arg_scope = UNIT_FILE_GLOBAL;
5178 arg_no_block = true;
5182 arg_no_legend = true;
5186 arg_no_pager = true;
5202 if (strv_extend(&arg_states, "failed") < 0)
5220 arg_no_reload = true;
5224 arg_kill_who = optarg;
5228 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5229 log_error("Failed to parse signal string %s.", optarg);
5234 case ARG_NO_ASK_PASSWORD:
5235 arg_ask_password = false;
5239 arg_transport = BUS_TRANSPORT_REMOTE;
5244 arg_transport = BUS_TRANSPORT_CONTAINER;
5253 if (safe_atou(optarg, &arg_lines) < 0) {
5254 log_error("Failed to parse lines '%s'", optarg);
5260 arg_output = output_mode_from_string(optarg);
5261 if (arg_output < 0) {
5262 log_error("Unknown output '%s'.", optarg);
5268 arg_ignore_inhibitors = true;
5279 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5282 s = strndup(word, size);
5286 if (strv_push(&arg_states, s) < 0) {
5298 assert_not_reached("Unhandled option");
5302 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5303 log_error("Cannot access user instance remotely.");
5310 static int halt_parse_argv(int argc, char *argv[]) {
5319 static const struct option options[] = {
5320 { "help", no_argument, NULL, ARG_HELP },
5321 { "halt", no_argument, NULL, ARG_HALT },
5322 { "poweroff", no_argument, NULL, 'p' },
5323 { "reboot", no_argument, NULL, ARG_REBOOT },
5324 { "force", no_argument, NULL, 'f' },
5325 { "wtmp-only", no_argument, NULL, 'w' },
5326 { "no-wtmp", no_argument, NULL, 'd' },
5327 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5336 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5337 if (runlevel == '0' || runlevel == '6')
5340 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5347 arg_action = ACTION_HALT;
5351 if (arg_action != ACTION_REBOOT)
5352 arg_action = ACTION_POWEROFF;
5356 arg_action = ACTION_REBOOT;
5378 /* Compatibility nops */
5385 assert_not_reached("Unhandled option");
5389 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5390 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5392 log_error("Failed to write reboot param to "
5393 REBOOT_PARAM_FILE": %s", strerror(-r));
5396 } else if (optind < argc) {
5397 log_error("Too many arguments.");
5404 static int parse_time_spec(const char *t, usec_t *_u) {
5408 if (streq(t, "now"))
5410 else if (!strchr(t, ':')) {
5413 if (safe_atou64(t, &u) < 0)
5416 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5425 hour = strtol(t, &e, 10);
5426 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5429 minute = strtol(e+1, &e, 10);
5430 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5433 n = now(CLOCK_REALTIME);
5434 s = (time_t) (n / USEC_PER_SEC);
5436 assert_se(localtime_r(&s, &tm));
5438 tm.tm_hour = (int) hour;
5439 tm.tm_min = (int) minute;
5442 assert_se(s = mktime(&tm));
5444 *_u = (usec_t) s * USEC_PER_SEC;
5447 *_u += USEC_PER_DAY;
5453 static int shutdown_parse_argv(int argc, char *argv[]) {
5460 static const struct option options[] = {
5461 { "help", no_argument, NULL, ARG_HELP },
5462 { "halt", no_argument, NULL, 'H' },
5463 { "poweroff", no_argument, NULL, 'P' },
5464 { "reboot", no_argument, NULL, 'r' },
5465 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5466 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5475 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5479 return shutdown_help();
5482 arg_action = ACTION_HALT;
5486 arg_action = ACTION_POWEROFF;
5491 arg_action = ACTION_KEXEC;
5493 arg_action = ACTION_REBOOT;
5497 arg_action = ACTION_KEXEC;
5501 if (arg_action != ACTION_HALT)
5502 arg_action = ACTION_POWEROFF;
5515 /* Compatibility nops */
5519 arg_action = ACTION_CANCEL_SHUTDOWN;
5526 assert_not_reached("Unhandled option");
5530 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5531 r = parse_time_spec(argv[optind], &arg_when);
5533 log_error("Failed to parse time specification: %s", argv[optind]);
5537 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5539 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5540 /* No time argument for shutdown cancel */
5541 arg_wall = argv + optind;
5542 else if (argc > optind + 1)
5543 /* We skip the time argument */
5544 arg_wall = argv + optind + 1;
5551 static int telinit_parse_argv(int argc, char *argv[]) {
5558 static const struct option options[] = {
5559 { "help", no_argument, NULL, ARG_HELP },
5560 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5564 static const struct {
5568 { '0', ACTION_POWEROFF },
5569 { '6', ACTION_REBOOT },
5570 { '1', ACTION_RESCUE },
5571 { '2', ACTION_RUNLEVEL2 },
5572 { '3', ACTION_RUNLEVEL3 },
5573 { '4', ACTION_RUNLEVEL4 },
5574 { '5', ACTION_RUNLEVEL5 },
5575 { 's', ACTION_RESCUE },
5576 { 'S', ACTION_RESCUE },
5577 { 'q', ACTION_RELOAD },
5578 { 'Q', ACTION_RELOAD },
5579 { 'u', ACTION_REEXEC },
5580 { 'U', ACTION_REEXEC }
5589 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5593 return telinit_help();
5603 assert_not_reached("Unhandled option");
5607 if (optind >= argc) {
5612 if (optind + 1 < argc) {
5613 log_error("Too many arguments.");
5617 if (strlen(argv[optind]) != 1) {
5618 log_error("Expected single character argument.");
5622 for (i = 0; i < ELEMENTSOF(table); i++)
5623 if (table[i].from == argv[optind][0])
5626 if (i >= ELEMENTSOF(table)) {
5627 log_error("Unknown command '%s'.", argv[optind]);
5631 arg_action = table[i].to;
5638 static int runlevel_parse_argv(int argc, char *argv[]) {
5644 static const struct option options[] = {
5645 { "help", no_argument, NULL, ARG_HELP },
5654 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5658 return runlevel_help();
5665 assert_not_reached("Unhandled option");
5669 if (optind < argc) {
5670 log_error("Too many arguments.");
5677 static int parse_argv(int argc, char *argv[]) {
5681 if (program_invocation_short_name) {
5683 if (strstr(program_invocation_short_name, "halt")) {
5684 arg_action = ACTION_HALT;
5685 return halt_parse_argv(argc, argv);
5686 } else if (strstr(program_invocation_short_name, "poweroff")) {
5687 arg_action = ACTION_POWEROFF;
5688 return halt_parse_argv(argc, argv);
5689 } else if (strstr(program_invocation_short_name, "reboot")) {
5691 arg_action = ACTION_KEXEC;
5693 arg_action = ACTION_REBOOT;
5694 return halt_parse_argv(argc, argv);
5695 } else if (strstr(program_invocation_short_name, "shutdown")) {
5696 arg_action = ACTION_POWEROFF;
5697 return shutdown_parse_argv(argc, argv);
5698 } else if (strstr(program_invocation_short_name, "init")) {
5700 if (sd_booted() > 0) {
5701 arg_action = _ACTION_INVALID;
5702 return telinit_parse_argv(argc, argv);
5704 /* Hmm, so some other init system is
5705 * running, we need to forward this
5706 * request to it. For now we simply
5707 * guess that it is Upstart. */
5709 execv(TELINIT, argv);
5711 log_error("Couldn't find an alternative telinit implementation to spawn.");
5715 } else if (strstr(program_invocation_short_name, "runlevel")) {
5716 arg_action = ACTION_RUNLEVEL;
5717 return runlevel_parse_argv(argc, argv);
5721 arg_action = ACTION_SYSTEMCTL;
5722 return systemctl_parse_argv(argc, argv);
5725 _pure_ static int action_to_runlevel(void) {
5727 static const char table[_ACTION_MAX] = {
5728 [ACTION_HALT] = '0',
5729 [ACTION_POWEROFF] = '0',
5730 [ACTION_REBOOT] = '6',
5731 [ACTION_RUNLEVEL2] = '2',
5732 [ACTION_RUNLEVEL3] = '3',
5733 [ACTION_RUNLEVEL4] = '4',
5734 [ACTION_RUNLEVEL5] = '5',
5735 [ACTION_RESCUE] = '1'
5738 assert(arg_action < _ACTION_MAX);
5740 return table[arg_action];
5743 static int talk_initctl(void) {
5745 struct init_request request = {
5746 .magic = INIT_MAGIC,
5748 .cmd = INIT_CMD_RUNLVL
5751 _cleanup_close_ int fd = -1;
5755 rl = action_to_runlevel();
5759 request.runlevel = rl;
5761 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5763 if (errno == ENOENT)
5766 log_error("Failed to open "INIT_FIFO": %m");
5771 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5773 log_error("Failed to write to "INIT_FIFO": %m");
5774 return errno > 0 ? -errno : -EIO;
5780 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5782 static const struct {
5790 int (* const dispatch)(sd_bus *bus, char **args);
5792 { "list-units", MORE, 0, list_units },
5793 { "list-unit-files", MORE, 1, list_unit_files },
5794 { "list-sockets", MORE, 1, list_sockets },
5795 { "list-timers", MORE, 1, list_timers },
5796 { "list-jobs", MORE, 1, list_jobs },
5797 { "clear-jobs", EQUAL, 1, daemon_reload },
5798 { "cancel", MORE, 2, cancel_job },
5799 { "start", MORE, 2, start_unit },
5800 { "stop", MORE, 2, start_unit },
5801 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5802 { "reload", MORE, 2, start_unit },
5803 { "restart", MORE, 2, start_unit },
5804 { "try-restart", MORE, 2, start_unit },
5805 { "reload-or-restart", MORE, 2, start_unit },
5806 { "reload-or-try-restart", MORE, 2, start_unit },
5807 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5808 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5809 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5810 { "isolate", EQUAL, 2, start_unit },
5811 { "kill", MORE, 2, kill_unit },
5812 { "is-active", MORE, 2, check_unit_active },
5813 { "check", MORE, 2, check_unit_active },
5814 { "is-failed", MORE, 2, check_unit_failed },
5815 { "show", MORE, 1, show },
5816 { "cat", MORE, 2, cat },
5817 { "status", MORE, 1, show },
5818 { "help", MORE, 2, show },
5819 { "snapshot", LESS, 2, snapshot },
5820 { "delete", MORE, 2, delete_snapshot },
5821 { "daemon-reload", EQUAL, 1, daemon_reload },
5822 { "daemon-reexec", EQUAL, 1, daemon_reload },
5823 { "show-environment", EQUAL, 1, show_environment },
5824 { "set-environment", MORE, 2, set_environment },
5825 { "unset-environment", MORE, 2, set_environment },
5826 { "halt", EQUAL, 1, start_special },
5827 { "poweroff", EQUAL, 1, start_special },
5828 { "reboot", EQUAL, 1, start_special },
5829 { "kexec", EQUAL, 1, start_special },
5830 { "suspend", EQUAL, 1, start_special },
5831 { "hibernate", EQUAL, 1, start_special },
5832 { "hybrid-sleep", EQUAL, 1, start_special },
5833 { "default", EQUAL, 1, start_special },
5834 { "rescue", EQUAL, 1, start_special },
5835 { "emergency", EQUAL, 1, start_special },
5836 { "exit", EQUAL, 1, start_special },
5837 { "reset-failed", MORE, 1, reset_failed },
5838 { "enable", MORE, 2, enable_unit },
5839 { "disable", MORE, 2, enable_unit },
5840 { "is-enabled", MORE, 2, unit_is_enabled },
5841 { "reenable", MORE, 2, enable_unit },
5842 { "preset", MORE, 2, enable_unit },
5843 { "mask", MORE, 2, enable_unit },
5844 { "unmask", MORE, 2, enable_unit },
5845 { "link", MORE, 2, enable_unit },
5846 { "switch-root", MORE, 2, switch_root },
5847 { "list-dependencies", LESS, 2, list_dependencies },
5848 { "set-default", EQUAL, 2, set_default },
5849 { "get-default", EQUAL, 1, get_default },
5850 { "set-property", MORE, 3, set_property },
5859 left = argc - optind;
5862 /* Special rule: no arguments means "list-units" */
5865 if (streq(argv[optind], "help") && !argv[optind+1]) {
5866 log_error("This command expects one or more "
5867 "unit names. Did you mean --help?");
5871 for (i = 0; i < ELEMENTSOF(verbs); i++)
5872 if (streq(argv[optind], verbs[i].verb))
5875 if (i >= ELEMENTSOF(verbs)) {
5876 log_error("Unknown operation '%s'.", argv[optind]);
5881 switch (verbs[i].argc_cmp) {
5884 if (left != verbs[i].argc) {
5885 log_error("Invalid number of arguments.");
5892 if (left < verbs[i].argc) {
5893 log_error("Too few arguments.");
5900 if (left > verbs[i].argc) {
5901 log_error("Too many arguments.");
5908 assert_not_reached("Unknown comparison operator.");
5911 /* Require a bus connection for all operations but
5913 if (!streq(verbs[i].verb, "enable") &&
5914 !streq(verbs[i].verb, "disable") &&
5915 !streq(verbs[i].verb, "is-enabled") &&
5916 !streq(verbs[i].verb, "list-unit-files") &&
5917 !streq(verbs[i].verb, "reenable") &&
5918 !streq(verbs[i].verb, "preset") &&
5919 !streq(verbs[i].verb, "mask") &&
5920 !streq(verbs[i].verb, "unmask") &&
5921 !streq(verbs[i].verb, "link") &&
5922 !streq(verbs[i].verb, "set-default") &&
5923 !streq(verbs[i].verb, "get-default")) {
5925 if (running_in_chroot() > 0) {
5926 log_info("Running in chroot, ignoring request.");
5930 if (((!streq(verbs[i].verb, "reboot") &&
5931 !streq(verbs[i].verb, "halt") &&
5932 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5933 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5939 if (!bus && !avoid_bus()) {
5940 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5945 return verbs[i].dispatch(bus, argv + optind);
5948 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5950 struct sd_shutdown_command c = {
5957 union sockaddr_union sockaddr = {
5958 .un.sun_family = AF_UNIX,
5959 .un.sun_path = "/run/systemd/shutdownd",
5962 struct iovec iovec[2] = {{
5963 .iov_base = (char*) &c,
5964 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5967 struct msghdr msghdr = {
5968 .msg_name = &sockaddr,
5969 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5970 + sizeof("/run/systemd/shutdownd") - 1,
5975 _cleanup_close_ int fd;
5977 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5981 if (!isempty(message)) {
5982 iovec[1].iov_base = (char*) message;
5983 iovec[1].iov_len = strlen(message);
5984 msghdr.msg_iovlen++;
5987 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5993 static int reload_with_fallback(sd_bus *bus) {
5996 /* First, try systemd via D-Bus. */
5997 if (daemon_reload(bus, NULL) >= 0)
6001 /* Nothing else worked, so let's try signals */
6002 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6004 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6005 log_error("kill() failed: %m");
6012 static int start_with_fallback(sd_bus *bus) {
6015 /* First, try systemd via D-Bus. */
6016 if (start_unit(bus, NULL) >= 0)
6020 /* Nothing else worked, so let's try
6022 if (talk_initctl() > 0)
6025 log_error("Failed to talk to init daemon.");
6029 warn_wall(arg_action);
6033 static int halt_now(enum action a) {
6035 /* Make sure C-A-D is handled by the kernel from this
6037 reboot(RB_ENABLE_CAD);
6042 log_info("Halting.");
6043 reboot(RB_HALT_SYSTEM);
6046 case ACTION_POWEROFF:
6047 log_info("Powering off.");
6048 reboot(RB_POWER_OFF);
6051 case ACTION_REBOOT: {
6052 _cleanup_free_ char *param = NULL;
6054 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6055 log_info("Rebooting with argument '%s'.", param);
6056 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6057 LINUX_REBOOT_CMD_RESTART2, param);
6060 log_info("Rebooting.");
6061 reboot(RB_AUTOBOOT);
6066 assert_not_reached("Unknown action.");
6070 static int halt_main(sd_bus *bus) {
6073 r = check_inhibitors(bus, arg_action);
6077 if (geteuid() != 0) {
6078 /* Try logind if we are a normal user and no special
6079 * mode applies. Maybe PolicyKit allows us to shutdown
6082 if (arg_when <= 0 &&
6085 (arg_action == ACTION_POWEROFF ||
6086 arg_action == ACTION_REBOOT)) {
6087 r = reboot_with_logind(bus, arg_action);
6092 log_error("Must be root.");
6097 _cleanup_free_ char *m;
6099 m = strv_join(arg_wall, " ");
6103 r = send_shutdownd(arg_when,
6104 arg_action == ACTION_HALT ? 'H' :
6105 arg_action == ACTION_POWEROFF ? 'P' :
6106 arg_action == ACTION_KEXEC ? 'K' :
6113 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6115 char date[FORMAT_TIMESTAMP_MAX];
6117 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6118 format_timestamp(date, sizeof(date), arg_when));
6123 if (!arg_dry && !arg_force)
6124 return start_with_fallback(bus);
6127 if (sd_booted() > 0)
6128 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6130 r = utmp_put_shutdown();
6132 log_warning("Failed to write utmp record: %s", strerror(-r));
6139 r = halt_now(arg_action);
6140 log_error("Failed to reboot: %s", strerror(-r));
6145 static int runlevel_main(void) {
6146 int r, runlevel, previous;
6148 r = utmp_get_runlevel(&runlevel, &previous);
6155 previous <= 0 ? 'N' : previous,
6156 runlevel <= 0 ? 'N' : runlevel);
6161 int main(int argc, char*argv[]) {
6162 _cleanup_bus_unref_ sd_bus *bus = NULL;
6165 setlocale(LC_ALL, "");
6166 log_parse_environment();
6169 /* Explicitly not on_tty() to avoid setting cached value.
6170 * This becomes relevant for piping output which might be
6172 original_stdout_is_tty = isatty(STDOUT_FILENO);
6174 r = parse_argv(argc, argv);
6178 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6179 * let's shortcut this */
6180 if (arg_action == ACTION_RUNLEVEL) {
6181 r = runlevel_main();
6185 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6186 log_info("Running in chroot, ignoring request.");
6192 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6194 /* systemctl_main() will print an error message for the bus
6195 * connection, but only if it needs to */
6197 switch (arg_action) {
6199 case ACTION_SYSTEMCTL:
6200 r = systemctl_main(bus, argc, argv, r);
6204 case ACTION_POWEROFF:
6210 case ACTION_RUNLEVEL2:
6211 case ACTION_RUNLEVEL3:
6212 case ACTION_RUNLEVEL4:
6213 case ACTION_RUNLEVEL5:
6215 case ACTION_EMERGENCY:
6216 case ACTION_DEFAULT:
6217 r = start_with_fallback(bus);
6222 r = reload_with_fallback(bus);
6225 case ACTION_CANCEL_SHUTDOWN: {
6226 _cleanup_free_ char *m = NULL;
6229 m = strv_join(arg_wall, " ");
6236 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6238 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6242 case ACTION_RUNLEVEL:
6243 case _ACTION_INVALID:
6245 assert_not_reached("Unknown action");
6250 ask_password_agent_close();
6251 polkit_agent_close();
6253 strv_free(arg_types);
6254 strv_free(arg_states);
6255 strv_free(arg_properties);
6257 return r < 0 ? EXIT_FAILURE : r;