1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
50 #include "utmp-wtmp.h"
53 #include "path-util.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
76 static char **arg_types = NULL;
77 static char **arg_states = NULL;
78 static char **arg_properties = NULL;
79 static bool arg_all = false;
80 static enum dependency {
86 } arg_dependency = DEPENDENCY_FORWARD;
87 static const char *arg_job_mode = "replace";
88 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
89 static bool arg_no_block = false;
90 static bool arg_no_legend = false;
91 static bool arg_no_pager = false;
92 static bool arg_no_wtmp = false;
93 static bool arg_no_wall = false;
94 static bool arg_no_reload = false;
95 static bool arg_show_types = false;
96 static bool arg_ignore_inhibitors = false;
97 static bool arg_dry = false;
98 static bool arg_quiet = false;
99 static bool arg_full = false;
100 static bool arg_recursive = 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 const struct {
143 { "start", "StartUnit" },
144 { "stop", "StopUnit" },
145 { "condstop", "StopUnit" },
146 { "reload", "ReloadUnit" },
147 { "restart", "RestartUnit" },
148 { "try-restart", "TryRestartUnit" },
149 { "condrestart", "TryRestartUnit" },
150 { "reload-or-restart", "ReloadOrRestartUnit" },
151 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
152 { "condreload", "ReloadOrTryRestartUnit" },
153 { "force-reload", "ReloadOrTryRestartUnit" }
156 static bool original_stdout_is_tty;
158 static int daemon_reload(sd_bus *bus, char **args);
159 static int halt_now(enum action a);
160 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
162 static char** strv_skip_first(char **strv) {
163 if (strv_length(strv) > 0)
168 static void pager_open_if_enabled(void) {
176 static void ask_password_agent_open_if_enabled(void) {
178 /* Open the password agent as a child process if necessary */
180 if (!arg_ask_password)
183 if (arg_scope != UNIT_FILE_SYSTEM)
186 if (arg_transport != BUS_TRANSPORT_LOCAL)
189 ask_password_agent_open();
193 static void polkit_agent_open_if_enabled(void) {
195 /* Open the polkit agent as a child process if necessary */
197 if (!arg_ask_password)
200 if (arg_scope != UNIT_FILE_SYSTEM)
203 if (arg_transport != BUS_TRANSPORT_LOCAL)
210 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
213 if (!sd_bus_error_is_set(error))
216 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
217 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
218 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
219 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
220 return EXIT_NOPERMISSION;
222 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
223 return EXIT_NOTINSTALLED;
225 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
226 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
227 return EXIT_NOTIMPLEMENTED;
229 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
230 return EXIT_NOTCONFIGURED;
238 static void warn_wall(enum action a) {
239 static const char *table[_ACTION_MAX] = {
240 [ACTION_HALT] = "The system is going down for system halt NOW!",
241 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
242 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
243 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
244 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
245 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
246 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
253 _cleanup_free_ char *p;
255 p = strv_join(arg_wall, " ");
262 utmp_wall(p, NULL, NULL);
270 utmp_wall(table[a], NULL, NULL);
273 static bool avoid_bus(void) {
275 if (running_in_chroot() > 0)
278 if (sd_booted() <= 0)
281 if (!isempty(arg_root))
284 if (arg_scope == UNIT_FILE_GLOBAL)
290 static int compare_unit_info(const void *a, const void *b) {
291 const UnitInfo *u = a, *v = b;
295 /* First, order by machine */
296 if (!u->machine && v->machine)
298 if (u->machine && !v->machine)
300 if (u->machine && v->machine) {
301 r = strcasecmp(u->machine, v->machine);
306 /* Second, order by unit type */
307 d1 = strrchr(u->id, '.');
308 d2 = strrchr(v->id, '.');
310 r = strcasecmp(d1, d2);
315 /* Third, order by name */
316 return strcasecmp(u->id, v->id);
319 static bool output_show_unit(const UnitInfo *u, char **patterns) {
322 if (!strv_isempty(arg_states))
324 strv_contains(arg_states, u->load_state) ||
325 strv_contains(arg_states, u->sub_state) ||
326 strv_contains(arg_states, u->active_state);
328 if (!strv_isempty(patterns)) {
331 STRV_FOREACH(pattern, patterns)
332 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
337 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
338 strv_find(arg_types, dot+1))) &&
339 (arg_all || !(streq(u->active_state, "inactive")
340 || u->following[0]) || u->job_id > 0);
343 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
344 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
346 unsigned n_shown = 0;
349 max_id_len = strlen("UNIT");
350 load_len = strlen("LOAD");
351 active_len = strlen("ACTIVE");
352 sub_len = strlen("SUB");
353 job_len = strlen("JOB");
356 for (u = unit_infos; u < unit_infos + c; u++) {
357 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
358 load_len = MAX(load_len, strlen(u->load_state));
359 active_len = MAX(active_len, strlen(u->active_state));
360 sub_len = MAX(sub_len, strlen(u->sub_state));
362 if (u->job_id != 0) {
363 job_len = MAX(job_len, strlen(u->job_type));
367 if (!arg_no_legend &&
368 (streq(u->active_state, "failed") ||
369 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
373 if (!arg_full && original_stdout_is_tty) {
376 id_len = MIN(max_id_len, 25u);
377 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
380 basic_len += job_len + 1;
382 if (basic_len < (unsigned) columns()) {
383 unsigned extra_len, incr;
384 extra_len = columns() - basic_len;
386 /* Either UNIT already got 25, or is fully satisfied.
387 * Grant up to 25 to DESC now. */
388 incr = MIN(extra_len, 25u);
392 /* split the remaining space between UNIT and DESC,
393 * but do not give UNIT more than it needs. */
395 incr = MIN(extra_len / 2, max_id_len - id_len);
397 desc_len += extra_len - incr;
403 for (u = unit_infos; u < unit_infos + c; u++) {
404 _cleanup_free_ char *e = NULL, *j = NULL;
405 const char *on_loaded = "", *off_loaded = "";
406 const char *on_active = "", *off_active = "";
407 const char *on_circle = "", *off_circle = "";
411 if (!n_shown && !arg_no_legend) {
416 printf("%-*s %-*s %-*s %-*s ",
419 active_len, "ACTIVE",
423 printf("%-*s ", job_len, "JOB");
425 if (!arg_full && arg_no_pager)
426 printf("%.*s\n", desc_len, "DESCRIPTION");
428 printf("%s\n", "DESCRIPTION");
433 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
434 on_loaded = ansi_highlight_red();
435 on_circle = ansi_highlight_yellow();
436 off_loaded = off_circle = ansi_highlight_off();
440 if (streq(u->active_state, "failed")) {
441 on_circle = on_active = ansi_highlight_red();
442 off_circle = off_active = ansi_highlight_off();
447 j = strjoin(u->machine, ":", u->id, NULL);
456 e = ellipsize(id, id_len, 33);
464 printf("%s%s%s", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
466 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
467 on_active, id_len, id, off_active,
468 on_loaded, load_len, u->load_state, off_loaded,
469 on_active, active_len, u->active_state,
470 sub_len, u->sub_state, off_active,
471 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
474 printf("%.*s\n", desc_len, u->description);
476 printf("%s\n", u->description);
479 if (!arg_no_legend) {
480 const char *on, *off;
484 "LOAD = Reflects whether the unit definition was properly loaded.\n"
485 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
486 "SUB = The low-level unit activation state, values depend on unit type.");
487 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
488 on = ansi_highlight();
489 off = ansi_highlight_off();
491 on = ansi_highlight_red();
492 off = ansi_highlight_off();
496 printf("%s%u loaded units listed.%s\n"
497 "To show all installed unit files use 'systemctl list-unit-files'.\n",
500 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
501 "To show all installed unit files use 'systemctl list-unit-files'.\n",
508 static int get_unit_list(
512 UnitInfo **unit_infos,
514 sd_bus_message **_reply) {
516 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
517 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
526 r = sd_bus_call_method(
528 "org.freedesktop.systemd1",
529 "/org/freedesktop/systemd1",
530 "org.freedesktop.systemd1.Manager",
536 log_error("Failed to list units: %s", bus_error_message(&error, r));
540 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
542 return bus_log_parse_error(r);
544 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
547 if (!output_show_unit(&u, patterns))
550 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
553 (*unit_infos)[c++] = u;
556 return bus_log_parse_error(r);
558 r = sd_bus_message_exit_container(reply);
560 return bus_log_parse_error(r);
568 static void message_set_freep(Set **set) {
571 while ((m = set_steal_first(*set)))
572 sd_bus_message_unref(m);
577 static int get_unit_list_recursive(
580 UnitInfo **_unit_infos,
584 _cleanup_free_ UnitInfo *unit_infos = NULL;
585 _cleanup_(message_set_freep) Set *replies;
586 sd_bus_message *reply;
594 replies = set_new(NULL, NULL);
598 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
602 r = set_put(replies, reply);
604 sd_bus_message_unref(reply);
609 _cleanup_strv_free_ char **machines = NULL;
612 r = sd_get_machine_names(&machines);
616 STRV_FOREACH(i, machines) {
617 _cleanup_bus_unref_ sd_bus *container = NULL;
620 r = sd_bus_open_system_container(&container, *i);
622 log_error("Failed to connect to container %s: %s", *i, strerror(-r));
626 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
632 r = set_put(replies, reply);
634 sd_bus_message_unref(reply);
639 *_machines = machines;
644 *_unit_infos = unit_infos;
653 static int list_units(sd_bus *bus, char **args) {
654 _cleanup_free_ UnitInfo *unit_infos = NULL;
655 _cleanup_(message_set_freep) Set *replies = NULL;
656 _cleanup_strv_free_ char **machines = NULL;
659 pager_open_if_enabled();
661 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
665 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
666 return output_units_list(unit_infos, r);
669 static int get_triggered_units(
674 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
677 r = sd_bus_get_property_strv(
679 "org.freedesktop.systemd1",
681 "org.freedesktop.systemd1.Unit",
687 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
692 static int get_listening(
694 const char* unit_path,
697 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
698 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
699 const char *type, *path;
702 r = sd_bus_get_property(
704 "org.freedesktop.systemd1",
706 "org.freedesktop.systemd1.Socket",
712 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
716 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
718 return bus_log_parse_error(r);
720 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
722 r = strv_extend(listening, type);
726 r = strv_extend(listening, path);
733 return bus_log_parse_error(r);
735 r = sd_bus_message_exit_container(reply);
737 return bus_log_parse_error(r);
749 /* Note: triggered is a list here, although it almost certainly
750 * will always be one unit. Nevertheless, dbus API allows for multiple
751 * values, so let's follow that.*/
754 /* The strv above is shared. free is set only in the first one. */
758 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
764 if (!a->machine && b->machine)
766 if (a->machine && !b->machine)
768 if (a->machine && b->machine) {
769 o = strcasecmp(a->machine, b->machine);
774 o = strcmp(a->path, b->path);
776 o = strcmp(a->type, b->type);
781 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
782 struct socket_info *s;
783 unsigned pathlen = strlen("LISTEN"),
784 typelen = strlen("TYPE") * arg_show_types,
785 socklen = strlen("UNIT"),
786 servlen = strlen("ACTIVATES");
787 const char *on, *off;
789 for (s = socket_infos; s < socket_infos + cs; s++) {
793 socklen = MAX(socklen, strlen(s->id));
795 typelen = MAX(typelen, strlen(s->type));
796 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
798 STRV_FOREACH(a, s->triggered)
799 tmp += strlen(*a) + 2*(a != s->triggered);
800 servlen = MAX(servlen, tmp);
805 printf("%-*s %-*.*s%-*s %s\n",
807 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
811 for (s = socket_infos; s < socket_infos + cs; s++) {
812 _cleanup_free_ char *j = NULL;
817 j = strjoin(s->machine, ":", s->path, NULL);
825 printf("%-*s %-*s %-*s",
826 pathlen, path, typelen, s->type, socklen, s->id);
829 pathlen, path, socklen, s->id);
830 STRV_FOREACH(a, s->triggered)
832 a == s->triggered ? "" : ",", *a);
836 on = ansi_highlight();
837 off = ansi_highlight_off();
841 on = ansi_highlight_red();
842 off = ansi_highlight_off();
845 if (!arg_no_legend) {
846 printf("%s%u sockets listed.%s\n", on, cs, off);
848 printf("Pass --all to see loaded but inactive sockets, too.\n");
854 static int list_sockets(sd_bus *bus, char **args) {
855 _cleanup_(message_set_freep) Set *replies = NULL;
856 _cleanup_strv_free_ char **machines = NULL;
857 _cleanup_free_ UnitInfo *unit_infos = NULL;
858 _cleanup_free_ struct socket_info *socket_infos = NULL;
860 struct socket_info *s;
865 pager_open_if_enabled();
867 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
871 for (u = unit_infos; u < unit_infos + n; u++) {
872 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
875 if (!endswith(u->id, ".socket"))
878 r = get_triggered_units(bus, u->unit_path, &triggered);
882 c = get_listening(bus, u->unit_path, &listening);
888 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
893 for (i = 0; i < c; i++)
894 socket_infos[cs + i] = (struct socket_info) {
895 .machine = u->machine,
897 .type = listening[i*2],
898 .path = listening[i*2 + 1],
899 .triggered = triggered,
900 .own_triggered = i==0,
903 /* from this point on we will cleanup those socket_infos */
906 listening = triggered = NULL; /* avoid cleanup */
909 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
910 (__compar_fn_t) socket_info_compare);
912 output_sockets_list(socket_infos, cs);
915 assert(cs == 0 || socket_infos);
916 for (s = socket_infos; s < socket_infos + cs; s++) {
919 if (s->own_triggered)
920 strv_free(s->triggered);
926 static int get_next_elapse(
929 dual_timestamp *next) {
931 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
939 r = sd_bus_get_property_trivial(
941 "org.freedesktop.systemd1",
943 "org.freedesktop.systemd1.Timer",
944 "NextElapseUSecMonotonic",
949 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
953 r = sd_bus_get_property_trivial(
955 "org.freedesktop.systemd1",
957 "org.freedesktop.systemd1.Timer",
958 "NextElapseUSecRealtime",
963 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
971 static int get_last_trigger(
976 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
983 r = sd_bus_get_property_trivial(
985 "org.freedesktop.systemd1",
987 "org.freedesktop.systemd1.Timer",
993 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1003 usec_t last_trigger;
1007 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1011 if (a->next_elapse < b->next_elapse)
1013 if (a->next_elapse > b->next_elapse)
1016 return strcmp(a->id, b->id);
1019 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1020 struct timer_info *t;
1022 nextlen = strlen("NEXT"),
1023 leftlen = strlen("LEFT"),
1024 lastlen = strlen("LAST"),
1025 passedlen = strlen("PASSED"),
1026 unitlen = strlen("UNIT"),
1027 activatelen = strlen("ACTIVATES");
1029 const char *on, *off;
1031 assert(timer_infos || n == 0);
1033 for (t = timer_infos; t < timer_infos + n; t++) {
1037 if (t->next_elapse > 0) {
1038 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1040 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1041 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1043 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1044 leftlen = MAX(leftlen, strlen(trel));
1047 if (t->last_trigger > 0) {
1048 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1050 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1051 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1053 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1054 passedlen = MAX(passedlen, strlen(trel));
1057 unitlen = MAX(unitlen, strlen(t->id));
1059 STRV_FOREACH(a, t->triggered)
1060 ul += strlen(*a) + 2*(a != t->triggered);
1062 activatelen = MAX(activatelen, ul);
1067 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1071 passedlen, "PASSED",
1075 for (t = timer_infos; t < timer_infos + n; t++) {
1076 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1077 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1080 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1081 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1083 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1084 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1086 printf("%-*s %-*s %-*s %-*s %-*s",
1087 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, t->id);
1089 STRV_FOREACH(a, t->triggered)
1091 a == t->triggered ? "" : ",", *a);
1095 on = ansi_highlight();
1096 off = ansi_highlight_off();
1100 on = ansi_highlight_red();
1101 off = ansi_highlight_off();
1104 if (!arg_no_legend) {
1105 printf("%s%u timers listed.%s\n", on, n, off);
1107 printf("Pass --all to see loaded but inactive timers, too.\n");
1113 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1119 if (next->monotonic != (usec_t) -1 && next->monotonic > 0) {
1122 if (next->monotonic > nw->monotonic)
1123 converted = nw->realtime + (next->monotonic - nw->monotonic);
1125 converted = nw->realtime - (nw->monotonic - next->monotonic);
1127 if (next->realtime != (usec_t) -1 && next->realtime > 0)
1128 next_elapse = MIN(converted, next->realtime);
1130 next_elapse = converted;
1133 next_elapse = next->realtime;
1138 static int list_timers(sd_bus *bus, char **args) {
1140 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1141 _cleanup_free_ struct timer_info *timer_infos = NULL;
1142 _cleanup_free_ UnitInfo *unit_infos = NULL;
1143 struct timer_info *t;
1150 pager_open_if_enabled();
1152 n = get_unit_list(bus, NULL, strv_skip_first(args), &unit_infos, 0, &reply);
1156 dual_timestamp_get(&nw);
1158 for (u = unit_infos; u < unit_infos + n; u++) {
1159 _cleanup_strv_free_ char **triggered = NULL;
1160 dual_timestamp next = {};
1163 if (!endswith(u->id, ".timer"))
1166 r = get_triggered_units(bus, u->unit_path, &triggered);
1170 r = get_next_elapse(bus, u->unit_path, &next);
1174 get_last_trigger(bus, u->unit_path, &last);
1176 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1181 m = calc_next_elapse(&nw, &next);
1183 timer_infos[c++] = (struct timer_info) {
1186 .last_trigger = last,
1187 .triggered = triggered,
1190 triggered = NULL; /* avoid cleanup */
1193 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1194 (__compar_fn_t) timer_info_compare);
1196 output_timers_list(timer_infos, c);
1199 for (t = timer_infos; t < timer_infos + c; t++)
1200 strv_free(t->triggered);
1205 static int compare_unit_file_list(const void *a, const void *b) {
1206 const char *d1, *d2;
1207 const UnitFileList *u = a, *v = b;
1209 d1 = strrchr(u->path, '.');
1210 d2 = strrchr(v->path, '.');
1215 r = strcasecmp(d1, d2);
1220 return strcasecmp(basename(u->path), basename(v->path));
1223 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1226 if (!strv_isempty(patterns)) {
1229 STRV_FOREACH(pattern, patterns)
1230 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1235 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1238 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1239 unsigned max_id_len, id_cols, state_cols;
1240 const UnitFileList *u;
1242 max_id_len = strlen("UNIT FILE");
1243 state_cols = strlen("STATE");
1245 for (u = units; u < units + c; u++) {
1246 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1247 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1251 unsigned basic_cols;
1253 id_cols = MIN(max_id_len, 25u);
1254 basic_cols = 1 + id_cols + state_cols;
1255 if (basic_cols < (unsigned) columns())
1256 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1258 id_cols = max_id_len;
1261 printf("%-*s %-*s\n",
1262 id_cols, "UNIT FILE",
1263 state_cols, "STATE");
1265 for (u = units; u < units + c; u++) {
1266 _cleanup_free_ char *e = NULL;
1267 const char *on, *off;
1270 if (u->state == UNIT_FILE_MASKED ||
1271 u->state == UNIT_FILE_MASKED_RUNTIME ||
1272 u->state == UNIT_FILE_DISABLED ||
1273 u->state == UNIT_FILE_INVALID) {
1274 on = ansi_highlight_red();
1275 off = ansi_highlight_off();
1276 } else if (u->state == UNIT_FILE_ENABLED) {
1277 on = ansi_highlight_green();
1278 off = ansi_highlight_off();
1282 id = basename(u->path);
1284 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1286 printf("%-*s %s%-*s%s\n",
1287 id_cols, e ? e : id,
1288 on, state_cols, unit_file_state_to_string(u->state), off);
1292 printf("\n%u unit files listed.\n", c);
1295 static int list_unit_files(sd_bus *bus, char **args) {
1296 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1297 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1298 _cleanup_free_ UnitFileList *units = NULL;
1306 pager_open_if_enabled();
1314 h = hashmap_new(string_hash_func, string_compare_func);
1318 r = unit_file_get_list(arg_scope, arg_root, h);
1320 unit_file_list_free(h);
1321 log_error("Failed to get unit file list: %s", strerror(-r));
1325 n_units = hashmap_size(h);
1326 units = new(UnitFileList, n_units);
1328 unit_file_list_free(h);
1332 HASHMAP_FOREACH(u, h, i) {
1333 if (!output_show_unit_file(u, strv_skip_first(args)))
1340 assert(c <= n_units);
1343 r = sd_bus_call_method(
1345 "org.freedesktop.systemd1",
1346 "/org/freedesktop/systemd1",
1347 "org.freedesktop.systemd1.Manager",
1353 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1357 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1359 return bus_log_parse_error(r);
1361 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1363 if (!GREEDY_REALLOC(units, size, c + 1))
1366 units[c] = (struct UnitFileList) {
1368 unit_file_state_from_string(state)
1371 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1376 return bus_log_parse_error(r);
1378 r = sd_bus_message_exit_container(reply);
1380 return bus_log_parse_error(r);
1384 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1385 output_unit_file_list(units, c);
1389 for (unit = units; unit < units + c; unit++)
1395 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1396 _cleanup_free_ char *n = NULL;
1397 size_t max_len = MAX(columns(),20u);
1403 for (i = level - 1; i >= 0; i--) {
1405 if (len > max_len - 3 && !arg_full) {
1406 printf("%s...\n",max_len % 2 ? "" : " ");
1409 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1413 if (len > max_len - 3 && !arg_full) {
1414 printf("%s...\n",max_len % 2 ? "" : " ");
1418 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1422 printf("%s\n", name);
1426 n = ellipsize(name, max_len-len, 100);
1434 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1436 static const char *dependencies[_DEPENDENCY_MAX] = {
1437 [DEPENDENCY_FORWARD] = "Requires\0"
1438 "RequiresOverridable\0"
1440 "RequisiteOverridable\0"
1442 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1443 "RequiredByOverridable\0"
1446 [DEPENDENCY_AFTER] = "After\0",
1447 [DEPENDENCY_BEFORE] = "Before\0",
1450 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1451 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1452 _cleanup_strv_free_ char **ret = NULL;
1453 _cleanup_free_ char *path = NULL;
1459 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1461 path = unit_dbus_path_from_name(name);
1465 r = sd_bus_call_method(
1467 "org.freedesktop.systemd1",
1469 "org.freedesktop.DBus.Properties",
1473 "s", "org.freedesktop.systemd1.Unit");
1475 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1479 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1481 return bus_log_parse_error(r);
1483 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1486 r = sd_bus_message_read(reply, "s", &prop);
1488 return bus_log_parse_error(r);
1490 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1491 r = sd_bus_message_skip(reply, "v");
1493 return bus_log_parse_error(r);
1496 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1498 return bus_log_parse_error(r);
1500 r = bus_message_read_strv_extend(reply, &ret);
1502 return bus_log_parse_error(r);
1504 r = sd_bus_message_exit_container(reply);
1506 return bus_log_parse_error(r);
1509 r = sd_bus_message_exit_container(reply);
1511 return bus_log_parse_error(r);
1515 return bus_log_parse_error(r);
1517 r = sd_bus_message_exit_container(reply);
1519 return bus_log_parse_error(r);
1527 static int list_dependencies_compare(const void *_a, const void *_b) {
1528 const char **a = (const char**) _a, **b = (const char**) _b;
1530 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1532 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1535 return strcasecmp(*a, *b);
1538 static int list_dependencies_one(
1543 unsigned int branches) {
1545 _cleanup_strv_free_ char **deps = NULL;
1553 r = strv_extend(units, name);
1557 r = list_dependencies_get_dependencies(bus, name, &deps);
1561 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1563 STRV_FOREACH(c, deps) {
1566 if (strv_contains(*units, *c)) {
1568 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1575 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1577 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1579 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1581 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1585 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1586 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1593 strv_remove(*units, name);
1598 static int list_dependencies(sd_bus *bus, char **args) {
1599 _cleanup_strv_free_ char **units = NULL;
1600 _cleanup_free_ char *unit = NULL;
1606 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1611 u = SPECIAL_DEFAULT_TARGET;
1613 pager_open_if_enabled();
1617 return list_dependencies_one(bus, u, 0, &units, 0);
1620 struct machine_info {
1624 char *control_group;
1625 uint32_t n_failed_units;
1630 static const struct bus_properties_map machine_info_property_map[] = {
1631 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1632 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1633 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1634 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1635 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1639 static void free_machines_list(struct machine_info *machine_infos, int n) {
1645 for (i = 0; i < n; i++) {
1646 free(machine_infos[i].name);
1647 free(machine_infos[i].state);
1648 free(machine_infos[i].control_group);
1651 free(machine_infos);
1654 static int compare_machine_info(const void *a, const void *b) {
1655 const struct machine_info *u = a, *v = b;
1657 if (u->is_host != v->is_host)
1658 return u->is_host > v->is_host ? -1 : 1;
1660 return strcasecmp(u->name, v->name);
1663 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1664 _cleanup_bus_unref_ sd_bus *container = NULL;
1670 r = sd_bus_open_system_container(&container, mi->name);
1677 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1684 static bool output_show_machine(const char *name, char **patterns) {
1689 if (strv_isempty(patterns))
1692 STRV_FOREACH(i, patterns)
1693 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1699 static int get_machine_list(
1701 struct machine_info **_machine_infos,
1704 struct machine_info *machine_infos = NULL;
1705 _cleanup_strv_free_ char **m = NULL;
1706 _cleanup_free_ char *hn = NULL;
1711 hn = gethostname_malloc();
1715 if (output_show_machine(hn, patterns)) {
1716 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1719 machine_infos[c].is_host = true;
1720 machine_infos[c].name = hn;
1723 get_machine_properties(bus, &machine_infos[c]);
1727 sd_get_machine_names(&m);
1728 STRV_FOREACH(i, m) {
1729 _cleanup_free_ char *class = NULL;
1731 if (!output_show_machine(*i, patterns))
1734 sd_machine_get_class(*i, &class);
1735 if (!streq_ptr(class, "container"))
1738 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1739 free_machines_list(machine_infos, c);
1743 machine_infos[c].is_host = false;
1744 machine_infos[c].name = strdup(*i);
1745 if (!machine_infos[c].name) {
1746 free_machines_list(machine_infos, c);
1750 get_machine_properties(NULL, &machine_infos[c]);
1754 *_machine_infos = machine_infos;
1758 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1759 struct machine_info *m;
1762 namelen = sizeof("NAME") - 1,
1763 statelen = sizeof("STATE") - 1,
1764 failedlen = sizeof("FAILED") - 1,
1765 jobslen = sizeof("JOBS") - 1;
1767 assert(machine_infos || n == 0);
1769 for (m = machine_infos; m < machine_infos + n; m++) {
1770 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1771 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1772 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1773 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1775 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1779 if (!arg_no_legend) {
1783 printf("%-*s %-*s %-*s %-*s\n",
1786 failedlen, "FAILED",
1790 for (m = machine_infos; m < machine_infos + n; m++) {
1791 const char *on_state = "", *off_state = "";
1792 const char *on_failed = "", *off_failed = "";
1793 bool circle = false;
1795 if (streq_ptr(m->state, "degraded")) {
1796 on_state = ansi_highlight_red();
1797 off_state = ansi_highlight_off();
1799 } else if (!streq_ptr(m->state, "running")) {
1800 on_state = ansi_highlight_yellow();
1801 off_state = ansi_highlight_off();
1805 if (m->n_failed_units > 0) {
1806 on_failed = ansi_highlight_red();
1807 off_failed = ansi_highlight_off();
1809 on_failed = off_failed = "";
1812 printf("%s%s%s", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1815 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1816 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1817 on_state, statelen, strna(m->state), off_state,
1818 on_failed, failedlen, m->n_failed_units, off_failed,
1819 jobslen, m->n_jobs);
1821 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1822 namelen, strna(m->name),
1823 on_state, statelen, strna(m->state), off_state,
1824 on_failed, failedlen, m->n_failed_units, off_failed,
1825 jobslen, m->n_jobs);
1829 printf("\n%u machines listed.\n", n);
1832 static int list_machines(sd_bus *bus, char **args) {
1833 struct machine_info *machine_infos = NULL;
1838 if (geteuid() != 0) {
1839 log_error("Must be root.");
1843 pager_open_if_enabled();
1845 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1849 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1850 output_machines_list(machine_infos, r);
1851 free_machines_list(machine_infos, r);
1856 static int get_default(sd_bus *bus, char **args) {
1857 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1858 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1859 _cleanup_free_ char *_path = NULL;
1863 if (!bus || avoid_bus()) {
1864 r = unit_file_get_default(arg_scope, arg_root, &_path);
1866 log_error("Failed to get default target: %s", strerror(-r));
1872 r = sd_bus_call_method(
1874 "org.freedesktop.systemd1",
1875 "/org/freedesktop/systemd1",
1876 "org.freedesktop.systemd1.Manager",
1882 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1886 r = sd_bus_message_read(reply, "s", &path);
1888 return bus_log_parse_error(r);
1892 printf("%s\n", path);
1897 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1900 assert(changes || n_changes == 0);
1902 for (i = 0; i < n_changes; i++) {
1903 if (changes[i].type == UNIT_FILE_SYMLINK)
1904 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1906 log_info("rm '%s'", changes[i].path);
1910 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1911 const char *type, *path, *source;
1914 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1916 return bus_log_parse_error(r);
1918 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1920 if (streq(type, "symlink"))
1921 log_info("ln -s '%s' '%s'", source, path);
1923 log_info("rm '%s'", path);
1927 return bus_log_parse_error(r);
1929 r = sd_bus_message_exit_container(m);
1931 return bus_log_parse_error(r);
1936 static int set_default(sd_bus *bus, char **args) {
1937 _cleanup_free_ char *unit = NULL;
1938 UnitFileChange *changes = NULL;
1939 unsigned n_changes = 0;
1942 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1946 if (!bus || avoid_bus()) {
1947 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1949 log_error("Failed to set default target: %s", strerror(-r));
1954 dump_unit_file_changes(changes, n_changes);
1958 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1959 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1961 r = sd_bus_call_method(
1963 "org.freedesktop.systemd1",
1964 "/org/freedesktop/systemd1",
1965 "org.freedesktop.systemd1.Manager",
1969 "sb", unit, arg_force);
1971 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1975 r = deserialize_and_dump_unit_file_changes(reply);
1979 /* Try to reload if enabled */
1981 r = daemon_reload(bus, args);
1986 unit_file_changes_free(changes, n_changes);
1993 const char *name, *type, *state;
1996 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1997 unsigned id_len, unit_len, type_len, state_len;
1998 const struct job_info *j;
1999 const char *on, *off;
2000 bool shorten = false;
2002 assert(n == 0 || jobs);
2005 on = ansi_highlight_green();
2006 off = ansi_highlight_off();
2008 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2012 pager_open_if_enabled();
2014 id_len = strlen("JOB");
2015 unit_len = strlen("UNIT");
2016 type_len = strlen("TYPE");
2017 state_len = strlen("STATE");
2019 for (j = jobs; j < jobs + n; j++) {
2020 uint32_t id = j->id;
2021 assert(j->name && j->type && j->state);
2023 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2024 unit_len = MAX(unit_len, strlen(j->name));
2025 type_len = MAX(type_len, strlen(j->type));
2026 state_len = MAX(state_len, strlen(j->state));
2029 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2030 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2035 printf("%*s %-*s %-*s %-*s\n",
2039 state_len, "STATE");
2041 for (j = jobs; j < jobs + n; j++) {
2042 _cleanup_free_ char *e = NULL;
2044 if (streq(j->state, "running")) {
2045 on = ansi_highlight();
2046 off = ansi_highlight_off();
2050 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2051 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2053 on, unit_len, e ? e : j->name, off,
2055 on, state_len, j->state, off);
2058 if (!arg_no_legend) {
2059 on = ansi_highlight();
2060 off = ansi_highlight_off();
2062 printf("\n%s%u jobs listed%s.\n", on, n, off);
2066 static bool output_show_job(struct job_info *job, char **patterns) {
2071 if (strv_isempty(patterns))
2074 STRV_FOREACH(pattern, patterns)
2075 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2080 static int list_jobs(sd_bus *bus, char **args) {
2081 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2082 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2083 const char *name, *type, *state, *job_path, *unit_path;
2084 _cleanup_free_ struct job_info *jobs = NULL;
2089 bool skipped = false;
2091 r = sd_bus_call_method(
2093 "org.freedesktop.systemd1",
2094 "/org/freedesktop/systemd1",
2095 "org.freedesktop.systemd1.Manager",
2101 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2105 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2107 return bus_log_parse_error(r);
2109 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2110 struct job_info job = { id, name, type, state };
2112 if (!output_show_job(&job, strv_skip_first(args))) {
2117 if (!GREEDY_REALLOC(jobs, size, c + 1))
2123 return bus_log_parse_error(r);
2125 r = sd_bus_message_exit_container(reply);
2127 return bus_log_parse_error(r);
2129 output_jobs_list(jobs, c, skipped);
2133 static int cancel_job(sd_bus *bus, char **args) {
2134 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2139 if (strv_length(args) <= 1)
2140 return daemon_reload(bus, args);
2142 STRV_FOREACH(name, args+1) {
2146 r = safe_atou32(*name, &id);
2148 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
2152 r = sd_bus_call_method(
2154 "org.freedesktop.systemd1",
2155 "/org/freedesktop/systemd1",
2156 "org.freedesktop.systemd1.Manager",
2162 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
2170 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2171 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2175 /* We ignore all errors here, since this is used to show a
2178 /* We don't use unit_dbus_path_from_name() directly since we
2179 * don't want to load the unit if it isn't loaded. */
2181 r = sd_bus_call_method(
2183 "org.freedesktop.systemd1",
2184 "/org/freedesktop/systemd1",
2185 "org.freedesktop.systemd1.Manager",
2193 r = sd_bus_message_read(reply, "o", &path);
2197 r = sd_bus_get_property_trivial(
2199 "org.freedesktop.systemd1",
2201 "org.freedesktop.systemd1.Unit",
2211 typedef struct WaitData {
2218 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2225 log_debug("Got D-Bus request: %s.%s() on %s",
2226 sd_bus_message_get_interface(m),
2227 sd_bus_message_get_member(m),
2228 sd_bus_message_get_path(m));
2230 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2231 log_error("Warning! D-Bus connection terminated.");
2233 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2235 const char *path, *result, *unit;
2239 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2241 ret = set_remove(d->set, (char*) path);
2247 if (!isempty(result))
2248 d->result = strdup(result);
2251 d->name = strdup(unit);
2256 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2258 ret = set_remove(d->set, (char*) path);
2265 d->result = strdup(result);
2271 bus_log_parse_error(r);
2277 static int enable_wait_for_jobs(sd_bus *bus) {
2282 r = sd_bus_add_match(
2285 "sender='org.freedesktop.systemd1',"
2286 "interface='org.freedesktop.systemd1.Manager',"
2287 "member='JobRemoved',"
2288 "path='/org/freedesktop/systemd1'",
2291 log_error("Failed to add match");
2295 /* This is slightly dirty, since we don't undo the match registrations. */
2299 static int bus_process_wait(sd_bus *bus) {
2303 r = sd_bus_process(bus, NULL);
2308 r = sd_bus_wait(bus, (uint64_t) -1);
2314 static int check_wait_response(WaitData *d) {
2320 if (streq(d->result, "timeout"))
2321 log_error("Job for %s timed out.", strna(d->name));
2322 else if (streq(d->result, "canceled"))
2323 log_error("Job for %s canceled.", strna(d->name));
2324 else if (streq(d->result, "dependency"))
2325 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2326 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2327 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2330 if (streq(d->result, "timeout"))
2332 else if (streq(d->result, "canceled"))
2334 else if (streq(d->result, "dependency"))
2336 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2342 static int wait_for_jobs(sd_bus *bus, Set *s) {
2343 WaitData d = { .set = s };
2349 q = sd_bus_add_filter(bus, wait_filter, &d);
2353 while (!set_isempty(s)) {
2354 q = bus_process_wait(bus);
2356 log_error("Failed to wait for response: %s", strerror(-r));
2361 q = check_wait_response(&d);
2362 /* Return the first error as it is most likely to be
2364 if (q < 0 && r == 0)
2366 log_debug("Got result %s/%s for job %s",
2367 strna(d.result), strerror(-q), strna(d.name));
2377 q = sd_bus_remove_filter(bus, wait_filter, &d);
2378 if (q < 0 && r == 0)
2384 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2385 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2386 _cleanup_free_ char *n = NULL, *state = NULL;
2392 n = unit_name_mangle(name, MANGLE_NOGLOB);
2396 /* We don't use unit_dbus_path_from_name() directly since we
2397 * don't want to load the unit if it isn't loaded. */
2399 r = sd_bus_call_method(
2401 "org.freedesktop.systemd1",
2402 "/org/freedesktop/systemd1",
2403 "org.freedesktop.systemd1.Manager",
2414 r = sd_bus_message_read(reply, "o", &path);
2416 return bus_log_parse_error(r);
2418 r = sd_bus_get_property_string(
2420 "org.freedesktop.systemd1",
2422 "org.freedesktop.systemd1.Unit",
2435 return nulstr_contains(good_states, state);
2438 static int check_triggering_units(
2442 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2443 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2444 _cleanup_strv_free_ char **triggered_by = NULL;
2445 bool print_warning_label = true;
2449 n = unit_name_mangle(name, MANGLE_NOGLOB);
2453 path = unit_dbus_path_from_name(n);
2457 r = sd_bus_get_property_string(
2459 "org.freedesktop.systemd1",
2461 "org.freedesktop.systemd1.Unit",
2466 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2470 if (streq(state, "masked"))
2473 r = sd_bus_get_property_strv(
2475 "org.freedesktop.systemd1",
2477 "org.freedesktop.systemd1.Unit",
2482 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2486 STRV_FOREACH(i, triggered_by) {
2487 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2489 log_error("Failed to check unit: %s", strerror(-r));
2496 if (print_warning_label) {
2497 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2498 print_warning_label = false;
2501 log_warning(" %s", *i);
2507 static const char *verb_to_method(const char *verb) {
2510 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2511 if (streq_ptr(unit_actions[i].verb, verb))
2512 return unit_actions[i].method;
2517 static const char *method_to_verb(const char *method) {
2520 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2521 if (streq_ptr(unit_actions[i].method, method))
2522 return unit_actions[i].verb;
2527 static int start_unit_one(
2532 sd_bus_error *error,
2535 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2544 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2545 r = sd_bus_call_method(
2547 "org.freedesktop.systemd1",
2548 "/org/freedesktop/systemd1",
2549 "org.freedesktop.systemd1.Manager",
2557 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2558 /* There's always a fallback possible for
2559 * legacy actions. */
2560 return -EADDRNOTAVAIL;
2562 verb = method_to_verb(method);
2564 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2568 r = sd_bus_message_read(reply, "o", &path);
2570 return bus_log_parse_error(r);
2572 if (need_daemon_reload(bus, name) > 0)
2573 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2574 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2583 log_debug("Adding %s to the set", p);
2584 r = set_consume(s, p);
2592 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2594 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2598 STRV_FOREACH(name, names) {
2602 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2604 t = unit_name_mangle(*name, MANGLE_GLOB);
2608 if (string_is_glob(t))
2609 r = strv_consume(&globs, t);
2611 r = strv_consume(&mangled, t);
2616 /* Query the manager only if any of the names are a glob, since
2617 * this is fairly expensive */
2618 if (!strv_isempty(globs)) {
2619 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2620 _cleanup_free_ UnitInfo *unit_infos = NULL;
2622 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2626 for (i = 0; i < r; i++)
2627 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2632 mangled = NULL; /* do not free */
2637 static const struct {
2641 } action_table[_ACTION_MAX] = {
2642 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2643 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2644 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2645 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2646 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2647 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2648 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2649 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2650 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2651 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2652 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2653 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2654 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2655 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2656 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2659 static enum action verb_to_action(const char *verb) {
2662 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2663 if (streq_ptr(action_table[i].verb, verb))
2666 return _ACTION_INVALID;
2669 static int start_unit(sd_bus *bus, char **args) {
2670 _cleanup_set_free_free_ Set *s = NULL;
2671 _cleanup_strv_free_ char **names = NULL;
2672 const char *method, *mode, *one_name;
2678 ask_password_agent_open_if_enabled();
2680 if (arg_action == ACTION_SYSTEMCTL) {
2682 method = verb_to_method(args[0]);
2683 action = verb_to_action(args[0]);
2685 mode = streq(args[0], "isolate") ? "isolate" :
2686 action_table[action].mode ?: arg_job_mode;
2688 one_name = action_table[action].target;
2690 assert(arg_action < ELEMENTSOF(action_table));
2691 assert(action_table[arg_action].target);
2693 method = "StartUnit";
2695 mode = action_table[arg_action].mode;
2696 one_name = action_table[arg_action].target;
2700 names = strv_new(one_name, NULL);
2702 r = expand_names(bus, args + 1, NULL, &names);
2704 log_error("Failed to expand names: %s", strerror(-r));
2707 if (!arg_no_block) {
2708 r = enable_wait_for_jobs(bus);
2710 log_error("Could not watch jobs: %s", strerror(-r));
2714 s = set_new(string_hash_func, string_compare_func);
2719 STRV_FOREACH(name, names) {
2720 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2723 q = start_unit_one(bus, method, *name, mode, &error, s);
2724 if (r >= 0 && q < 0)
2725 r = translate_bus_error_to_exit_status(q, &error);
2728 if (!arg_no_block) {
2731 q = wait_for_jobs(bus, s);
2735 /* When stopping units, warn if they can still be triggered by
2736 * another active unit (socket, path, timer) */
2737 if (!arg_quiet && streq(method, "StopUnit"))
2738 STRV_FOREACH(name, names)
2739 check_triggering_units(bus, *name);
2745 /* Ask systemd-logind, which might grant access to unprivileged users
2746 * through PolicyKit */
2747 static int reboot_with_logind(sd_bus *bus, enum action a) {
2749 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2756 polkit_agent_open_if_enabled();
2764 case ACTION_POWEROFF:
2765 method = "PowerOff";
2768 case ACTION_SUSPEND:
2772 case ACTION_HIBERNATE:
2773 method = "Hibernate";
2776 case ACTION_HYBRID_SLEEP:
2777 method = "HybridSleep";
2784 r = sd_bus_call_method(
2786 "org.freedesktop.login1",
2787 "/org/freedesktop/login1",
2788 "org.freedesktop.login1.Manager",
2794 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2802 static int check_inhibitors(sd_bus *bus, enum action a) {
2804 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2805 _cleanup_strv_free_ char **sessions = NULL;
2806 const char *what, *who, *why, *mode;
2815 if (arg_ignore_inhibitors || arg_force > 0)
2827 r = sd_bus_call_method(
2829 "org.freedesktop.login1",
2830 "/org/freedesktop/login1",
2831 "org.freedesktop.login1.Manager",
2837 /* If logind is not around, then there are no inhibitors... */
2840 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2842 return bus_log_parse_error(r);
2844 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2845 _cleanup_free_ char *comm = NULL, *user = NULL;
2846 _cleanup_strv_free_ char **sv = NULL;
2848 if (!streq(mode, "block"))
2851 sv = strv_split(what, ":");
2855 if (!strv_contains(sv,
2857 a == ACTION_POWEROFF ||
2858 a == ACTION_REBOOT ||
2859 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2862 get_process_comm(pid, &comm);
2863 user = uid_to_name(uid);
2865 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2866 who, (unsigned long) pid, strna(comm), strna(user), why);
2871 return bus_log_parse_error(r);
2873 r = sd_bus_message_exit_container(reply);
2875 return bus_log_parse_error(r);
2877 /* Check for current sessions */
2878 sd_get_sessions(&sessions);
2879 STRV_FOREACH(s, sessions) {
2880 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2882 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2885 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2888 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2891 sd_session_get_tty(*s, &tty);
2892 sd_session_get_seat(*s, &seat);
2893 sd_session_get_service(*s, &service);
2894 user = uid_to_name(uid);
2896 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2903 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2904 action_table[a].verb);
2912 static int start_special(sd_bus *bus, char **args) {
2918 a = verb_to_action(args[0]);
2920 r = check_inhibitors(bus, a);
2924 if (arg_force >= 2 && geteuid() != 0) {
2925 log_error("Must be root.");
2929 if (arg_force >= 2 &&
2930 (a == ACTION_HALT ||
2931 a == ACTION_POWEROFF ||
2932 a == ACTION_REBOOT))
2935 if (arg_force >= 1 &&
2936 (a == ACTION_HALT ||
2937 a == ACTION_POWEROFF ||
2938 a == ACTION_REBOOT ||
2939 a == ACTION_KEXEC ||
2941 return daemon_reload(bus, args);
2943 /* first try logind, to allow authentication with polkit */
2944 if (geteuid() != 0 &&
2945 (a == ACTION_POWEROFF ||
2946 a == ACTION_REBOOT ||
2947 a == ACTION_SUSPEND ||
2948 a == ACTION_HIBERNATE ||
2949 a == ACTION_HYBRID_SLEEP)) {
2950 r = reboot_with_logind(bus, a);
2955 r = start_unit(bus, args);
2956 if (r == EXIT_SUCCESS)
2962 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2963 _cleanup_strv_free_ char **names = NULL;
2970 r = expand_names(bus, args, NULL, &names);
2972 log_error("Failed to expand names: %s", strerror(-r));
2976 STRV_FOREACH(name, names) {
2979 state = check_one_unit(bus, *name, good_states, arg_quiet);
2989 static int check_unit_active(sd_bus *bus, char **args) {
2990 /* According to LSB: 3, "program is not running" */
2991 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2994 static int check_unit_failed(sd_bus *bus, char **args) {
2995 return check_unit_generic(bus, 1, "failed\0", args + 1);
2998 static int kill_unit(sd_bus *bus, char **args) {
2999 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3000 _cleanup_strv_free_ char **names = NULL;
3008 arg_kill_who = "all";
3010 r = expand_names(bus, args + 1, NULL, &names);
3012 log_error("Failed to expand names: %s", strerror(-r));
3014 STRV_FOREACH(name, names) {
3015 q = sd_bus_call_method(
3017 "org.freedesktop.systemd1",
3018 "/org/freedesktop/systemd1",
3019 "org.freedesktop.systemd1.Manager",
3023 "ssi", *names, arg_kill_who, arg_signal);
3025 log_error("Failed to kill unit %s: %s",
3026 *names, bus_error_message(&error, r));
3035 typedef struct ExecStatusInfo {
3043 usec_t start_timestamp;
3044 usec_t exit_timestamp;
3049 LIST_FIELDS(struct ExecStatusInfo, exec);
3052 static void exec_status_info_free(ExecStatusInfo *i) {
3061 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3062 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3065 int32_t code, status;
3071 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3073 return bus_log_parse_error(r);
3077 r = sd_bus_message_read(m, "s", &path);
3079 return bus_log_parse_error(r);
3081 i->path = strdup(path);
3085 r = sd_bus_message_read_strv(m, &i->argv);
3087 return bus_log_parse_error(r);
3089 r = sd_bus_message_read(m,
3092 &start_timestamp, &start_timestamp_monotonic,
3093 &exit_timestamp, &exit_timestamp_monotonic,
3097 return bus_log_parse_error(r);
3100 i->start_timestamp = (usec_t) start_timestamp;
3101 i->exit_timestamp = (usec_t) exit_timestamp;
3102 i->pid = (pid_t) pid;
3106 r = sd_bus_message_exit_container(m);
3108 return bus_log_parse_error(r);
3113 typedef struct UnitStatusInfo {
3115 const char *load_state;
3116 const char *active_state;
3117 const char *sub_state;
3118 const char *unit_file_state;
3120 const char *description;
3121 const char *following;
3123 char **documentation;
3125 const char *fragment_path;
3126 const char *source_path;
3127 const char *control_group;
3129 char **dropin_paths;
3131 const char *load_error;
3134 usec_t inactive_exit_timestamp;
3135 usec_t inactive_exit_timestamp_monotonic;
3136 usec_t active_enter_timestamp;
3137 usec_t active_exit_timestamp;
3138 usec_t inactive_enter_timestamp;
3140 bool need_daemon_reload;
3145 const char *status_text;
3146 const char *pid_file;
3149 usec_t start_timestamp;
3150 usec_t exit_timestamp;
3152 int exit_code, exit_status;
3154 usec_t condition_timestamp;
3155 bool condition_result;
3156 bool failed_condition_trigger;
3157 bool failed_condition_negate;
3158 const char *failed_condition;
3159 const char *failed_condition_param;
3162 unsigned n_accepted;
3163 unsigned n_connections;
3166 /* Pairs of type, path */
3170 const char *sysfs_path;
3172 /* Mount, Automount */
3178 LIST_HEAD(ExecStatusInfo, exec);
3181 static void print_status_info(
3186 const char *active_on, *active_off, *on, *off, *ss;
3188 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3189 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3192 arg_all * OUTPUT_SHOW_ALL |
3193 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3194 on_tty() * OUTPUT_COLOR |
3195 !arg_quiet * OUTPUT_WARN_CUTOFF |
3196 arg_full * OUTPUT_FULL_WIDTH;
3201 /* This shows pretty information about a unit. See
3202 * print_property() for a low-level property printer */
3204 if (streq_ptr(i->active_state, "failed")) {
3205 active_on = ansi_highlight_red();
3206 active_off = ansi_highlight_off();
3207 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3208 active_on = ansi_highlight_green();
3209 active_off = ansi_highlight_off();
3211 active_on = active_off = "";
3213 printf("%s%s%s%s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3215 if (i->description && !streq_ptr(i->id, i->description))
3216 printf(" - %s", i->description);
3221 printf(" Follow: unit currently follows state of %s\n", i->following);
3223 if (streq_ptr(i->load_state, "error")) {
3224 on = ansi_highlight_red();
3225 off = ansi_highlight_off();
3229 path = i->source_path ? i->source_path : i->fragment_path;
3232 printf(" Loaded: %s%s%s (Reason: %s)\n",
3233 on, strna(i->load_state), off, i->load_error);
3234 else if (path && i->unit_file_state)
3235 printf(" Loaded: %s%s%s (%s; %s)\n",
3236 on, strna(i->load_state), off, path, i->unit_file_state);
3238 printf(" Loaded: %s%s%s (%s)\n",
3239 on, strna(i->load_state), off, path);
3241 printf(" Loaded: %s%s%s\n",
3242 on, strna(i->load_state), off);
3244 if (!strv_isempty(i->dropin_paths)) {
3245 _cleanup_free_ char *dir = NULL;
3249 STRV_FOREACH(dropin, i->dropin_paths) {
3250 if (! dir || last) {
3251 printf(dir ? " " : " Drop-In: ");
3256 if (path_get_parent(*dropin, &dir) < 0) {
3261 printf("%s\n %s", dir,
3262 draw_special_char(DRAW_TREE_RIGHT));
3265 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3267 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3271 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3273 printf(" Active: %s%s (%s)%s",
3274 active_on, strna(i->active_state), ss, active_off);
3276 printf(" Active: %s%s%s",
3277 active_on, strna(i->active_state), active_off);
3279 if (!isempty(i->result) && !streq(i->result, "success"))
3280 printf(" (Result: %s)", i->result);
3282 timestamp = (streq_ptr(i->active_state, "active") ||
3283 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3284 (streq_ptr(i->active_state, "inactive") ||
3285 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3286 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3287 i->active_exit_timestamp;
3289 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3290 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3293 printf(" since %s; %s\n", s2, s1);
3295 printf(" since %s\n", s2);
3299 if (!i->condition_result && i->condition_timestamp > 0) {
3300 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3301 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3303 printf(" start condition failed at %s%s%s\n",
3304 s2, s1 ? "; " : "", s1 ? s1 : "");
3305 if (i->failed_condition_trigger)
3306 printf(" none of the trigger conditions were met\n");
3307 else if (i->failed_condition)
3308 printf(" %s=%s%s was not met\n",
3309 i->failed_condition,
3310 i->failed_condition_negate ? "!" : "",
3311 i->failed_condition_param);
3315 printf(" Device: %s\n", i->sysfs_path);
3317 printf(" Where: %s\n", i->where);
3319 printf(" What: %s\n", i->what);
3321 STRV_FOREACH(t, i->documentation)
3322 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3324 STRV_FOREACH_PAIR(t, t2, i->listen)
3325 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3328 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3330 LIST_FOREACH(exec, p, i->exec) {
3331 _cleanup_free_ char *argv = NULL;
3334 /* Only show exited processes here */
3338 argv = strv_join(p->argv, " ");
3339 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3341 good = is_clean_exit_lsb(p->code, p->status, NULL);
3343 on = ansi_highlight_red();
3344 off = ansi_highlight_off();
3348 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3350 if (p->code == CLD_EXITED) {
3353 printf("status=%i", p->status);
3355 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3360 printf("signal=%s", signal_to_string(p->status));
3362 printf(")%s\n", off);
3364 if (i->main_pid == p->pid &&
3365 i->start_timestamp == p->start_timestamp &&
3366 i->exit_timestamp == p->start_timestamp)
3367 /* Let's not show this twice */
3370 if (p->pid == i->control_pid)
3374 if (i->main_pid > 0 || i->control_pid > 0) {
3375 if (i->main_pid > 0) {
3376 printf(" Main PID: %u", (unsigned) i->main_pid);
3379 _cleanup_free_ char *comm = NULL;
3380 get_process_comm(i->main_pid, &comm);
3382 printf(" (%s)", comm);
3383 } else if (i->exit_code > 0) {
3384 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3386 if (i->exit_code == CLD_EXITED) {
3389 printf("status=%i", i->exit_status);
3391 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3396 printf("signal=%s", signal_to_string(i->exit_status));
3400 if (i->control_pid > 0)
3404 if (i->control_pid > 0) {
3405 _cleanup_free_ char *c = NULL;
3407 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3409 get_process_comm(i->control_pid, &c);
3418 printf(" Status: \"%s\"\n", i->status_text);
3420 if (i->control_group &&
3421 (i->main_pid > 0 || i->control_pid > 0 ||
3422 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3425 printf(" CGroup: %s\n", i->control_group);
3427 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3430 static const char prefix[] = " ";
3433 if (c > sizeof(prefix) - 1)
3434 c -= sizeof(prefix) - 1;
3438 if (i->main_pid > 0)
3439 extra[k++] = i->main_pid;
3441 if (i->control_pid > 0)
3442 extra[k++] = i->control_pid;
3444 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3448 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3449 show_journal_by_unit(stdout,
3453 i->inactive_exit_timestamp_monotonic,
3456 flags | OUTPUT_BEGIN_NEWLINE,
3457 arg_scope == UNIT_FILE_SYSTEM,
3461 if (i->need_daemon_reload)
3462 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3463 ansi_highlight_red(),
3464 ansi_highlight_off(),
3465 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3468 static void show_unit_help(UnitStatusInfo *i) {
3473 if (!i->documentation) {
3474 log_info("Documentation for %s not known.", i->id);
3478 STRV_FOREACH(p, i->documentation) {
3480 if (startswith(*p, "man:")) {
3481 const char *args[4] = { "man", NULL, NULL, NULL };
3482 _cleanup_free_ char *page = NULL, *section = NULL;
3489 if ((*p)[k-1] == ')')
3490 e = strrchr(*p, '(');
3493 page = strndup((*p) + 4, e - *p - 4);
3494 section = strndup(e + 1, *p + k - e - 2);
3495 if (!page || !section) {
3507 log_error("Failed to fork: %m");
3513 execvp(args[0], (char**) args);
3514 log_error("Failed to execute man: %m");
3515 _exit(EXIT_FAILURE);
3518 wait_for_terminate(pid, NULL);
3520 log_info("Can't show: %s", *p);
3524 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3531 switch (contents[0]) {
3533 case SD_BUS_TYPE_STRING: {
3536 r = sd_bus_message_read(m, "s", &s);
3538 return bus_log_parse_error(r);
3541 if (streq(name, "Id"))
3543 else if (streq(name, "LoadState"))
3545 else if (streq(name, "ActiveState"))
3546 i->active_state = s;
3547 else if (streq(name, "SubState"))
3549 else if (streq(name, "Description"))
3551 else if (streq(name, "FragmentPath"))
3552 i->fragment_path = s;
3553 else if (streq(name, "SourcePath"))
3556 else if (streq(name, "DefaultControlGroup")) {
3558 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3560 i->control_group = e;
3563 else if (streq(name, "ControlGroup"))
3564 i->control_group = s;
3565 else if (streq(name, "StatusText"))
3567 else if (streq(name, "PIDFile"))
3569 else if (streq(name, "SysFSPath"))
3571 else if (streq(name, "Where"))
3573 else if (streq(name, "What"))
3575 else if (streq(name, "Following"))
3577 else if (streq(name, "UnitFileState"))
3578 i->unit_file_state = s;
3579 else if (streq(name, "Result"))
3586 case SD_BUS_TYPE_BOOLEAN: {
3589 r = sd_bus_message_read(m, "b", &b);
3591 return bus_log_parse_error(r);
3593 if (streq(name, "Accept"))
3595 else if (streq(name, "NeedDaemonReload"))
3596 i->need_daemon_reload = b;
3597 else if (streq(name, "ConditionResult"))
3598 i->condition_result = b;
3603 case SD_BUS_TYPE_UINT32: {
3606 r = sd_bus_message_read(m, "u", &u);
3608 return bus_log_parse_error(r);
3610 if (streq(name, "MainPID")) {
3612 i->main_pid = (pid_t) u;
3615 } else if (streq(name, "ControlPID"))
3616 i->control_pid = (pid_t) u;
3617 else if (streq(name, "ExecMainPID")) {
3619 i->main_pid = (pid_t) u;
3620 } else if (streq(name, "NAccepted"))
3622 else if (streq(name, "NConnections"))
3623 i->n_connections = u;
3628 case SD_BUS_TYPE_INT32: {
3631 r = sd_bus_message_read(m, "i", &j);
3633 return bus_log_parse_error(r);
3635 if (streq(name, "ExecMainCode"))
3636 i->exit_code = (int) j;
3637 else if (streq(name, "ExecMainStatus"))
3638 i->exit_status = (int) j;
3643 case SD_BUS_TYPE_UINT64: {
3646 r = sd_bus_message_read(m, "t", &u);
3648 return bus_log_parse_error(r);
3650 if (streq(name, "ExecMainStartTimestamp"))
3651 i->start_timestamp = (usec_t) u;
3652 else if (streq(name, "ExecMainExitTimestamp"))
3653 i->exit_timestamp = (usec_t) u;
3654 else if (streq(name, "ActiveEnterTimestamp"))
3655 i->active_enter_timestamp = (usec_t) u;
3656 else if (streq(name, "InactiveEnterTimestamp"))
3657 i->inactive_enter_timestamp = (usec_t) u;
3658 else if (streq(name, "InactiveExitTimestamp"))
3659 i->inactive_exit_timestamp = (usec_t) u;
3660 else if (streq(name, "InactiveExitTimestampMonotonic"))
3661 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3662 else if (streq(name, "ActiveExitTimestamp"))
3663 i->active_exit_timestamp = (usec_t) u;
3664 else if (streq(name, "ConditionTimestamp"))
3665 i->condition_timestamp = (usec_t) u;
3670 case SD_BUS_TYPE_ARRAY:
3672 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3673 _cleanup_free_ ExecStatusInfo *info = NULL;
3675 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3677 return bus_log_parse_error(r);
3679 info = new0(ExecStatusInfo, 1);
3683 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3685 info->name = strdup(name);
3689 LIST_PREPEND(exec, i->exec, info);
3691 info = new0(ExecStatusInfo, 1);
3697 return bus_log_parse_error(r);
3699 r = sd_bus_message_exit_container(m);
3701 return bus_log_parse_error(r);
3705 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3706 const char *type, *path;
3708 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3710 return bus_log_parse_error(r);
3712 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3714 r = strv_extend(&i->listen, type);
3718 r = strv_extend(&i->listen, path);
3723 return bus_log_parse_error(r);
3725 r = sd_bus_message_exit_container(m);
3727 return bus_log_parse_error(r);
3731 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3733 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3735 return bus_log_parse_error(r);
3737 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3739 r = sd_bus_message_read_strv(m, &i->documentation);
3741 return bus_log_parse_error(r);
3743 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3744 const char *cond, *param;
3745 int trigger, negate;
3748 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3750 return bus_log_parse_error(r);
3752 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3753 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3754 if (state < 0 && (!trigger || !i->failed_condition)) {
3755 i->failed_condition = cond;
3756 i->failed_condition_trigger = trigger;
3757 i->failed_condition_negate = negate;
3758 i->failed_condition_param = param;
3762 return bus_log_parse_error(r);
3764 r = sd_bus_message_exit_container(m);
3766 return bus_log_parse_error(r);
3773 case SD_BUS_TYPE_STRUCT_BEGIN:
3775 if (streq(name, "LoadError")) {
3776 const char *n, *message;
3778 r = sd_bus_message_read(m, "(ss)", &n, &message);
3780 return bus_log_parse_error(r);
3782 if (!isempty(message))
3783 i->load_error = message;
3796 r = sd_bus_message_skip(m, contents);
3798 return bus_log_parse_error(r);
3803 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3809 /* This is a low-level property printer, see
3810 * print_status_info() for the nicer output */
3812 if (arg_properties && !strv_find(arg_properties, name)) {
3813 /* skip what we didn't read */
3814 r = sd_bus_message_skip(m, contents);
3818 switch (contents[0]) {
3820 case SD_BUS_TYPE_STRUCT_BEGIN:
3822 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3825 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3827 return bus_log_parse_error(r);
3830 printf("%s=%u\n", name, (unsigned) u);
3832 printf("%s=\n", name);
3836 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3839 r = sd_bus_message_read(m, "(so)", &s, NULL);
3841 return bus_log_parse_error(r);
3843 if (arg_all || !isempty(s))
3844 printf("%s=%s\n", name, s);
3848 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3849 const char *a = NULL, *b = NULL;
3851 r = sd_bus_message_read(m, "(ss)", &a, &b);
3853 return bus_log_parse_error(r);
3855 if (arg_all || !isempty(a) || !isempty(b))
3856 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3859 } else if (streq_ptr(name, "SystemCallFilter")) {
3860 _cleanup_strv_free_ char **l = NULL;
3863 r = sd_bus_message_enter_container(m, 'r', "bas");
3865 return bus_log_parse_error(r);
3867 r = sd_bus_message_read(m, "b", &whitelist);
3869 return bus_log_parse_error(r);
3871 r = sd_bus_message_read_strv(m, &l);
3873 return bus_log_parse_error(r);
3875 r = sd_bus_message_exit_container(m);
3877 return bus_log_parse_error(r);
3879 if (arg_all || whitelist || !strv_isempty(l)) {
3883 fputs(name, stdout);
3889 STRV_FOREACH(i, l) {
3897 fputc('\n', stdout);
3905 case SD_BUS_TYPE_ARRAY:
3907 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3911 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3913 return bus_log_parse_error(r);
3915 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3916 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3919 return bus_log_parse_error(r);
3921 r = sd_bus_message_exit_container(m);
3923 return bus_log_parse_error(r);
3927 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3928 const char *type, *path;
3930 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3932 return bus_log_parse_error(r);
3934 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3935 printf("%s=%s\n", type, path);
3937 return bus_log_parse_error(r);
3939 r = sd_bus_message_exit_container(m);
3941 return bus_log_parse_error(r);
3945 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3946 const char *type, *path;
3948 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3950 return bus_log_parse_error(r);
3952 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3953 printf("Listen%s=%s\n", type, path);
3955 return bus_log_parse_error(r);
3957 r = sd_bus_message_exit_container(m);
3959 return bus_log_parse_error(r);
3963 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3965 uint64_t value, next_elapse;
3967 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3969 return bus_log_parse_error(r);
3971 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3972 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3974 printf("%s={ value=%s ; next_elapse=%s }\n",
3976 format_timespan(timespan1, sizeof(timespan1), value, 0),
3977 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3980 return bus_log_parse_error(r);
3982 r = sd_bus_message_exit_container(m);
3984 return bus_log_parse_error(r);
3988 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3989 ExecStatusInfo info = {};
3991 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3993 return bus_log_parse_error(r);
3995 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3996 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3997 _cleanup_free_ char *tt;
3999 tt = strv_join(info.argv, " ");
4001 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
4005 yes_no(info.ignore),
4006 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4007 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4008 (unsigned) info. pid,
4009 sigchld_code_to_string(info.code),
4011 info.code == CLD_EXITED ? "" : "/",
4012 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4015 strv_free(info.argv);
4019 r = sd_bus_message_exit_container(m);
4021 return bus_log_parse_error(r);
4025 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4026 const char *path, *rwm;
4028 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4030 return bus_log_parse_error(r);
4032 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4033 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4035 return bus_log_parse_error(r);
4037 r = sd_bus_message_exit_container(m);
4039 return bus_log_parse_error(r);
4043 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4047 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4049 return bus_log_parse_error(r);
4051 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4052 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4054 return bus_log_parse_error(r);
4056 r = sd_bus_message_exit_container(m);
4058 return bus_log_parse_error(r);
4062 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4066 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4068 return bus_log_parse_error(r);
4070 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4071 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4073 return bus_log_parse_error(r);
4075 r = sd_bus_message_exit_container(m);
4077 return bus_log_parse_error(r);
4085 r = bus_print_property(name, m, arg_all);
4087 return bus_log_parse_error(r);
4090 r = sd_bus_message_skip(m, contents);
4092 return bus_log_parse_error(r);
4095 printf("%s=[unprintable]\n", name);
4101 static int show_one(
4105 bool show_properties,
4109 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4110 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4111 UnitStatusInfo info = {};
4118 log_debug("Showing one %s", path);
4120 r = sd_bus_call_method(
4122 "org.freedesktop.systemd1",
4124 "org.freedesktop.DBus.Properties",
4130 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4134 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4136 return bus_log_parse_error(r);
4143 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4144 const char *name, *contents;
4146 r = sd_bus_message_read(reply, "s", &name);
4148 return bus_log_parse_error(r);
4150 r = sd_bus_message_peek_type(reply, NULL, &contents);
4152 return bus_log_parse_error(r);
4154 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4156 return bus_log_parse_error(r);
4158 if (show_properties)
4159 r = print_property(name, reply, contents);
4161 r = status_property(name, reply, &info, contents);
4165 r = sd_bus_message_exit_container(reply);
4167 return bus_log_parse_error(r);
4169 r = sd_bus_message_exit_container(reply);
4171 return bus_log_parse_error(r);
4174 return bus_log_parse_error(r);
4176 r = sd_bus_message_exit_container(reply);
4178 return bus_log_parse_error(r);
4182 if (!show_properties) {
4183 if (streq(verb, "help"))
4184 show_unit_help(&info);
4186 print_status_info(&info, ellipsized);
4189 strv_free(info.documentation);
4190 strv_free(info.dropin_paths);
4191 strv_free(info.listen);
4193 if (!streq_ptr(info.active_state, "active") &&
4194 !streq_ptr(info.active_state, "reloading") &&
4195 streq(verb, "status")) {
4196 /* According to LSB: "program not running" */
4197 /* 0: program is running or service is OK
4198 * 1: program is dead and /run PID file exists
4199 * 2: program is dead and /run/lock lock file exists
4200 * 3: program is not running
4201 * 4: program or service status is unknown
4203 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4209 while ((p = info.exec)) {
4210 LIST_REMOVE(exec, info.exec, p);
4211 exec_status_info_free(p);
4217 static int get_unit_dbus_path_by_pid(
4222 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4223 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4227 r = sd_bus_call_method(
4229 "org.freedesktop.systemd1",
4230 "/org/freedesktop/systemd1",
4231 "org.freedesktop.systemd1.Manager",
4237 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
4241 r = sd_bus_message_read(reply, "o", &u);
4243 return bus_log_parse_error(r);
4253 static int show_all(
4256 bool show_properties,
4260 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4261 _cleanup_free_ UnitInfo *unit_infos = NULL;
4266 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4270 pager_open_if_enabled();
4274 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4276 for (u = unit_infos; u < unit_infos + c; u++) {
4277 _cleanup_free_ char *p = NULL;
4279 p = unit_dbus_path_from_name(u->id);
4283 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4291 static int show_system_status(sd_bus *bus) {
4292 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4293 _cleanup_free_ char *hn = NULL;
4294 struct machine_info mi = {};
4295 const char *on, *off;
4298 hn = gethostname_malloc();
4302 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4304 log_error("Failed to read server status: %s", strerror(-r));
4308 if (streq_ptr(mi.state, "degraded")) {
4309 on = ansi_highlight_red();
4310 off = ansi_highlight_off();
4311 } else if (!streq_ptr(mi.state, "running")) {
4312 on = ansi_highlight_yellow();
4313 off = ansi_highlight_off();
4317 printf("%s%s%s%s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4319 printf(" State: %s%s%s\n",
4320 on, strna(mi.state), off);
4322 printf(" Jobs: %u queued\n", mi.n_jobs);
4323 printf(" Failed: %u units\n", mi.n_failed_units);
4325 printf(" Since: %s; %s\n",
4326 format_timestamp(since2, sizeof(since2), mi.timestamp),
4327 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4329 printf(" CGroup: %s\n", mi.control_group ?: "/");
4330 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4332 arg_all * OUTPUT_SHOW_ALL |
4333 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4334 on_tty() * OUTPUT_COLOR |
4335 !arg_quiet * OUTPUT_WARN_CUTOFF |
4336 arg_full * OUTPUT_FULL_WIDTH;
4338 static const char prefix[] = " ";
4342 if (c > sizeof(prefix) - 1)
4343 c -= sizeof(prefix) - 1;
4347 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4351 free(mi.control_group);
4356 static int show(sd_bus *bus, char **args) {
4357 bool show_properties, show_status, new_line = false;
4358 bool ellipsized = false;
4364 show_properties = streq(args[0], "show");
4365 show_status = streq(args[0], "status");
4367 if (show_properties)
4368 pager_open_if_enabled();
4370 /* If no argument is specified inspect the manager itself */
4372 if (show_properties && strv_length(args) <= 1)
4373 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4375 if (show_status && strv_length(args) <= 1) {
4377 pager_open_if_enabled();
4378 show_system_status(bus);
4382 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4384 _cleanup_free_ char **patterns = NULL;
4387 STRV_FOREACH(name, args + 1) {
4388 _cleanup_free_ char *unit = NULL;
4391 if (safe_atou32(*name, &id) < 0) {
4392 if (strv_push(&patterns, *name) < 0)
4396 } else if (show_properties) {
4397 /* Interpret as job id */
4398 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4402 /* Interpret as PID */
4403 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4410 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4413 if (!strv_isempty(patterns)) {
4414 _cleanup_strv_free_ char **names = NULL;
4416 r = expand_names(bus, patterns, NULL, &names);
4418 log_error("Failed to expand names: %s", strerror(-r));
4420 STRV_FOREACH(name, names) {
4421 _cleanup_free_ char *unit;
4423 unit = unit_dbus_path_from_name(*name);
4427 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4432 if (ellipsized && !arg_quiet)
4433 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4438 static int cat(sd_bus *bus, char **args) {
4439 _cleanup_free_ char *unit = NULL;
4440 _cleanup_strv_free_ char **names = NULL;
4448 r = expand_names(bus, args + 1, NULL, &names);
4450 log_error("Failed to expand names: %s", strerror(-r));
4452 pager_open_if_enabled();
4454 STRV_FOREACH(name, names) {
4455 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4456 _cleanup_strv_free_ char **dropin_paths = NULL;
4457 _cleanup_free_ char *fragment_path = NULL;
4460 unit = unit_dbus_path_from_name(*name);
4464 if (need_daemon_reload(bus, *name) > 0)
4465 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4466 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4468 r = sd_bus_get_property_string(
4470 "org.freedesktop.systemd1",
4472 "org.freedesktop.systemd1.Unit",
4477 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4481 r = sd_bus_get_property_strv(
4483 "org.freedesktop.systemd1",
4485 "org.freedesktop.systemd1.Unit",
4490 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4499 if (!isempty(fragment_path)) {
4500 printf("%s# %s%s\n",
4501 ansi_highlight_blue(),
4503 ansi_highlight_off());
4506 r = sendfile_full(STDOUT_FILENO, fragment_path);
4508 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4513 STRV_FOREACH(path, dropin_paths) {
4514 printf("%s%s# %s%s\n",
4515 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4516 ansi_highlight_blue(),
4518 ansi_highlight_off());
4521 r = sendfile_full(STDOUT_FILENO, *path);
4523 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4529 return r < 0 ? r : 0;
4532 static int set_property(sd_bus *bus, char **args) {
4533 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4534 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4535 _cleanup_free_ char *n = NULL;
4539 r = sd_bus_message_new_method_call(
4542 "org.freedesktop.systemd1",
4543 "/org/freedesktop/systemd1",
4544 "org.freedesktop.systemd1.Manager",
4545 "SetUnitProperties");
4547 return bus_log_create_error(r);
4549 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4553 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4555 return bus_log_create_error(r);
4557 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4559 return bus_log_create_error(r);
4561 STRV_FOREACH(i, args + 2) {
4562 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4564 return bus_log_create_error(r);
4566 r = bus_append_unit_property_assignment(m, *i);
4570 r = sd_bus_message_close_container(m);
4572 return bus_log_create_error(r);
4575 r = sd_bus_message_close_container(m);
4577 return bus_log_create_error(r);
4579 r = sd_bus_call(bus, m, 0, &error, NULL);
4581 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4588 static int snapshot(sd_bus *bus, char **args) {
4589 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4590 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4591 _cleanup_free_ char *n = NULL, *id = NULL;
4595 if (strv_length(args) > 1)
4596 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4602 r = sd_bus_call_method(
4604 "org.freedesktop.systemd1",
4605 "/org/freedesktop/systemd1",
4606 "org.freedesktop.systemd1.Manager",
4612 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4616 r = sd_bus_message_read(reply, "o", &path);
4618 return bus_log_parse_error(r);
4620 r = sd_bus_get_property_string(
4622 "org.freedesktop.systemd1",
4624 "org.freedesktop.systemd1.Unit",
4629 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4639 static int delete_snapshot(sd_bus *bus, char **args) {
4640 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4641 _cleanup_strv_free_ char **names = NULL;
4647 r = expand_names(bus, args + 1, ".snapshot", &names);
4649 log_error("Failed to expand names: %s", strerror(-r));
4651 STRV_FOREACH(name, names) {
4652 q = sd_bus_call_method(
4654 "org.freedesktop.systemd1",
4655 "/org/freedesktop/systemd1",
4656 "org.freedesktop.systemd1.Manager",
4662 log_error("Failed to remove snapshot %s: %s",
4663 *name, bus_error_message(&error, r));
4672 static int daemon_reload(sd_bus *bus, char **args) {
4673 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4677 if (arg_action == ACTION_RELOAD)
4679 else if (arg_action == ACTION_REEXEC)
4680 method = "Reexecute";
4682 assert(arg_action == ACTION_SYSTEMCTL);
4685 streq(args[0], "clear-jobs") ||
4686 streq(args[0], "cancel") ? "ClearJobs" :
4687 streq(args[0], "daemon-reexec") ? "Reexecute" :
4688 streq(args[0], "reset-failed") ? "ResetFailed" :
4689 streq(args[0], "halt") ? "Halt" :
4690 streq(args[0], "poweroff") ? "PowerOff" :
4691 streq(args[0], "reboot") ? "Reboot" :
4692 streq(args[0], "kexec") ? "KExec" :
4693 streq(args[0], "exit") ? "Exit" :
4694 /* "daemon-reload" */ "Reload";
4697 r = sd_bus_call_method(
4699 "org.freedesktop.systemd1",
4700 "/org/freedesktop/systemd1",
4701 "org.freedesktop.systemd1.Manager",
4707 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4708 /* There's always a fallback possible for
4709 * legacy actions. */
4711 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4712 /* On reexecution, we expect a disconnect, not a
4716 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4718 return r < 0 ? r : 0;
4721 static int reset_failed(sd_bus *bus, char **args) {
4722 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4723 _cleanup_strv_free_ char **names = NULL;
4727 if (strv_length(args) <= 1)
4728 return daemon_reload(bus, args);
4730 r = expand_names(bus, args + 1, NULL, &names);
4732 log_error("Failed to expand names: %s", strerror(-r));
4734 STRV_FOREACH(name, names) {
4735 q = sd_bus_call_method(
4737 "org.freedesktop.systemd1",
4738 "/org/freedesktop/systemd1",
4739 "org.freedesktop.systemd1.Manager",
4745 log_error("Failed to reset failed state of unit %s: %s",
4746 *name, bus_error_message(&error, r));
4755 static int show_environment(sd_bus *bus, char **args) {
4756 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4757 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4761 pager_open_if_enabled();
4763 r = sd_bus_get_property(
4765 "org.freedesktop.systemd1",
4766 "/org/freedesktop/systemd1",
4767 "org.freedesktop.systemd1.Manager",
4773 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4777 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4779 return bus_log_parse_error(r);
4781 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4784 return bus_log_parse_error(r);
4786 r = sd_bus_message_exit_container(reply);
4788 return bus_log_parse_error(r);
4793 static int switch_root(sd_bus *bus, char **args) {
4794 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4795 _cleanup_free_ char *cmdline_init = NULL;
4796 const char *root, *init;
4800 l = strv_length(args);
4801 if (l < 2 || l > 3) {
4802 log_error("Wrong number of arguments.");
4811 r = parse_env_file("/proc/cmdline", WHITESPACE,
4812 "init", &cmdline_init,
4815 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4817 init = cmdline_init;
4824 const char *root_systemd_path = NULL, *root_init_path = NULL;
4826 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4827 root_init_path = strappenda3(root, "/", init);
4829 /* If the passed init is actually the same as the
4830 * systemd binary, then let's suppress it. */
4831 if (files_same(root_init_path, root_systemd_path) > 0)
4835 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4837 r = sd_bus_call_method(
4839 "org.freedesktop.systemd1",
4840 "/org/freedesktop/systemd1",
4841 "org.freedesktop.systemd1.Manager",
4847 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4854 static int set_environment(sd_bus *bus, char **args) {
4855 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4856 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4863 method = streq(args[0], "set-environment")
4865 : "UnsetEnvironment";
4867 r = sd_bus_message_new_method_call(
4870 "org.freedesktop.systemd1",
4871 "/org/freedesktop/systemd1",
4872 "org.freedesktop.systemd1.Manager",
4875 return bus_log_create_error(r);
4877 r = sd_bus_message_append_strv(m, args + 1);
4879 return bus_log_create_error(r);
4881 r = sd_bus_call(bus, m, 0, &error, NULL);
4883 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4890 static int import_environment(sd_bus *bus, char **args) {
4891 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4892 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4898 r = sd_bus_message_new_method_call(
4901 "org.freedesktop.systemd1",
4902 "/org/freedesktop/systemd1",
4903 "org.freedesktop.systemd1.Manager",
4906 return bus_log_create_error(r);
4908 if (strv_isempty(args + 1))
4909 r = sd_bus_message_append_strv(m, environ);
4913 r = sd_bus_message_open_container(m, 'a', "s");
4915 return bus_log_create_error(r);
4917 STRV_FOREACH(a, args + 1) {
4919 if (!env_name_is_valid(*a)) {
4920 log_error("Not a valid environment variable name: %s", *a);
4924 STRV_FOREACH(b, environ) {
4927 eq = startswith(*b, *a);
4928 if (eq && *eq == '=') {
4930 r = sd_bus_message_append(m, "s", *b);
4932 return bus_log_create_error(r);
4939 r = sd_bus_message_close_container(m);
4942 return bus_log_create_error(r);
4944 r = sd_bus_call(bus, m, 0, &error, NULL);
4946 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4953 static int enable_sysv_units(const char *verb, char **args) {
4956 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4957 unsigned f = 1, t = 1;
4958 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4960 if (arg_scope != UNIT_FILE_SYSTEM)
4963 if (!streq(verb, "enable") &&
4964 !streq(verb, "disable") &&
4965 !streq(verb, "is-enabled"))
4968 /* Processes all SysV units, and reshuffles the array so that
4969 * afterwards only the native units remain */
4971 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4976 for (f = 0; args[f]; f++) {
4978 _cleanup_free_ char *p = NULL, *q = NULL;
4979 bool found_native = false, found_sysv;
4981 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4989 if (!endswith(name, ".service"))
4992 if (path_is_absolute(name))
4995 STRV_FOREACH(k, paths.unit_path) {
4996 if (!isempty(arg_root))
4997 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4999 asprintf(&p, "%s/%s", *k, name);
5006 found_native = access(p, F_OK) >= 0;
5017 if (!isempty(arg_root))
5018 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
5020 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
5026 p[strlen(p) - sizeof(".service") + 1] = 0;
5027 found_sysv = access(p, F_OK) >= 0;
5032 /* Mark this entry, so that we don't try enabling it as native unit */
5033 args[f] = (char*) "";
5035 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5037 if (!isempty(arg_root))
5038 argv[c++] = q = strappend("--root=", arg_root);
5040 argv[c++] = basename(p);
5042 streq(verb, "enable") ? "on" :
5043 streq(verb, "disable") ? "off" : "--level=5";
5046 l = strv_join((char**)argv, " ");
5052 log_info("Executing %s", l);
5057 log_error("Failed to fork: %m");
5060 } else if (pid == 0) {
5063 execv(argv[0], (char**) argv);
5064 _exit(EXIT_FAILURE);
5067 j = wait_for_terminate(pid, &status);
5069 log_error("Failed to wait for child: %s", strerror(-r));
5074 if (status.si_code == CLD_EXITED) {
5075 if (streq(verb, "is-enabled")) {
5076 if (status.si_status == 0) {
5085 } else if (status.si_status != 0) {
5096 /* Drop all SysV units */
5097 for (f = 0, t = 0; args[f]; f++) {
5099 if (isempty(args[f]))
5102 args[t++] = args[f];
5111 static int mangle_names(char **original_names, char ***mangled_names) {
5112 char **i, **l, **name;
5114 l = new(char*, strv_length(original_names) + 1);
5119 STRV_FOREACH(name, original_names) {
5121 /* When enabling units qualified path names are OK,
5122 * too, hence allow them explicitly. */
5127 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5143 static int enable_unit(sd_bus *bus, char **args) {
5144 _cleanup_strv_free_ char **names = NULL;
5145 const char *verb = args[0];
5146 UnitFileChange *changes = NULL;
5147 unsigned n_changes = 0;
5148 int carries_install_info = -1;
5154 r = mangle_names(args+1, &names);
5158 r = enable_sysv_units(verb, names);
5162 /* If the operation was fully executed by the SysV compat,
5163 * let's finish early */
5164 if (strv_isempty(names))
5167 if (!bus || avoid_bus()) {
5168 if (streq(verb, "enable")) {
5169 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5170 carries_install_info = r;
5171 } else if (streq(verb, "disable"))
5172 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5173 else if (streq(verb, "reenable")) {
5174 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5175 carries_install_info = r;
5176 } else if (streq(verb, "link"))
5177 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5178 else if (streq(verb, "preset")) {
5179 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5180 carries_install_info = r;
5181 } else if (streq(verb, "mask"))
5182 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5183 else if (streq(verb, "unmask"))
5184 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5186 assert_not_reached("Unknown verb");
5189 log_error("Operation failed: %s", strerror(-r));
5194 dump_unit_file_changes(changes, n_changes);
5198 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5199 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5200 int expect_carries_install_info = false;
5201 bool send_force = true;
5204 if (streq(verb, "enable")) {
5205 method = "EnableUnitFiles";
5206 expect_carries_install_info = true;
5207 } else if (streq(verb, "disable")) {
5208 method = "DisableUnitFiles";
5210 } else if (streq(verb, "reenable")) {
5211 method = "ReenableUnitFiles";
5212 expect_carries_install_info = true;
5213 } else if (streq(verb, "link"))
5214 method = "LinkUnitFiles";
5215 else if (streq(verb, "preset")) {
5216 method = "PresetUnitFiles";
5217 expect_carries_install_info = true;
5218 } else if (streq(verb, "mask"))
5219 method = "MaskUnitFiles";
5220 else if (streq(verb, "unmask")) {
5221 method = "UnmaskUnitFiles";
5224 assert_not_reached("Unknown verb");
5226 r = sd_bus_message_new_method_call(
5229 "org.freedesktop.systemd1",
5230 "/org/freedesktop/systemd1",
5231 "org.freedesktop.systemd1.Manager",
5234 return bus_log_create_error(r);
5236 r = sd_bus_message_append_strv(m, names);
5238 return bus_log_create_error(r);
5240 r = sd_bus_message_append(m, "b", arg_runtime);
5242 return bus_log_create_error(r);
5245 r = sd_bus_message_append(m, "b", arg_force);
5247 return bus_log_create_error(r);
5250 r = sd_bus_call(bus, m, 0, &error, &reply);
5252 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5256 if (expect_carries_install_info) {
5257 r = sd_bus_message_read(reply, "b", &carries_install_info);
5259 return bus_log_parse_error(r);
5262 r = deserialize_and_dump_unit_file_changes(reply);
5266 /* Try to reload if enabled */
5268 r = daemon_reload(bus, args);
5273 if (carries_install_info == 0)
5274 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5275 "using systemctl.\n"
5276 "Possible reasons for having this kind of units are:\n"
5277 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5278 " .wants/ or .requires/ directory.\n"
5279 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5280 " a requirement dependency on it.\n"
5281 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5282 " D-Bus, udev, scripted systemctl call, ...).\n");
5285 unit_file_changes_free(changes, n_changes);
5290 static int unit_is_enabled(sd_bus *bus, char **args) {
5292 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5293 _cleanup_strv_free_ char **names = NULL;
5298 r = mangle_names(args+1, &names);
5302 r = enable_sysv_units(args[0], names);
5308 if (!bus || avoid_bus()) {
5310 STRV_FOREACH(name, names) {
5311 UnitFileState state;
5313 state = unit_file_get_state(arg_scope, arg_root, *name);
5315 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5319 if (state == UNIT_FILE_ENABLED ||
5320 state == UNIT_FILE_ENABLED_RUNTIME ||
5321 state == UNIT_FILE_STATIC)
5325 puts(unit_file_state_to_string(state));
5329 STRV_FOREACH(name, names) {
5330 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5333 r = sd_bus_call_method(
5335 "org.freedesktop.systemd1",
5336 "/org/freedesktop/systemd1",
5337 "org.freedesktop.systemd1.Manager",
5343 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5347 r = sd_bus_message_read(reply, "s", &s);
5349 return bus_log_parse_error(r);
5351 if (streq(s, "enabled") ||
5352 streq(s, "enabled-runtime") ||
5364 static int systemctl_help(void) {
5366 pager_open_if_enabled();
5368 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5369 "Query or send control commands to the systemd manager.\n\n"
5370 " -h --help Show this help\n"
5371 " --version Show package version\n"
5372 " --system Connect to system manager\n"
5373 " --user Connect to user service manager\n"
5374 " -H --host=[USER@]HOST\n"
5375 " Operate on remote host\n"
5376 " -M --machine=CONTAINER\n"
5377 " Operate on local container\n"
5378 " -t --type=TYPE List only units of a particular type\n"
5379 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5380 " -p --property=NAME Show only properties by this name\n"
5381 " -a --all Show all loaded units/properties, including dead/empty\n"
5382 " ones. To list all units installed on the system, use\n"
5383 " the 'list-unit-files' command instead.\n"
5384 " -l --full Don't ellipsize unit names on output\n"
5385 " -r --recursive Show unit list of host and local containers\n"
5386 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5387 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5388 " queueing a new job\n"
5389 " --show-types When showing sockets, explicitly show their type\n"
5390 " -i --ignore-inhibitors\n"
5391 " When shutting down or sleeping, ignore inhibitors\n"
5392 " --kill-who=WHO Who to send signal to\n"
5393 " -s --signal=SIGNAL Which signal to send\n"
5394 " -q --quiet Suppress output\n"
5395 " --no-block Do not wait until operation finished\n"
5396 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5397 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5399 " --no-legend Do not print a legend (column headers and hints)\n"
5400 " --no-pager Do not pipe output into a pager\n"
5401 " --no-ask-password\n"
5402 " Do not ask for system passwords\n"
5403 " --global Enable/disable unit files globally\n"
5404 " --runtime Enable unit files only temporarily until next reboot\n"
5405 " -f --force When enabling unit files, override existing symlinks\n"
5406 " When shutting down, execute action immediately\n"
5407 " --root=PATH Enable unit files in the specified root directory\n"
5408 " -n --lines=INTEGER Number of journal entries to show\n"
5409 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5410 " verbose, export, json, json-pretty, json-sse, cat)\n"
5411 " --plain Print unit dependencies as a list instead of a tree\n\n"
5413 " list-units [PATTERN...] List loaded units\n"
5414 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5415 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5416 " start NAME... Start (activate) one or more units\n"
5417 " stop NAME... Stop (deactivate) one or more units\n"
5418 " reload NAME... Reload one or more units\n"
5419 " restart NAME... Start or restart one or more units\n"
5420 " try-restart NAME... Restart one or more units if active\n"
5421 " reload-or-restart NAME... Reload one or more units if possible,\n"
5422 " otherwise start or restart\n"
5423 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5424 " otherwise restart if active\n"
5425 " isolate NAME Start one unit and stop all others\n"
5426 " kill NAME... Send signal to processes of a unit\n"
5427 " is-active PATTERN... Check whether units are active\n"
5428 " is-failed PATTERN... Check whether units are failed\n"
5429 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5430 " show [PATTERN...|JOB...] Show properties of one or more\n"
5431 " units/jobs or the manager\n"
5432 " cat PATTERN... Show files and drop-ins of one or more units\n"
5433 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5434 " help PATTERN...|PID... Show manual for one or more units\n"
5435 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5437 " list-dependencies [NAME] Recursively show units which are required\n"
5438 " or wanted by this unit or by which this\n"
5439 " unit is required or wanted\n\n"
5440 "Unit File Commands:\n"
5441 " list-unit-files [PATTERN...] List installed unit files\n"
5442 " enable NAME... Enable one or more unit files\n"
5443 " disable NAME... Disable one or more unit files\n"
5444 " reenable NAME... Reenable one or more unit files\n"
5445 " preset NAME... Enable/disable one or more unit files\n"
5446 " based on preset configuration\n"
5447 " is-enabled NAME... Check whether unit files are enabled\n\n"
5448 " mask NAME... Mask one or more units\n"
5449 " unmask NAME... Unmask one or more units\n"
5450 " link PATH... Link one or more units files into\n"
5451 " the search path\n"
5452 " get-default Get the name of the default target\n"
5453 " set-default NAME Set the default target\n\n"
5454 "Machine Commands:\n"
5455 " list-machines [PATTERN...] List local containers and host\n\n"
5457 " list-jobs [PATTERN...] List jobs\n"
5458 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5459 "Snapshot Commands:\n"
5460 " snapshot [NAME] Create a snapshot\n"
5461 " delete NAME... Remove one or more snapshots\n\n"
5462 "Environment Commands:\n"
5463 " show-environment Dump environment\n"
5464 " set-environment NAME=VALUE... Set one or more environment variables\n"
5465 " unset-environment NAME... Unset one or more environment variables\n"
5466 " import-environment NAME... Import all, one or more environment variables\n\n"
5467 "Manager Lifecycle Commands:\n"
5468 " daemon-reload Reload systemd manager configuration\n"
5469 " daemon-reexec Reexecute systemd manager\n\n"
5470 "System Commands:\n"
5471 " default Enter system default mode\n"
5472 " rescue Enter system rescue mode\n"
5473 " emergency Enter system emergency mode\n"
5474 " halt Shut down and halt the system\n"
5475 " poweroff Shut down and power-off the system\n"
5476 " reboot [ARG] Shut down and reboot the system\n"
5477 " kexec Shut down and reboot the system with kexec\n"
5478 " exit Request user instance exit\n"
5479 " switch-root ROOT [INIT] Change to a different root file system\n"
5480 " suspend Suspend the system\n"
5481 " hibernate Hibernate the system\n"
5482 " hybrid-sleep Hibernate and suspend the system\n",
5483 program_invocation_short_name);
5488 static int halt_help(void) {
5490 printf("%s [OPTIONS...]%s\n\n"
5491 "%s the system.\n\n"
5492 " --help Show this help\n"
5493 " --halt Halt the machine\n"
5494 " -p --poweroff Switch off the machine\n"
5495 " --reboot Reboot the machine\n"
5496 " -f --force Force immediate halt/power-off/reboot\n"
5497 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5498 " -d --no-wtmp Don't write wtmp record\n"
5499 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5500 program_invocation_short_name,
5501 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5502 arg_action == ACTION_REBOOT ? "Reboot" :
5503 arg_action == ACTION_POWEROFF ? "Power off" :
5509 static int shutdown_help(void) {
5511 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5512 "Shut down the system.\n\n"
5513 " --help Show this help\n"
5514 " -H --halt Halt the machine\n"
5515 " -P --poweroff Power-off the machine\n"
5516 " -r --reboot Reboot the machine\n"
5517 " -h Equivalent to --poweroff, overridden by --halt\n"
5518 " -k Don't halt/power-off/reboot, just send warnings\n"
5519 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5520 " -c Cancel a pending shutdown\n",
5521 program_invocation_short_name);
5526 static int telinit_help(void) {
5528 printf("%s [OPTIONS...] {COMMAND}\n\n"
5529 "Send control commands to the init daemon.\n\n"
5530 " --help Show this help\n"
5531 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5533 " 0 Power-off the machine\n"
5534 " 6 Reboot the machine\n"
5535 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5536 " 1, s, S Enter rescue mode\n"
5537 " q, Q Reload init daemon configuration\n"
5538 " u, U Reexecute init daemon\n",
5539 program_invocation_short_name);
5544 static int runlevel_help(void) {
5546 printf("%s [OPTIONS...]\n\n"
5547 "Prints the previous and current runlevel of the init system.\n\n"
5548 " --help Show this help\n",
5549 program_invocation_short_name);
5554 static int help_types(void) {
5558 puts("Available unit types:");
5559 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5560 t = unit_type_to_string(i);
5568 static int systemctl_parse_argv(int argc, char *argv[]) {
5577 ARG_IGNORE_DEPENDENCIES,
5589 ARG_NO_ASK_PASSWORD,
5598 static const struct option options[] = {
5599 { "help", no_argument, NULL, 'h' },
5600 { "version", no_argument, NULL, ARG_VERSION },
5601 { "type", required_argument, NULL, 't' },
5602 { "property", required_argument, NULL, 'p' },
5603 { "all", no_argument, NULL, 'a' },
5604 { "reverse", no_argument, NULL, ARG_REVERSE },
5605 { "after", no_argument, NULL, ARG_AFTER },
5606 { "before", no_argument, NULL, ARG_BEFORE },
5607 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5608 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5609 { "full", no_argument, NULL, 'l' },
5610 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5611 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5612 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5613 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5614 { "ignore-inhibitors", no_argument, NULL, 'i' },
5615 { "user", no_argument, NULL, ARG_USER },
5616 { "system", no_argument, NULL, ARG_SYSTEM },
5617 { "global", no_argument, NULL, ARG_GLOBAL },
5618 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5619 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5620 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5621 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5622 { "quiet", no_argument, NULL, 'q' },
5623 { "root", required_argument, NULL, ARG_ROOT },
5624 { "force", no_argument, NULL, ARG_FORCE },
5625 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5626 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5627 { "signal", required_argument, NULL, 's' },
5628 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5629 { "host", required_argument, NULL, 'H' },
5630 { "machine", required_argument, NULL, 'M' },
5631 { "runtime", no_argument, NULL, ARG_RUNTIME },
5632 { "lines", required_argument, NULL, 'n' },
5633 { "output", required_argument, NULL, 'o' },
5634 { "plain", no_argument, NULL, ARG_PLAIN },
5635 { "state", required_argument, NULL, ARG_STATE },
5636 { "recursive", no_argument, NULL, 'r' },
5645 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0) {
5650 return systemctl_help();
5653 puts(PACKAGE_STRING);
5654 puts(SYSTEMD_FEATURES);
5661 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5662 _cleanup_free_ char *type;
5664 type = strndup(word, size);
5668 if (streq(type, "help")) {
5673 if (unit_type_from_string(type) >= 0) {
5674 if (strv_push(&arg_types, type))
5680 /* It's much nicer to use --state= for
5681 * load states, but let's support this
5682 * in --types= too for compatibility
5683 * with old versions */
5684 if (unit_load_state_from_string(optarg) >= 0) {
5685 if (strv_push(&arg_states, type) < 0)
5691 log_error("Unknown unit type or load state '%s'.", type);
5692 log_info("Use -t help to see a list of allowed values.");
5700 /* Make sure that if the empty property list
5701 was specified, we won't show any properties. */
5702 if (isempty(optarg) && !arg_properties) {
5703 arg_properties = new0(char*, 1);
5704 if (!arg_properties)
5710 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5713 prop = strndup(word, size);
5717 if (strv_consume(&arg_properties, prop) < 0)
5722 /* If the user asked for a particular
5723 * property, show it to him, even if it is
5735 arg_dependency = DEPENDENCY_REVERSE;
5739 arg_dependency = DEPENDENCY_AFTER;
5743 arg_dependency = DEPENDENCY_BEFORE;
5746 case ARG_SHOW_TYPES:
5747 arg_show_types = true;
5751 arg_job_mode = optarg;
5755 arg_job_mode = "fail";
5758 case ARG_IRREVERSIBLE:
5759 arg_job_mode = "replace-irreversibly";
5762 case ARG_IGNORE_DEPENDENCIES:
5763 arg_job_mode = "ignore-dependencies";
5767 arg_scope = UNIT_FILE_USER;
5771 arg_scope = UNIT_FILE_SYSTEM;
5775 arg_scope = UNIT_FILE_GLOBAL;
5779 arg_no_block = true;
5783 arg_no_legend = true;
5787 arg_no_pager = true;
5803 if (strv_extend(&arg_states, "failed") < 0)
5821 arg_no_reload = true;
5825 arg_kill_who = optarg;
5829 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5830 log_error("Failed to parse signal string %s.", optarg);
5835 case ARG_NO_ASK_PASSWORD:
5836 arg_ask_password = false;
5840 arg_transport = BUS_TRANSPORT_REMOTE;
5845 arg_transport = BUS_TRANSPORT_CONTAINER;
5854 if (safe_atou(optarg, &arg_lines) < 0) {
5855 log_error("Failed to parse lines '%s'", optarg);
5861 arg_output = output_mode_from_string(optarg);
5862 if (arg_output < 0) {
5863 log_error("Unknown output '%s'.", optarg);
5869 arg_ignore_inhibitors = true;
5880 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5883 s = strndup(word, size);
5887 if (strv_consume(&arg_states, s) < 0)
5894 if (geteuid() != 0) {
5895 log_error("--recursive requires root priviliges.");
5899 arg_recursive = true;
5906 assert_not_reached("Unhandled option");
5910 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5911 log_error("Cannot access user instance remotely.");
5918 static int halt_parse_argv(int argc, char *argv[]) {
5927 static const struct option options[] = {
5928 { "help", no_argument, NULL, ARG_HELP },
5929 { "halt", no_argument, NULL, ARG_HALT },
5930 { "poweroff", no_argument, NULL, 'p' },
5931 { "reboot", no_argument, NULL, ARG_REBOOT },
5932 { "force", no_argument, NULL, 'f' },
5933 { "wtmp-only", no_argument, NULL, 'w' },
5934 { "no-wtmp", no_argument, NULL, 'd' },
5935 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5944 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5945 if (runlevel == '0' || runlevel == '6')
5948 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5955 arg_action = ACTION_HALT;
5959 if (arg_action != ACTION_REBOOT)
5960 arg_action = ACTION_POWEROFF;
5964 arg_action = ACTION_REBOOT;
5986 /* Compatibility nops */
5993 assert_not_reached("Unhandled option");
5997 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5998 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
6000 log_error("Failed to write reboot param to "
6001 REBOOT_PARAM_FILE": %s", strerror(-r));
6004 } else if (optind < argc) {
6005 log_error("Too many arguments.");
6012 static int parse_time_spec(const char *t, usec_t *_u) {
6016 if (streq(t, "now"))
6018 else if (!strchr(t, ':')) {
6021 if (safe_atou64(t, &u) < 0)
6024 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6033 hour = strtol(t, &e, 10);
6034 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6037 minute = strtol(e+1, &e, 10);
6038 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6041 n = now(CLOCK_REALTIME);
6042 s = (time_t) (n / USEC_PER_SEC);
6044 assert_se(localtime_r(&s, &tm));
6046 tm.tm_hour = (int) hour;
6047 tm.tm_min = (int) minute;
6050 assert_se(s = mktime(&tm));
6052 *_u = (usec_t) s * USEC_PER_SEC;
6055 *_u += USEC_PER_DAY;
6061 static int shutdown_parse_argv(int argc, char *argv[]) {
6068 static const struct option options[] = {
6069 { "help", no_argument, NULL, ARG_HELP },
6070 { "halt", no_argument, NULL, 'H' },
6071 { "poweroff", no_argument, NULL, 'P' },
6072 { "reboot", no_argument, NULL, 'r' },
6073 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6074 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6083 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
6087 return shutdown_help();
6090 arg_action = ACTION_HALT;
6094 arg_action = ACTION_POWEROFF;
6099 arg_action = ACTION_KEXEC;
6101 arg_action = ACTION_REBOOT;
6105 arg_action = ACTION_KEXEC;
6109 if (arg_action != ACTION_HALT)
6110 arg_action = ACTION_POWEROFF;
6123 /* Compatibility nops */
6127 arg_action = ACTION_CANCEL_SHUTDOWN;
6134 assert_not_reached("Unhandled option");
6138 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6139 r = parse_time_spec(argv[optind], &arg_when);
6141 log_error("Failed to parse time specification: %s", argv[optind]);
6145 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6147 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6148 /* No time argument for shutdown cancel */
6149 arg_wall = argv + optind;
6150 else if (argc > optind + 1)
6151 /* We skip the time argument */
6152 arg_wall = argv + optind + 1;
6159 static int telinit_parse_argv(int argc, char *argv[]) {
6166 static const struct option options[] = {
6167 { "help", no_argument, NULL, ARG_HELP },
6168 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6172 static const struct {
6176 { '0', ACTION_POWEROFF },
6177 { '6', ACTION_REBOOT },
6178 { '1', ACTION_RESCUE },
6179 { '2', ACTION_RUNLEVEL2 },
6180 { '3', ACTION_RUNLEVEL3 },
6181 { '4', ACTION_RUNLEVEL4 },
6182 { '5', ACTION_RUNLEVEL5 },
6183 { 's', ACTION_RESCUE },
6184 { 'S', ACTION_RESCUE },
6185 { 'q', ACTION_RELOAD },
6186 { 'Q', ACTION_RELOAD },
6187 { 'u', ACTION_REEXEC },
6188 { 'U', ACTION_REEXEC }
6197 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6201 return telinit_help();
6211 assert_not_reached("Unhandled option");
6215 if (optind >= argc) {
6220 if (optind + 1 < argc) {
6221 log_error("Too many arguments.");
6225 if (strlen(argv[optind]) != 1) {
6226 log_error("Expected single character argument.");
6230 for (i = 0; i < ELEMENTSOF(table); i++)
6231 if (table[i].from == argv[optind][0])
6234 if (i >= ELEMENTSOF(table)) {
6235 log_error("Unknown command '%s'.", argv[optind]);
6239 arg_action = table[i].to;
6246 static int runlevel_parse_argv(int argc, char *argv[]) {
6252 static const struct option options[] = {
6253 { "help", no_argument, NULL, ARG_HELP },
6262 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6266 return runlevel_help();
6272 assert_not_reached("Unhandled option");
6276 if (optind < argc) {
6277 log_error("Too many arguments.");
6284 static int parse_argv(int argc, char *argv[]) {
6288 if (program_invocation_short_name) {
6290 if (strstr(program_invocation_short_name, "halt")) {
6291 arg_action = ACTION_HALT;
6292 return halt_parse_argv(argc, argv);
6293 } else if (strstr(program_invocation_short_name, "poweroff")) {
6294 arg_action = ACTION_POWEROFF;
6295 return halt_parse_argv(argc, argv);
6296 } else if (strstr(program_invocation_short_name, "reboot")) {
6298 arg_action = ACTION_KEXEC;
6300 arg_action = ACTION_REBOOT;
6301 return halt_parse_argv(argc, argv);
6302 } else if (strstr(program_invocation_short_name, "shutdown")) {
6303 arg_action = ACTION_POWEROFF;
6304 return shutdown_parse_argv(argc, argv);
6305 } else if (strstr(program_invocation_short_name, "init")) {
6307 if (sd_booted() > 0) {
6308 arg_action = _ACTION_INVALID;
6309 return telinit_parse_argv(argc, argv);
6311 /* Hmm, so some other init system is
6312 * running, we need to forward this
6313 * request to it. For now we simply
6314 * guess that it is Upstart. */
6316 execv(TELINIT, argv);
6318 log_error("Couldn't find an alternative telinit implementation to spawn.");
6322 } else if (strstr(program_invocation_short_name, "runlevel")) {
6323 arg_action = ACTION_RUNLEVEL;
6324 return runlevel_parse_argv(argc, argv);
6328 arg_action = ACTION_SYSTEMCTL;
6329 return systemctl_parse_argv(argc, argv);
6332 _pure_ static int action_to_runlevel(void) {
6334 static const char table[_ACTION_MAX] = {
6335 [ACTION_HALT] = '0',
6336 [ACTION_POWEROFF] = '0',
6337 [ACTION_REBOOT] = '6',
6338 [ACTION_RUNLEVEL2] = '2',
6339 [ACTION_RUNLEVEL3] = '3',
6340 [ACTION_RUNLEVEL4] = '4',
6341 [ACTION_RUNLEVEL5] = '5',
6342 [ACTION_RESCUE] = '1'
6345 assert(arg_action < _ACTION_MAX);
6347 return table[arg_action];
6350 static int talk_initctl(void) {
6352 struct init_request request = {
6353 .magic = INIT_MAGIC,
6355 .cmd = INIT_CMD_RUNLVL
6358 _cleanup_close_ int fd = -1;
6362 rl = action_to_runlevel();
6366 request.runlevel = rl;
6368 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6370 if (errno == ENOENT)
6373 log_error("Failed to open "INIT_FIFO": %m");
6378 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6380 log_error("Failed to write to "INIT_FIFO": %m");
6381 return errno > 0 ? -errno : -EIO;
6387 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6389 static const struct {
6397 int (* const dispatch)(sd_bus *bus, char **args);
6403 { "list-units", MORE, 0, list_units },
6404 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6405 { "list-sockets", MORE, 1, list_sockets },
6406 { "list-timers", MORE, 1, list_timers },
6407 { "list-jobs", MORE, 1, list_jobs },
6408 { "list-machines", MORE, 1, list_machines },
6409 { "clear-jobs", EQUAL, 1, daemon_reload },
6410 { "cancel", MORE, 2, cancel_job },
6411 { "start", MORE, 2, start_unit },
6412 { "stop", MORE, 2, start_unit },
6413 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6414 { "reload", MORE, 2, start_unit },
6415 { "restart", MORE, 2, start_unit },
6416 { "try-restart", MORE, 2, start_unit },
6417 { "reload-or-restart", MORE, 2, start_unit },
6418 { "reload-or-try-restart", MORE, 2, start_unit },
6419 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6420 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6421 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6422 { "isolate", EQUAL, 2, start_unit },
6423 { "kill", MORE, 2, kill_unit },
6424 { "is-active", MORE, 2, check_unit_active },
6425 { "check", MORE, 2, check_unit_active },
6426 { "is-failed", MORE, 2, check_unit_failed },
6427 { "show", MORE, 1, show },
6428 { "cat", MORE, 2, cat },
6429 { "status", MORE, 1, show },
6430 { "help", MORE, 2, show },
6431 { "snapshot", LESS, 2, snapshot },
6432 { "delete", MORE, 2, delete_snapshot },
6433 { "daemon-reload", EQUAL, 1, daemon_reload },
6434 { "daemon-reexec", EQUAL, 1, daemon_reload },
6435 { "show-environment", EQUAL, 1, show_environment },
6436 { "set-environment", MORE, 2, set_environment },
6437 { "unset-environment", MORE, 2, set_environment },
6438 { "import-environment", MORE, 1, import_environment},
6439 { "halt", EQUAL, 1, start_special, FORCE },
6440 { "poweroff", EQUAL, 1, start_special, FORCE },
6441 { "reboot", EQUAL, 1, start_special, FORCE },
6442 { "kexec", EQUAL, 1, start_special },
6443 { "suspend", EQUAL, 1, start_special },
6444 { "hibernate", EQUAL, 1, start_special },
6445 { "hybrid-sleep", EQUAL, 1, start_special },
6446 { "default", EQUAL, 1, start_special },
6447 { "rescue", EQUAL, 1, start_special },
6448 { "emergency", EQUAL, 1, start_special },
6449 { "exit", EQUAL, 1, start_special },
6450 { "reset-failed", MORE, 1, reset_failed },
6451 { "enable", MORE, 2, enable_unit, NOBUS },
6452 { "disable", MORE, 2, enable_unit, NOBUS },
6453 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6454 { "reenable", MORE, 2, enable_unit, NOBUS },
6455 { "preset", MORE, 2, enable_unit, NOBUS },
6456 { "mask", MORE, 2, enable_unit, NOBUS },
6457 { "unmask", MORE, 2, enable_unit, NOBUS },
6458 { "link", MORE, 2, enable_unit, NOBUS },
6459 { "switch-root", MORE, 2, switch_root },
6460 { "list-dependencies", LESS, 2, list_dependencies },
6461 { "set-default", EQUAL, 2, set_default, NOBUS },
6462 { "get-default", EQUAL, 1, get_default, NOBUS },
6463 { "set-property", MORE, 3, set_property },
6472 left = argc - optind;
6474 /* Special rule: no arguments (left == 0) means "list-units" */
6476 if (streq(argv[optind], "help") && !argv[optind+1]) {
6477 log_error("This command expects one or more "
6478 "unit names. Did you mean --help?");
6482 for (; verb->verb; verb++)
6483 if (streq(argv[optind], verb->verb))
6486 log_error("Unknown operation '%s'.", argv[optind]);
6491 switch (verb->argc_cmp) {
6494 if (left != verb->argc) {
6495 log_error("Invalid number of arguments.");
6502 if (left < verb->argc) {
6503 log_error("Too few arguments.");
6510 if (left > verb->argc) {
6511 log_error("Too many arguments.");
6518 assert_not_reached("Unknown comparison operator.");
6521 /* Require a bus connection for all operations but
6523 if (verb->bus == NOBUS) {
6524 if (!bus && !avoid_bus()) {
6525 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6530 if (running_in_chroot() > 0) {
6531 log_info("Running in chroot, ignoring request.");
6535 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6536 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6541 return verb->dispatch(bus, argv + optind);
6544 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6546 struct sd_shutdown_command c = {
6553 union sockaddr_union sockaddr = {
6554 .un.sun_family = AF_UNIX,
6555 .un.sun_path = "/run/systemd/shutdownd",
6558 struct iovec iovec[2] = {{
6559 .iov_base = (char*) &c,
6560 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6563 struct msghdr msghdr = {
6564 .msg_name = &sockaddr,
6565 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6566 + strlen("/run/systemd/shutdownd"),
6571 _cleanup_close_ int fd;
6573 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6577 if (!isempty(message)) {
6578 iovec[1].iov_base = (char*) message;
6579 iovec[1].iov_len = strlen(message);
6580 msghdr.msg_iovlen++;
6583 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6589 static int reload_with_fallback(sd_bus *bus) {
6592 /* First, try systemd via D-Bus. */
6593 if (daemon_reload(bus, NULL) >= 0)
6597 /* Nothing else worked, so let's try signals */
6598 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6600 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6601 log_error("kill() failed: %m");
6608 static int start_with_fallback(sd_bus *bus) {
6611 /* First, try systemd via D-Bus. */
6612 if (start_unit(bus, NULL) >= 0)
6616 /* Nothing else worked, so let's try
6618 if (talk_initctl() > 0)
6621 log_error("Failed to talk to init daemon.");
6625 warn_wall(arg_action);
6629 static int halt_now(enum action a) {
6631 /* Make sure C-A-D is handled by the kernel from this
6633 reboot(RB_ENABLE_CAD);
6638 log_info("Halting.");
6639 reboot(RB_HALT_SYSTEM);
6642 case ACTION_POWEROFF:
6643 log_info("Powering off.");
6644 reboot(RB_POWER_OFF);
6647 case ACTION_REBOOT: {
6648 _cleanup_free_ char *param = NULL;
6650 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6651 log_info("Rebooting with argument '%s'.", param);
6652 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6653 LINUX_REBOOT_CMD_RESTART2, param);
6656 log_info("Rebooting.");
6657 reboot(RB_AUTOBOOT);
6662 assert_not_reached("Unknown action.");
6666 static int halt_main(sd_bus *bus) {
6669 r = check_inhibitors(bus, arg_action);
6673 if (geteuid() != 0) {
6674 /* Try logind if we are a normal user and no special
6675 * mode applies. Maybe PolicyKit allows us to shutdown
6678 if (arg_when <= 0 &&
6681 (arg_action == ACTION_POWEROFF ||
6682 arg_action == ACTION_REBOOT)) {
6683 r = reboot_with_logind(bus, arg_action);
6688 log_error("Must be root.");
6693 _cleanup_free_ char *m;
6695 m = strv_join(arg_wall, " ");
6699 r = send_shutdownd(arg_when,
6700 arg_action == ACTION_HALT ? 'H' :
6701 arg_action == ACTION_POWEROFF ? 'P' :
6702 arg_action == ACTION_KEXEC ? 'K' :
6709 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6711 char date[FORMAT_TIMESTAMP_MAX];
6713 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6714 format_timestamp(date, sizeof(date), arg_when));
6719 if (!arg_dry && !arg_force)
6720 return start_with_fallback(bus);
6723 if (sd_booted() > 0)
6724 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6726 r = utmp_put_shutdown();
6728 log_warning("Failed to write utmp record: %s", strerror(-r));
6735 r = halt_now(arg_action);
6736 log_error("Failed to reboot: %s", strerror(-r));
6741 static int runlevel_main(void) {
6742 int r, runlevel, previous;
6744 r = utmp_get_runlevel(&runlevel, &previous);
6751 previous <= 0 ? 'N' : previous,
6752 runlevel <= 0 ? 'N' : runlevel);
6757 int main(int argc, char*argv[]) {
6758 _cleanup_bus_unref_ sd_bus *bus = NULL;
6761 setlocale(LC_ALL, "");
6762 log_parse_environment();
6765 /* Explicitly not on_tty() to avoid setting cached value.
6766 * This becomes relevant for piping output which might be
6768 original_stdout_is_tty = isatty(STDOUT_FILENO);
6770 r = parse_argv(argc, argv);
6774 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6775 * let's shortcut this */
6776 if (arg_action == ACTION_RUNLEVEL) {
6777 r = runlevel_main();
6781 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6782 log_info("Running in chroot, ignoring request.");
6788 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6790 /* systemctl_main() will print an error message for the bus
6791 * connection, but only if it needs to */
6793 switch (arg_action) {
6795 case ACTION_SYSTEMCTL:
6796 r = systemctl_main(bus, argc, argv, r);
6800 case ACTION_POWEROFF:
6806 case ACTION_RUNLEVEL2:
6807 case ACTION_RUNLEVEL3:
6808 case ACTION_RUNLEVEL4:
6809 case ACTION_RUNLEVEL5:
6811 case ACTION_EMERGENCY:
6812 case ACTION_DEFAULT:
6813 r = start_with_fallback(bus);
6818 r = reload_with_fallback(bus);
6821 case ACTION_CANCEL_SHUTDOWN: {
6822 _cleanup_free_ char *m = NULL;
6825 m = strv_join(arg_wall, " ");
6832 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6834 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6838 case ACTION_RUNLEVEL:
6839 case _ACTION_INVALID:
6841 assert_not_reached("Unknown action");
6846 ask_password_agent_close();
6847 polkit_agent_close();
6849 strv_free(arg_types);
6850 strv_free(arg_states);
6851 strv_free(arg_properties);
6853 return r < 0 ? EXIT_FAILURE : r;