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) {
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 max_id_len = MAX(max_id_len, strlen(u->id));
329 load_len = MAX(load_len, strlen(u->load_state));
330 active_len = MAX(active_len, strlen(u->active_state));
331 sub_len = MAX(sub_len, strlen(u->sub_state));
333 if (u->job_id != 0) {
334 job_len = MAX(job_len, strlen(u->job_type));
339 if (!arg_full && original_stdout_is_tty) {
342 id_len = MIN(max_id_len, 25u);
343 basic_len = 5 + id_len + 5 + active_len + sub_len;
346 basic_len += job_len + 1;
348 if (basic_len < (unsigned) columns()) {
349 unsigned extra_len, incr;
350 extra_len = columns() - basic_len;
352 /* Either UNIT already got 25, or is fully satisfied.
353 * Grant up to 25 to DESC now. */
354 incr = MIN(extra_len, 25u);
358 /* split the remaining space between UNIT and DESC,
359 * but do not give UNIT more than it needs. */
361 incr = MIN(extra_len / 2, max_id_len - id_len);
363 desc_len += extra_len - incr;
369 for (u = unit_infos; u < unit_infos + c; u++) {
370 _cleanup_free_ char *e = NULL;
371 const char *on_loaded, *off_loaded, *on = "";
372 const char *on_active, *off_active, *off = "";
374 if (!n_shown && !arg_no_legend) {
375 printf("%-*s %-*s %-*s %-*s ",
378 active_len, "ACTIVE",
382 printf("%-*s ", job_len, "JOB");
384 if (!arg_full && arg_no_pager)
385 printf("%.*s\n", desc_len, "DESCRIPTION");
387 printf("%s\n", "DESCRIPTION");
392 if (streq(u->load_state, "error") ||
393 streq(u->load_state, "not-found")) {
394 on_loaded = on = ansi_highlight_red();
395 off_loaded = off = ansi_highlight_off();
397 on_loaded = off_loaded = "";
399 if (streq(u->active_state, "failed")) {
400 on_active = on = ansi_highlight_red();
401 off_active = off = ansi_highlight_off();
403 on_active = off_active = "";
405 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
407 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
408 on, id_len, e ? e : u->id, off,
409 on_loaded, load_len, u->load_state, off_loaded,
410 on_active, active_len, u->active_state,
411 sub_len, u->sub_state, off_active,
412 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
415 printf("%.*s\n", desc_len, u->description);
417 printf("%s\n", u->description);
420 if (!arg_no_legend) {
421 const char *on, *off;
424 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
425 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
426 "SUB = The low-level unit activation state, values depend on unit type.\n");
428 printf("JOB = Pending job for the unit.\n");
430 on = ansi_highlight();
431 off = ansi_highlight_off();
433 on = ansi_highlight_red();
434 off = ansi_highlight_off();
438 printf("%s%u loaded units listed.%s\n"
439 "To show all installed unit files use 'systemctl list-unit-files'.\n",
442 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
443 "To show all installed unit files use 'systemctl list-unit-files'.\n",
448 static int get_unit_list(
450 sd_bus_message **_reply,
451 UnitInfo **_unit_infos,
454 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
455 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
456 _cleanup_free_ UnitInfo *unit_infos = NULL;
465 r = sd_bus_call_method(
467 "org.freedesktop.systemd1",
468 "/org/freedesktop/systemd1",
469 "org.freedesktop.systemd1.Manager",
475 log_error("Failed to list units: %s", bus_error_message(&error, r));
479 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
481 return bus_log_parse_error(r);
483 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
484 if (!output_show_unit(&u, patterns))
487 if (!GREEDY_REALLOC(unit_infos, size, c+1))
493 return bus_log_parse_error(r);
495 r = sd_bus_message_exit_container(reply);
497 return bus_log_parse_error(r);
502 *_unit_infos = unit_infos;
508 static int list_units(sd_bus *bus, char **args) {
509 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
510 _cleanup_free_ UnitInfo *unit_infos = NULL;
513 pager_open_if_enabled();
515 r = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
519 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
520 output_units_list(unit_infos, r);
525 static int get_triggered_units(
530 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
533 r = sd_bus_get_property_strv(
535 "org.freedesktop.systemd1",
537 "org.freedesktop.systemd1.Unit",
543 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
548 static int get_listening(
550 const char* unit_path,
553 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
554 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
555 const char *type, *path;
558 r = sd_bus_get_property(
560 "org.freedesktop.systemd1",
562 "org.freedesktop.systemd1.Socket",
568 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
572 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
574 return bus_log_parse_error(r);
576 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
578 r = strv_extend(listening, type);
582 r = strv_extend(listening, path);
589 return bus_log_parse_error(r);
591 r = sd_bus_message_exit_container(reply);
593 return bus_log_parse_error(r);
604 /* Note: triggered is a list here, although it almost certainly
605 * will always be one unit. Nevertheless, dbus API allows for multiple
606 * values, so let's follow that.*/
609 /* The strv above is shared. free is set only in the first one. */
613 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
619 o = strcmp(a->path, b->path);
621 o = strcmp(a->type, b->type);
626 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
627 struct socket_info *s;
628 unsigned pathlen = sizeof("LISTEN") - 1,
629 typelen = (sizeof("TYPE") - 1) * arg_show_types,
630 socklen = sizeof("UNIT") - 1,
631 servlen = sizeof("ACTIVATES") - 1;
632 const char *on, *off;
634 for (s = socket_infos; s < socket_infos + cs; s++) {
638 socklen = MAX(socklen, strlen(s->id));
640 typelen = MAX(typelen, strlen(s->type));
641 pathlen = MAX(pathlen, strlen(s->path));
643 STRV_FOREACH(a, s->triggered)
644 tmp += strlen(*a) + 2*(a != s->triggered);
645 servlen = MAX(servlen, tmp);
650 printf("%-*s %-*.*s%-*s %s\n",
652 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
656 for (s = socket_infos; s < socket_infos + cs; s++) {
660 printf("%-*s %-*s %-*s",
661 pathlen, s->path, typelen, s->type, socklen, s->id);
664 pathlen, s->path, socklen, s->id);
665 STRV_FOREACH(a, s->triggered)
667 a == s->triggered ? "" : ",", *a);
671 on = ansi_highlight();
672 off = ansi_highlight_off();
676 on = ansi_highlight_red();
677 off = ansi_highlight_off();
680 if (!arg_no_legend) {
681 printf("%s%u sockets listed.%s\n", on, cs, off);
683 printf("Pass --all to see loaded but inactive sockets, too.\n");
689 static int list_sockets(sd_bus *bus, char **args) {
690 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
691 _cleanup_free_ UnitInfo *unit_infos = NULL;
692 _cleanup_free_ struct socket_info *socket_infos = NULL;
694 struct socket_info *s;
699 pager_open_if_enabled();
701 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
705 for (u = unit_infos; u < unit_infos + n; u++) {
706 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
709 if (!endswith(u->id, ".socket"))
712 r = get_triggered_units(bus, u->unit_path, &triggered);
716 c = get_listening(bus, u->unit_path, &listening);
722 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
727 for (i = 0; i < c; i++)
728 socket_infos[cs + i] = (struct socket_info) {
730 .type = listening[i*2],
731 .path = listening[i*2 + 1],
732 .triggered = triggered,
733 .own_triggered = i==0,
736 /* from this point on we will cleanup those socket_infos */
739 listening = triggered = NULL; /* avoid cleanup */
742 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
743 (__compar_fn_t) socket_info_compare);
745 output_sockets_list(socket_infos, cs);
748 assert(cs == 0 || socket_infos);
749 for (s = socket_infos; s < socket_infos + cs; s++) {
752 if (s->own_triggered)
753 strv_free(s->triggered);
759 static int get_next_elapse(
762 dual_timestamp *next) {
764 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
772 r = sd_bus_get_property_trivial(
774 "org.freedesktop.systemd1",
776 "org.freedesktop.systemd1.Timer",
777 "NextElapseUSecMonotonic",
782 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
786 r = sd_bus_get_property_trivial(
788 "org.freedesktop.systemd1",
790 "org.freedesktop.systemd1.Timer",
791 "NextElapseUSecRealtime",
796 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
810 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
814 if (a->next_elapse < b->next_elapse)
816 if (a->next_elapse > b->next_elapse)
819 return strcmp(a->id, b->id);
822 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
823 struct timer_info *t;
825 nextlen = sizeof("NEXT") - 1,
826 leftlen = sizeof("LEFT") - 1,
827 unitlen = sizeof("UNIT") - 1,
828 activatelen = sizeof("ACTIVATES") - 1;
830 const char *on, *off;
832 assert(timer_infos || n == 0);
834 for (t = timer_infos; t < timer_infos + n; t++) {
838 if (t->next_elapse > 0) {
839 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
841 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
842 nextlen = MAX(nextlen, strlen(tstamp) + 1);
844 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
845 leftlen = MAX(leftlen, strlen(trel));
848 unitlen = MAX(unitlen, strlen(t->id));
850 STRV_FOREACH(a, t->triggered)
851 ul += strlen(*a) + 2*(a != t->triggered);
852 activatelen = MAX(activatelen, ul);
857 printf("%-*s %-*s %-*s %s\n",
863 for (t = timer_infos; t < timer_infos + n; t++) {
864 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
867 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
868 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
870 printf("%-*s %-*s %-*s",
871 nextlen, tstamp, leftlen, trel, unitlen, t->id);
873 STRV_FOREACH(a, t->triggered)
875 a == t->triggered ? "" : ",", *a);
879 on = ansi_highlight();
880 off = ansi_highlight_off();
884 on = ansi_highlight_red();
885 off = ansi_highlight_off();
888 if (!arg_no_legend) {
889 printf("%s%u timers listed.%s\n", on, n, off);
891 printf("Pass --all to see loaded but inactive timers, too.\n");
897 static int list_timers(sd_bus *bus, char **args) {
899 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
900 _cleanup_free_ struct timer_info *timer_infos = NULL;
901 _cleanup_free_ UnitInfo *unit_infos = NULL;
902 struct timer_info *t;
909 pager_open_if_enabled();
911 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
915 dual_timestamp_get(&nw);
917 for (u = unit_infos; u < unit_infos + n; u++) {
918 _cleanup_strv_free_ char **triggered = NULL;
922 if (!endswith(u->id, ".timer"))
925 r = get_triggered_units(bus, u->unit_path, &triggered);
929 r = get_next_elapse(bus, u->unit_path, &next);
933 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
936 if (next.monotonic > nw.monotonic)
937 converted = nw.realtime + (next.monotonic - nw.monotonic);
939 converted = nw.realtime - (nw.monotonic - next.monotonic);
941 if (next.realtime != (usec_t) -1 && next.realtime > 0)
942 m = MIN(converted, next.realtime);
948 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
953 timer_infos[c++] = (struct timer_info) {
956 .triggered = triggered,
959 triggered = NULL; /* avoid cleanup */
962 qsort_safe(timer_infos, c, sizeof(struct timer_info),
963 (__compar_fn_t) timer_info_compare);
965 output_timers_list(timer_infos, c);
968 for (t = timer_infos; t < timer_infos + c; t++)
969 strv_free(t->triggered);
974 static int compare_unit_file_list(const void *a, const void *b) {
976 const UnitFileList *u = a, *v = b;
978 d1 = strrchr(u->path, '.');
979 d2 = strrchr(v->path, '.');
984 r = strcasecmp(d1, d2);
989 return strcasecmp(basename(u->path), basename(v->path));
992 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
995 if (!strv_isempty(patterns)) {
998 STRV_FOREACH(pattern, patterns)
999 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1004 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1007 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1008 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
1009 const UnitFileList *u;
1011 max_id_len = sizeof("UNIT FILE")-1;
1012 state_cols = sizeof("STATE")-1;
1014 for (u = units; u < units + c; u++) {
1015 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1016 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1020 unsigned basic_cols;
1022 id_cols = MIN(max_id_len, 25u);
1023 basic_cols = 1 + id_cols + state_cols;
1024 if (basic_cols < (unsigned) columns())
1025 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1027 id_cols = max_id_len;
1030 printf("%-*s %-*s\n",
1031 id_cols, "UNIT FILE",
1032 state_cols, "STATE");
1034 for (u = units; u < units + c; u++) {
1035 _cleanup_free_ char *e = NULL;
1036 const char *on, *off;
1041 if (u->state == UNIT_FILE_MASKED ||
1042 u->state == UNIT_FILE_MASKED_RUNTIME ||
1043 u->state == UNIT_FILE_DISABLED ||
1044 u->state == UNIT_FILE_INVALID) {
1045 on = ansi_highlight_red();
1046 off = ansi_highlight_off();
1047 } else if (u->state == UNIT_FILE_ENABLED) {
1048 on = ansi_highlight_green();
1049 off = ansi_highlight_off();
1053 id = basename(u->path);
1055 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1057 printf("%-*s %s%-*s%s\n",
1058 id_cols, e ? e : id,
1059 on, state_cols, unit_file_state_to_string(u->state), off);
1063 printf("\n%u unit files listed.\n", n_shown);
1066 static int list_unit_files(sd_bus *bus, char **args) {
1067 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1068 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1069 _cleanup_free_ UnitFileList *units = NULL;
1077 pager_open_if_enabled();
1085 h = hashmap_new(string_hash_func, string_compare_func);
1089 r = unit_file_get_list(arg_scope, arg_root, h);
1091 unit_file_list_free(h);
1092 log_error("Failed to get unit file list: %s", strerror(-r));
1096 n_units = hashmap_size(h);
1097 units = new(UnitFileList, n_units);
1099 unit_file_list_free(h);
1103 HASHMAP_FOREACH(u, h, i) {
1104 if (!output_show_unit_file(u, strv_skip_first(args)))
1111 assert(c <= n_units);
1114 r = sd_bus_call_method(
1116 "org.freedesktop.systemd1",
1117 "/org/freedesktop/systemd1",
1118 "org.freedesktop.systemd1.Manager",
1124 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1128 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1130 return bus_log_parse_error(r);
1132 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1134 if (!GREEDY_REALLOC(units, size, c + 1))
1137 units[c] = (struct UnitFileList) {
1139 unit_file_state_from_string(state)
1142 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1147 return bus_log_parse_error(r);
1149 r = sd_bus_message_exit_container(reply);
1151 return bus_log_parse_error(r);
1155 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1156 output_unit_file_list(units, c);
1160 for (unit = units; unit < units + c; unit++)
1166 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1167 _cleanup_free_ char *n = NULL;
1168 size_t max_len = MAX(columns(),20u);
1174 for (i = level - 1; i >= 0; i--) {
1176 if (len > max_len - 3 && !arg_full) {
1177 printf("%s...\n",max_len % 2 ? "" : " ");
1180 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1184 if (len > max_len - 3 && !arg_full) {
1185 printf("%s...\n",max_len % 2 ? "" : " ");
1189 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1193 printf("%s\n", name);
1197 n = ellipsize(name, max_len-len, 100);
1205 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1207 static const char *dependencies[_DEPENDENCY_MAX] = {
1208 [DEPENDENCY_FORWARD] = "Requires\0"
1209 "RequiresOverridable\0"
1211 "RequisiteOverridable\0"
1213 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1214 "RequiredByOverridable\0"
1217 [DEPENDENCY_AFTER] = "After\0",
1218 [DEPENDENCY_BEFORE] = "Before\0",
1221 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1222 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1223 _cleanup_strv_free_ char **ret = NULL;
1224 _cleanup_free_ char *path = NULL;
1230 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1232 path = unit_dbus_path_from_name(name);
1236 r = sd_bus_call_method(
1238 "org.freedesktop.systemd1",
1240 "org.freedesktop.DBus.Properties",
1244 "s", "org.freedesktop.systemd1.Unit");
1246 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1250 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1252 return bus_log_parse_error(r);
1254 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1257 r = sd_bus_message_read(reply, "s", &prop);
1259 return bus_log_parse_error(r);
1261 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1262 r = sd_bus_message_skip(reply, "v");
1264 return bus_log_parse_error(r);
1267 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1269 return bus_log_parse_error(r);
1271 r = bus_message_read_strv_extend(reply, &ret);
1273 return bus_log_parse_error(r);
1275 r = sd_bus_message_exit_container(reply);
1277 return bus_log_parse_error(r);
1280 r = sd_bus_message_exit_container(reply);
1282 return bus_log_parse_error(r);
1286 return bus_log_parse_error(r);
1288 r = sd_bus_message_exit_container(reply);
1290 return bus_log_parse_error(r);
1298 static int list_dependencies_compare(const void *_a, const void *_b) {
1299 const char **a = (const char**) _a, **b = (const char**) _b;
1301 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1303 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1306 return strcasecmp(*a, *b);
1309 static int list_dependencies_one(
1314 unsigned int branches) {
1316 _cleanup_strv_free_ char **deps = NULL, **u;
1324 u = strv_append(*units, name);
1328 r = list_dependencies_get_dependencies(bus, name, &deps);
1332 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1334 STRV_FOREACH(c, deps) {
1337 if (strv_contains(u, *c)) {
1339 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1346 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1348 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1350 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1352 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1356 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1357 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1372 static int list_dependencies(sd_bus *bus, char **args) {
1373 _cleanup_strv_free_ char **units = NULL;
1374 _cleanup_free_ char *unit = NULL;
1380 unit = unit_name_mangle(args[1]);
1385 u = SPECIAL_DEFAULT_TARGET;
1387 pager_open_if_enabled();
1391 return list_dependencies_one(bus, u, 0, &units, 0);
1394 static int get_default(sd_bus *bus, char **args) {
1395 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1396 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1397 _cleanup_free_ char *_path = NULL;
1401 if (!bus || avoid_bus()) {
1402 r = unit_file_get_default(arg_scope, arg_root, &_path);
1404 log_error("Failed to get default target: %s", strerror(-r));
1410 r = sd_bus_call_method(
1412 "org.freedesktop.systemd1",
1413 "/org/freedesktop/systemd1",
1414 "org.freedesktop.systemd1.Manager",
1420 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1424 r = sd_bus_message_read(reply, "s", &path);
1426 return bus_log_parse_error(r);
1430 printf("%s\n", path);
1435 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1438 assert(changes || n_changes == 0);
1440 for (i = 0; i < n_changes; i++) {
1441 if (changes[i].type == UNIT_FILE_SYMLINK)
1442 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1444 log_info("rm '%s'", changes[i].path);
1448 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1449 const char *type, *path, *source;
1452 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1454 return bus_log_parse_error(r);
1456 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1458 if (streq(type, "symlink"))
1459 log_info("ln -s '%s' '%s'", source, path);
1461 log_info("rm '%s'", path);
1465 return bus_log_parse_error(r);
1467 r = sd_bus_message_exit_container(m);
1469 return bus_log_parse_error(r);
1474 static int set_default(sd_bus *bus, char **args) {
1475 _cleanup_free_ char *unit = NULL;
1476 UnitFileChange *changes = NULL;
1477 unsigned n_changes = 0;
1480 unit = unit_name_mangle_with_suffix(args[1], ".target");
1484 if (!bus || avoid_bus()) {
1485 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1487 log_error("Failed to set default target: %s", strerror(-r));
1492 dump_unit_file_changes(changes, n_changes);
1496 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1497 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1499 r = sd_bus_call_method(
1501 "org.freedesktop.systemd1",
1502 "/org/freedesktop/systemd1",
1503 "org.freedesktop.systemd1.Manager",
1507 "sb", unit, arg_force);
1509 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1513 r = deserialize_and_dump_unit_file_changes(reply);
1517 /* Try to reload if enabeld */
1519 r = daemon_reload(bus, args);
1524 unit_file_changes_free(changes, n_changes);
1531 const char *name, *type, *state;
1534 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1535 unsigned id_len, unit_len, type_len, state_len;
1536 const struct job_info *j;
1537 const char *on, *off;
1538 bool shorten = false;
1540 assert(n == 0 || jobs);
1543 on = ansi_highlight_green();
1544 off = ansi_highlight_off();
1546 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1550 pager_open_if_enabled();
1552 id_len = sizeof("JOB")-1;
1553 unit_len = sizeof("UNIT")-1;
1554 type_len = sizeof("TYPE")-1;
1555 state_len = sizeof("STATE")-1;
1557 for (j = jobs; j < jobs + n; j++) {
1558 uint32_t id = j->id;
1559 assert(j->name && j->type && j->state);
1561 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1562 unit_len = MAX(unit_len, strlen(j->name));
1563 type_len = MAX(type_len, strlen(j->type));
1564 state_len = MAX(state_len, strlen(j->state));
1567 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1568 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1573 printf("%*s %-*s %-*s %-*s\n",
1577 state_len, "STATE");
1579 for (j = jobs; j < jobs + n; j++) {
1580 _cleanup_free_ char *e = NULL;
1582 if (streq(j->state, "running")) {
1583 on = ansi_highlight();
1584 off = ansi_highlight_off();
1588 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1589 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1591 on, unit_len, e ? e : j->name, off,
1593 on, state_len, j->state, off);
1596 if (!arg_no_legend) {
1597 on = ansi_highlight();
1598 off = ansi_highlight_off();
1600 printf("\n%s%u jobs listed%s.\n", on, n, off);
1604 static bool output_show_job(struct job_info *job, char **patterns) {
1605 if (!strv_isempty(patterns)) {
1608 STRV_FOREACH(pattern, patterns)
1609 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1617 static int list_jobs(sd_bus *bus, char **args) {
1618 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1619 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1620 const char *name, *type, *state, *job_path, *unit_path;
1621 _cleanup_free_ struct job_info *jobs = NULL;
1626 bool skipped = false;
1628 r = sd_bus_call_method(
1630 "org.freedesktop.systemd1",
1631 "/org/freedesktop/systemd1",
1632 "org.freedesktop.systemd1.Manager",
1638 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1642 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1644 return bus_log_parse_error(r);
1646 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1647 struct job_info job = { id, name, type, state };
1649 if (!output_show_job(&job, strv_skip_first(args))) {
1654 if (!GREEDY_REALLOC(jobs, size, c + 1))
1660 return bus_log_parse_error(r);
1662 r = sd_bus_message_exit_container(reply);
1664 return bus_log_parse_error(r);
1666 output_jobs_list(jobs, c, skipped);
1670 static int cancel_job(sd_bus *bus, char **args) {
1671 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1676 if (strv_length(args) <= 1)
1677 return daemon_reload(bus, args);
1679 STRV_FOREACH(name, args+1) {
1683 r = safe_atou32(*name, &id);
1685 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1689 r = sd_bus_call_method(
1691 "org.freedesktop.systemd1",
1692 "/org/freedesktop/systemd1",
1693 "org.freedesktop.systemd1.Manager",
1699 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1707 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1708 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1709 _cleanup_free_ char *n = NULL;
1713 /* We ignore all errors here, since this is used to show a
1716 n = unit_name_mangle(unit);
1720 /* We don't use unit_dbus_path_from_name() directly since we
1721 * don't want to load the unit if it isn't loaded. */
1723 r = sd_bus_call_method(
1725 "org.freedesktop.systemd1",
1726 "/org/freedesktop/systemd1",
1727 "org.freedesktop.systemd1.Manager",
1735 r = sd_bus_message_read(reply, "o", &path);
1739 r = sd_bus_get_property_trivial(
1741 "org.freedesktop.systemd1",
1743 "org.freedesktop.systemd1.Unit",
1753 typedef struct WaitData {
1760 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1767 log_debug("Got D-Bus request: %s.%s() on %s",
1768 sd_bus_message_get_interface(m),
1769 sd_bus_message_get_member(m),
1770 sd_bus_message_get_path(m));
1772 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1773 log_error("Warning! D-Bus connection terminated.");
1775 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1777 const char *path, *result, *unit;
1781 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1783 ret = set_remove(d->set, (char*) path);
1789 if (!isempty(result))
1790 d->result = strdup(result);
1793 d->name = strdup(unit);
1798 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1800 ret = set_remove(d->set, (char*) path);
1807 d->result = strdup(result);
1813 bus_log_parse_error(r);
1819 static int enable_wait_for_jobs(sd_bus *bus) {
1824 r = sd_bus_add_match(
1827 "sender='org.freedesktop.systemd1',"
1828 "interface='org.freedesktop.systemd1.Manager',"
1829 "member='JobRemoved',"
1830 "path='/org/freedesktop/systemd1'",
1833 log_error("Failed to add match");
1837 /* This is slightly dirty, since we don't undo the match registrations. */
1841 static int bus_process_wait(sd_bus *bus) {
1845 r = sd_bus_process(bus, NULL);
1850 r = sd_bus_wait(bus, (uint64_t) -1);
1856 static int check_wait_response(WaitData *d) {
1862 if (streq(d->result, "timeout"))
1863 log_error("Job for %s timed out.", strna(d->name));
1864 else if (streq(d->result, "canceled"))
1865 log_error("Job for %s canceled.", strna(d->name));
1866 else if (streq(d->result, "dependency"))
1867 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1868 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1869 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1872 if (streq(d->result, "timeout"))
1874 else if (streq(d->result, "canceled"))
1876 else if (streq(d->result, "dependency"))
1878 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1884 static int wait_for_jobs(sd_bus *bus, Set *s) {
1885 WaitData d = { .set = s };
1891 q = sd_bus_add_filter(bus, wait_filter, &d);
1895 while (!set_isempty(s)) {
1896 q = bus_process_wait(bus);
1901 q = check_wait_response(&d);
1902 /* Return the first error as it is most likely to be
1904 if (q < 0 && r == 0)
1915 q = sd_bus_remove_filter(bus, wait_filter, &d);
1916 if (q < 0 && r == 0)
1922 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1923 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1924 _cleanup_free_ char *n = NULL, *state = NULL;
1930 n = unit_name_mangle(name);
1934 /* We don't use unit_dbus_path_from_name() directly since we
1935 * don't want to load the unit if it isn't loaded. */
1937 r = sd_bus_call_method(
1939 "org.freedesktop.systemd1",
1940 "/org/freedesktop/systemd1",
1941 "org.freedesktop.systemd1.Manager",
1952 r = sd_bus_message_read(reply, "o", &path);
1954 return bus_log_parse_error(r);
1956 r = sd_bus_get_property_string(
1958 "org.freedesktop.systemd1",
1960 "org.freedesktop.systemd1.Unit",
1973 return nulstr_contains(good_states, state);
1976 static int check_triggering_units(
1980 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1981 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1982 _cleanup_strv_free_ char **triggered_by = NULL;
1983 bool print_warning_label = true;
1987 n = unit_name_mangle(name);
1991 path = unit_dbus_path_from_name(n);
1995 r = sd_bus_get_property_string(
1997 "org.freedesktop.systemd1",
1999 "org.freedesktop.systemd1.Unit",
2004 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2008 if (streq(state, "masked"))
2011 r = sd_bus_get_property_strv(
2013 "org.freedesktop.systemd1",
2015 "org.freedesktop.systemd1.Unit",
2020 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2024 STRV_FOREACH(i, triggered_by) {
2025 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2027 log_error("Failed to check unit: %s", strerror(-r));
2034 if (print_warning_label) {
2035 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2036 print_warning_label = false;
2039 log_warning(" %s", *i);
2045 static int start_unit_one(
2050 sd_bus_error *error,
2053 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2054 _cleanup_free_ char *n;
2063 n = unit_name_mangle(name);
2067 r = sd_bus_call_method(
2069 "org.freedesktop.systemd1",
2070 "/org/freedesktop/systemd1",
2071 "org.freedesktop.systemd1.Manager",
2077 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2078 /* There's always a fallback possible for
2079 * legacy actions. */
2080 return -EADDRNOTAVAIL;
2082 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
2086 r = sd_bus_message_read(reply, "o", &path);
2088 return bus_log_parse_error(r);
2090 if (need_daemon_reload(bus, n) > 0)
2091 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2092 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2101 r = set_consume(s, p);
2109 static const struct {
2113 } action_table[_ACTION_MAX] = {
2114 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2115 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2116 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2117 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2118 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2119 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2120 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2121 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2122 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2123 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2124 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2125 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2126 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2127 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2128 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2131 static enum action verb_to_action(const char *verb) {
2134 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2135 if (streq_ptr(action_table[i].verb, verb))
2138 return _ACTION_INVALID;
2141 static int start_unit(sd_bus *bus, char **args) {
2142 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2143 _cleanup_set_free_free_ Set *s = NULL;
2144 const char *method, *mode;
2147 char **names, *strv[] = {NULL, NULL}; /* at most one name */
2151 ask_password_agent_open_if_enabled();
2153 if (arg_action == ACTION_SYSTEMCTL) {
2156 streq(args[0], "stop") ||
2157 streq(args[0], "condstop") ? "StopUnit" :
2158 streq(args[0], "reload") ? "ReloadUnit" :
2159 streq(args[0], "restart") ? "RestartUnit" :
2161 streq(args[0], "try-restart") ||
2162 streq(args[0], "condrestart") ? "TryRestartUnit" :
2164 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2166 streq(args[0], "reload-or-try-restart") ||
2167 streq(args[0], "condreload") ||
2168 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2170 action = verb_to_action(args[0]);
2172 mode = streq(args[0], "isolate") ? "isolate" :
2173 action_table[action].mode ?: arg_job_mode;
2175 strv[0] = (char*) action_table[action].target;
2177 assert(arg_action < ELEMENTSOF(action_table));
2178 assert(action_table[arg_action].target);
2180 method = "StartUnit";
2182 mode = action_table[arg_action].mode;
2183 strv[0] = (char*) action_table[arg_action].target;
2191 if (!arg_no_block) {
2192 r = enable_wait_for_jobs(bus);
2194 log_error("Could not watch jobs: %s", strerror(-r));
2198 s = set_new(string_hash_func, string_compare_func);
2203 STRV_FOREACH(name, names) {
2206 q = start_unit_one(bus, method, *name, mode, &error, s);
2207 if (r == 0 && q < 0) {
2208 r = translate_bus_error_to_exit_status(q, &error);
2209 sd_bus_error_free(&error);
2213 if (!arg_no_block) {
2216 q = wait_for_jobs(bus, s);
2220 /* When stopping units, warn if they can still be triggered by
2221 * another active unit (socket, path, timer) */
2222 if (!arg_quiet && streq(method, "StopUnit"))
2223 STRV_FOREACH(name, names)
2224 check_triggering_units(bus, *name);
2230 /* Ask systemd-logind, which might grant access to unprivileged users
2231 * through PolicyKit */
2232 static int reboot_with_logind(sd_bus *bus, enum action a) {
2234 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2241 polkit_agent_open_if_enabled();
2249 case ACTION_POWEROFF:
2250 method = "PowerOff";
2253 case ACTION_SUSPEND:
2257 case ACTION_HIBERNATE:
2258 method = "Hibernate";
2261 case ACTION_HYBRID_SLEEP:
2262 method = "HybridSleep";
2269 r = sd_bus_call_method(
2271 "org.freedesktop.login1",
2272 "/org/freedesktop/login1",
2273 "org.freedesktop.login1.Manager",
2279 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2287 static int check_inhibitors(sd_bus *bus, enum action a) {
2289 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2290 _cleanup_strv_free_ char **sessions = NULL;
2291 const char *what, *who, *why, *mode;
2300 if (arg_ignore_inhibitors || arg_force > 0)
2312 r = sd_bus_call_method(
2314 "org.freedesktop.login1",
2315 "/org/freedesktop/login1",
2316 "org.freedesktop.login1.Manager",
2322 /* If logind is not around, then there are no inhibitors... */
2325 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2327 return bus_log_parse_error(r);
2329 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2330 _cleanup_free_ char *comm = NULL, *user = NULL;
2331 _cleanup_strv_free_ char **sv = NULL;
2333 if (!streq(mode, "block"))
2336 sv = strv_split(what, ":");
2340 if (!strv_contains(sv,
2342 a == ACTION_POWEROFF ||
2343 a == ACTION_REBOOT ||
2344 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2347 get_process_comm(pid, &comm);
2348 user = uid_to_name(uid);
2350 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2351 who, (unsigned long) pid, strna(comm), strna(user), why);
2356 return bus_log_parse_error(r);
2358 r = sd_bus_message_exit_container(reply);
2360 return bus_log_parse_error(r);
2362 /* Check for current sessions */
2363 sd_get_sessions(&sessions);
2364 STRV_FOREACH(s, sessions) {
2365 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2367 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2370 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2373 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2376 sd_session_get_tty(*s, &tty);
2377 sd_session_get_seat(*s, &seat);
2378 sd_session_get_service(*s, &service);
2379 user = uid_to_name(uid);
2381 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2388 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2389 action_table[a].verb);
2397 static int start_special(sd_bus *bus, char **args) {
2403 a = verb_to_action(args[0]);
2405 r = check_inhibitors(bus, a);
2409 if (arg_force >= 2 && geteuid() != 0) {
2410 log_error("Must be root.");
2414 if (arg_force >= 2 &&
2415 (a == ACTION_HALT ||
2416 a == ACTION_POWEROFF ||
2417 a == ACTION_REBOOT))
2420 if (arg_force >= 1 &&
2421 (a == ACTION_HALT ||
2422 a == ACTION_POWEROFF ||
2423 a == ACTION_REBOOT ||
2424 a == ACTION_KEXEC ||
2426 return daemon_reload(bus, args);
2428 /* first try logind, to allow authentication with polkit */
2429 if (geteuid() != 0 &&
2430 (a == ACTION_POWEROFF ||
2431 a == ACTION_REBOOT ||
2432 a == ACTION_SUSPEND ||
2433 a == ACTION_HIBERNATE ||
2434 a == ACTION_HYBRID_SLEEP)) {
2435 r = reboot_with_logind(bus, a);
2440 r = start_unit(bus, args);
2441 if (r == EXIT_SUCCESS)
2447 static int check_unit_active(sd_bus *bus, char **args) {
2449 int r = 3; /* According to LSB: "program is not running" */
2454 STRV_FOREACH(name, args+1) {
2457 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2467 static int check_unit_failed(sd_bus *bus, char **args) {
2474 STRV_FOREACH(name, args+1) {
2477 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2487 static int kill_unit(sd_bus *bus, char **args) {
2488 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2496 arg_kill_who = "all";
2498 STRV_FOREACH(name, args+1) {
2499 _cleanup_free_ char *n = NULL;
2501 n = unit_name_mangle(*name);
2505 r = sd_bus_call_method(
2507 "org.freedesktop.systemd1",
2508 "/org/freedesktop/systemd1",
2509 "org.freedesktop.systemd1.Manager",
2513 "ssi", n, arg_kill_who, arg_signal);
2515 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2523 typedef struct ExecStatusInfo {
2531 usec_t start_timestamp;
2532 usec_t exit_timestamp;
2537 LIST_FIELDS(struct ExecStatusInfo, exec);
2540 static void exec_status_info_free(ExecStatusInfo *i) {
2549 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2550 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2553 int32_t code, status;
2559 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2561 return bus_log_parse_error(r);
2565 r = sd_bus_message_read(m, "s", &path);
2567 return bus_log_parse_error(r);
2569 i->path = strdup(path);
2573 r = sd_bus_message_read_strv(m, &i->argv);
2575 return bus_log_parse_error(r);
2577 r = sd_bus_message_read(m,
2580 &start_timestamp, &start_timestamp_monotonic,
2581 &exit_timestamp, &exit_timestamp_monotonic,
2585 return bus_log_parse_error(r);
2588 i->start_timestamp = (usec_t) start_timestamp;
2589 i->exit_timestamp = (usec_t) exit_timestamp;
2590 i->pid = (pid_t) pid;
2594 r = sd_bus_message_exit_container(m);
2596 return bus_log_parse_error(r);
2601 typedef struct UnitStatusInfo {
2603 const char *load_state;
2604 const char *active_state;
2605 const char *sub_state;
2606 const char *unit_file_state;
2608 const char *description;
2609 const char *following;
2611 char **documentation;
2613 const char *fragment_path;
2614 const char *source_path;
2615 const char *control_group;
2617 char **dropin_paths;
2619 const char *load_error;
2622 usec_t inactive_exit_timestamp;
2623 usec_t inactive_exit_timestamp_monotonic;
2624 usec_t active_enter_timestamp;
2625 usec_t active_exit_timestamp;
2626 usec_t inactive_enter_timestamp;
2628 bool need_daemon_reload;
2633 const char *status_text;
2634 const char *pid_file;
2637 usec_t start_timestamp;
2638 usec_t exit_timestamp;
2640 int exit_code, exit_status;
2642 usec_t condition_timestamp;
2643 bool condition_result;
2644 bool failed_condition_trigger;
2645 bool failed_condition_negate;
2646 const char *failed_condition;
2647 const char *failed_condition_param;
2650 unsigned n_accepted;
2651 unsigned n_connections;
2654 /* Pairs of type, path */
2658 const char *sysfs_path;
2660 /* Mount, Automount */
2666 LIST_HEAD(ExecStatusInfo, exec);
2669 static void print_status_info(
2674 const char *on, *off, *ss;
2676 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2677 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2680 arg_all * OUTPUT_SHOW_ALL |
2681 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2682 on_tty() * OUTPUT_COLOR |
2683 !arg_quiet * OUTPUT_WARN_CUTOFF |
2684 arg_full * OUTPUT_FULL_WIDTH;
2689 /* This shows pretty information about a unit. See
2690 * print_property() for a low-level property printer */
2692 printf("%s", strna(i->id));
2694 if (i->description && !streq_ptr(i->id, i->description))
2695 printf(" - %s", i->description);
2700 printf(" Follow: unit currently follows state of %s\n", i->following);
2702 if (streq_ptr(i->load_state, "error")) {
2703 on = ansi_highlight_red();
2704 off = ansi_highlight_off();
2708 path = i->source_path ? i->source_path : i->fragment_path;
2711 printf(" Loaded: %s%s%s (Reason: %s)\n",
2712 on, strna(i->load_state), off, i->load_error);
2713 else if (path && i->unit_file_state)
2714 printf(" Loaded: %s%s%s (%s; %s)\n",
2715 on, strna(i->load_state), off, path, i->unit_file_state);
2717 printf(" Loaded: %s%s%s (%s)\n",
2718 on, strna(i->load_state), off, path);
2720 printf(" Loaded: %s%s%s\n",
2721 on, strna(i->load_state), off);
2723 if (!strv_isempty(i->dropin_paths)) {
2724 _cleanup_free_ char *dir = NULL;
2728 STRV_FOREACH(dropin, i->dropin_paths) {
2729 if (! dir || last) {
2730 printf(dir ? " " : " Drop-In: ");
2735 if (path_get_parent(*dropin, &dir) < 0) {
2740 printf("%s\n %s", dir,
2741 draw_special_char(DRAW_TREE_RIGHT));
2744 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2746 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2750 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2752 if (streq_ptr(i->active_state, "failed")) {
2753 on = ansi_highlight_red();
2754 off = ansi_highlight_off();
2755 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2756 on = ansi_highlight_green();
2757 off = ansi_highlight_off();
2762 printf(" Active: %s%s (%s)%s",
2763 on, strna(i->active_state), ss, off);
2765 printf(" Active: %s%s%s",
2766 on, strna(i->active_state), off);
2768 if (!isempty(i->result) && !streq(i->result, "success"))
2769 printf(" (Result: %s)", i->result);
2771 timestamp = (streq_ptr(i->active_state, "active") ||
2772 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2773 (streq_ptr(i->active_state, "inactive") ||
2774 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2775 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2776 i->active_exit_timestamp;
2778 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2779 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2782 printf(" since %s; %s\n", s2, s1);
2784 printf(" since %s\n", s2);
2788 if (!i->condition_result && i->condition_timestamp > 0) {
2789 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2790 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2792 printf(" start condition failed at %s%s%s\n",
2793 s2, s1 ? "; " : "", s1 ? s1 : "");
2794 if (i->failed_condition_trigger)
2795 printf(" none of the trigger conditions were met\n");
2796 else if (i->failed_condition)
2797 printf(" %s=%s%s was not met\n",
2798 i->failed_condition,
2799 i->failed_condition_negate ? "!" : "",
2800 i->failed_condition_param);
2804 printf(" Device: %s\n", i->sysfs_path);
2806 printf(" Where: %s\n", i->where);
2808 printf(" What: %s\n", i->what);
2810 STRV_FOREACH(t, i->documentation)
2811 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2813 STRV_FOREACH_PAIR(t, t2, i->listen)
2814 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2817 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2819 LIST_FOREACH(exec, p, i->exec) {
2820 _cleanup_free_ char *argv = NULL;
2823 /* Only show exited processes here */
2827 argv = strv_join(p->argv, " ");
2828 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2830 good = is_clean_exit_lsb(p->code, p->status, NULL);
2832 on = ansi_highlight_red();
2833 off = ansi_highlight_off();
2837 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2839 if (p->code == CLD_EXITED) {
2842 printf("status=%i", p->status);
2844 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2849 printf("signal=%s", signal_to_string(p->status));
2851 printf(")%s\n", off);
2853 if (i->main_pid == p->pid &&
2854 i->start_timestamp == p->start_timestamp &&
2855 i->exit_timestamp == p->start_timestamp)
2856 /* Let's not show this twice */
2859 if (p->pid == i->control_pid)
2863 if (i->main_pid > 0 || i->control_pid > 0) {
2864 if (i->main_pid > 0) {
2865 printf(" Main PID: %u", (unsigned) i->main_pid);
2868 _cleanup_free_ char *comm = NULL;
2869 get_process_comm(i->main_pid, &comm);
2871 printf(" (%s)", comm);
2872 } else if (i->exit_code > 0) {
2873 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2875 if (i->exit_code == CLD_EXITED) {
2878 printf("status=%i", i->exit_status);
2880 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2885 printf("signal=%s", signal_to_string(i->exit_status));
2889 if (i->control_pid > 0)
2893 if (i->control_pid > 0) {
2894 _cleanup_free_ char *c = NULL;
2896 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2898 get_process_comm(i->control_pid, &c);
2907 printf(" Status: \"%s\"\n", i->status_text);
2909 if (i->control_group &&
2910 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2913 printf(" CGroup: %s\n", i->control_group);
2915 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2918 char prefix[] = " ";
2921 if (c > sizeof(prefix) - 1)
2922 c -= sizeof(prefix) - 1;
2926 if (i->main_pid > 0)
2927 extra[k++] = i->main_pid;
2929 if (i->control_pid > 0)
2930 extra[k++] = i->control_pid;
2932 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2933 c, false, extra, k, flags);
2937 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2939 show_journal_by_unit(stdout,
2943 i->inactive_exit_timestamp_monotonic,
2947 arg_scope == UNIT_FILE_SYSTEM,
2951 if (i->need_daemon_reload)
2952 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2953 ansi_highlight_red(),
2954 ansi_highlight_off(),
2955 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2958 static void show_unit_help(UnitStatusInfo *i) {
2963 if (!i->documentation) {
2964 log_info("Documentation for %s not known.", i->id);
2968 STRV_FOREACH(p, i->documentation) {
2970 if (startswith(*p, "man:")) {
2971 const char *args[4] = { "man", NULL, NULL, NULL };
2972 _cleanup_free_ char *page = NULL, *section = NULL;
2979 if ((*p)[k-1] == ')')
2980 e = strrchr(*p, '(');
2983 page = strndup((*p) + 4, e - *p - 4);
2984 section = strndup(e + 1, *p + k - e - 2);
2985 if (!page || !section) {
2997 log_error("Failed to fork: %m");
3003 execvp(args[0], (char**) args);
3004 log_error("Failed to execute man: %m");
3005 _exit(EXIT_FAILURE);
3008 wait_for_terminate(pid, NULL);
3010 log_info("Can't show: %s", *p);
3014 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3021 switch (contents[0]) {
3023 case SD_BUS_TYPE_STRING: {
3026 r = sd_bus_message_read(m, "s", &s);
3028 return bus_log_parse_error(r);
3031 if (streq(name, "Id"))
3033 else if (streq(name, "LoadState"))
3035 else if (streq(name, "ActiveState"))
3036 i->active_state = s;
3037 else if (streq(name, "SubState"))
3039 else if (streq(name, "Description"))
3041 else if (streq(name, "FragmentPath"))
3042 i->fragment_path = s;
3043 else if (streq(name, "SourcePath"))
3046 else if (streq(name, "DefaultControlGroup")) {
3048 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3050 i->control_group = e;
3053 else if (streq(name, "ControlGroup"))
3054 i->control_group = s;
3055 else if (streq(name, "StatusText"))
3057 else if (streq(name, "PIDFile"))
3059 else if (streq(name, "SysFSPath"))
3061 else if (streq(name, "Where"))
3063 else if (streq(name, "What"))
3065 else if (streq(name, "Following"))
3067 else if (streq(name, "UnitFileState"))
3068 i->unit_file_state = s;
3069 else if (streq(name, "Result"))
3076 case SD_BUS_TYPE_BOOLEAN: {
3079 r = sd_bus_message_read(m, "b", &b);
3081 return bus_log_parse_error(r);
3083 if (streq(name, "Accept"))
3085 else if (streq(name, "NeedDaemonReload"))
3086 i->need_daemon_reload = b;
3087 else if (streq(name, "ConditionResult"))
3088 i->condition_result = b;
3093 case SD_BUS_TYPE_UINT32: {
3096 r = sd_bus_message_read(m, "u", &u);
3098 return bus_log_parse_error(r);
3100 if (streq(name, "MainPID")) {
3102 i->main_pid = (pid_t) u;
3105 } else if (streq(name, "ControlPID"))
3106 i->control_pid = (pid_t) u;
3107 else if (streq(name, "ExecMainPID")) {
3109 i->main_pid = (pid_t) u;
3110 } else if (streq(name, "NAccepted"))
3112 else if (streq(name, "NConnections"))
3113 i->n_connections = u;
3118 case SD_BUS_TYPE_INT32: {
3121 r = sd_bus_message_read(m, "i", &j);
3123 return bus_log_parse_error(r);
3125 if (streq(name, "ExecMainCode"))
3126 i->exit_code = (int) j;
3127 else if (streq(name, "ExecMainStatus"))
3128 i->exit_status = (int) j;
3133 case SD_BUS_TYPE_UINT64: {
3136 r = sd_bus_message_read(m, "t", &u);
3138 return bus_log_parse_error(r);
3140 if (streq(name, "ExecMainStartTimestamp"))
3141 i->start_timestamp = (usec_t) u;
3142 else if (streq(name, "ExecMainExitTimestamp"))
3143 i->exit_timestamp = (usec_t) u;
3144 else if (streq(name, "ActiveEnterTimestamp"))
3145 i->active_enter_timestamp = (usec_t) u;
3146 else if (streq(name, "InactiveEnterTimestamp"))
3147 i->inactive_enter_timestamp = (usec_t) u;
3148 else if (streq(name, "InactiveExitTimestamp"))
3149 i->inactive_exit_timestamp = (usec_t) u;
3150 else if (streq(name, "InactiveExitTimestampMonotonic"))
3151 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3152 else if (streq(name, "ActiveExitTimestamp"))
3153 i->active_exit_timestamp = (usec_t) u;
3154 else if (streq(name, "ConditionTimestamp"))
3155 i->condition_timestamp = (usec_t) u;
3160 case SD_BUS_TYPE_ARRAY:
3162 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3163 _cleanup_free_ ExecStatusInfo *info = NULL;
3165 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3167 return bus_log_parse_error(r);
3169 info = new0(ExecStatusInfo, 1);
3173 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3175 info->name = strdup(name);
3179 LIST_PREPEND(exec, i->exec, info);
3181 info = new0(ExecStatusInfo, 1);
3187 return bus_log_parse_error(r);
3189 r = sd_bus_message_exit_container(m);
3191 return bus_log_parse_error(r);
3195 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3196 const char *type, *path;
3198 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3200 return bus_log_parse_error(r);
3202 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3204 r = strv_extend(&i->listen, type);
3208 r = strv_extend(&i->listen, path);
3213 return bus_log_parse_error(r);
3215 r = sd_bus_message_exit_container(m);
3217 return bus_log_parse_error(r);
3221 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3223 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3225 return bus_log_parse_error(r);
3227 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3229 r = sd_bus_message_read_strv(m, &i->documentation);
3231 return bus_log_parse_error(r);
3233 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3234 const char *cond, *param;
3235 int trigger, negate;
3238 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3240 return bus_log_parse_error(r);
3242 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3243 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3244 if (state < 0 && (!trigger || !i->failed_condition)) {
3245 i->failed_condition = cond;
3246 i->failed_condition_trigger = trigger;
3247 i->failed_condition_negate = negate;
3248 i->failed_condition_param = param;
3252 return bus_log_parse_error(r);
3254 r = sd_bus_message_exit_container(m);
3256 return bus_log_parse_error(r);
3263 case SD_BUS_TYPE_STRUCT_BEGIN:
3265 if (streq(name, "LoadError")) {
3266 const char *n, *message;
3268 r = sd_bus_message_read(m, "(ss)", &n, &message);
3270 return bus_log_parse_error(r);
3272 if (!isempty(message))
3273 i->load_error = message;
3286 r = sd_bus_message_skip(m, contents);
3288 return bus_log_parse_error(r);
3293 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3299 /* This is a low-level property printer, see
3300 * print_status_info() for the nicer output */
3302 if (arg_properties && !strv_find(arg_properties, name)) {
3303 /* skip what we didn't read */
3304 r = sd_bus_message_skip(m, contents);
3308 switch (contents[0]) {
3310 case SD_BUS_TYPE_STRUCT_BEGIN:
3312 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3315 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3317 return bus_log_parse_error(r);
3320 printf("%s=%u\n", name, (unsigned) u);
3322 printf("%s=\n", name);
3326 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3329 r = sd_bus_message_read(m, "(so)", &s, NULL);
3331 return bus_log_parse_error(r);
3333 if (arg_all || !isempty(s))
3334 printf("%s=%s\n", name, s);
3338 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3339 const char *a = NULL, *b = NULL;
3341 r = sd_bus_message_read(m, "(ss)", &a, &b);
3343 return bus_log_parse_error(r);
3345 if (arg_all || !isempty(a) || !isempty(b))
3346 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3353 case SD_BUS_TYPE_ARRAY:
3355 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3359 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3361 return bus_log_parse_error(r);
3363 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3364 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3367 return bus_log_parse_error(r);
3369 r = sd_bus_message_exit_container(m);
3371 return bus_log_parse_error(r);
3375 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3376 const char *type, *path;
3378 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3380 return bus_log_parse_error(r);
3382 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3383 printf("%s=%s\n", type, path);
3385 return bus_log_parse_error(r);
3387 r = sd_bus_message_exit_container(m);
3389 return bus_log_parse_error(r);
3393 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3394 const char *type, *path;
3396 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3398 return bus_log_parse_error(r);
3400 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3401 printf("Listen%s=%s\n", type, path);
3403 return bus_log_parse_error(r);
3405 r = sd_bus_message_exit_container(m);
3407 return bus_log_parse_error(r);
3411 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3413 uint64_t value, next_elapse;
3415 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3417 return bus_log_parse_error(r);
3419 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3420 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3422 printf("%s={ value=%s ; next_elapse=%s }\n",
3424 format_timespan(timespan1, sizeof(timespan1), value, 0),
3425 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3428 return bus_log_parse_error(r);
3430 r = sd_bus_message_exit_container(m);
3432 return bus_log_parse_error(r);
3436 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3437 ExecStatusInfo info = {};
3439 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3441 return bus_log_parse_error(r);
3443 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3444 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3445 _cleanup_free_ char *tt;
3447 tt = strv_join(info.argv, " ");
3449 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3453 yes_no(info.ignore),
3454 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3455 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3456 (unsigned) info. pid,
3457 sigchld_code_to_string(info.code),
3459 info.code == CLD_EXITED ? "" : "/",
3460 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3463 strv_free(info.argv);
3467 r = sd_bus_message_exit_container(m);
3469 return bus_log_parse_error(r);
3473 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3474 const char *path, *rwm;
3476 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3478 return bus_log_parse_error(r);
3480 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3481 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3483 return bus_log_parse_error(r);
3485 r = sd_bus_message_exit_container(m);
3487 return bus_log_parse_error(r);
3491 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3495 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3497 return bus_log_parse_error(r);
3499 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3500 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3502 return bus_log_parse_error(r);
3504 r = sd_bus_message_exit_container(m);
3506 return bus_log_parse_error(r);
3510 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3514 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3516 return bus_log_parse_error(r);
3518 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3519 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3521 return bus_log_parse_error(r);
3523 r = sd_bus_message_exit_container(m);
3525 return bus_log_parse_error(r);
3533 r = bus_print_property(name, m, arg_all);
3535 return bus_log_parse_error(r);
3538 r = sd_bus_message_skip(m, contents);
3540 return bus_log_parse_error(r);
3543 printf("%s=[unprintable]\n", name);
3549 static int show_one(
3553 bool show_properties,
3557 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3558 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3559 UnitStatusInfo info = {};
3566 r = sd_bus_call_method(
3568 "org.freedesktop.systemd1",
3570 "org.freedesktop.DBus.Properties",
3576 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3580 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3582 return bus_log_parse_error(r);
3589 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3590 const char *name, *contents;
3592 r = sd_bus_message_read(reply, "s", &name);
3594 return bus_log_parse_error(r);
3596 r = sd_bus_message_peek_type(reply, NULL, &contents);
3598 return bus_log_parse_error(r);
3600 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3602 return bus_log_parse_error(r);
3604 if (show_properties)
3605 r = print_property(name, reply, contents);
3607 r = status_property(name, reply, &info, contents);
3611 r = sd_bus_message_exit_container(reply);
3613 return bus_log_parse_error(r);
3615 r = sd_bus_message_exit_container(reply);
3617 return bus_log_parse_error(r);
3620 return bus_log_parse_error(r);
3622 r = sd_bus_message_exit_container(reply);
3624 return bus_log_parse_error(r);
3628 if (!show_properties) {
3629 if (streq(verb, "help"))
3630 show_unit_help(&info);
3632 print_status_info(&info, ellipsized);
3635 strv_free(info.documentation);
3636 strv_free(info.dropin_paths);
3637 strv_free(info.listen);
3639 if (!streq_ptr(info.active_state, "active") &&
3640 !streq_ptr(info.active_state, "reloading") &&
3641 streq(verb, "status")) {
3642 /* According to LSB: "program not running" */
3643 /* 0: program is running or service is OK
3644 * 1: program is dead and /var/run pid file exists
3645 * 2: program is dead and /var/lock lock file exists
3646 * 3: program is not running
3647 * 4: program or service status is unknown
3649 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3655 while ((p = info.exec)) {
3656 LIST_REMOVE(exec, info.exec, p);
3657 exec_status_info_free(p);
3663 static int get_unit_dbus_path_by_pid(
3668 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3669 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3673 r = sd_bus_call_method(
3675 "org.freedesktop.systemd1",
3676 "/org/freedesktop/systemd1",
3677 "org.freedesktop.systemd1.Manager",
3683 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3687 r = sd_bus_message_read(reply, "o", &u);
3689 return bus_log_parse_error(r);
3699 static int show_all(
3702 bool show_properties,
3706 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3707 _cleanup_free_ UnitInfo *unit_infos = NULL;
3712 r = get_unit_list(bus, &reply, &unit_infos, NULL);
3716 pager_open_if_enabled();
3720 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3722 for (u = unit_infos; u < unit_infos + c; u++) {
3723 _cleanup_free_ char *p = NULL;
3725 p = unit_dbus_path_from_name(u->id);
3729 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3737 static int cat(sd_bus *bus, char **args) {
3738 _cleanup_free_ char *unit = NULL, *n = NULL;
3746 pager_open_if_enabled();
3748 STRV_FOREACH(name, args+1) {
3749 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3750 _cleanup_strv_free_ char **dropin_paths = NULL;
3751 _cleanup_free_ char *fragment_path = NULL;
3754 n = unit_name_mangle(*name);
3758 unit = unit_dbus_path_from_name(n);
3762 if (need_daemon_reload(bus, n) > 0)
3763 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3764 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3766 r = sd_bus_get_property_string(
3768 "org.freedesktop.systemd1",
3770 "org.freedesktop.systemd1.Unit",
3775 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3779 r = sd_bus_get_property_strv(
3781 "org.freedesktop.systemd1",
3783 "org.freedesktop.systemd1.Unit",
3788 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3797 if (!isempty(fragment_path)) {
3798 printf("%s# %s%s\n",
3799 ansi_highlight_blue(),
3801 ansi_highlight_off());
3804 r = sendfile_full(STDOUT_FILENO, fragment_path);
3806 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3811 STRV_FOREACH(path, dropin_paths) {
3812 printf("%s%s# %s%s\n",
3813 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3814 ansi_highlight_blue(),
3816 ansi_highlight_off());
3819 r = sendfile_full(STDOUT_FILENO, *path);
3821 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3827 return r < 0 ? r : 0;
3830 static int show(sd_bus *bus, char **args) {
3832 bool show_properties, show_status, new_line = false;
3834 bool ellipsized = false;
3839 show_properties = streq(args[0], "show");
3840 show_status = streq(args[0], "status");
3842 if (show_properties)
3843 pager_open_if_enabled();
3845 /* If no argument is specified inspect the manager itself */
3847 if (show_properties && strv_length(args) <= 1)
3848 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3850 if (show_status && strv_length(args) <= 1)
3851 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3853 STRV_FOREACH(name, args+1) {
3854 _cleanup_free_ char *unit = NULL;
3857 if (safe_atou32(*name, &id) < 0) {
3858 _cleanup_free_ char *n = NULL;
3859 /* Interpret as unit name */
3861 n = unit_name_mangle(*name);
3865 unit = unit_dbus_path_from_name(n);
3869 } else if (show_properties) {
3870 /* Interpret as job id */
3871 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3875 /* Interpret as PID */
3876 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3883 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3886 if (ellipsized && !arg_quiet)
3887 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3892 static int append_assignment(sd_bus_message *m, const char *assignment) {
3900 eq = strchr(assignment, '=');
3902 log_error("Not an assignment: %s", assignment);
3906 field = strndupa(assignment, eq - assignment);
3909 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3911 return bus_log_create_error(r);
3913 if (streq(field, "CPUAccounting") ||
3914 streq(field, "MemoryAccounting") ||
3915 streq(field, "BlockIOAccounting")) {
3917 r = parse_boolean(eq);
3919 log_error("Failed to parse boolean assignment %s.", assignment);
3923 r = sd_bus_message_append(m, "v", "b", r);
3925 } else if (streq(field, "MemoryLimit")) {
3928 r = parse_bytes(eq, &bytes);
3930 log_error("Failed to parse bytes specification %s", assignment);
3934 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3936 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3939 r = safe_atou64(eq, &u);
3941 log_error("Failed to parse %s value %s.", field, eq);
3945 r = sd_bus_message_append(m, "v", "t", u);
3947 } else if (streq(field, "DevicePolicy"))
3948 r = sd_bus_message_append(m, "v", "s", eq);
3950 else if (streq(field, "DeviceAllow")) {
3953 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3955 const char *path, *rwm;
3958 e = strchr(eq, ' ');
3960 path = strndupa(eq, e - eq);
3967 if (!path_startswith(path, "/dev")) {
3968 log_error("%s is not a device file in /dev.", path);
3972 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3975 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3978 r = sd_bus_message_append(m, "v", "a(st)", 0);
3980 const char *path, *bandwidth;
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 = parse_bytes(bandwidth, &bytes);
4000 log_error("Failed to parse byte value %s.", bandwidth);
4004 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4007 } else if (streq(field, "BlockIODeviceWeight")) {
4010 r = sd_bus_message_append(m, "v", "a(st)", 0);
4012 const char *path, *weight;
4016 e = strchr(eq, ' ');
4018 path = strndupa(eq, e - eq);
4021 log_error("Failed to parse %s value %s.", field, eq);
4025 if (!path_startswith(path, "/dev")) {
4026 log_error("%s is not a device file in /dev.", path);
4030 r = safe_atou64(weight, &u);
4032 log_error("Failed to parse %s value %s.", field, weight);
4035 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4039 log_error("Unknown assignment %s.", assignment);
4044 return bus_log_create_error(r);
4049 static int set_property(sd_bus *bus, char **args) {
4050 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4051 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4052 _cleanup_free_ char *n = NULL;
4056 r = sd_bus_message_new_method_call(
4058 "org.freedesktop.systemd1",
4059 "/org/freedesktop/systemd1",
4060 "org.freedesktop.systemd1.Manager",
4061 "SetUnitProperties",
4064 return bus_log_create_error(r);
4066 n = unit_name_mangle(args[1]);
4070 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4072 return bus_log_create_error(r);
4074 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4076 return bus_log_create_error(r);
4078 STRV_FOREACH(i, args + 2) {
4079 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4081 return bus_log_create_error(r);
4083 r = append_assignment(m, *i);
4087 r = sd_bus_message_close_container(m);
4089 return bus_log_create_error(r);
4092 r = sd_bus_message_close_container(m);
4094 return bus_log_create_error(r);
4096 r = sd_bus_call(bus, m, 0, &error, NULL);
4098 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4105 static int snapshot(sd_bus *bus, char **args) {
4106 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4107 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4108 _cleanup_free_ char *n = NULL, *id = NULL;
4112 if (strv_length(args) > 1)
4113 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
4119 r = sd_bus_call_method(
4121 "org.freedesktop.systemd1",
4122 "/org/freedesktop/systemd1",
4123 "org.freedesktop.systemd1.Manager",
4129 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4133 r = sd_bus_message_read(reply, "o", &path);
4135 return bus_log_parse_error(r);
4137 r = sd_bus_get_property_string(
4139 "org.freedesktop.systemd1",
4141 "org.freedesktop.systemd1.Unit",
4146 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4156 static int delete_snapshot(sd_bus *bus, char **args) {
4157 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4163 STRV_FOREACH(name, args+1) {
4164 _cleanup_free_ char *n = NULL;
4166 n = unit_name_mangle_with_suffix(*name, ".snapshot");
4170 r = sd_bus_call_method(
4172 "org.freedesktop.systemd1",
4173 "/org/freedesktop/systemd1",
4174 "org.freedesktop.systemd1.Manager",
4180 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
4188 static int daemon_reload(sd_bus *bus, char **args) {
4189 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4193 if (arg_action == ACTION_RELOAD)
4195 else if (arg_action == ACTION_REEXEC)
4196 method = "Reexecute";
4198 assert(arg_action == ACTION_SYSTEMCTL);
4201 streq(args[0], "clear-jobs") ||
4202 streq(args[0], "cancel") ? "ClearJobs" :
4203 streq(args[0], "daemon-reexec") ? "Reexecute" :
4204 streq(args[0], "reset-failed") ? "ResetFailed" :
4205 streq(args[0], "halt") ? "Halt" :
4206 streq(args[0], "poweroff") ? "PowerOff" :
4207 streq(args[0], "reboot") ? "Reboot" :
4208 streq(args[0], "kexec") ? "KExec" :
4209 streq(args[0], "exit") ? "Exit" :
4210 /* "daemon-reload" */ "Reload";
4213 r = sd_bus_call_method(
4215 "org.freedesktop.systemd1",
4216 "/org/freedesktop/systemd1",
4217 "org.freedesktop.systemd1.Manager",
4223 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4224 /* There's always a fallback possible for
4225 * legacy actions. */
4227 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4228 /* On reexecution, we expect a disconnect, not a
4232 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4234 return r < 0 ? r : 0;
4237 static int reset_failed(sd_bus *bus, char **args) {
4238 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4242 if (strv_length(args) <= 1)
4243 return daemon_reload(bus, args);
4245 STRV_FOREACH(name, args+1) {
4246 _cleanup_free_ char *n;
4248 n = unit_name_mangle(*name);
4252 r = sd_bus_call_method(
4254 "org.freedesktop.systemd1",
4255 "/org/freedesktop/systemd1",
4256 "org.freedesktop.systemd1.Manager",
4262 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4270 static int show_environment(sd_bus *bus, char **args) {
4271 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4272 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4276 pager_open_if_enabled();
4278 r = sd_bus_get_property(
4280 "org.freedesktop.systemd1",
4281 "/org/freedesktop/systemd1",
4282 "org.freedesktop.systemd1.Manager",
4288 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4292 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4294 return bus_log_parse_error(r);
4296 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4299 return bus_log_parse_error(r);
4301 r = sd_bus_message_exit_container(reply);
4303 return bus_log_parse_error(r);
4308 static int switch_root(sd_bus *bus, char **args) {
4309 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4310 _cleanup_free_ char *init = NULL;
4315 l = strv_length(args);
4316 if (l < 2 || l > 3) {
4317 log_error("Wrong number of arguments.");
4324 init = strdup(args[2]);
4326 parse_env_file("/proc/cmdline", WHITESPACE,
4337 log_debug("switching root - root: %s; init: %s", root, init);
4339 r = sd_bus_call_method(
4341 "org.freedesktop.systemd1",
4342 "/org/freedesktop/systemd1",
4343 "org.freedesktop.systemd1.Manager",
4349 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4356 static int set_environment(sd_bus *bus, char **args) {
4357 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4358 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4365 method = streq(args[0], "set-environment")
4367 : "UnsetEnvironment";
4369 r = sd_bus_message_new_method_call(
4371 "org.freedesktop.systemd1",
4372 "/org/freedesktop/systemd1",
4373 "org.freedesktop.systemd1.Manager",
4377 return bus_log_create_error(r);
4379 r = sd_bus_message_append_strv(m, args + 1);
4381 return bus_log_create_error(r);
4383 r = sd_bus_call(bus, m, 0, &error, NULL);
4385 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4392 static int enable_sysv_units(const char *verb, char **args) {
4395 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4396 unsigned f = 1, t = 1;
4397 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4399 if (arg_scope != UNIT_FILE_SYSTEM)
4402 if (!streq(verb, "enable") &&
4403 !streq(verb, "disable") &&
4404 !streq(verb, "is-enabled"))
4407 /* Processes all SysV units, and reshuffles the array so that
4408 * afterwards only the native units remain */
4410 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4415 for (f = 0; args[f]; f++) {
4417 _cleanup_free_ char *p = NULL, *q = NULL;
4418 bool found_native = false, found_sysv;
4420 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4428 if (!endswith(name, ".service"))
4431 if (path_is_absolute(name))
4434 STRV_FOREACH(k, paths.unit_path) {
4435 if (!isempty(arg_root))
4436 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4438 asprintf(&p, "%s/%s", *k, name);
4445 found_native = access(p, F_OK) >= 0;
4456 if (!isempty(arg_root))
4457 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4459 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4465 p[strlen(p) - sizeof(".service") + 1] = 0;
4466 found_sysv = access(p, F_OK) >= 0;
4471 /* Mark this entry, so that we don't try enabling it as native unit */
4472 args[f] = (char*) "";
4474 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4476 if (!isempty(arg_root))
4477 argv[c++] = q = strappend("--root=", arg_root);
4479 argv[c++] = basename(p);
4481 streq(verb, "enable") ? "on" :
4482 streq(verb, "disable") ? "off" : "--level=5";
4485 l = strv_join((char**)argv, " ");
4491 log_info("Executing %s", l);
4496 log_error("Failed to fork: %m");
4499 } else if (pid == 0) {
4502 execv(argv[0], (char**) argv);
4503 _exit(EXIT_FAILURE);
4506 j = wait_for_terminate(pid, &status);
4508 log_error("Failed to wait for child: %s", strerror(-r));
4513 if (status.si_code == CLD_EXITED) {
4514 if (streq(verb, "is-enabled")) {
4515 if (status.si_status == 0) {
4524 } else if (status.si_status != 0) {
4535 /* Drop all SysV units */
4536 for (f = 0, t = 0; args[f]; f++) {
4538 if (isempty(args[f]))
4541 args[t++] = args[f];
4550 static int mangle_names(char **original_names, char ***mangled_names) {
4551 char **i, **l, **name;
4553 l = new(char*, strv_length(original_names) + 1);
4558 STRV_FOREACH(name, original_names) {
4560 /* When enabling units qualified path names are OK,
4561 * too, hence allow them explicitly. */
4566 *i = unit_name_mangle(*name);
4582 static int enable_unit(sd_bus *bus, char **args) {
4583 _cleanup_strv_free_ char **mangled_names = NULL;
4584 const char *verb = args[0];
4585 UnitFileChange *changes = NULL;
4586 unsigned n_changes = 0;
4587 int carries_install_info = -1;
4593 r = mangle_names(args+1, &mangled_names);
4597 r = enable_sysv_units(verb, mangled_names);
4601 if (!bus || avoid_bus()) {
4602 if (streq(verb, "enable")) {
4603 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4604 carries_install_info = r;
4605 } else if (streq(verb, "disable"))
4606 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4607 else if (streq(verb, "reenable")) {
4608 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4609 carries_install_info = r;
4610 } else if (streq(verb, "link"))
4611 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4612 else if (streq(verb, "preset")) {
4613 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4614 carries_install_info = r;
4615 } else if (streq(verb, "mask"))
4616 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4617 else if (streq(verb, "unmask"))
4618 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4620 assert_not_reached("Unknown verb");
4623 log_error("Operation failed: %s", strerror(-r));
4628 dump_unit_file_changes(changes, n_changes);
4632 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4633 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4634 int expect_carries_install_info = false;
4635 bool send_force = true;
4638 if (streq(verb, "enable")) {
4639 method = "EnableUnitFiles";
4640 expect_carries_install_info = true;
4641 } else if (streq(verb, "disable")) {
4642 method = "DisableUnitFiles";
4644 } else if (streq(verb, "reenable")) {
4645 method = "ReenableUnitFiles";
4646 expect_carries_install_info = true;
4647 } else if (streq(verb, "link"))
4648 method = "LinkUnitFiles";
4649 else if (streq(verb, "preset")) {
4650 method = "PresetUnitFiles";
4651 expect_carries_install_info = true;
4652 } else if (streq(verb, "mask"))
4653 method = "MaskUnitFiles";
4654 else if (streq(verb, "unmask")) {
4655 method = "UnmaskUnitFiles";
4658 assert_not_reached("Unknown verb");
4660 r = sd_bus_message_new_method_call(
4662 "org.freedesktop.systemd1",
4663 "/org/freedesktop/systemd1",
4664 "org.freedesktop.systemd1.Manager",
4668 return bus_log_create_error(r);
4670 r = sd_bus_message_append_strv(m, mangled_names);
4672 return bus_log_create_error(r);
4674 r = sd_bus_message_append(m, "b", arg_runtime);
4676 return bus_log_create_error(r);
4679 r = sd_bus_message_append(m, "b", arg_force);
4681 return bus_log_create_error(r);
4684 r = sd_bus_call(bus, m, 0, &error, &reply);
4686 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4690 if (expect_carries_install_info) {
4691 r = sd_bus_message_read(reply, "b", &carries_install_info);
4693 return bus_log_parse_error(r);
4696 r = deserialize_and_dump_unit_file_changes(reply);
4700 /* Try to reload if enabeld */
4702 r = daemon_reload(bus, args);
4707 if (carries_install_info == 0)
4708 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4709 "using systemctl.\n"
4710 "Possible reasons for having this kind of units are:\n"
4711 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4712 " .wants/ or .requires/ directory.\n"
4713 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4714 " a requirement dependency on it.\n"
4715 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4716 " D-Bus, udev, scripted systemctl call, ...).\n");
4719 unit_file_changes_free(changes, n_changes);
4724 static int unit_is_enabled(sd_bus *bus, char **args) {
4726 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4727 _cleanup_strv_free_ char **mangled_names = NULL;
4732 r = mangle_names(args+1, &mangled_names);
4736 r = enable_sysv_units(args[0], mangled_names);
4742 if (!bus || avoid_bus()) {
4744 STRV_FOREACH(name, mangled_names) {
4745 UnitFileState state;
4747 state = unit_file_get_state(arg_scope, arg_root, *name);
4749 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4753 if (state == UNIT_FILE_ENABLED ||
4754 state == UNIT_FILE_ENABLED_RUNTIME ||
4755 state == UNIT_FILE_STATIC)
4759 puts(unit_file_state_to_string(state));
4763 STRV_FOREACH(name, mangled_names) {
4764 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4767 r = sd_bus_call_method(
4769 "org.freedesktop.systemd1",
4770 "/org/freedesktop/systemd1",
4771 "org.freedesktop.systemd1.Manager",
4777 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4781 r = sd_bus_message_read(reply, "s", &s);
4783 return bus_log_parse_error(r);
4785 if (streq(s, "enabled") ||
4786 streq(s, "enabled-runtime") ||
4798 static int systemctl_help(void) {
4800 pager_open_if_enabled();
4802 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4803 "Query or send control commands to the systemd manager.\n\n"
4804 " -h --help Show this help\n"
4805 " --version Show package version\n"
4806 " --system Connect to system manager\n"
4807 " --user Connect to user service manager\n"
4808 " -H --host=[USER@]HOST\n"
4809 " Operate on remote host\n"
4810 " -M --machine=CONTAINER\n"
4811 " Operate on local container\n"
4812 " -t --type=TYPE List only units of a particular type\n"
4813 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4814 " -p --property=NAME Show only properties by this name\n"
4815 " -a --all Show all loaded units/properties, including dead/empty\n"
4816 " ones. To list all units installed on the system, use\n"
4817 " the 'list-unit-files' command instead.\n"
4818 " -l --full Don't ellipsize unit names on output\n"
4819 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4820 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4821 " queueing a new job\n"
4822 " --show-types When showing sockets, explicitly show their type\n"
4823 " -i --ignore-inhibitors\n"
4824 " When shutting down or sleeping, ignore inhibitors\n"
4825 " --kill-who=WHO Who to send signal to\n"
4826 " -s --signal=SIGNAL Which signal to send\n"
4827 " -q --quiet Suppress output\n"
4828 " --no-block Do not wait until operation finished\n"
4829 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4830 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4832 " --no-legend Do not print a legend (column headers and hints)\n"
4833 " --no-pager Do not pipe output into a pager\n"
4834 " --no-ask-password\n"
4835 " Do not ask for system passwords\n"
4836 " --global Enable/disable unit files globally\n"
4837 " --runtime Enable unit files only temporarily until next reboot\n"
4838 " -f --force When enabling unit files, override existing symlinks\n"
4839 " When shutting down, execute action immediately\n"
4840 " --root=PATH Enable unit files in the specified root directory\n"
4841 " -n --lines=INTEGER Number of journal entries to show\n"
4842 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4843 " verbose, export, json, json-pretty, json-sse, cat)\n"
4844 " --plain Print unit dependencies as a list instead of a tree\n\n"
4846 " list-units [PATTERN...] List loaded units\n"
4847 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4848 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4849 " start NAME... Start (activate) one or more units\n"
4850 " stop NAME... Stop (deactivate) one or more units\n"
4851 " reload NAME... Reload one or more units\n"
4852 " restart NAME... Start or restart one or more units\n"
4853 " try-restart NAME... Restart one or more units if active\n"
4854 " reload-or-restart NAME... Reload one or more units if possible,\n"
4855 " otherwise start or restart\n"
4856 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
4857 " otherwise restart if active\n"
4858 " isolate NAME Start one unit and stop all others\n"
4859 " kill NAME... Send signal to processes of a unit\n"
4860 " is-active NAME... Check whether units are active\n"
4861 " is-failed NAME... Check whether units are failed\n"
4862 " status [NAME...|PID...] Show runtime status of one or more units\n"
4863 " show [NAME...|JOB...] Show properties of one or more\n"
4864 " units/jobs or the manager\n"
4865 " cat NAME... Show files and drop-ins of one or more units\n"
4866 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
4867 " help NAME...|PID... Show manual for one or more units\n"
4868 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4870 " list-dependencies [NAME] Recursively show units which are required\n"
4871 " or wanted by this unit or by which this\n"
4872 " unit is required or wanted\n\n"
4873 "Unit File Commands:\n"
4874 " list-unit-files [PATTERN...] List installed unit files\n"
4875 " enable NAME... Enable one or more unit files\n"
4876 " disable NAME... Disable one or more unit files\n"
4877 " reenable NAME... Reenable one or more unit files\n"
4878 " preset NAME... Enable/disable one or more unit files\n"
4879 " based on preset configuration\n"
4880 " is-enabled NAME... Check whether unit files are enabled\n\n"
4881 " mask NAME... Mask one or more units\n"
4882 " unmask NAME... Unmask one or more units\n"
4883 " link PATH... Link one or more units files into\n"
4884 " the search path\n"
4885 " get-default Get the name of the default target\n"
4886 " set-default NAME Set the default target\n\n"
4888 " list-jobs [PATTERN...] List jobs\n"
4889 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4890 "Snapshot Commands:\n"
4891 " snapshot [NAME] Create a snapshot\n"
4892 " delete NAME... Remove one or more snapshots\n\n"
4893 "Environment Commands:\n"
4894 " show-environment Dump environment\n"
4895 " set-environment NAME=VALUE... Set one or more environment variables\n"
4896 " unset-environment NAME... Unset one or more environment variables\n\n"
4897 "Manager Lifecycle Commands:\n"
4898 " daemon-reload Reload systemd manager configuration\n"
4899 " daemon-reexec Reexecute systemd manager\n\n"
4900 "System Commands:\n"
4901 " default Enter system default mode\n"
4902 " rescue Enter system rescue mode\n"
4903 " emergency Enter system emergency mode\n"
4904 " halt Shut down and halt the system\n"
4905 " poweroff Shut down and power-off the system\n"
4906 " reboot [ARG] Shut down and reboot the system\n"
4907 " kexec Shut down and reboot the system with kexec\n"
4908 " exit Request user instance exit\n"
4909 " switch-root ROOT [INIT] Change to a different root file system\n"
4910 " suspend Suspend the system\n"
4911 " hibernate Hibernate the system\n"
4912 " hybrid-sleep Hibernate and suspend the system\n",
4913 program_invocation_short_name);
4918 static int halt_help(void) {
4920 printf("%s [OPTIONS...]%s\n\n"
4921 "%s the system.\n\n"
4922 " --help Show this help\n"
4923 " --halt Halt the machine\n"
4924 " -p --poweroff Switch off the machine\n"
4925 " --reboot Reboot the machine\n"
4926 " -f --force Force immediate halt/power-off/reboot\n"
4927 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4928 " -d --no-wtmp Don't write wtmp record\n"
4929 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4930 program_invocation_short_name,
4931 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4932 arg_action == ACTION_REBOOT ? "Reboot" :
4933 arg_action == ACTION_POWEROFF ? "Power off" :
4939 static int shutdown_help(void) {
4941 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4942 "Shut down the system.\n\n"
4943 " --help Show this help\n"
4944 " -H --halt Halt the machine\n"
4945 " -P --poweroff Power-off the machine\n"
4946 " -r --reboot Reboot the machine\n"
4947 " -h Equivalent to --poweroff, overridden by --halt\n"
4948 " -k Don't halt/power-off/reboot, just send warnings\n"
4949 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4950 " -c Cancel a pending shutdown\n",
4951 program_invocation_short_name);
4956 static int telinit_help(void) {
4958 printf("%s [OPTIONS...] {COMMAND}\n\n"
4959 "Send control commands to the init daemon.\n\n"
4960 " --help Show this help\n"
4961 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4963 " 0 Power-off the machine\n"
4964 " 6 Reboot the machine\n"
4965 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4966 " 1, s, S Enter rescue mode\n"
4967 " q, Q Reload init daemon configuration\n"
4968 " u, U Reexecute init daemon\n",
4969 program_invocation_short_name);
4974 static int runlevel_help(void) {
4976 printf("%s [OPTIONS...]\n\n"
4977 "Prints the previous and current runlevel of the init system.\n\n"
4978 " --help Show this help\n",
4979 program_invocation_short_name);
4984 static int help_types(void) {
4988 puts("Available unit types:");
4989 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
4990 t = unit_type_to_string(i);
4998 static int systemctl_parse_argv(int argc, char *argv[]) {
5007 ARG_IGNORE_DEPENDENCIES,
5019 ARG_NO_ASK_PASSWORD,
5028 static const struct option options[] = {
5029 { "help", no_argument, NULL, 'h' },
5030 { "version", no_argument, NULL, ARG_VERSION },
5031 { "type", required_argument, NULL, 't' },
5032 { "property", required_argument, NULL, 'p' },
5033 { "all", no_argument, NULL, 'a' },
5034 { "reverse", no_argument, NULL, ARG_REVERSE },
5035 { "after", no_argument, NULL, ARG_AFTER },
5036 { "before", no_argument, NULL, ARG_BEFORE },
5037 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5038 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5039 { "full", no_argument, NULL, 'l' },
5040 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5041 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5042 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5043 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5044 { "ignore-inhibitors", no_argument, NULL, 'i' },
5045 { "user", no_argument, NULL, ARG_USER },
5046 { "system", no_argument, NULL, ARG_SYSTEM },
5047 { "global", no_argument, NULL, ARG_GLOBAL },
5048 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5049 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5050 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5051 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5052 { "quiet", no_argument, NULL, 'q' },
5053 { "root", required_argument, NULL, ARG_ROOT },
5054 { "force", no_argument, NULL, ARG_FORCE },
5055 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5056 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5057 { "signal", required_argument, NULL, 's' },
5058 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5059 { "host", required_argument, NULL, 'H' },
5060 { "machine", required_argument, NULL, 'M' },
5061 { "runtime", no_argument, NULL, ARG_RUNTIME },
5062 { "lines", required_argument, NULL, 'n' },
5063 { "output", required_argument, NULL, 'o' },
5064 { "plain", no_argument, NULL, ARG_PLAIN },
5065 { "state", required_argument, NULL, ARG_STATE },
5074 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5079 return systemctl_help();
5082 puts(PACKAGE_STRING);
5083 puts(SYSTEMD_FEATURES);
5090 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5091 _cleanup_free_ char *type;
5093 type = strndup(word, size);
5097 if (streq(type, "help")) {
5102 if (unit_type_from_string(type) >= 0) {
5103 if (strv_push(&arg_types, type))
5109 /* It's much nicer to use --state= for
5110 * load states, but let's support this
5111 * in --types= too for compatibility
5112 * with old versions */
5113 if (unit_load_state_from_string(optarg) >= 0) {
5114 if (strv_push(&arg_states, type) < 0)
5120 log_error("Unknown unit type or load state '%s'.", type);
5121 log_info("Use -t help to see a list of allowed values.");
5129 /* Make sure that if the empty property list
5130 was specified, we won't show any properties. */
5131 if (isempty(optarg) && !arg_properties) {
5132 arg_properties = new0(char*, 1);
5133 if (!arg_properties)
5139 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5142 prop = strndup(word, size);
5146 if (strv_push(&arg_properties, prop) < 0) {
5153 /* If the user asked for a particular
5154 * property, show it to him, even if it is
5166 arg_dependency = DEPENDENCY_REVERSE;
5170 arg_dependency = DEPENDENCY_AFTER;
5174 arg_dependency = DEPENDENCY_BEFORE;
5177 case ARG_SHOW_TYPES:
5178 arg_show_types = true;
5182 arg_job_mode = optarg;
5186 arg_job_mode = "fail";
5189 case ARG_IRREVERSIBLE:
5190 arg_job_mode = "replace-irreversibly";
5193 case ARG_IGNORE_DEPENDENCIES:
5194 arg_job_mode = "ignore-dependencies";
5198 arg_scope = UNIT_FILE_USER;
5202 arg_scope = UNIT_FILE_SYSTEM;
5206 arg_scope = UNIT_FILE_GLOBAL;
5210 arg_no_block = true;
5214 arg_no_legend = true;
5218 arg_no_pager = true;
5234 if (strv_extend(&arg_states, "failed") < 0)
5252 arg_no_reload = true;
5256 arg_kill_who = optarg;
5260 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5261 log_error("Failed to parse signal string %s.", optarg);
5266 case ARG_NO_ASK_PASSWORD:
5267 arg_ask_password = false;
5271 arg_transport = BUS_TRANSPORT_REMOTE;
5276 arg_transport = BUS_TRANSPORT_CONTAINER;
5285 if (safe_atou(optarg, &arg_lines) < 0) {
5286 log_error("Failed to parse lines '%s'", optarg);
5292 arg_output = output_mode_from_string(optarg);
5293 if (arg_output < 0) {
5294 log_error("Unknown output '%s'.", optarg);
5300 arg_ignore_inhibitors = true;
5311 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5314 s = strndup(word, size);
5318 if (strv_push(&arg_states, s) < 0) {
5330 assert_not_reached("Unhandled option");
5334 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5335 log_error("Cannot access user instance remotely.");
5342 static int halt_parse_argv(int argc, char *argv[]) {
5351 static const struct option options[] = {
5352 { "help", no_argument, NULL, ARG_HELP },
5353 { "halt", no_argument, NULL, ARG_HALT },
5354 { "poweroff", no_argument, NULL, 'p' },
5355 { "reboot", no_argument, NULL, ARG_REBOOT },
5356 { "force", no_argument, NULL, 'f' },
5357 { "wtmp-only", no_argument, NULL, 'w' },
5358 { "no-wtmp", no_argument, NULL, 'd' },
5359 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5368 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5369 if (runlevel == '0' || runlevel == '6')
5372 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5379 arg_action = ACTION_HALT;
5383 if (arg_action != ACTION_REBOOT)
5384 arg_action = ACTION_POWEROFF;
5388 arg_action = ACTION_REBOOT;
5410 /* Compatibility nops */
5417 assert_not_reached("Unhandled option");
5421 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5422 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5424 log_error("Failed to write reboot param to "
5425 REBOOT_PARAM_FILE": %s", strerror(-r));
5428 } else if (optind < argc) {
5429 log_error("Too many arguments.");
5436 static int parse_time_spec(const char *t, usec_t *_u) {
5440 if (streq(t, "now"))
5442 else if (!strchr(t, ':')) {
5445 if (safe_atou64(t, &u) < 0)
5448 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5457 hour = strtol(t, &e, 10);
5458 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5461 minute = strtol(e+1, &e, 10);
5462 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5465 n = now(CLOCK_REALTIME);
5466 s = (time_t) (n / USEC_PER_SEC);
5468 assert_se(localtime_r(&s, &tm));
5470 tm.tm_hour = (int) hour;
5471 tm.tm_min = (int) minute;
5474 assert_se(s = mktime(&tm));
5476 *_u = (usec_t) s * USEC_PER_SEC;
5479 *_u += USEC_PER_DAY;
5485 static int shutdown_parse_argv(int argc, char *argv[]) {
5492 static const struct option options[] = {
5493 { "help", no_argument, NULL, ARG_HELP },
5494 { "halt", no_argument, NULL, 'H' },
5495 { "poweroff", no_argument, NULL, 'P' },
5496 { "reboot", no_argument, NULL, 'r' },
5497 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5498 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5507 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5511 return shutdown_help();
5514 arg_action = ACTION_HALT;
5518 arg_action = ACTION_POWEROFF;
5523 arg_action = ACTION_KEXEC;
5525 arg_action = ACTION_REBOOT;
5529 arg_action = ACTION_KEXEC;
5533 if (arg_action != ACTION_HALT)
5534 arg_action = ACTION_POWEROFF;
5547 /* Compatibility nops */
5551 arg_action = ACTION_CANCEL_SHUTDOWN;
5558 assert_not_reached("Unhandled option");
5562 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5563 r = parse_time_spec(argv[optind], &arg_when);
5565 log_error("Failed to parse time specification: %s", argv[optind]);
5569 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5571 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5572 /* No time argument for shutdown cancel */
5573 arg_wall = argv + optind;
5574 else if (argc > optind + 1)
5575 /* We skip the time argument */
5576 arg_wall = argv + optind + 1;
5583 static int telinit_parse_argv(int argc, char *argv[]) {
5590 static const struct option options[] = {
5591 { "help", no_argument, NULL, ARG_HELP },
5592 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5596 static const struct {
5600 { '0', ACTION_POWEROFF },
5601 { '6', ACTION_REBOOT },
5602 { '1', ACTION_RESCUE },
5603 { '2', ACTION_RUNLEVEL2 },
5604 { '3', ACTION_RUNLEVEL3 },
5605 { '4', ACTION_RUNLEVEL4 },
5606 { '5', ACTION_RUNLEVEL5 },
5607 { 's', ACTION_RESCUE },
5608 { 'S', ACTION_RESCUE },
5609 { 'q', ACTION_RELOAD },
5610 { 'Q', ACTION_RELOAD },
5611 { 'u', ACTION_REEXEC },
5612 { 'U', ACTION_REEXEC }
5621 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5625 return telinit_help();
5635 assert_not_reached("Unhandled option");
5639 if (optind >= argc) {
5644 if (optind + 1 < argc) {
5645 log_error("Too many arguments.");
5649 if (strlen(argv[optind]) != 1) {
5650 log_error("Expected single character argument.");
5654 for (i = 0; i < ELEMENTSOF(table); i++)
5655 if (table[i].from == argv[optind][0])
5658 if (i >= ELEMENTSOF(table)) {
5659 log_error("Unknown command '%s'.", argv[optind]);
5663 arg_action = table[i].to;
5670 static int runlevel_parse_argv(int argc, char *argv[]) {
5676 static const struct option options[] = {
5677 { "help", no_argument, NULL, ARG_HELP },
5686 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5690 return runlevel_help();
5697 assert_not_reached("Unhandled option");
5701 if (optind < argc) {
5702 log_error("Too many arguments.");
5709 static int parse_argv(int argc, char *argv[]) {
5713 if (program_invocation_short_name) {
5715 if (strstr(program_invocation_short_name, "halt")) {
5716 arg_action = ACTION_HALT;
5717 return halt_parse_argv(argc, argv);
5718 } else if (strstr(program_invocation_short_name, "poweroff")) {
5719 arg_action = ACTION_POWEROFF;
5720 return halt_parse_argv(argc, argv);
5721 } else if (strstr(program_invocation_short_name, "reboot")) {
5723 arg_action = ACTION_KEXEC;
5725 arg_action = ACTION_REBOOT;
5726 return halt_parse_argv(argc, argv);
5727 } else if (strstr(program_invocation_short_name, "shutdown")) {
5728 arg_action = ACTION_POWEROFF;
5729 return shutdown_parse_argv(argc, argv);
5730 } else if (strstr(program_invocation_short_name, "init")) {
5732 if (sd_booted() > 0) {
5733 arg_action = _ACTION_INVALID;
5734 return telinit_parse_argv(argc, argv);
5736 /* Hmm, so some other init system is
5737 * running, we need to forward this
5738 * request to it. For now we simply
5739 * guess that it is Upstart. */
5741 execv(TELINIT, argv);
5743 log_error("Couldn't find an alternative telinit implementation to spawn.");
5747 } else if (strstr(program_invocation_short_name, "runlevel")) {
5748 arg_action = ACTION_RUNLEVEL;
5749 return runlevel_parse_argv(argc, argv);
5753 arg_action = ACTION_SYSTEMCTL;
5754 return systemctl_parse_argv(argc, argv);
5757 _pure_ static int action_to_runlevel(void) {
5759 static const char table[_ACTION_MAX] = {
5760 [ACTION_HALT] = '0',
5761 [ACTION_POWEROFF] = '0',
5762 [ACTION_REBOOT] = '6',
5763 [ACTION_RUNLEVEL2] = '2',
5764 [ACTION_RUNLEVEL3] = '3',
5765 [ACTION_RUNLEVEL4] = '4',
5766 [ACTION_RUNLEVEL5] = '5',
5767 [ACTION_RESCUE] = '1'
5770 assert(arg_action < _ACTION_MAX);
5772 return table[arg_action];
5775 static int talk_initctl(void) {
5777 struct init_request request = {
5778 .magic = INIT_MAGIC,
5780 .cmd = INIT_CMD_RUNLVL
5783 _cleanup_close_ int fd = -1;
5787 rl = action_to_runlevel();
5791 request.runlevel = rl;
5793 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5795 if (errno == ENOENT)
5798 log_error("Failed to open "INIT_FIFO": %m");
5803 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5805 log_error("Failed to write to "INIT_FIFO": %m");
5806 return errno > 0 ? -errno : -EIO;
5812 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5814 static const struct {
5822 int (* const dispatch)(sd_bus *bus, char **args);
5828 { "list-units", MORE, 0, list_units },
5829 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
5830 { "list-sockets", MORE, 1, list_sockets },
5831 { "list-timers", MORE, 1, list_timers },
5832 { "list-jobs", MORE, 1, list_jobs },
5833 { "clear-jobs", EQUAL, 1, daemon_reload },
5834 { "cancel", MORE, 2, cancel_job },
5835 { "start", MORE, 2, start_unit },
5836 { "stop", MORE, 2, start_unit },
5837 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5838 { "reload", MORE, 2, start_unit },
5839 { "restart", MORE, 2, start_unit },
5840 { "try-restart", MORE, 2, start_unit },
5841 { "reload-or-restart", MORE, 2, start_unit },
5842 { "reload-or-try-restart", MORE, 2, start_unit },
5843 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5844 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5845 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5846 { "isolate", EQUAL, 2, start_unit },
5847 { "kill", MORE, 2, kill_unit },
5848 { "is-active", MORE, 2, check_unit_active },
5849 { "check", MORE, 2, check_unit_active },
5850 { "is-failed", MORE, 2, check_unit_failed },
5851 { "show", MORE, 1, show },
5852 { "cat", MORE, 2, cat },
5853 { "status", MORE, 1, show },
5854 { "help", MORE, 2, show },
5855 { "snapshot", LESS, 2, snapshot },
5856 { "delete", MORE, 2, delete_snapshot },
5857 { "daemon-reload", EQUAL, 1, daemon_reload },
5858 { "daemon-reexec", EQUAL, 1, daemon_reload },
5859 { "show-environment", EQUAL, 1, show_environment },
5860 { "set-environment", MORE, 2, set_environment },
5861 { "unset-environment", MORE, 2, set_environment },
5862 { "halt", EQUAL, 1, start_special, FORCE },
5863 { "poweroff", EQUAL, 1, start_special, FORCE },
5864 { "reboot", EQUAL, 1, start_special, FORCE },
5865 { "kexec", EQUAL, 1, start_special },
5866 { "suspend", EQUAL, 1, start_special },
5867 { "hibernate", EQUAL, 1, start_special },
5868 { "hybrid-sleep", EQUAL, 1, start_special },
5869 { "default", EQUAL, 1, start_special },
5870 { "rescue", EQUAL, 1, start_special },
5871 { "emergency", EQUAL, 1, start_special },
5872 { "exit", EQUAL, 1, start_special },
5873 { "reset-failed", MORE, 1, reset_failed },
5874 { "enable", MORE, 2, enable_unit, NOBUS },
5875 { "disable", MORE, 2, enable_unit, NOBUS },
5876 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
5877 { "reenable", MORE, 2, enable_unit, NOBUS },
5878 { "preset", MORE, 2, enable_unit, NOBUS },
5879 { "mask", MORE, 2, enable_unit, NOBUS },
5880 { "unmask", MORE, 2, enable_unit, NOBUS },
5881 { "link", MORE, 2, enable_unit, NOBUS },
5882 { "switch-root", MORE, 2, switch_root },
5883 { "list-dependencies", LESS, 2, list_dependencies },
5884 { "set-default", EQUAL, 2, set_default, NOBUS },
5885 { "get-default", EQUAL, 1, get_default, NOBUS },
5886 { "set-property", MORE, 3, set_property },
5895 left = argc - optind;
5897 /* Special rule: no arguments (left == 0) means "list-units" */
5899 if (streq(argv[optind], "help") && !argv[optind+1]) {
5900 log_error("This command expects one or more "
5901 "unit names. Did you mean --help?");
5905 for (; verb->verb; verb++)
5906 if (streq(argv[optind], verb->verb))
5909 log_error("Unknown operation '%s'.", argv[optind]);
5914 switch (verb->argc_cmp) {
5917 if (left != verb->argc) {
5918 log_error("Invalid number of arguments.");
5925 if (left < verb->argc) {
5926 log_error("Too few arguments.");
5933 if (left > verb->argc) {
5934 log_error("Too many arguments.");
5941 assert_not_reached("Unknown comparison operator.");
5944 /* Require a bus connection for all operations but
5946 if (verb->bus == NOBUS) {
5947 if (!bus && !avoid_bus()) {
5948 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5953 if (running_in_chroot() > 0) {
5954 log_info("Running in chroot, ignoring request.");
5958 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
5959 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
5964 return verb->dispatch(bus, argv + optind);
5967 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5969 struct sd_shutdown_command c = {
5976 union sockaddr_union sockaddr = {
5977 .un.sun_family = AF_UNIX,
5978 .un.sun_path = "/run/systemd/shutdownd",
5981 struct iovec iovec[2] = {{
5982 .iov_base = (char*) &c,
5983 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5986 struct msghdr msghdr = {
5987 .msg_name = &sockaddr,
5988 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5989 + sizeof("/run/systemd/shutdownd") - 1,
5994 _cleanup_close_ int fd;
5996 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6000 if (!isempty(message)) {
6001 iovec[1].iov_base = (char*) message;
6002 iovec[1].iov_len = strlen(message);
6003 msghdr.msg_iovlen++;
6006 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6012 static int reload_with_fallback(sd_bus *bus) {
6015 /* First, try systemd via D-Bus. */
6016 if (daemon_reload(bus, NULL) >= 0)
6020 /* Nothing else worked, so let's try signals */
6021 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6023 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6024 log_error("kill() failed: %m");
6031 static int start_with_fallback(sd_bus *bus) {
6034 /* First, try systemd via D-Bus. */
6035 if (start_unit(bus, NULL) >= 0)
6039 /* Nothing else worked, so let's try
6041 if (talk_initctl() > 0)
6044 log_error("Failed to talk to init daemon.");
6048 warn_wall(arg_action);
6052 static int halt_now(enum action a) {
6054 /* Make sure C-A-D is handled by the kernel from this
6056 reboot(RB_ENABLE_CAD);
6061 log_info("Halting.");
6062 reboot(RB_HALT_SYSTEM);
6065 case ACTION_POWEROFF:
6066 log_info("Powering off.");
6067 reboot(RB_POWER_OFF);
6070 case ACTION_REBOOT: {
6071 _cleanup_free_ char *param = NULL;
6073 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6074 log_info("Rebooting with argument '%s'.", param);
6075 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6076 LINUX_REBOOT_CMD_RESTART2, param);
6079 log_info("Rebooting.");
6080 reboot(RB_AUTOBOOT);
6085 assert_not_reached("Unknown action.");
6089 static int halt_main(sd_bus *bus) {
6092 r = check_inhibitors(bus, arg_action);
6096 if (geteuid() != 0) {
6097 /* Try logind if we are a normal user and no special
6098 * mode applies. Maybe PolicyKit allows us to shutdown
6101 if (arg_when <= 0 &&
6104 (arg_action == ACTION_POWEROFF ||
6105 arg_action == ACTION_REBOOT)) {
6106 r = reboot_with_logind(bus, arg_action);
6111 log_error("Must be root.");
6116 _cleanup_free_ char *m;
6118 m = strv_join(arg_wall, " ");
6122 r = send_shutdownd(arg_when,
6123 arg_action == ACTION_HALT ? 'H' :
6124 arg_action == ACTION_POWEROFF ? 'P' :
6125 arg_action == ACTION_KEXEC ? 'K' :
6132 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6134 char date[FORMAT_TIMESTAMP_MAX];
6136 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6137 format_timestamp(date, sizeof(date), arg_when));
6142 if (!arg_dry && !arg_force)
6143 return start_with_fallback(bus);
6146 if (sd_booted() > 0)
6147 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6149 r = utmp_put_shutdown();
6151 log_warning("Failed to write utmp record: %s", strerror(-r));
6158 r = halt_now(arg_action);
6159 log_error("Failed to reboot: %s", strerror(-r));
6164 static int runlevel_main(void) {
6165 int r, runlevel, previous;
6167 r = utmp_get_runlevel(&runlevel, &previous);
6174 previous <= 0 ? 'N' : previous,
6175 runlevel <= 0 ? 'N' : runlevel);
6180 int main(int argc, char*argv[]) {
6181 _cleanup_bus_unref_ sd_bus *bus = NULL;
6184 setlocale(LC_ALL, "");
6185 log_parse_environment();
6188 /* Explicitly not on_tty() to avoid setting cached value.
6189 * This becomes relevant for piping output which might be
6191 original_stdout_is_tty = isatty(STDOUT_FILENO);
6193 r = parse_argv(argc, argv);
6197 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6198 * let's shortcut this */
6199 if (arg_action == ACTION_RUNLEVEL) {
6200 r = runlevel_main();
6204 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6205 log_info("Running in chroot, ignoring request.");
6211 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6213 /* systemctl_main() will print an error message for the bus
6214 * connection, but only if it needs to */
6216 switch (arg_action) {
6218 case ACTION_SYSTEMCTL:
6219 r = systemctl_main(bus, argc, argv, r);
6223 case ACTION_POWEROFF:
6229 case ACTION_RUNLEVEL2:
6230 case ACTION_RUNLEVEL3:
6231 case ACTION_RUNLEVEL4:
6232 case ACTION_RUNLEVEL5:
6234 case ACTION_EMERGENCY:
6235 case ACTION_DEFAULT:
6236 r = start_with_fallback(bus);
6241 r = reload_with_fallback(bus);
6244 case ACTION_CANCEL_SHUTDOWN: {
6245 _cleanup_free_ char *m = NULL;
6248 m = strv_join(arg_wall, " ");
6255 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6257 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6261 case ACTION_RUNLEVEL:
6262 case _ACTION_INVALID:
6264 assert_not_reached("Unknown action");
6269 ask_password_agent_close();
6270 polkit_agent_close();
6272 strv_free(arg_types);
6273 strv_free(arg_states);
6274 strv_free(arg_properties);
6276 return r < 0 ? EXIT_FAILURE : r;