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"
73 #include "bus-message.h"
74 #include "bus-error.h"
75 #include "bus-common-errors.h"
79 static char **arg_types = NULL;
80 static char **arg_states = NULL;
81 static char **arg_properties = NULL;
82 static bool arg_all = false;
83 static enum dependency {
89 } arg_dependency = DEPENDENCY_FORWARD;
90 static const char *arg_job_mode = "replace";
91 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
92 static bool arg_no_block = false;
93 static bool arg_no_legend = false;
94 static bool arg_no_pager = false;
95 static bool arg_no_wtmp = false;
96 static bool arg_no_wall = false;
97 static bool arg_no_reload = false;
98 static bool arg_show_types = false;
99 static bool arg_ignore_inhibitors = false;
100 static bool arg_dry = false;
101 static bool arg_quiet = false;
102 static bool arg_full = false;
103 static bool arg_recursive = false;
104 static int arg_force = 0;
105 static bool arg_ask_password = true;
106 static bool arg_runtime = false;
107 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
108 static char **arg_wall = NULL;
109 static const char *arg_kill_who = NULL;
110 static int arg_signal = SIGTERM;
111 static const char *arg_root = NULL;
112 static usec_t arg_when = 0;
134 ACTION_CANCEL_SHUTDOWN,
136 } arg_action = ACTION_SYSTEMCTL;
137 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
138 static char *arg_host = NULL;
139 static unsigned arg_lines = 10;
140 static OutputMode arg_output = OUTPUT_SHORT;
141 static bool arg_plain = false;
143 static bool original_stdout_is_tty;
145 static int daemon_reload(sd_bus *bus, char **args);
146 static int halt_now(enum action a);
147 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
149 static char** strv_skip_first(char **strv) {
150 if (strv_length(strv) > 0)
155 static void pager_open_if_enabled(void) {
163 static void ask_password_agent_open_if_enabled(void) {
165 /* Open the password agent as a child process if necessary */
167 if (!arg_ask_password)
170 if (arg_scope != UNIT_FILE_SYSTEM)
173 if (arg_transport != BUS_TRANSPORT_LOCAL)
176 ask_password_agent_open();
179 static void polkit_agent_open_if_enabled(void) {
181 /* Open the polkit agent as a child process if necessary */
183 if (!arg_ask_password)
186 if (arg_scope != UNIT_FILE_SYSTEM)
189 if (arg_transport != BUS_TRANSPORT_LOCAL)
195 static OutputFlags get_output_flags(void) {
197 arg_all * OUTPUT_SHOW_ALL |
198 arg_full * OUTPUT_FULL_WIDTH |
199 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
200 on_tty() * OUTPUT_COLOR |
201 !arg_quiet * OUTPUT_WARN_CUTOFF;
204 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
207 if (!sd_bus_error_is_set(error))
210 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
211 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
212 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
213 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
214 return EXIT_NOPERMISSION;
216 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
217 return EXIT_NOTINSTALLED;
219 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
220 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
221 return EXIT_NOTIMPLEMENTED;
223 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
224 return EXIT_NOTCONFIGURED;
232 static void warn_wall(enum action a) {
233 static const char *table[_ACTION_MAX] = {
234 [ACTION_HALT] = "The system is going down for system halt NOW!",
235 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
236 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
237 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
238 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
239 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
240 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
247 _cleanup_free_ char *p;
249 p = strv_join(arg_wall, " ");
256 utmp_wall(p, NULL, NULL);
264 utmp_wall(table[a], NULL, NULL);
267 static bool avoid_bus(void) {
269 if (running_in_chroot() > 0)
272 if (sd_booted() <= 0)
275 if (!isempty(arg_root))
278 if (arg_scope == UNIT_FILE_GLOBAL)
284 static int compare_unit_info(const void *a, const void *b) {
285 const UnitInfo *u = a, *v = b;
289 /* First, order by machine */
290 if (!u->machine && v->machine)
292 if (u->machine && !v->machine)
294 if (u->machine && v->machine) {
295 r = strcasecmp(u->machine, v->machine);
300 /* Second, order by unit type */
301 d1 = strrchr(u->id, '.');
302 d2 = strrchr(v->id, '.');
304 r = strcasecmp(d1, d2);
309 /* Third, order by name */
310 return strcasecmp(u->id, v->id);
313 static bool output_show_unit(const UnitInfo *u, char **patterns) {
314 if (!strv_isempty(patterns)) {
317 STRV_FOREACH(pattern, patterns)
318 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
327 dot = strrchr(u->id, '.');
331 if (!strv_find(arg_types, dot+1))
341 if (streq(u->active_state, "inactive") || u->following[0])
347 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
348 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
350 unsigned n_shown = 0;
353 max_id_len = strlen("UNIT");
354 load_len = strlen("LOAD");
355 active_len = strlen("ACTIVE");
356 sub_len = strlen("SUB");
357 job_len = strlen("JOB");
360 for (u = unit_infos; u < unit_infos + c; u++) {
361 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
362 load_len = MAX(load_len, strlen(u->load_state));
363 active_len = MAX(active_len, strlen(u->active_state));
364 sub_len = MAX(sub_len, strlen(u->sub_state));
366 if (u->job_id != 0) {
367 job_len = MAX(job_len, strlen(u->job_type));
371 if (!arg_no_legend &&
372 (streq(u->active_state, "failed") ||
373 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
377 if (!arg_full && original_stdout_is_tty) {
380 id_len = MIN(max_id_len, 25u);
381 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
384 basic_len += job_len + 1;
386 if (basic_len < (unsigned) columns()) {
387 unsigned extra_len, incr;
388 extra_len = columns() - basic_len;
390 /* Either UNIT already got 25, or is fully satisfied.
391 * Grant up to 25 to DESC now. */
392 incr = MIN(extra_len, 25u);
396 /* split the remaining space between UNIT and DESC,
397 * but do not give UNIT more than it needs. */
399 incr = MIN(extra_len / 2, max_id_len - id_len);
401 desc_len += extra_len - incr;
407 for (u = unit_infos; u < unit_infos + c; u++) {
408 _cleanup_free_ char *e = NULL, *j = NULL;
409 const char *on_loaded = "", *off_loaded = "";
410 const char *on_active = "", *off_active = "";
411 const char *on_circle = "", *off_circle = "";
415 if (!n_shown && !arg_no_legend) {
420 printf("%-*s %-*s %-*s %-*s ",
423 active_len, "ACTIVE",
427 printf("%-*s ", job_len, "JOB");
429 if (!arg_full && arg_no_pager)
430 printf("%.*s\n", desc_len, "DESCRIPTION");
432 printf("%s\n", "DESCRIPTION");
437 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
438 on_loaded = ansi_highlight_red();
439 on_circle = ansi_highlight_yellow();
440 off_loaded = off_circle = ansi_highlight_off();
444 if (streq(u->active_state, "failed")) {
445 on_circle = on_active = ansi_highlight_red();
446 off_circle = off_active = ansi_highlight_off();
451 j = strjoin(u->machine, ":", u->id, NULL);
460 e = ellipsize(id, id_len, 33);
468 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
470 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
471 on_active, id_len, id, off_active,
472 on_loaded, load_len, u->load_state, off_loaded,
473 on_active, active_len, u->active_state,
474 sub_len, u->sub_state, off_active,
475 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
478 printf("%.*s\n", desc_len, u->description);
480 printf("%s\n", u->description);
483 if (!arg_no_legend) {
484 const char *on, *off;
488 "LOAD = Reflects whether the unit definition was properly loaded.\n"
489 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
490 "SUB = The low-level unit activation state, values depend on unit type.");
491 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
492 on = ansi_highlight();
493 off = ansi_highlight_off();
495 on = ansi_highlight_red();
496 off = ansi_highlight_off();
500 printf("%s%u loaded units listed.%s\n"
501 "To show all installed unit files use 'systemctl list-unit-files'.\n",
504 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
505 "To show all installed unit files use 'systemctl list-unit-files'.\n",
512 static int get_unit_list(
516 UnitInfo **unit_infos,
518 sd_bus_message **_reply) {
520 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
521 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
522 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
531 r = sd_bus_message_new_method_call(
534 "org.freedesktop.systemd1",
535 "/org/freedesktop/systemd1",
536 "org.freedesktop.systemd1.Manager",
537 "ListUnitsFiltered");
540 return bus_log_create_error(r);
542 r = sd_bus_message_append_strv(m, arg_states);
544 return bus_log_create_error(r);
546 r = sd_bus_call(bus, m, 0, &error, &reply);
548 log_error("Failed to list units: %s", bus_error_message(&error, r));
552 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
554 return bus_log_parse_error(r);
556 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
559 if (!output_show_unit(&u, patterns))
562 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
565 (*unit_infos)[c++] = u;
568 return bus_log_parse_error(r);
570 r = sd_bus_message_exit_container(reply);
572 return bus_log_parse_error(r);
580 static void message_set_freep(Set **set) {
583 while ((m = set_steal_first(*set)))
584 sd_bus_message_unref(m);
589 static int get_unit_list_recursive(
592 UnitInfo **_unit_infos,
596 _cleanup_free_ UnitInfo *unit_infos = NULL;
597 _cleanup_(message_set_freep) Set *replies;
598 sd_bus_message *reply;
606 replies = set_new(NULL);
610 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
614 r = set_put(replies, reply);
616 sd_bus_message_unref(reply);
621 _cleanup_strv_free_ char **machines = NULL;
624 r = sd_get_machine_names(&machines);
628 STRV_FOREACH(i, machines) {
629 _cleanup_bus_close_unref_ sd_bus *container = NULL;
632 r = sd_bus_open_system_machine(&container, *i);
634 log_error_errno(r, "Failed to connect to container %s: %m", *i);
638 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
644 r = set_put(replies, reply);
646 sd_bus_message_unref(reply);
651 *_machines = machines;
656 *_unit_infos = unit_infos;
665 static int list_units(sd_bus *bus, char **args) {
666 _cleanup_free_ UnitInfo *unit_infos = NULL;
667 _cleanup_(message_set_freep) Set *replies = NULL;
668 _cleanup_strv_free_ char **machines = NULL;
671 pager_open_if_enabled();
673 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
677 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
678 return output_units_list(unit_infos, r);
681 static int get_triggered_units(
686 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
689 r = sd_bus_get_property_strv(
691 "org.freedesktop.systemd1",
693 "org.freedesktop.systemd1.Unit",
699 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
704 static int get_listening(
706 const char* unit_path,
709 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
710 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
711 const char *type, *path;
714 r = sd_bus_get_property(
716 "org.freedesktop.systemd1",
718 "org.freedesktop.systemd1.Socket",
724 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
728 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
730 return bus_log_parse_error(r);
732 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
734 r = strv_extend(listening, type);
738 r = strv_extend(listening, path);
745 return bus_log_parse_error(r);
747 r = sd_bus_message_exit_container(reply);
749 return bus_log_parse_error(r);
761 /* Note: triggered is a list here, although it almost certainly
762 * will always be one unit. Nevertheless, dbus API allows for multiple
763 * values, so let's follow that. */
766 /* The strv above is shared. free is set only in the first one. */
770 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
776 if (!a->machine && b->machine)
778 if (a->machine && !b->machine)
780 if (a->machine && b->machine) {
781 o = strcasecmp(a->machine, b->machine);
786 o = strcmp(a->path, b->path);
788 o = strcmp(a->type, b->type);
793 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
794 struct socket_info *s;
795 unsigned pathlen = strlen("LISTEN"),
796 typelen = strlen("TYPE") * arg_show_types,
797 socklen = strlen("UNIT"),
798 servlen = strlen("ACTIVATES");
799 const char *on, *off;
801 for (s = socket_infos; s < socket_infos + cs; s++) {
805 socklen = MAX(socklen, strlen(s->id));
807 typelen = MAX(typelen, strlen(s->type));
808 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
810 STRV_FOREACH(a, s->triggered)
811 tmp += strlen(*a) + 2*(a != s->triggered);
812 servlen = MAX(servlen, tmp);
817 printf("%-*s %-*.*s%-*s %s\n",
819 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
823 for (s = socket_infos; s < socket_infos + cs; s++) {
824 _cleanup_free_ char *j = NULL;
829 j = strjoin(s->machine, ":", s->path, NULL);
837 printf("%-*s %-*s %-*s",
838 pathlen, path, typelen, s->type, socklen, s->id);
841 pathlen, path, socklen, s->id);
842 STRV_FOREACH(a, s->triggered)
844 a == s->triggered ? "" : ",", *a);
848 on = ansi_highlight();
849 off = ansi_highlight_off();
853 on = ansi_highlight_red();
854 off = ansi_highlight_off();
857 if (!arg_no_legend) {
858 printf("%s%u sockets listed.%s\n", on, cs, off);
860 printf("Pass --all to see loaded but inactive sockets, too.\n");
866 static int list_sockets(sd_bus *bus, char **args) {
867 _cleanup_(message_set_freep) Set *replies = NULL;
868 _cleanup_strv_free_ char **machines = NULL;
869 _cleanup_free_ UnitInfo *unit_infos = NULL;
870 _cleanup_free_ struct socket_info *socket_infos = NULL;
872 struct socket_info *s;
877 pager_open_if_enabled();
879 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
883 for (u = unit_infos; u < unit_infos + n; u++) {
884 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
887 if (!endswith(u->id, ".socket"))
890 r = get_triggered_units(bus, u->unit_path, &triggered);
894 c = get_listening(bus, u->unit_path, &listening);
900 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
905 for (i = 0; i < c; i++)
906 socket_infos[cs + i] = (struct socket_info) {
907 .machine = u->machine,
909 .type = listening[i*2],
910 .path = listening[i*2 + 1],
911 .triggered = triggered,
912 .own_triggered = i==0,
915 /* from this point on we will cleanup those socket_infos */
918 listening = triggered = NULL; /* avoid cleanup */
921 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
922 (__compar_fn_t) socket_info_compare);
924 output_sockets_list(socket_infos, cs);
927 assert(cs == 0 || socket_infos);
928 for (s = socket_infos; s < socket_infos + cs; s++) {
931 if (s->own_triggered)
932 strv_free(s->triggered);
938 static int get_next_elapse(
941 dual_timestamp *next) {
943 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
951 r = sd_bus_get_property_trivial(
953 "org.freedesktop.systemd1",
955 "org.freedesktop.systemd1.Timer",
956 "NextElapseUSecMonotonic",
961 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
965 r = sd_bus_get_property_trivial(
967 "org.freedesktop.systemd1",
969 "org.freedesktop.systemd1.Timer",
970 "NextElapseUSecRealtime",
975 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
983 static int get_last_trigger(
988 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
995 r = sd_bus_get_property_trivial(
997 "org.freedesktop.systemd1",
999 "org.freedesktop.systemd1.Timer",
1005 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1013 const char* machine;
1016 usec_t last_trigger;
1020 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1026 if (!a->machine && b->machine)
1028 if (a->machine && !b->machine)
1030 if (a->machine && b->machine) {
1031 o = strcasecmp(a->machine, b->machine);
1036 if (a->next_elapse < b->next_elapse)
1038 if (a->next_elapse > b->next_elapse)
1041 return strcmp(a->id, b->id);
1044 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1045 struct timer_info *t;
1047 nextlen = strlen("NEXT"),
1048 leftlen = strlen("LEFT"),
1049 lastlen = strlen("LAST"),
1050 passedlen = strlen("PASSED"),
1051 unitlen = strlen("UNIT"),
1052 activatelen = strlen("ACTIVATES");
1054 const char *on, *off;
1056 assert(timer_infos || n == 0);
1058 for (t = timer_infos; t < timer_infos + n; t++) {
1062 if (t->next_elapse > 0) {
1063 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1065 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1066 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1068 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1069 leftlen = MAX(leftlen, strlen(trel));
1072 if (t->last_trigger > 0) {
1073 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1075 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1076 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1078 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1079 passedlen = MAX(passedlen, strlen(trel));
1082 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1084 STRV_FOREACH(a, t->triggered)
1085 ul += strlen(*a) + 2*(a != t->triggered);
1087 activatelen = MAX(activatelen, ul);
1092 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1096 passedlen, "PASSED",
1100 for (t = timer_infos; t < timer_infos + n; t++) {
1101 _cleanup_free_ char *j = NULL;
1103 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1104 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1107 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1108 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1110 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1111 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1114 j = strjoin(t->machine, ":", t->id, NULL);
1121 printf("%-*s %-*s %-*s %-*s %-*s",
1122 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1124 STRV_FOREACH(a, t->triggered)
1126 a == t->triggered ? "" : ",", *a);
1130 on = ansi_highlight();
1131 off = ansi_highlight_off();
1135 on = ansi_highlight_red();
1136 off = ansi_highlight_off();
1139 if (!arg_no_legend) {
1140 printf("%s%u timers listed.%s\n", on, n, off);
1142 printf("Pass --all to see loaded but inactive timers, too.\n");
1148 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1154 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1157 if (next->monotonic > nw->monotonic)
1158 converted = nw->realtime + (next->monotonic - nw->monotonic);
1160 converted = nw->realtime - (nw->monotonic - next->monotonic);
1162 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1163 next_elapse = MIN(converted, next->realtime);
1165 next_elapse = converted;
1168 next_elapse = next->realtime;
1173 static int list_timers(sd_bus *bus, char **args) {
1174 _cleanup_(message_set_freep) Set *replies = NULL;
1175 _cleanup_strv_free_ char **machines = NULL;
1176 _cleanup_free_ struct timer_info *timer_infos = NULL;
1177 _cleanup_free_ UnitInfo *unit_infos = NULL;
1178 struct timer_info *t;
1185 pager_open_if_enabled();
1187 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1191 dual_timestamp_get(&nw);
1193 for (u = unit_infos; u < unit_infos + n; u++) {
1194 _cleanup_strv_free_ char **triggered = NULL;
1195 dual_timestamp next = {};
1198 if (!endswith(u->id, ".timer"))
1201 r = get_triggered_units(bus, u->unit_path, &triggered);
1205 r = get_next_elapse(bus, u->unit_path, &next);
1209 get_last_trigger(bus, u->unit_path, &last);
1211 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1216 m = calc_next_elapse(&nw, &next);
1218 timer_infos[c++] = (struct timer_info) {
1219 .machine = u->machine,
1222 .last_trigger = last,
1223 .triggered = triggered,
1226 triggered = NULL; /* avoid cleanup */
1229 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1230 (__compar_fn_t) timer_info_compare);
1232 output_timers_list(timer_infos, c);
1235 for (t = timer_infos; t < timer_infos + c; t++)
1236 strv_free(t->triggered);
1241 static int compare_unit_file_list(const void *a, const void *b) {
1242 const char *d1, *d2;
1243 const UnitFileList *u = a, *v = b;
1245 d1 = strrchr(u->path, '.');
1246 d2 = strrchr(v->path, '.');
1251 r = strcasecmp(d1, d2);
1256 return strcasecmp(basename(u->path), basename(v->path));
1259 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1260 if (!strv_isempty(patterns)) {
1263 STRV_FOREACH(pattern, patterns)
1264 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1270 if (!strv_isempty(arg_types)) {
1273 dot = strrchr(u->path, '.');
1277 if (!strv_find(arg_types, dot+1))
1281 if (!strv_isempty(arg_states)) {
1282 if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
1289 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1290 unsigned max_id_len, id_cols, state_cols;
1291 const UnitFileList *u;
1293 max_id_len = strlen("UNIT FILE");
1294 state_cols = strlen("STATE");
1296 for (u = units; u < units + c; u++) {
1297 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1298 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1302 unsigned basic_cols;
1304 id_cols = MIN(max_id_len, 25u);
1305 basic_cols = 1 + id_cols + state_cols;
1306 if (basic_cols < (unsigned) columns())
1307 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1309 id_cols = max_id_len;
1312 printf("%-*s %-*s\n",
1313 id_cols, "UNIT FILE",
1314 state_cols, "STATE");
1316 for (u = units; u < units + c; u++) {
1317 _cleanup_free_ char *e = NULL;
1318 const char *on, *off;
1321 if (u->state == UNIT_FILE_MASKED ||
1322 u->state == UNIT_FILE_MASKED_RUNTIME ||
1323 u->state == UNIT_FILE_DISABLED ||
1324 u->state == UNIT_FILE_INVALID) {
1325 on = ansi_highlight_red();
1326 off = ansi_highlight_off();
1327 } else if (u->state == UNIT_FILE_ENABLED) {
1328 on = ansi_highlight_green();
1329 off = ansi_highlight_off();
1333 id = basename(u->path);
1335 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1337 printf("%-*s %s%-*s%s\n",
1338 id_cols, e ? e : id,
1339 on, state_cols, unit_file_state_to_string(u->state), off);
1343 printf("\n%u unit files listed.\n", c);
1346 static int list_unit_files(sd_bus *bus, char **args) {
1347 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1348 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1349 _cleanup_free_ UnitFileList *units = NULL;
1357 pager_open_if_enabled();
1365 h = hashmap_new(&string_hash_ops);
1369 r = unit_file_get_list(arg_scope, arg_root, h);
1371 unit_file_list_free(h);
1372 log_error_errno(r, "Failed to get unit file list: %m");
1376 n_units = hashmap_size(h);
1378 units = new(UnitFileList, n_units);
1379 if (!units && n_units > 0) {
1380 unit_file_list_free(h);
1384 HASHMAP_FOREACH(u, h, i) {
1385 if (!output_show_unit_file(u, strv_skip_first(args)))
1392 assert(c <= n_units);
1395 r = sd_bus_call_method(
1397 "org.freedesktop.systemd1",
1398 "/org/freedesktop/systemd1",
1399 "org.freedesktop.systemd1.Manager",
1405 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1409 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1411 return bus_log_parse_error(r);
1413 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1415 if (!GREEDY_REALLOC(units, size, c + 1))
1418 units[c] = (struct UnitFileList) {
1420 unit_file_state_from_string(state)
1423 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1428 return bus_log_parse_error(r);
1430 r = sd_bus_message_exit_container(reply);
1432 return bus_log_parse_error(r);
1435 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1436 output_unit_file_list(units, c);
1439 for (unit = units; unit < units + c; unit++)
1446 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1447 _cleanup_free_ char *n = NULL;
1448 size_t max_len = MAX(columns(),20u);
1454 for (i = level - 1; i >= 0; i--) {
1456 if (len > max_len - 3 && !arg_full) {
1457 printf("%s...\n",max_len % 2 ? "" : " ");
1460 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1464 if (len > max_len - 3 && !arg_full) {
1465 printf("%s...\n",max_len % 2 ? "" : " ");
1469 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1473 printf("%s\n", name);
1477 n = ellipsize(name, max_len-len, 100);
1485 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1487 static const char *dependencies[_DEPENDENCY_MAX] = {
1488 [DEPENDENCY_FORWARD] = "Requires\0"
1489 "RequiresOverridable\0"
1491 "RequisiteOverridable\0"
1494 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1495 "RequiredByOverridable\0"
1499 [DEPENDENCY_AFTER] = "After\0",
1500 [DEPENDENCY_BEFORE] = "Before\0",
1503 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1504 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1505 _cleanup_strv_free_ char **ret = NULL;
1506 _cleanup_free_ char *path = NULL;
1512 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1514 path = unit_dbus_path_from_name(name);
1518 r = sd_bus_call_method(
1520 "org.freedesktop.systemd1",
1522 "org.freedesktop.DBus.Properties",
1526 "s", "org.freedesktop.systemd1.Unit");
1528 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1532 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1534 return bus_log_parse_error(r);
1536 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1539 r = sd_bus_message_read(reply, "s", &prop);
1541 return bus_log_parse_error(r);
1543 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1544 r = sd_bus_message_skip(reply, "v");
1546 return bus_log_parse_error(r);
1549 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1551 return bus_log_parse_error(r);
1553 r = bus_message_read_strv_extend(reply, &ret);
1555 return bus_log_parse_error(r);
1557 r = sd_bus_message_exit_container(reply);
1559 return bus_log_parse_error(r);
1562 r = sd_bus_message_exit_container(reply);
1564 return bus_log_parse_error(r);
1568 return bus_log_parse_error(r);
1570 r = sd_bus_message_exit_container(reply);
1572 return bus_log_parse_error(r);
1580 static int list_dependencies_compare(const void *_a, const void *_b) {
1581 const char **a = (const char**) _a, **b = (const char**) _b;
1583 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1585 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1588 return strcasecmp(*a, *b);
1591 static int list_dependencies_one(
1596 unsigned int branches) {
1598 _cleanup_strv_free_ char **deps = NULL;
1606 r = strv_extend(units, name);
1610 r = list_dependencies_get_dependencies(bus, name, &deps);
1614 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1616 STRV_FOREACH(c, deps) {
1619 if (strv_contains(*units, *c)) {
1621 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1628 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1630 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1632 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1634 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1638 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1639 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1646 strv_remove(*units, name);
1651 static int list_dependencies(sd_bus *bus, char **args) {
1652 _cleanup_strv_free_ char **units = NULL;
1653 _cleanup_free_ char *unit = NULL;
1659 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1664 u = SPECIAL_DEFAULT_TARGET;
1666 pager_open_if_enabled();
1670 return list_dependencies_one(bus, u, 0, &units, 0);
1673 struct machine_info {
1677 char *control_group;
1678 uint32_t n_failed_units;
1683 static const struct bus_properties_map machine_info_property_map[] = {
1684 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1685 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1686 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1687 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1688 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1692 static void free_machines_list(struct machine_info *machine_infos, int n) {
1698 for (i = 0; i < n; i++) {
1699 free(machine_infos[i].name);
1700 free(machine_infos[i].state);
1701 free(machine_infos[i].control_group);
1704 free(machine_infos);
1707 static int compare_machine_info(const void *a, const void *b) {
1708 const struct machine_info *u = a, *v = b;
1710 if (u->is_host != v->is_host)
1711 return u->is_host > v->is_host ? -1 : 1;
1713 return strcasecmp(u->name, v->name);
1716 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1717 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1723 r = sd_bus_open_system_machine(&container, mi->name);
1730 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1737 static bool output_show_machine(const char *name, char **patterns) {
1742 if (strv_isempty(patterns))
1745 STRV_FOREACH(i, patterns)
1746 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1752 static int get_machine_list(
1754 struct machine_info **_machine_infos,
1757 struct machine_info *machine_infos = NULL;
1758 _cleanup_strv_free_ char **m = NULL;
1759 _cleanup_free_ char *hn = NULL;
1764 hn = gethostname_malloc();
1768 if (output_show_machine(hn, patterns)) {
1769 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1772 machine_infos[c].is_host = true;
1773 machine_infos[c].name = hn;
1776 get_machine_properties(bus, &machine_infos[c]);
1780 sd_get_machine_names(&m);
1781 STRV_FOREACH(i, m) {
1782 _cleanup_free_ char *class = NULL;
1784 if (!output_show_machine(*i, patterns))
1787 sd_machine_get_class(*i, &class);
1788 if (!streq_ptr(class, "container"))
1791 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1792 free_machines_list(machine_infos, c);
1796 machine_infos[c].is_host = false;
1797 machine_infos[c].name = strdup(*i);
1798 if (!machine_infos[c].name) {
1799 free_machines_list(machine_infos, c);
1803 get_machine_properties(NULL, &machine_infos[c]);
1807 *_machine_infos = machine_infos;
1811 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1812 struct machine_info *m;
1815 namelen = sizeof("NAME") - 1,
1816 statelen = sizeof("STATE") - 1,
1817 failedlen = sizeof("FAILED") - 1,
1818 jobslen = sizeof("JOBS") - 1;
1820 assert(machine_infos || n == 0);
1822 for (m = machine_infos; m < machine_infos + n; m++) {
1823 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1824 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1825 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1826 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1828 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1832 if (!arg_no_legend) {
1836 printf("%-*s %-*s %-*s %-*s\n",
1839 failedlen, "FAILED",
1843 for (m = machine_infos; m < machine_infos + n; m++) {
1844 const char *on_state = "", *off_state = "";
1845 const char *on_failed = "", *off_failed = "";
1846 bool circle = false;
1848 if (streq_ptr(m->state, "degraded")) {
1849 on_state = ansi_highlight_red();
1850 off_state = ansi_highlight_off();
1852 } else if (!streq_ptr(m->state, "running")) {
1853 on_state = ansi_highlight_yellow();
1854 off_state = ansi_highlight_off();
1858 if (m->n_failed_units > 0) {
1859 on_failed = ansi_highlight_red();
1860 off_failed = ansi_highlight_off();
1862 on_failed = off_failed = "";
1865 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1868 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1869 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1870 on_state, statelen, strna(m->state), off_state,
1871 on_failed, failedlen, m->n_failed_units, off_failed,
1872 jobslen, m->n_jobs);
1874 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1875 namelen, strna(m->name),
1876 on_state, statelen, strna(m->state), off_state,
1877 on_failed, failedlen, m->n_failed_units, off_failed,
1878 jobslen, m->n_jobs);
1882 printf("\n%u machines listed.\n", n);
1885 static int list_machines(sd_bus *bus, char **args) {
1886 struct machine_info *machine_infos = NULL;
1891 if (geteuid() != 0) {
1892 log_error("Must be root.");
1896 pager_open_if_enabled();
1898 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1902 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1903 output_machines_list(machine_infos, r);
1904 free_machines_list(machine_infos, r);
1909 static int get_default(sd_bus *bus, char **args) {
1910 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1911 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1912 _cleanup_free_ char *_path = NULL;
1916 if (!bus || avoid_bus()) {
1917 r = unit_file_get_default(arg_scope, arg_root, &_path);
1919 return log_error_errno(r, "Failed to get default target: %m");
1923 r = sd_bus_call_method(
1925 "org.freedesktop.systemd1",
1926 "/org/freedesktop/systemd1",
1927 "org.freedesktop.systemd1.Manager",
1933 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1937 r = sd_bus_message_read(reply, "s", &path);
1939 return bus_log_parse_error(r);
1943 printf("%s\n", path);
1948 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1951 assert(changes || n_changes == 0);
1953 for (i = 0; i < n_changes; i++) {
1954 if (changes[i].type == UNIT_FILE_SYMLINK)
1955 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1957 log_info("Removed symlink %s.", changes[i].path);
1961 static int set_default(sd_bus *bus, char **args) {
1962 _cleanup_free_ char *unit = NULL;
1963 UnitFileChange *changes = NULL;
1964 unsigned n_changes = 0;
1967 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1971 if (!bus || avoid_bus()) {
1972 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1974 return log_error_errno(r, "Failed to set default target: %m");
1977 dump_unit_file_changes(changes, n_changes);
1981 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1982 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1984 r = sd_bus_message_new_method_call(
1987 "org.freedesktop.systemd1",
1988 "/org/freedesktop/systemd1",
1989 "org.freedesktop.systemd1.Manager",
1990 "SetDefaultTarget");
1992 return bus_log_create_error(r);
1994 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
1996 return bus_log_create_error(r);
1998 r = sd_bus_message_append(m, "sb", unit, 1);
2000 return bus_log_create_error(r);
2002 r = sd_bus_call(bus, m, 0, &error, &reply);
2004 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2008 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
2012 /* Try to reload if enabled */
2014 r = daemon_reload(bus, args);
2019 unit_file_changes_free(changes, n_changes);
2026 const char *name, *type, *state;
2029 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2030 unsigned id_len, unit_len, type_len, state_len;
2031 const struct job_info *j;
2032 const char *on, *off;
2033 bool shorten = false;
2035 assert(n == 0 || jobs);
2038 on = ansi_highlight_green();
2039 off = ansi_highlight_off();
2041 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2045 pager_open_if_enabled();
2047 id_len = strlen("JOB");
2048 unit_len = strlen("UNIT");
2049 type_len = strlen("TYPE");
2050 state_len = strlen("STATE");
2052 for (j = jobs; j < jobs + n; j++) {
2053 uint32_t id = j->id;
2054 assert(j->name && j->type && j->state);
2056 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2057 unit_len = MAX(unit_len, strlen(j->name));
2058 type_len = MAX(type_len, strlen(j->type));
2059 state_len = MAX(state_len, strlen(j->state));
2062 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2063 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2068 printf("%*s %-*s %-*s %-*s\n",
2072 state_len, "STATE");
2074 for (j = jobs; j < jobs + n; j++) {
2075 _cleanup_free_ char *e = NULL;
2077 if (streq(j->state, "running")) {
2078 on = ansi_highlight();
2079 off = ansi_highlight_off();
2083 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2084 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2086 on, unit_len, e ? e : j->name, off,
2088 on, state_len, j->state, off);
2091 if (!arg_no_legend) {
2092 on = ansi_highlight();
2093 off = ansi_highlight_off();
2095 printf("\n%s%u jobs listed%s.\n", on, n, off);
2099 static bool output_show_job(struct job_info *job, char **patterns) {
2104 if (strv_isempty(patterns))
2107 STRV_FOREACH(pattern, patterns)
2108 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2113 static int list_jobs(sd_bus *bus, char **args) {
2114 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2115 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2116 const char *name, *type, *state, *job_path, *unit_path;
2117 _cleanup_free_ struct job_info *jobs = NULL;
2122 bool skipped = false;
2124 r = sd_bus_call_method(
2126 "org.freedesktop.systemd1",
2127 "/org/freedesktop/systemd1",
2128 "org.freedesktop.systemd1.Manager",
2134 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2138 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2140 return bus_log_parse_error(r);
2142 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2143 struct job_info job = { id, name, type, state };
2145 if (!output_show_job(&job, strv_skip_first(args))) {
2150 if (!GREEDY_REALLOC(jobs, size, c + 1))
2156 return bus_log_parse_error(r);
2158 r = sd_bus_message_exit_container(reply);
2160 return bus_log_parse_error(r);
2162 output_jobs_list(jobs, c, skipped);
2166 static int cancel_job(sd_bus *bus, char **args) {
2167 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2173 if (strv_length(args) <= 1)
2174 return daemon_reload(bus, args);
2176 STRV_FOREACH(name, args+1) {
2177 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2181 q = safe_atou32(*name, &id);
2183 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2185 q = sd_bus_message_new_method_call(
2188 "org.freedesktop.systemd1",
2189 "/org/freedesktop/systemd1",
2190 "org.freedesktop.systemd1.Manager",
2193 return bus_log_create_error(q);
2195 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2197 return bus_log_create_error(1);
2199 q = sd_bus_message_append(m, "u", id);
2201 return bus_log_create_error(q);
2203 q = sd_bus_call(bus, m, 0, &error, NULL);
2205 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2214 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2215 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2219 /* We ignore all errors here, since this is used to show a
2222 /* We don't use unit_dbus_path_from_name() directly since we
2223 * don't want to load the unit if it isn't loaded. */
2225 r = sd_bus_call_method(
2227 "org.freedesktop.systemd1",
2228 "/org/freedesktop/systemd1",
2229 "org.freedesktop.systemd1.Manager",
2237 r = sd_bus_message_read(reply, "o", &path);
2241 r = sd_bus_get_property_trivial(
2243 "org.freedesktop.systemd1",
2245 "org.freedesktop.systemd1.Unit",
2255 static void warn_unit_file_changed(const char *name) {
2256 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2257 ansi_highlight_red(),
2258 ansi_highlight_off(),
2260 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2263 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2270 STRV_FOREACH(p, lp->unit_path) {
2271 _cleanup_free_ char *path;
2273 path = path_join(arg_root, *p, unit_name);
2277 if (access(path, F_OK) == 0) {
2287 static int unit_find_paths(sd_bus *bus,
2288 const char *unit_name,
2289 bool avoid_bus_cache,
2291 char **fragment_path,
2292 char ***dropin_paths) {
2296 * Finds where the unit is defined on disk. Returns 0 if the unit
2297 * is not found. Returns 1 if it is found, and sets
2298 * - the path to the unit in *path, if it exists on disk,
2299 * - and a strv of existing drop-ins in *dropins,
2300 * if the arg is not NULL and any dropins were found.
2304 assert(fragment_path);
2307 if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2308 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2309 _cleanup_free_ char *unit = NULL;
2310 _cleanup_free_ char *path = NULL;
2311 _cleanup_strv_free_ char **dropins = NULL;
2313 unit = unit_dbus_path_from_name(unit_name);
2317 if (need_daemon_reload(bus, unit_name) > 0)
2318 warn_unit_file_changed(unit_name);
2320 r = sd_bus_get_property_string(
2322 "org.freedesktop.systemd1",
2324 "org.freedesktop.systemd1.Unit",
2329 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2331 r = sd_bus_get_property_strv(
2333 "org.freedesktop.systemd1",
2335 "org.freedesktop.systemd1.Unit",
2340 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2343 if (!isempty(path)) {
2344 *fragment_path = path;
2349 if (dropin_paths && !strv_isempty(dropins)) {
2350 *dropin_paths = dropins;
2355 _cleanup_set_free_ Set *names;
2357 names = set_new(NULL);
2361 r = set_put(names, unit_name);
2365 r = unit_file_find_path(lp, unit_name, fragment_path);
2370 _cleanup_free_ char *template;
2372 template = unit_name_template(unit_name);
2376 if (!streq(template, unit_name)) {
2377 r = unit_file_find_path(lp, template, fragment_path);
2384 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
2390 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2391 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2392 _cleanup_free_ char *n = NULL, *state = NULL;
2398 n = unit_name_mangle(name, MANGLE_NOGLOB);
2402 /* We don't use unit_dbus_path_from_name() directly since we
2403 * don't want to load the unit if it isn't loaded. */
2405 r = sd_bus_call_method(
2407 "org.freedesktop.systemd1",
2408 "/org/freedesktop/systemd1",
2409 "org.freedesktop.systemd1.Manager",
2420 r = sd_bus_message_read(reply, "o", &path);
2422 return bus_log_parse_error(r);
2424 r = sd_bus_get_property_string(
2426 "org.freedesktop.systemd1",
2428 "org.freedesktop.systemd1.Unit",
2441 return nulstr_contains(good_states, state);
2444 static int check_triggering_units(
2448 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2449 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2450 _cleanup_strv_free_ char **triggered_by = NULL;
2451 bool print_warning_label = true;
2455 n = unit_name_mangle(name, MANGLE_NOGLOB);
2459 path = unit_dbus_path_from_name(n);
2463 r = sd_bus_get_property_string(
2465 "org.freedesktop.systemd1",
2467 "org.freedesktop.systemd1.Unit",
2472 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2476 if (streq(state, "masked"))
2479 r = sd_bus_get_property_strv(
2481 "org.freedesktop.systemd1",
2483 "org.freedesktop.systemd1.Unit",
2488 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2492 STRV_FOREACH(i, triggered_by) {
2493 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2495 return log_error_errno(r, "Failed to check unit: %m");
2500 if (print_warning_label) {
2501 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2502 print_warning_label = false;
2505 log_warning(" %s", *i);
2511 static const struct {
2514 } unit_actions[] = {
2515 { "start", "StartUnit" },
2516 { "stop", "StopUnit" },
2517 { "condstop", "StopUnit" },
2518 { "reload", "ReloadUnit" },
2519 { "restart", "RestartUnit" },
2520 { "try-restart", "TryRestartUnit" },
2521 { "condrestart", "TryRestartUnit" },
2522 { "reload-or-restart", "ReloadOrRestartUnit" },
2523 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2524 { "condreload", "ReloadOrTryRestartUnit" },
2525 { "force-reload", "ReloadOrTryRestartUnit" }
2528 static const char *verb_to_method(const char *verb) {
2531 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2532 if (streq_ptr(unit_actions[i].verb, verb))
2533 return unit_actions[i].method;
2538 static const char *method_to_verb(const char *method) {
2541 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2542 if (streq_ptr(unit_actions[i].method, method))
2543 return unit_actions[i].verb;
2548 static int start_unit_one(
2553 sd_bus_error *error,
2554 BusWaitForJobs *w) {
2556 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2565 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2567 r = sd_bus_message_new_method_call(
2570 "org.freedesktop.systemd1",
2571 "/org/freedesktop/systemd1",
2572 "org.freedesktop.systemd1.Manager",
2575 return bus_log_create_error(r);
2577 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2579 return bus_log_create_error(r);
2581 r = sd_bus_message_append(m, "ss", name, mode);
2583 return bus_log_create_error(r);
2585 r = sd_bus_call(bus, m, 0, error, &reply);
2589 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2590 /* There's always a fallback possible for
2591 * legacy actions. */
2592 return -EADDRNOTAVAIL;
2594 verb = method_to_verb(method);
2596 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2600 r = sd_bus_message_read(reply, "o", &path);
2602 return bus_log_parse_error(r);
2604 if (need_daemon_reload(bus, name) > 0)
2605 warn_unit_file_changed(name);
2608 log_debug("Adding %s to the set", path);
2609 r = bus_wait_for_jobs_add(w, path);
2617 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2619 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2623 STRV_FOREACH(name, names) {
2627 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2629 t = unit_name_mangle(*name, MANGLE_GLOB);
2633 if (string_is_glob(t))
2634 r = strv_consume(&globs, t);
2636 r = strv_consume(&mangled, t);
2641 /* Query the manager only if any of the names are a glob, since
2642 * this is fairly expensive */
2643 if (!strv_isempty(globs)) {
2644 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2645 _cleanup_free_ UnitInfo *unit_infos = NULL;
2648 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2650 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2654 for (i = 0; i < r; i++)
2655 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2660 mangled = NULL; /* do not free */
2665 static const struct {
2669 } action_table[_ACTION_MAX] = {
2670 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2671 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2672 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2673 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2674 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2675 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2676 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2677 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2678 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2679 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2680 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2681 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2682 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2683 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2684 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2687 static enum action verb_to_action(const char *verb) {
2690 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2691 if (streq_ptr(action_table[i].verb, verb))
2694 return _ACTION_INVALID;
2697 static int start_unit(sd_bus *bus, char **args) {
2698 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2699 const char *method, *mode, *one_name, *suffix = NULL;
2700 _cleanup_strv_free_ char **names = NULL;
2706 ask_password_agent_open_if_enabled();
2707 polkit_agent_open_if_enabled();
2709 if (arg_action == ACTION_SYSTEMCTL) {
2711 method = verb_to_method(args[0]);
2712 action = verb_to_action(args[0]);
2714 if (streq(args[0], "isolate")) {
2718 mode = action_table[action].mode ?: arg_job_mode;
2720 one_name = action_table[action].target;
2722 assert(arg_action < ELEMENTSOF(action_table));
2723 assert(action_table[arg_action].target);
2725 method = "StartUnit";
2727 mode = action_table[arg_action].mode;
2728 one_name = action_table[arg_action].target;
2732 names = strv_new(one_name, NULL);
2734 r = expand_names(bus, args + 1, suffix, &names);
2736 log_error_errno(r, "Failed to expand names: %m");
2739 if (!arg_no_block) {
2740 r = bus_wait_for_jobs_new(bus, &w);
2742 return log_error_errno(r, "Could not watch jobs: %m");
2745 STRV_FOREACH(name, names) {
2746 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2749 q = start_unit_one(bus, method, *name, mode, &error, w);
2750 if (r >= 0 && q < 0)
2751 r = translate_bus_error_to_exit_status(q, &error);
2754 if (!arg_no_block) {
2757 q = bus_wait_for_jobs(w, arg_quiet);
2761 /* When stopping units, warn if they can still be triggered by
2762 * another active unit (socket, path, timer) */
2763 if (!arg_quiet && streq(method, "StopUnit"))
2764 STRV_FOREACH(name, names)
2765 check_triggering_units(bus, *name);
2771 /* Ask systemd-logind, which might grant access to unprivileged users
2772 * through PolicyKit */
2773 static int reboot_with_logind(sd_bus *bus, enum action a) {
2775 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2782 polkit_agent_open_if_enabled();
2790 case ACTION_POWEROFF:
2791 method = "PowerOff";
2794 case ACTION_SUSPEND:
2798 case ACTION_HIBERNATE:
2799 method = "Hibernate";
2802 case ACTION_HYBRID_SLEEP:
2803 method = "HybridSleep";
2810 r = sd_bus_call_method(
2812 "org.freedesktop.login1",
2813 "/org/freedesktop/login1",
2814 "org.freedesktop.login1.Manager",
2818 "b", arg_ask_password);
2820 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2828 static int check_inhibitors(sd_bus *bus, enum action a) {
2830 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2831 _cleanup_strv_free_ char **sessions = NULL;
2832 const char *what, *who, *why, *mode;
2841 if (arg_ignore_inhibitors || arg_force > 0)
2853 r = sd_bus_call_method(
2855 "org.freedesktop.login1",
2856 "/org/freedesktop/login1",
2857 "org.freedesktop.login1.Manager",
2863 /* If logind is not around, then there are no inhibitors... */
2866 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2868 return bus_log_parse_error(r);
2870 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2871 _cleanup_free_ char *comm = NULL, *user = NULL;
2872 _cleanup_strv_free_ char **sv = NULL;
2874 if (!streq(mode, "block"))
2877 sv = strv_split(what, ":");
2881 if (!strv_contains(sv,
2883 a == ACTION_POWEROFF ||
2884 a == ACTION_REBOOT ||
2885 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2888 get_process_comm(pid, &comm);
2889 user = uid_to_name(uid);
2891 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2892 who, pid, strna(comm), strna(user), why);
2897 return bus_log_parse_error(r);
2899 r = sd_bus_message_exit_container(reply);
2901 return bus_log_parse_error(r);
2903 /* Check for current sessions */
2904 sd_get_sessions(&sessions);
2905 STRV_FOREACH(s, sessions) {
2906 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2908 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2911 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2914 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2917 sd_session_get_tty(*s, &tty);
2918 sd_session_get_seat(*s, &seat);
2919 sd_session_get_service(*s, &service);
2920 user = uid_to_name(uid);
2922 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2929 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2930 action_table[a].verb);
2938 static int start_special(sd_bus *bus, char **args) {
2944 a = verb_to_action(args[0]);
2946 r = check_inhibitors(bus, a);
2950 if (arg_force >= 2 && geteuid() != 0) {
2951 log_error("Must be root.");
2955 if (arg_force >= 2 &&
2956 (a == ACTION_HALT ||
2957 a == ACTION_POWEROFF ||
2958 a == ACTION_REBOOT))
2961 if (arg_force >= 1 &&
2962 (a == ACTION_HALT ||
2963 a == ACTION_POWEROFF ||
2964 a == ACTION_REBOOT ||
2965 a == ACTION_KEXEC ||
2967 return daemon_reload(bus, args);
2969 /* first try logind, to allow authentication with polkit */
2970 if (geteuid() != 0 &&
2971 (a == ACTION_POWEROFF ||
2972 a == ACTION_REBOOT ||
2973 a == ACTION_SUSPEND ||
2974 a == ACTION_HIBERNATE ||
2975 a == ACTION_HYBRID_SLEEP)) {
2976 r = reboot_with_logind(bus, a);
2977 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
2981 r = start_unit(bus, args);
2982 if (r == EXIT_SUCCESS)
2988 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2989 _cleanup_strv_free_ char **names = NULL;
2996 r = expand_names(bus, args, NULL, &names);
2998 return log_error_errno(r, "Failed to expand names: %m");
3000 STRV_FOREACH(name, names) {
3003 state = check_one_unit(bus, *name, good_states, arg_quiet);
3013 static int check_unit_active(sd_bus *bus, char **args) {
3014 /* According to LSB: 3, "program is not running" */
3015 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3018 static int check_unit_failed(sd_bus *bus, char **args) {
3019 return check_unit_generic(bus, 1, "failed\0", args + 1);
3022 static int kill_unit(sd_bus *bus, char **args) {
3023 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3024 _cleanup_strv_free_ char **names = NULL;
3031 polkit_agent_open_if_enabled();
3034 arg_kill_who = "all";
3036 r = expand_names(bus, args + 1, NULL, &names);
3038 log_error_errno(r, "Failed to expand names: %m");
3040 STRV_FOREACH(name, names) {
3041 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3043 q = sd_bus_message_new_method_call(
3046 "org.freedesktop.systemd1",
3047 "/org/freedesktop/systemd1",
3048 "org.freedesktop.systemd1.Manager",
3051 return bus_log_create_error(q);
3053 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3055 return bus_log_create_error(q);
3057 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3059 return bus_log_create_error(q);
3061 q = sd_bus_call(bus, m, 0, &error, NULL);
3063 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3072 typedef struct ExecStatusInfo {
3080 usec_t start_timestamp;
3081 usec_t exit_timestamp;
3086 LIST_FIELDS(struct ExecStatusInfo, exec);
3089 static void exec_status_info_free(ExecStatusInfo *i) {
3098 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3099 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3102 int32_t code, status;
3108 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3110 return bus_log_parse_error(r);
3114 r = sd_bus_message_read(m, "s", &path);
3116 return bus_log_parse_error(r);
3118 i->path = strdup(path);
3122 r = sd_bus_message_read_strv(m, &i->argv);
3124 return bus_log_parse_error(r);
3126 r = sd_bus_message_read(m,
3129 &start_timestamp, &start_timestamp_monotonic,
3130 &exit_timestamp, &exit_timestamp_monotonic,
3134 return bus_log_parse_error(r);
3137 i->start_timestamp = (usec_t) start_timestamp;
3138 i->exit_timestamp = (usec_t) exit_timestamp;
3139 i->pid = (pid_t) pid;
3143 r = sd_bus_message_exit_container(m);
3145 return bus_log_parse_error(r);
3150 typedef struct UnitStatusInfo {
3152 const char *load_state;
3153 const char *active_state;
3154 const char *sub_state;
3155 const char *unit_file_state;
3156 const char *unit_file_preset;
3158 const char *description;
3159 const char *following;
3161 char **documentation;
3163 const char *fragment_path;
3164 const char *source_path;
3165 const char *control_group;
3167 char **dropin_paths;
3169 const char *load_error;
3172 usec_t inactive_exit_timestamp;
3173 usec_t inactive_exit_timestamp_monotonic;
3174 usec_t active_enter_timestamp;
3175 usec_t active_exit_timestamp;
3176 usec_t inactive_enter_timestamp;
3178 bool need_daemon_reload;
3183 const char *status_text;
3184 const char *pid_file;
3188 usec_t start_timestamp;
3189 usec_t exit_timestamp;
3191 int exit_code, exit_status;
3193 usec_t condition_timestamp;
3194 bool condition_result;
3195 bool failed_condition_trigger;
3196 bool failed_condition_negate;
3197 const char *failed_condition;
3198 const char *failed_condition_parameter;
3200 usec_t assert_timestamp;
3202 bool failed_assert_trigger;
3203 bool failed_assert_negate;
3204 const char *failed_assert;
3205 const char *failed_assert_parameter;
3208 unsigned n_accepted;
3209 unsigned n_connections;
3212 /* Pairs of type, path */
3216 const char *sysfs_path;
3218 /* Mount, Automount */
3224 LIST_HEAD(ExecStatusInfo, exec);
3227 static void print_status_info(
3232 const char *active_on, *active_off, *on, *off, *ss;
3234 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3235 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3241 /* This shows pretty information about a unit. See
3242 * print_property() for a low-level property printer */
3244 if (streq_ptr(i->active_state, "failed")) {
3245 active_on = ansi_highlight_red();
3246 active_off = ansi_highlight_off();
3247 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3248 active_on = ansi_highlight_green();
3249 active_off = ansi_highlight_off();
3251 active_on = active_off = "";
3253 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3255 if (i->description && !streq_ptr(i->id, i->description))
3256 printf(" - %s", i->description);
3261 printf(" Follow: unit currently follows state of %s\n", i->following);
3263 if (streq_ptr(i->load_state, "error")) {
3264 on = ansi_highlight_red();
3265 off = ansi_highlight_off();
3269 path = i->source_path ? i->source_path : i->fragment_path;
3272 printf(" Loaded: %s%s%s (Reason: %s)\n",
3273 on, strna(i->load_state), off, i->load_error);
3274 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3275 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3276 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3277 else if (path && !isempty(i->unit_file_state))
3278 printf(" Loaded: %s%s%s (%s; %s)\n",
3279 on, strna(i->load_state), off, path, i->unit_file_state);
3281 printf(" Loaded: %s%s%s (%s)\n",
3282 on, strna(i->load_state), off, path);
3284 printf(" Loaded: %s%s%s\n",
3285 on, strna(i->load_state), off);
3287 if (!strv_isempty(i->dropin_paths)) {
3288 _cleanup_free_ char *dir = NULL;
3292 STRV_FOREACH(dropin, i->dropin_paths) {
3293 if (! dir || last) {
3294 printf(dir ? " " : " Drop-In: ");
3299 if (path_get_parent(*dropin, &dir) < 0) {
3304 printf("%s\n %s", dir,
3305 draw_special_char(DRAW_TREE_RIGHT));
3308 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3310 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3314 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3316 printf(" Active: %s%s (%s)%s",
3317 active_on, strna(i->active_state), ss, active_off);
3319 printf(" Active: %s%s%s",
3320 active_on, strna(i->active_state), active_off);
3322 if (!isempty(i->result) && !streq(i->result, "success"))
3323 printf(" (Result: %s)", i->result);
3325 timestamp = (streq_ptr(i->active_state, "active") ||
3326 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3327 (streq_ptr(i->active_state, "inactive") ||
3328 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3329 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3330 i->active_exit_timestamp;
3332 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3333 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3336 printf(" since %s; %s\n", s2, s1);
3338 printf(" since %s\n", s2);
3342 if (!i->condition_result && i->condition_timestamp > 0) {
3343 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3344 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3346 printf("Condition: start %scondition failed%s at %s%s%s\n",
3347 ansi_highlight_yellow(), ansi_highlight_off(),
3348 s2, s1 ? "; " : "", s1 ? s1 : "");
3349 if (i->failed_condition_trigger)
3350 printf(" none of the trigger conditions were met\n");
3351 else if (i->failed_condition)
3352 printf(" %s=%s%s was not met\n",
3353 i->failed_condition,
3354 i->failed_condition_negate ? "!" : "",
3355 i->failed_condition_parameter);
3358 if (!i->assert_result && i->assert_timestamp > 0) {
3359 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3360 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3362 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3363 ansi_highlight_red(), ansi_highlight_off(),
3364 s2, s1 ? "; " : "", s1 ? s1 : "");
3365 if (i->failed_assert_trigger)
3366 printf(" none of the trigger assertions were met\n");
3367 else if (i->failed_assert)
3368 printf(" %s=%s%s was not met\n",
3370 i->failed_assert_negate ? "!" : "",
3371 i->failed_assert_parameter);
3375 printf(" Device: %s\n", i->sysfs_path);
3377 printf(" Where: %s\n", i->where);
3379 printf(" What: %s\n", i->what);
3381 STRV_FOREACH(t, i->documentation)
3382 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3384 STRV_FOREACH_PAIR(t, t2, i->listen)
3385 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3388 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3390 LIST_FOREACH(exec, p, i->exec) {
3391 _cleanup_free_ char *argv = NULL;
3394 /* Only show exited processes here */
3398 argv = strv_join(p->argv, " ");
3399 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3401 good = is_clean_exit_lsb(p->code, p->status, NULL);
3403 on = ansi_highlight_red();
3404 off = ansi_highlight_off();
3408 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3410 if (p->code == CLD_EXITED) {
3413 printf("status=%i", p->status);
3415 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3420 printf("signal=%s", signal_to_string(p->status));
3422 printf(")%s\n", off);
3424 if (i->main_pid == p->pid &&
3425 i->start_timestamp == p->start_timestamp &&
3426 i->exit_timestamp == p->start_timestamp)
3427 /* Let's not show this twice */
3430 if (p->pid == i->control_pid)
3434 if (i->main_pid > 0 || i->control_pid > 0) {
3435 if (i->main_pid > 0) {
3436 printf(" Main PID: "PID_FMT, i->main_pid);
3439 _cleanup_free_ char *comm = NULL;
3440 get_process_comm(i->main_pid, &comm);
3442 printf(" (%s)", comm);
3443 } else if (i->exit_code > 0) {
3444 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3446 if (i->exit_code == CLD_EXITED) {
3449 printf("status=%i", i->exit_status);
3451 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3456 printf("signal=%s", signal_to_string(i->exit_status));
3460 if (i->control_pid > 0)
3464 if (i->control_pid > 0) {
3465 _cleanup_free_ char *c = NULL;
3467 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3469 get_process_comm(i->control_pid, &c);
3478 printf(" Status: \"%s\"\n", i->status_text);
3479 if (i->status_errno > 0)
3480 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3482 if (i->control_group &&
3483 (i->main_pid > 0 || i->control_pid > 0 ||
3484 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3487 printf(" CGroup: %s\n", i->control_group);
3489 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3492 static const char prefix[] = " ";
3495 if (c > sizeof(prefix) - 1)
3496 c -= sizeof(prefix) - 1;
3500 if (i->main_pid > 0)
3501 extra[k++] = i->main_pid;
3503 if (i->control_pid > 0)
3504 extra[k++] = i->control_pid;
3506 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3510 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3511 show_journal_by_unit(
3516 i->inactive_exit_timestamp_monotonic,
3519 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3520 SD_JOURNAL_LOCAL_ONLY,
3521 arg_scope == UNIT_FILE_SYSTEM,
3525 if (i->need_daemon_reload)
3526 warn_unit_file_changed(i->id);
3529 static void show_unit_help(UnitStatusInfo *i) {
3534 if (!i->documentation) {
3535 log_info("Documentation for %s not known.", i->id);
3539 STRV_FOREACH(p, i->documentation)
3540 if (startswith(*p, "man:"))
3541 show_man_page(*p + 4, false);
3543 log_info("Can't show: %s", *p);
3546 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3553 switch (contents[0]) {
3555 case SD_BUS_TYPE_STRING: {
3558 r = sd_bus_message_read(m, "s", &s);
3560 return bus_log_parse_error(r);
3563 if (streq(name, "Id"))
3565 else if (streq(name, "LoadState"))
3567 else if (streq(name, "ActiveState"))
3568 i->active_state = s;
3569 else if (streq(name, "SubState"))
3571 else if (streq(name, "Description"))
3573 else if (streq(name, "FragmentPath"))
3574 i->fragment_path = s;
3575 else if (streq(name, "SourcePath"))
3578 else if (streq(name, "DefaultControlGroup")) {
3580 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3582 i->control_group = e;
3585 else if (streq(name, "ControlGroup"))
3586 i->control_group = s;
3587 else if (streq(name, "StatusText"))
3589 else if (streq(name, "PIDFile"))
3591 else if (streq(name, "SysFSPath"))
3593 else if (streq(name, "Where"))
3595 else if (streq(name, "What"))
3597 else if (streq(name, "Following"))
3599 else if (streq(name, "UnitFileState"))
3600 i->unit_file_state = s;
3601 else if (streq(name, "UnitFilePreset"))
3602 i->unit_file_preset = s;
3603 else if (streq(name, "Result"))
3610 case SD_BUS_TYPE_BOOLEAN: {
3613 r = sd_bus_message_read(m, "b", &b);
3615 return bus_log_parse_error(r);
3617 if (streq(name, "Accept"))
3619 else if (streq(name, "NeedDaemonReload"))
3620 i->need_daemon_reload = b;
3621 else if (streq(name, "ConditionResult"))
3622 i->condition_result = b;
3623 else if (streq(name, "AssertResult"))
3624 i->assert_result = b;
3629 case SD_BUS_TYPE_UINT32: {
3632 r = sd_bus_message_read(m, "u", &u);
3634 return bus_log_parse_error(r);
3636 if (streq(name, "MainPID")) {
3638 i->main_pid = (pid_t) u;
3641 } else if (streq(name, "ControlPID"))
3642 i->control_pid = (pid_t) u;
3643 else if (streq(name, "ExecMainPID")) {
3645 i->main_pid = (pid_t) u;
3646 } else if (streq(name, "NAccepted"))
3648 else if (streq(name, "NConnections"))
3649 i->n_connections = u;
3654 case SD_BUS_TYPE_INT32: {
3657 r = sd_bus_message_read(m, "i", &j);
3659 return bus_log_parse_error(r);
3661 if (streq(name, "ExecMainCode"))
3662 i->exit_code = (int) j;
3663 else if (streq(name, "ExecMainStatus"))
3664 i->exit_status = (int) j;
3665 else if (streq(name, "StatusErrno"))
3666 i->status_errno = (int) j;
3671 case SD_BUS_TYPE_UINT64: {
3674 r = sd_bus_message_read(m, "t", &u);
3676 return bus_log_parse_error(r);
3678 if (streq(name, "ExecMainStartTimestamp"))
3679 i->start_timestamp = (usec_t) u;
3680 else if (streq(name, "ExecMainExitTimestamp"))
3681 i->exit_timestamp = (usec_t) u;
3682 else if (streq(name, "ActiveEnterTimestamp"))
3683 i->active_enter_timestamp = (usec_t) u;
3684 else if (streq(name, "InactiveEnterTimestamp"))
3685 i->inactive_enter_timestamp = (usec_t) u;
3686 else if (streq(name, "InactiveExitTimestamp"))
3687 i->inactive_exit_timestamp = (usec_t) u;
3688 else if (streq(name, "InactiveExitTimestampMonotonic"))
3689 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3690 else if (streq(name, "ActiveExitTimestamp"))
3691 i->active_exit_timestamp = (usec_t) u;
3692 else if (streq(name, "ConditionTimestamp"))
3693 i->condition_timestamp = (usec_t) u;
3694 else if (streq(name, "AssertTimestamp"))
3695 i->assert_timestamp = (usec_t) u;
3700 case SD_BUS_TYPE_ARRAY:
3702 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3703 _cleanup_free_ ExecStatusInfo *info = NULL;
3705 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3707 return bus_log_parse_error(r);
3709 info = new0(ExecStatusInfo, 1);
3713 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3715 info->name = strdup(name);
3719 LIST_PREPEND(exec, i->exec, info);
3721 info = new0(ExecStatusInfo, 1);
3727 return bus_log_parse_error(r);
3729 r = sd_bus_message_exit_container(m);
3731 return bus_log_parse_error(r);
3735 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3736 const char *type, *path;
3738 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3740 return bus_log_parse_error(r);
3742 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3744 r = strv_extend(&i->listen, type);
3748 r = strv_extend(&i->listen, path);
3753 return bus_log_parse_error(r);
3755 r = sd_bus_message_exit_container(m);
3757 return bus_log_parse_error(r);
3761 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3763 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3765 return bus_log_parse_error(r);
3767 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3769 r = sd_bus_message_read_strv(m, &i->documentation);
3771 return bus_log_parse_error(r);
3773 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3774 const char *cond, *param;
3775 int trigger, negate;
3778 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3780 return bus_log_parse_error(r);
3782 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3783 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3784 if (state < 0 && (!trigger || !i->failed_condition)) {
3785 i->failed_condition = cond;
3786 i->failed_condition_trigger = trigger;
3787 i->failed_condition_negate = negate;
3788 i->failed_condition_parameter = param;
3792 return bus_log_parse_error(r);
3794 r = sd_bus_message_exit_container(m);
3796 return bus_log_parse_error(r);
3798 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3799 const char *cond, *param;
3800 int trigger, negate;
3803 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3805 return bus_log_parse_error(r);
3807 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3808 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3809 if (state < 0 && (!trigger || !i->failed_assert)) {
3810 i->failed_assert = cond;
3811 i->failed_assert_trigger = trigger;
3812 i->failed_assert_negate = negate;
3813 i->failed_assert_parameter = param;
3817 return bus_log_parse_error(r);
3819 r = sd_bus_message_exit_container(m);
3821 return bus_log_parse_error(r);
3828 case SD_BUS_TYPE_STRUCT_BEGIN:
3830 if (streq(name, "LoadError")) {
3831 const char *n, *message;
3833 r = sd_bus_message_read(m, "(ss)", &n, &message);
3835 return bus_log_parse_error(r);
3837 if (!isempty(message))
3838 i->load_error = message;
3851 r = sd_bus_message_skip(m, contents);
3853 return bus_log_parse_error(r);
3858 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3864 /* This is a low-level property printer, see
3865 * print_status_info() for the nicer output */
3867 if (arg_properties && !strv_find(arg_properties, name)) {
3868 /* skip what we didn't read */
3869 r = sd_bus_message_skip(m, contents);
3873 switch (contents[0]) {
3875 case SD_BUS_TYPE_STRUCT_BEGIN:
3877 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3880 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3882 return bus_log_parse_error(r);
3885 printf("%s=%"PRIu32"\n", name, u);
3887 printf("%s=\n", name);
3891 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3894 r = sd_bus_message_read(m, "(so)", &s, NULL);
3896 return bus_log_parse_error(r);
3898 if (arg_all || !isempty(s))
3899 printf("%s=%s\n", name, s);
3903 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3904 const char *a = NULL, *b = NULL;
3906 r = sd_bus_message_read(m, "(ss)", &a, &b);
3908 return bus_log_parse_error(r);
3910 if (arg_all || !isempty(a) || !isempty(b))
3911 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3914 } else if (streq_ptr(name, "SystemCallFilter")) {
3915 _cleanup_strv_free_ char **l = NULL;
3918 r = sd_bus_message_enter_container(m, 'r', "bas");
3920 return bus_log_parse_error(r);
3922 r = sd_bus_message_read(m, "b", &whitelist);
3924 return bus_log_parse_error(r);
3926 r = sd_bus_message_read_strv(m, &l);
3928 return bus_log_parse_error(r);
3930 r = sd_bus_message_exit_container(m);
3932 return bus_log_parse_error(r);
3934 if (arg_all || whitelist || !strv_isempty(l)) {
3938 fputs(name, stdout);
3944 STRV_FOREACH(i, l) {
3952 fputc('\n', stdout);
3960 case SD_BUS_TYPE_ARRAY:
3962 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3966 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3968 return bus_log_parse_error(r);
3970 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3971 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3974 return bus_log_parse_error(r);
3976 r = sd_bus_message_exit_container(m);
3978 return bus_log_parse_error(r);
3982 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3983 const char *type, *path;
3985 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3987 return bus_log_parse_error(r);
3989 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3990 printf("%s=%s\n", type, path);
3992 return bus_log_parse_error(r);
3994 r = sd_bus_message_exit_container(m);
3996 return bus_log_parse_error(r);
4000 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4001 const char *type, *path;
4003 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4005 return bus_log_parse_error(r);
4007 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4008 printf("Listen%s=%s\n", type, path);
4010 return bus_log_parse_error(r);
4012 r = sd_bus_message_exit_container(m);
4014 return bus_log_parse_error(r);
4018 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4020 uint64_t value, next_elapse;
4022 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4024 return bus_log_parse_error(r);
4026 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4027 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4029 printf("%s={ value=%s ; next_elapse=%s }\n",
4031 format_timespan(timespan1, sizeof(timespan1), value, 0),
4032 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
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 && startswith(name, "Exec")) {
4044 ExecStatusInfo info = {};
4046 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4048 return bus_log_parse_error(r);
4050 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4051 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4052 _cleanup_free_ char *tt;
4054 tt = strv_join(info.argv, " ");
4056 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4060 yes_no(info.ignore),
4061 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4062 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4064 sigchld_code_to_string(info.code),
4066 info.code == CLD_EXITED ? "" : "/",
4067 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4070 strv_free(info.argv);
4074 r = sd_bus_message_exit_container(m);
4076 return bus_log_parse_error(r);
4080 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4081 const char *path, *rwm;
4083 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4085 return bus_log_parse_error(r);
4087 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4088 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4090 return bus_log_parse_error(r);
4092 r = sd_bus_message_exit_container(m);
4094 return bus_log_parse_error(r);
4098 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4102 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4104 return bus_log_parse_error(r);
4106 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4107 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4109 return bus_log_parse_error(r);
4111 r = sd_bus_message_exit_container(m);
4113 return bus_log_parse_error(r);
4117 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4121 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4123 return bus_log_parse_error(r);
4125 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4126 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4128 return bus_log_parse_error(r);
4130 r = sd_bus_message_exit_container(m);
4132 return bus_log_parse_error(r);
4140 r = bus_print_property(name, m, arg_all);
4142 return bus_log_parse_error(r);
4145 r = sd_bus_message_skip(m, contents);
4147 return bus_log_parse_error(r);
4150 printf("%s=[unprintable]\n", name);
4156 static int show_one(
4160 bool show_properties,
4164 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4165 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4166 UnitStatusInfo info = {};
4173 log_debug("Showing one %s", path);
4175 r = sd_bus_call_method(
4177 "org.freedesktop.systemd1",
4179 "org.freedesktop.DBus.Properties",
4185 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4189 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4191 return bus_log_parse_error(r);
4198 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4199 const char *name, *contents;
4201 r = sd_bus_message_read(reply, "s", &name);
4203 return bus_log_parse_error(r);
4205 r = sd_bus_message_peek_type(reply, NULL, &contents);
4207 return bus_log_parse_error(r);
4209 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4211 return bus_log_parse_error(r);
4213 if (show_properties)
4214 r = print_property(name, reply, contents);
4216 r = status_property(name, reply, &info, contents);
4220 r = sd_bus_message_exit_container(reply);
4222 return bus_log_parse_error(r);
4224 r = sd_bus_message_exit_container(reply);
4226 return bus_log_parse_error(r);
4229 return bus_log_parse_error(r);
4231 r = sd_bus_message_exit_container(reply);
4233 return bus_log_parse_error(r);
4237 if (!show_properties) {
4238 if (streq(verb, "help"))
4239 show_unit_help(&info);
4241 print_status_info(&info, ellipsized);
4244 strv_free(info.documentation);
4245 strv_free(info.dropin_paths);
4246 strv_free(info.listen);
4248 if (!streq_ptr(info.active_state, "active") &&
4249 !streq_ptr(info.active_state, "reloading") &&
4250 streq(verb, "status")) {
4251 /* According to LSB: "program not running" */
4252 /* 0: program is running or service is OK
4253 * 1: program is dead and /run PID file exists
4254 * 2: program is dead and /run/lock lock file exists
4255 * 3: program is not running
4256 * 4: program or service status is unknown
4258 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4264 while ((p = info.exec)) {
4265 LIST_REMOVE(exec, info.exec, p);
4266 exec_status_info_free(p);
4272 static int get_unit_dbus_path_by_pid(
4277 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4278 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4282 r = sd_bus_call_method(
4284 "org.freedesktop.systemd1",
4285 "/org/freedesktop/systemd1",
4286 "org.freedesktop.systemd1.Manager",
4292 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4296 r = sd_bus_message_read(reply, "o", &u);
4298 return bus_log_parse_error(r);
4308 static int show_all(
4311 bool show_properties,
4315 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4316 _cleanup_free_ UnitInfo *unit_infos = NULL;
4321 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4325 pager_open_if_enabled();
4329 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4331 for (u = unit_infos; u < unit_infos + c; u++) {
4332 _cleanup_free_ char *p = NULL;
4334 p = unit_dbus_path_from_name(u->id);
4338 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4341 else if (r > 0 && ret == 0)
4348 static int show_system_status(sd_bus *bus) {
4349 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4350 _cleanup_free_ char *hn = NULL;
4351 struct machine_info mi = {};
4352 const char *on, *off;
4355 hn = gethostname_malloc();
4359 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4361 return log_error_errno(r, "Failed to read server status: %m");
4363 if (streq_ptr(mi.state, "degraded")) {
4364 on = ansi_highlight_red();
4365 off = ansi_highlight_off();
4366 } else if (!streq_ptr(mi.state, "running")) {
4367 on = ansi_highlight_yellow();
4368 off = ansi_highlight_off();
4372 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4374 printf(" State: %s%s%s\n",
4375 on, strna(mi.state), off);
4377 printf(" Jobs: %u queued\n", mi.n_jobs);
4378 printf(" Failed: %u units\n", mi.n_failed_units);
4380 printf(" Since: %s; %s\n",
4381 format_timestamp(since2, sizeof(since2), mi.timestamp),
4382 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4384 printf(" CGroup: %s\n", mi.control_group ?: "/");
4385 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4386 static const char prefix[] = " ";
4390 if (c > sizeof(prefix) - 1)
4391 c -= sizeof(prefix) - 1;
4395 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4399 free(mi.control_group);
4404 static int show(sd_bus *bus, char **args) {
4405 bool show_properties, show_status, new_line = false;
4406 bool ellipsized = false;
4412 show_properties = streq(args[0], "show");
4413 show_status = streq(args[0], "status");
4415 if (show_properties)
4416 pager_open_if_enabled();
4418 /* If no argument is specified inspect the manager itself */
4420 if (show_properties && strv_length(args) <= 1)
4421 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4423 if (show_status && strv_length(args) <= 1) {
4425 pager_open_if_enabled();
4426 show_system_status(bus);
4430 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4432 _cleanup_free_ char **patterns = NULL;
4435 STRV_FOREACH(name, args + 1) {
4436 _cleanup_free_ char *unit = NULL;
4439 if (safe_atou32(*name, &id) < 0) {
4440 if (strv_push(&patterns, *name) < 0)
4444 } else if (show_properties) {
4445 /* Interpret as job id */
4446 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4450 /* Interpret as PID */
4451 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4458 r = show_one(args[0], bus, unit, show_properties,
4459 &new_line, &ellipsized);
4462 else if (r > 0 && ret == 0)
4466 if (!strv_isempty(patterns)) {
4467 _cleanup_strv_free_ char **names = NULL;
4469 r = expand_names(bus, patterns, NULL, &names);
4471 log_error_errno(r, "Failed to expand names: %m");
4473 STRV_FOREACH(name, names) {
4474 _cleanup_free_ char *unit;
4476 unit = unit_dbus_path_from_name(*name);
4480 r = show_one(args[0], bus, unit, show_properties,
4481 &new_line, &ellipsized);
4484 else if (r > 0 && ret == 0)
4490 if (ellipsized && !arg_quiet)
4491 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4496 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4500 assert(user_runtime);
4503 if (arg_scope == UNIT_FILE_USER) {
4504 r = user_config_home(user_home);
4506 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4508 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4510 r = user_runtime_dir(user_runtime);
4512 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4514 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4517 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4519 return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
4524 static int cat(sd_bus *bus, char **args) {
4525 _cleanup_free_ char *user_home = NULL;
4526 _cleanup_free_ char *user_runtime = NULL;
4527 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4528 _cleanup_strv_free_ char **names = NULL;
4530 bool first = true, avoid_bus_cache;
4535 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4539 r = expand_names(bus, args + 1, NULL, &names);
4541 log_error_errno(r, "Failed to expand names: %m");
4543 avoid_bus_cache = !bus || avoid_bus();
4545 pager_open_if_enabled();
4547 STRV_FOREACH(name, names) {
4548 _cleanup_free_ char *fragment_path = NULL;
4549 _cleanup_strv_free_ char **dropin_paths = NULL;
4552 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4556 log_warning("Unit %s does not have any files on disk", *name);
4565 if (fragment_path) {
4566 printf("%s# %s%s\n",
4567 ansi_highlight_blue(),
4569 ansi_highlight_off());
4572 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4574 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4579 STRV_FOREACH(path, dropin_paths) {
4580 printf("%s%s# %s%s\n",
4581 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4582 ansi_highlight_blue(),
4584 ansi_highlight_off());
4587 r = copy_file_fd(*path, STDOUT_FILENO, false);
4589 log_warning_errno(r, "Failed to cat %s: %m", *path);
4595 return r < 0 ? r : 0;
4598 static int set_property(sd_bus *bus, char **args) {
4599 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4600 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4601 _cleanup_free_ char *n = NULL;
4605 polkit_agent_open_if_enabled();
4607 r = sd_bus_message_new_method_call(
4610 "org.freedesktop.systemd1",
4611 "/org/freedesktop/systemd1",
4612 "org.freedesktop.systemd1.Manager",
4613 "SetUnitProperties");
4615 return bus_log_create_error(r);
4617 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4619 return bus_log_create_error(r);
4621 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4625 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4627 return bus_log_create_error(r);
4629 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4631 return bus_log_create_error(r);
4633 STRV_FOREACH(i, args + 2) {
4634 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4636 return bus_log_create_error(r);
4638 r = bus_append_unit_property_assignment(m, *i);
4642 r = sd_bus_message_close_container(m);
4644 return bus_log_create_error(r);
4647 r = sd_bus_message_close_container(m);
4649 return bus_log_create_error(r);
4651 r = sd_bus_call(bus, m, 0, &error, NULL);
4653 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4660 static int snapshot(sd_bus *bus, char **args) {
4661 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4662 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4663 _cleanup_free_ char *n = NULL, *id = NULL;
4667 polkit_agent_open_if_enabled();
4669 if (strv_length(args) > 1)
4670 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4676 r = sd_bus_message_new_method_call(
4679 "org.freedesktop.systemd1",
4680 "/org/freedesktop/systemd1",
4681 "org.freedesktop.systemd1.Manager",
4684 return bus_log_create_error(r);
4686 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4688 return bus_log_create_error(r);
4690 r = sd_bus_message_append(m, "sb", n, false);
4692 return bus_log_create_error(r);
4694 r = sd_bus_call(bus, m, 0, &error, &reply);
4696 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4700 r = sd_bus_message_read(reply, "o", &path);
4702 return bus_log_parse_error(r);
4704 r = sd_bus_get_property_string(
4706 "org.freedesktop.systemd1",
4708 "org.freedesktop.systemd1.Unit",
4713 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4723 static int delete_snapshot(sd_bus *bus, char **args) {
4724 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4725 _cleanup_strv_free_ char **names = NULL;
4731 polkit_agent_open_if_enabled();
4733 r = expand_names(bus, args + 1, ".snapshot", &names);
4735 log_error_errno(r, "Failed to expand names: %m");
4737 STRV_FOREACH(name, names) {
4738 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4741 q = sd_bus_message_new_method_call(
4744 "org.freedesktop.systemd1",
4745 "/org/freedesktop/systemd1",
4746 "org.freedesktop.systemd1.Manager",
4749 return bus_log_create_error(q);
4751 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4753 return bus_log_create_error(q);
4755 q = sd_bus_message_append(m, "s", *name);
4757 return bus_log_create_error(q);
4759 q = sd_bus_call(bus, m, 0, &error, NULL);
4761 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4770 static int daemon_reload(sd_bus *bus, char **args) {
4771 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4772 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4776 polkit_agent_open_if_enabled();
4778 if (arg_action == ACTION_RELOAD)
4780 else if (arg_action == ACTION_REEXEC)
4781 method = "Reexecute";
4783 assert(arg_action == ACTION_SYSTEMCTL);
4786 streq(args[0], "clear-jobs") ||
4787 streq(args[0], "cancel") ? "ClearJobs" :
4788 streq(args[0], "daemon-reexec") ? "Reexecute" :
4789 streq(args[0], "reset-failed") ? "ResetFailed" :
4790 streq(args[0], "halt") ? "Halt" :
4791 streq(args[0], "poweroff") ? "PowerOff" :
4792 streq(args[0], "reboot") ? "Reboot" :
4793 streq(args[0], "kexec") ? "KExec" :
4794 streq(args[0], "exit") ? "Exit" :
4795 /* "daemon-reload" */ "Reload";
4798 r = sd_bus_message_new_method_call(
4801 "org.freedesktop.systemd1",
4802 "/org/freedesktop/systemd1",
4803 "org.freedesktop.systemd1.Manager",
4806 return bus_log_create_error(r);
4808 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4810 return bus_log_create_error(r);
4812 r = sd_bus_call(bus, m, 0, &error, NULL);
4813 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4814 /* There's always a fallback possible for
4815 * legacy actions. */
4817 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4818 /* On reexecution, we expect a disconnect, not a
4822 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4824 return r < 0 ? r : 0;
4827 static int reset_failed(sd_bus *bus, char **args) {
4828 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4829 _cleanup_strv_free_ char **names = NULL;
4833 if (strv_length(args) <= 1)
4834 return daemon_reload(bus, args);
4836 polkit_agent_open_if_enabled();
4838 r = expand_names(bus, args + 1, NULL, &names);
4840 log_error_errno(r, "Failed to expand names: %m");
4842 STRV_FOREACH(name, names) {
4843 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4845 q = sd_bus_message_new_method_call(
4848 "org.freedesktop.systemd1",
4849 "/org/freedesktop/systemd1",
4850 "org.freedesktop.systemd1.Manager",
4853 return bus_log_create_error(q);
4855 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4857 return bus_log_create_error(q);
4859 q = sd_bus_message_append(m, "s", *name);
4861 return bus_log_create_error(q);
4863 q = sd_bus_call(bus, m, 0, &error, NULL);
4865 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4874 static int show_environment(sd_bus *bus, char **args) {
4875 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4876 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4880 pager_open_if_enabled();
4882 r = sd_bus_get_property(
4884 "org.freedesktop.systemd1",
4885 "/org/freedesktop/systemd1",
4886 "org.freedesktop.systemd1.Manager",
4892 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4896 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4898 return bus_log_parse_error(r);
4900 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4903 return bus_log_parse_error(r);
4905 r = sd_bus_message_exit_container(reply);
4907 return bus_log_parse_error(r);
4912 static int switch_root(sd_bus *bus, char **args) {
4913 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4914 _cleanup_free_ char *cmdline_init = NULL;
4915 const char *root, *init;
4919 l = strv_length(args);
4920 if (l < 2 || l > 3) {
4921 log_error("Wrong number of arguments.");
4930 r = parse_env_file("/proc/cmdline", WHITESPACE,
4931 "init", &cmdline_init,
4934 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4936 init = cmdline_init;
4943 const char *root_systemd_path = NULL, *root_init_path = NULL;
4945 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4946 root_init_path = strappenda(root, "/", init);
4948 /* If the passed init is actually the same as the
4949 * systemd binary, then let's suppress it. */
4950 if (files_same(root_init_path, root_systemd_path) > 0)
4954 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4956 r = sd_bus_call_method(
4958 "org.freedesktop.systemd1",
4959 "/org/freedesktop/systemd1",
4960 "org.freedesktop.systemd1.Manager",
4966 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4973 static int set_environment(sd_bus *bus, char **args) {
4974 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4975 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4982 method = streq(args[0], "set-environment")
4984 : "UnsetEnvironment";
4986 r = sd_bus_message_new_method_call(
4989 "org.freedesktop.systemd1",
4990 "/org/freedesktop/systemd1",
4991 "org.freedesktop.systemd1.Manager",
4994 return bus_log_create_error(r);
4996 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4998 return bus_log_create_error(r);
5000 r = sd_bus_message_append_strv(m, args + 1);
5002 return bus_log_create_error(r);
5004 r = sd_bus_call(bus, m, 0, &error, NULL);
5006 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5013 static int import_environment(sd_bus *bus, char **args) {
5014 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5015 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5021 r = sd_bus_message_new_method_call(
5024 "org.freedesktop.systemd1",
5025 "/org/freedesktop/systemd1",
5026 "org.freedesktop.systemd1.Manager",
5029 return bus_log_create_error(r);
5031 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5033 return bus_log_create_error(r);
5035 if (strv_isempty(args + 1))
5036 r = sd_bus_message_append_strv(m, environ);
5040 r = sd_bus_message_open_container(m, 'a', "s");
5042 return bus_log_create_error(r);
5044 STRV_FOREACH(a, args + 1) {
5046 if (!env_name_is_valid(*a)) {
5047 log_error("Not a valid environment variable name: %s", *a);
5051 STRV_FOREACH(b, environ) {
5054 eq = startswith(*b, *a);
5055 if (eq && *eq == '=') {
5057 r = sd_bus_message_append(m, "s", *b);
5059 return bus_log_create_error(r);
5066 r = sd_bus_message_close_container(m);
5069 return bus_log_create_error(r);
5071 r = sd_bus_call(bus, m, 0, &error, NULL);
5073 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5080 static int enable_sysv_units(const char *verb, char **args) {
5083 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5085 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5087 if (arg_scope != UNIT_FILE_SYSTEM)
5090 if (!streq(verb, "enable") &&
5091 !streq(verb, "disable") &&
5092 !streq(verb, "is-enabled"))
5095 /* Processes all SysV units, and reshuffles the array so that
5096 * afterwards only the native units remain */
5098 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5105 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5106 bool found_native = false, found_sysv;
5108 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5116 if (!endswith(name, ".service"))
5119 if (path_is_absolute(name))
5122 STRV_FOREACH(k, paths.unit_path) {
5123 _cleanup_free_ char *path = NULL;
5125 path = path_join(arg_root, *k, name);
5129 found_native = access(path, F_OK) >= 0;
5137 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5141 p[strlen(p) - strlen(".service")] = 0;
5142 found_sysv = access(p, F_OK) >= 0;
5146 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5148 if (!isempty(arg_root))
5149 argv[c++] = q = strappend("--root=", arg_root);
5151 argv[c++] = basename(p);
5153 streq(verb, "enable") ? "on" :
5154 streq(verb, "disable") ? "off" : "--level=5";
5157 l = strv_join((char**)argv, " ");
5161 log_info("Executing %s", l);
5165 return log_error_errno(errno, "Failed to fork: %m");
5166 else if (pid == 0) {
5169 execv(argv[0], (char**) argv);
5170 _exit(EXIT_FAILURE);
5173 j = wait_for_terminate(pid, &status);
5175 log_error_errno(r, "Failed to wait for child: %m");
5179 if (status.si_code == CLD_EXITED) {
5180 if (streq(verb, "is-enabled")) {
5181 if (status.si_status == 0) {
5190 } else if (status.si_status != 0)
5195 /* Remove this entry, so that we don't try enabling it as native unit */
5198 assert(args[f] == name);
5199 strv_remove(args, name);
5206 static int mangle_names(char **original_names, char ***mangled_names) {
5207 char **i, **l, **name;
5209 l = new(char*, strv_length(original_names) + 1);
5214 STRV_FOREACH(name, original_names) {
5216 /* When enabling units qualified path names are OK,
5217 * too, hence allow them explicitly. */
5222 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5238 static int enable_unit(sd_bus *bus, char **args) {
5239 _cleanup_strv_free_ char **names = NULL;
5240 const char *verb = args[0];
5241 UnitFileChange *changes = NULL;
5242 unsigned n_changes = 0;
5243 int carries_install_info = -1;
5249 r = mangle_names(args+1, &names);
5253 r = enable_sysv_units(verb, names);
5257 /* If the operation was fully executed by the SysV compat,
5258 * let's finish early */
5259 if (strv_isempty(names))
5262 if (!bus || avoid_bus()) {
5263 if (streq(verb, "enable")) {
5264 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5265 carries_install_info = r;
5266 } else if (streq(verb, "disable"))
5267 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5268 else if (streq(verb, "reenable")) {
5269 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5270 carries_install_info = r;
5271 } else if (streq(verb, "link"))
5272 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5273 else if (streq(verb, "preset")) {
5274 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5275 carries_install_info = r;
5276 } else if (streq(verb, "mask"))
5277 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5278 else if (streq(verb, "unmask"))
5279 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5281 assert_not_reached("Unknown verb");
5284 log_error_errno(r, "Operation failed: %m");
5289 dump_unit_file_changes(changes, n_changes);
5293 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5294 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5295 int expect_carries_install_info = false;
5296 bool send_force = true, send_preset_mode = false;
5299 polkit_agent_open_if_enabled();
5301 if (streq(verb, "enable")) {
5302 method = "EnableUnitFiles";
5303 expect_carries_install_info = true;
5304 } else if (streq(verb, "disable")) {
5305 method = "DisableUnitFiles";
5307 } else if (streq(verb, "reenable")) {
5308 method = "ReenableUnitFiles";
5309 expect_carries_install_info = true;
5310 } else if (streq(verb, "link"))
5311 method = "LinkUnitFiles";
5312 else if (streq(verb, "preset")) {
5314 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5315 method = "PresetUnitFilesWithMode";
5316 send_preset_mode = true;
5318 method = "PresetUnitFiles";
5320 expect_carries_install_info = true;
5321 } else if (streq(verb, "mask"))
5322 method = "MaskUnitFiles";
5323 else if (streq(verb, "unmask")) {
5324 method = "UnmaskUnitFiles";
5327 assert_not_reached("Unknown verb");
5329 r = sd_bus_message_new_method_call(
5332 "org.freedesktop.systemd1",
5333 "/org/freedesktop/systemd1",
5334 "org.freedesktop.systemd1.Manager",
5337 return bus_log_create_error(r);
5339 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5341 return bus_log_create_error(r);
5343 r = sd_bus_message_append_strv(m, names);
5345 return bus_log_create_error(r);
5347 if (send_preset_mode) {
5348 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5350 return bus_log_create_error(r);
5353 r = sd_bus_message_append(m, "b", arg_runtime);
5355 return bus_log_create_error(r);
5358 r = sd_bus_message_append(m, "b", arg_force);
5360 return bus_log_create_error(r);
5363 r = sd_bus_call(bus, m, 0, &error, &reply);
5365 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5369 if (expect_carries_install_info) {
5370 r = sd_bus_message_read(reply, "b", &carries_install_info);
5372 return bus_log_parse_error(r);
5375 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5379 /* Try to reload if enabled */
5381 r = daemon_reload(bus, args);
5386 if (carries_install_info == 0)
5387 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5388 "using systemctl.\n"
5389 "Possible reasons for having this kind of units are:\n"
5390 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5391 " .wants/ or .requires/ directory.\n"
5392 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5393 " a requirement dependency on it.\n"
5394 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5395 " D-Bus, udev, scripted systemctl call, ...).\n");
5398 unit_file_changes_free(changes, n_changes);
5403 static int add_dependency(sd_bus *bus, char **args) {
5404 _cleanup_strv_free_ char **names = NULL;
5405 _cleanup_free_ char *target = NULL;
5406 const char *verb = args[0];
5413 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5417 r = mangle_names(args+2, &names);
5421 if (streq(verb, "add-wants"))
5423 else if (streq(verb, "add-requires"))
5424 dep = UNIT_REQUIRES;
5426 assert_not_reached("Unknown verb");
5428 if (!bus || avoid_bus()) {
5429 UnitFileChange *changes = NULL;
5430 unsigned n_changes = 0;
5432 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5435 return log_error_errno(r, "Can't add dependency: %m");
5438 dump_unit_file_changes(changes, n_changes);
5440 unit_file_changes_free(changes, n_changes);
5443 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5444 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5446 polkit_agent_open_if_enabled();
5448 r = sd_bus_message_new_method_call(
5451 "org.freedesktop.systemd1",
5452 "/org/freedesktop/systemd1",
5453 "org.freedesktop.systemd1.Manager",
5454 "AddDependencyUnitFiles");
5456 return bus_log_create_error(r);
5458 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5460 return bus_log_create_error(r);
5462 r = sd_bus_message_append_strv(m, names);
5464 return bus_log_create_error(r);
5466 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5468 return bus_log_create_error(r);
5470 r = sd_bus_call(bus, m, 0, &error, &reply);
5472 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5476 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5481 r = daemon_reload(bus, args);
5489 static int preset_all(sd_bus *bus, char **args) {
5490 UnitFileChange *changes = NULL;
5491 unsigned n_changes = 0;
5494 if (!bus || avoid_bus()) {
5496 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5498 log_error_errno(r, "Operation failed: %m");
5503 dump_unit_file_changes(changes, n_changes);
5508 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5509 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5511 polkit_agent_open_if_enabled();
5513 r = sd_bus_message_new_method_call(
5516 "org.freedesktop.systemd1",
5517 "/org/freedesktop/systemd1",
5518 "org.freedesktop.systemd1.Manager",
5519 "PresetAllUnitFiles");
5521 return bus_log_create_error(r);
5523 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5525 return bus_log_create_error(r);
5527 r = sd_bus_message_append(
5530 unit_file_preset_mode_to_string(arg_preset_mode),
5534 return bus_log_create_error(r);
5536 r = sd_bus_call(bus, m, 0, &error, &reply);
5538 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5542 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5547 r = daemon_reload(bus, args);
5553 unit_file_changes_free(changes, n_changes);
5558 static int unit_is_enabled(sd_bus *bus, char **args) {
5560 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5561 _cleanup_strv_free_ char **names = NULL;
5566 r = mangle_names(args+1, &names);
5570 r = enable_sysv_units(args[0], names);
5576 if (!bus || avoid_bus()) {
5578 STRV_FOREACH(name, names) {
5579 UnitFileState state;
5581 state = unit_file_get_state(arg_scope, arg_root, *name);
5583 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5585 if (state == UNIT_FILE_ENABLED ||
5586 state == UNIT_FILE_ENABLED_RUNTIME ||
5587 state == UNIT_FILE_STATIC ||
5588 state == UNIT_FILE_INDIRECT)
5592 puts(unit_file_state_to_string(state));
5596 STRV_FOREACH(name, names) {
5597 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5600 r = sd_bus_call_method(
5602 "org.freedesktop.systemd1",
5603 "/org/freedesktop/systemd1",
5604 "org.freedesktop.systemd1.Manager",
5610 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5614 r = sd_bus_message_read(reply, "s", &s);
5616 return bus_log_parse_error(r);
5618 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5629 static int is_system_running(sd_bus *bus, char **args) {
5630 _cleanup_free_ char *state = NULL;
5633 r = sd_bus_get_property_string(
5635 "org.freedesktop.systemd1",
5636 "/org/freedesktop/systemd1",
5637 "org.freedesktop.systemd1.Manager",
5650 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5653 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5658 assert(original_path);
5661 r = tempfn_random(new_path, &t);
5663 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5665 r = mkdir_parents(new_path, 0755);
5667 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5672 r = copy_file(original_path, t, 0, 0644, 0);
5676 log_error_errno(r, "Failed to create temporary file %s: %m", t);
5681 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5691 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5692 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5694 switch (arg_scope) {
5695 case UNIT_FILE_SYSTEM:
5696 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5698 run = path_join(arg_root, "/run/systemd/system/", name);
5700 case UNIT_FILE_GLOBAL:
5701 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5703 run = path_join(arg_root, "/run/systemd/user/", name);
5705 case UNIT_FILE_USER:
5707 assert(user_runtime);
5709 path = path_join(arg_root, user_home, name);
5711 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5714 run = path_join(arg_root, user_runtime, name);
5718 assert_not_reached("Invalid scope");
5720 if (!path || (arg_runtime && !run))
5724 if (access(path, F_OK) >= 0)
5725 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5727 if (path2 && access(path2, F_OK) >= 0)
5728 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5741 static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
5742 char *tmp_new_path, *ending;
5747 assert(ret_new_path);
5748 assert(ret_tmp_path);
5750 ending = strappenda(unit_name, ".d/override.conf");
5751 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5755 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5761 *ret_new_path = tmp_new_path;
5762 *ret_tmp_path = tmp_tmp_path;
5767 static int unit_file_create_copy(const char *unit_name,
5768 const char *fragment_path,
5769 const char *user_home,
5770 const char *user_runtime,
5771 char **ret_new_path,
5772 char **ret_tmp_path) {
5777 assert(fragment_path);
5779 assert(ret_new_path);
5780 assert(ret_tmp_path);
5782 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5786 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5789 r = ask_char(&response, "yn", "%s already exists, are you sure to overwrite it with %s? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5794 if (response != 'y') {
5795 log_warning("%s ignored", unit_name);
5801 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5803 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5808 *ret_new_path = tmp_new_path;
5809 *ret_tmp_path = tmp_tmp_path;
5814 static int run_editor(char **paths) {
5822 log_error_errno(errno, "Failed to fork: %m");
5828 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5830 char **tmp_path, **original_path, **p;
5834 argc = strv_length(paths)/2 + 1;
5835 args = newa(const char*, argc + 1);
5838 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5839 args[i] = *tmp_path;
5844 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5845 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5846 * we try to execute well known editors
5848 editor = getenv("SYSTEMD_EDITOR");
5850 editor = getenv("EDITOR");
5852 editor = getenv("VISUAL");
5854 if (!isempty(editor)) {
5856 execvp(editor, (char* const*) args);
5859 STRV_FOREACH(p, backup_editors) {
5861 execvp(*p, (char* const*) args);
5862 /* We do not fail if the editor doesn't exist
5863 * because we want to try each one of them before
5866 if (errno != ENOENT) {
5867 log_error("Failed to execute %s: %m", editor);
5868 _exit(EXIT_FAILURE);
5872 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5873 _exit(EXIT_FAILURE);
5876 r = wait_for_terminate_and_warn("editor", pid, true);
5878 return log_error_errno(r, "Failed to wait for child: %m");
5883 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5884 _cleanup_free_ char *user_home = NULL;
5885 _cleanup_free_ char *user_runtime = NULL;
5886 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5887 bool avoid_bus_cache;
5894 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5898 avoid_bus_cache = !bus || avoid_bus();
5900 STRV_FOREACH(name, names) {
5901 _cleanup_free_ char *path = NULL;
5902 char *new_path, *tmp_path;
5904 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5907 else if (r == 0 || !path)
5908 // FIXME: support units with path==NULL (no FragmentPath)
5909 return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
5912 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5914 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5918 r = strv_push_pair(paths, new_path, tmp_path);
5926 static int edit(sd_bus *bus, char **args) {
5927 _cleanup_strv_free_ char **names = NULL;
5928 _cleanup_strv_free_ char **paths = NULL;
5929 char **original, **tmp;
5935 log_error("Cannot edit units if we are not on a tty");
5939 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5940 log_error("Cannot remotely edit units");
5944 r = expand_names(bus, args + 1, NULL, &names);
5946 return log_error_errno(r, "Failed to expand names: %m");
5949 log_error("No unit name found by expanding names");
5953 r = find_paths_to_edit(bus, names, &paths);
5957 if (strv_isempty(paths)) {
5958 log_error("Cannot find any units to edit");
5962 r = run_editor(paths);
5966 STRV_FOREACH_PAIR(original, tmp, paths) {
5967 /* If the temporary file is empty we ignore it.
5968 * It's useful if the user wants to cancel its modification
5970 if (null_or_empty_path(*tmp)) {
5971 log_warning("Edition of %s canceled: temporary file empty", *original);
5974 r = rename(*tmp, *original);
5976 r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
5981 if (!arg_no_reload && bus && !avoid_bus())
5982 r = daemon_reload(bus, args);
5985 STRV_FOREACH_PAIR(original, tmp, paths)
5986 unlink_noerrno(*tmp);
5991 static void systemctl_help(void) {
5993 pager_open_if_enabled();
5995 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5996 "Query or send control commands to the systemd manager.\n\n"
5997 " -h --help Show this help\n"
5998 " --version Show package version\n"
5999 " --system Connect to system manager\n"
6000 " --user Connect to user service manager\n"
6001 " -H --host=[USER@]HOST\n"
6002 " Operate on remote host\n"
6003 " -M --machine=CONTAINER\n"
6004 " Operate on local container\n"
6005 " -t --type=TYPE List only units of a particular type\n"
6006 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
6007 " -p --property=NAME Show only properties by this name\n"
6008 " -a --all Show all loaded units/properties, including dead/empty\n"
6009 " ones. To list all units installed on the system, use\n"
6010 " the 'list-unit-files' command instead.\n"
6011 " -l --full Don't ellipsize unit names on output\n"
6012 " -r --recursive Show unit list of host and local containers\n"
6013 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6014 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6015 " queueing a new job\n"
6016 " --show-types When showing sockets, explicitly show their type\n"
6017 " -i --ignore-inhibitors\n"
6018 " When shutting down or sleeping, ignore inhibitors\n"
6019 " --kill-who=WHO Who to send signal to\n"
6020 " -s --signal=SIGNAL Which signal to send\n"
6021 " -q --quiet Suppress output\n"
6022 " --no-block Do not wait until operation finished\n"
6023 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6024 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
6026 " --no-legend Do not print a legend (column headers and hints)\n"
6027 " --no-pager Do not pipe output into a pager\n"
6028 " --no-ask-password\n"
6029 " Do not ask for system passwords\n"
6030 " --global Enable/disable unit files globally\n"
6031 " --runtime Enable unit files only temporarily until next reboot\n"
6032 " -f --force When enabling unit files, override existing symlinks\n"
6033 " When shutting down, execute action immediately\n"
6034 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
6035 " or only disable\n"
6036 " --root=PATH Enable unit files in the specified root directory\n"
6037 " -n --lines=INTEGER Number of journal entries to show\n"
6038 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6039 " short-precise, short-monotonic, verbose,\n"
6040 " export, json, json-pretty, json-sse, cat)\n"
6041 " --plain Print unit dependencies as a list instead of a tree\n\n"
6043 " list-units [PATTERN...] List loaded units\n"
6044 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6045 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6046 " start NAME... Start (activate) one or more units\n"
6047 " stop NAME... Stop (deactivate) one or more units\n"
6048 " reload NAME... Reload one or more units\n"
6049 " restart NAME... Start or restart one or more units\n"
6050 " try-restart NAME... Restart one or more units if active\n"
6051 " reload-or-restart NAME... Reload one or more units if possible,\n"
6052 " otherwise start or restart\n"
6053 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6054 " otherwise restart if active\n"
6055 " isolate NAME Start one unit and stop all others\n"
6056 " kill NAME... Send signal to processes of a unit\n"
6057 " is-active PATTERN... Check whether units are active\n"
6058 " is-failed PATTERN... Check whether units are failed\n"
6059 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6060 " show [PATTERN...|JOB...] Show properties of one or more\n"
6061 " units/jobs or the manager\n"
6062 " cat PATTERN... Show files and drop-ins of one or more units\n"
6063 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6064 " help PATTERN...|PID... Show manual for one or more units\n"
6065 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6067 " list-dependencies [NAME] Recursively show units which are required\n"
6068 " or wanted by this unit or by which this\n"
6069 " unit is required or wanted\n\n"
6070 "Unit File Commands:\n"
6071 " list-unit-files [PATTERN...] List installed unit files\n"
6072 " enable NAME... Enable one or more unit files\n"
6073 " disable NAME... Disable one or more unit files\n"
6074 " reenable NAME... Reenable one or more unit files\n"
6075 " preset NAME... Enable/disable one or more unit files\n"
6076 " based on preset configuration\n"
6077 " preset-all Enable/disable all unit files based on\n"
6078 " preset configuration\n"
6079 " is-enabled NAME... Check whether unit files are enabled\n"
6080 " mask NAME... Mask one or more units\n"
6081 " unmask NAME... Unmask one or more units\n"
6082 " link PATH... Link one or more units files into\n"
6083 " the search path\n"
6084 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6085 " on specified one or more units\n"
6086 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6087 " on specified one or more units\n"
6088 " edit NAME... Edit one or more unit files\n"
6089 " get-default Get the name of the default target\n"
6090 " set-default NAME Set the default target\n\n"
6091 "Machine Commands:\n"
6092 " list-machines [PATTERN...] List local containers and host\n\n"
6094 " list-jobs [PATTERN...] List jobs\n"
6095 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6096 "Snapshot Commands:\n"
6097 " snapshot [NAME] Create a snapshot\n"
6098 " delete NAME... Remove one or more snapshots\n\n"
6099 "Environment Commands:\n"
6100 " show-environment Dump environment\n"
6101 " set-environment NAME=VALUE... Set one or more environment variables\n"
6102 " unset-environment NAME... Unset one or more environment variables\n"
6103 " import-environment NAME... Import all, one or more environment variables\n\n"
6104 "Manager Lifecycle Commands:\n"
6105 " daemon-reload Reload systemd manager configuration\n"
6106 " daemon-reexec Reexecute systemd manager\n\n"
6107 "System Commands:\n"
6108 " is-system-running Check whether system is fully running\n"
6109 " default Enter system default mode\n"
6110 " rescue Enter system rescue mode\n"
6111 " emergency Enter system emergency mode\n"
6112 " halt Shut down and halt the system\n"
6113 " poweroff Shut down and power-off the system\n"
6114 " reboot [ARG] Shut down and reboot the system\n"
6115 " kexec Shut down and reboot the system with kexec\n"
6116 " exit Request user instance exit\n"
6117 " switch-root ROOT [INIT] Change to a different root file system\n"
6118 " suspend Suspend the system\n"
6119 " hibernate Hibernate the system\n"
6120 " hybrid-sleep Hibernate and suspend the system\n",
6121 program_invocation_short_name);
6124 static void halt_help(void) {
6125 printf("%s [OPTIONS...]%s\n\n"
6126 "%s the system.\n\n"
6127 " --help Show this help\n"
6128 " --halt Halt the machine\n"
6129 " -p --poweroff Switch off the machine\n"
6130 " --reboot Reboot the machine\n"
6131 " -f --force Force immediate halt/power-off/reboot\n"
6132 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6133 " -d --no-wtmp Don't write wtmp record\n"
6134 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6135 program_invocation_short_name,
6136 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6137 arg_action == ACTION_REBOOT ? "Reboot" :
6138 arg_action == ACTION_POWEROFF ? "Power off" :
6142 static void shutdown_help(void) {
6143 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6144 "Shut down the system.\n\n"
6145 " --help Show this help\n"
6146 " -H --halt Halt the machine\n"
6147 " -P --poweroff Power-off the machine\n"
6148 " -r --reboot Reboot the machine\n"
6149 " -h Equivalent to --poweroff, overridden by --halt\n"
6150 " -k Don't halt/power-off/reboot, just send warnings\n"
6151 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6152 " -c Cancel a pending shutdown\n",
6153 program_invocation_short_name);
6156 static void telinit_help(void) {
6157 printf("%s [OPTIONS...] {COMMAND}\n\n"
6158 "Send control commands to the init daemon.\n\n"
6159 " --help Show this help\n"
6160 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6162 " 0 Power-off the machine\n"
6163 " 6 Reboot the machine\n"
6164 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6165 " 1, s, S Enter rescue mode\n"
6166 " q, Q Reload init daemon configuration\n"
6167 " u, U Reexecute init daemon\n",
6168 program_invocation_short_name);
6171 static void runlevel_help(void) {
6172 printf("%s [OPTIONS...]\n\n"
6173 "Prints the previous and current runlevel of the init system.\n\n"
6174 " --help Show this help\n",
6175 program_invocation_short_name);
6178 static void help_types(void) {
6183 puts("Available unit types:");
6184 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6185 t = unit_type_to_string(i);
6191 static int systemctl_parse_argv(int argc, char *argv[]) {
6200 ARG_IGNORE_DEPENDENCIES,
6212 ARG_NO_ASK_PASSWORD,
6222 static const struct option options[] = {
6223 { "help", no_argument, NULL, 'h' },
6224 { "version", no_argument, NULL, ARG_VERSION },
6225 { "type", required_argument, NULL, 't' },
6226 { "property", required_argument, NULL, 'p' },
6227 { "all", no_argument, NULL, 'a' },
6228 { "reverse", no_argument, NULL, ARG_REVERSE },
6229 { "after", no_argument, NULL, ARG_AFTER },
6230 { "before", no_argument, NULL, ARG_BEFORE },
6231 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6232 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6233 { "full", no_argument, NULL, 'l' },
6234 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6235 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6236 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6237 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6238 { "ignore-inhibitors", no_argument, NULL, 'i' },
6239 { "user", no_argument, NULL, ARG_USER },
6240 { "system", no_argument, NULL, ARG_SYSTEM },
6241 { "global", no_argument, NULL, ARG_GLOBAL },
6242 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6243 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6244 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6245 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6246 { "quiet", no_argument, NULL, 'q' },
6247 { "root", required_argument, NULL, ARG_ROOT },
6248 { "force", no_argument, NULL, ARG_FORCE },
6249 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6250 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6251 { "signal", required_argument, NULL, 's' },
6252 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6253 { "host", required_argument, NULL, 'H' },
6254 { "machine", required_argument, NULL, 'M' },
6255 { "runtime", no_argument, NULL, ARG_RUNTIME },
6256 { "lines", required_argument, NULL, 'n' },
6257 { "output", required_argument, NULL, 'o' },
6258 { "plain", no_argument, NULL, ARG_PLAIN },
6259 { "state", required_argument, NULL, ARG_STATE },
6260 { "recursive", no_argument, NULL, 'r' },
6261 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6270 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6279 puts(PACKAGE_STRING);
6280 puts(SYSTEMD_FEATURES);
6284 const char *word, *state;
6287 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6288 _cleanup_free_ char *type;
6290 type = strndup(word, size);
6294 if (streq(type, "help")) {
6299 if (unit_type_from_string(type) >= 0) {
6300 if (strv_push(&arg_types, type))
6306 /* It's much nicer to use --state= for
6307 * load states, but let's support this
6308 * in --types= too for compatibility
6309 * with old versions */
6310 if (unit_load_state_from_string(optarg) >= 0) {
6311 if (strv_push(&arg_states, type) < 0)
6317 log_error("Unknown unit type or load state '%s'.", type);
6318 log_info("Use -t help to see a list of allowed values.");
6326 /* Make sure that if the empty property list
6327 was specified, we won't show any properties. */
6328 if (isempty(optarg) && !arg_properties) {
6329 arg_properties = new0(char*, 1);
6330 if (!arg_properties)
6333 const char *word, *state;
6336 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6339 prop = strndup(word, size);
6343 if (strv_consume(&arg_properties, prop) < 0)
6348 /* If the user asked for a particular
6349 * property, show it to him, even if it is
6361 arg_dependency = DEPENDENCY_REVERSE;
6365 arg_dependency = DEPENDENCY_AFTER;
6369 arg_dependency = DEPENDENCY_BEFORE;
6372 case ARG_SHOW_TYPES:
6373 arg_show_types = true;
6377 arg_job_mode = optarg;
6381 arg_job_mode = "fail";
6384 case ARG_IRREVERSIBLE:
6385 arg_job_mode = "replace-irreversibly";
6388 case ARG_IGNORE_DEPENDENCIES:
6389 arg_job_mode = "ignore-dependencies";
6393 arg_scope = UNIT_FILE_USER;
6397 arg_scope = UNIT_FILE_SYSTEM;
6401 arg_scope = UNIT_FILE_GLOBAL;
6405 arg_no_block = true;
6409 arg_no_legend = true;
6413 arg_no_pager = true;
6429 if (strv_extend(&arg_states, "failed") < 0)
6447 arg_no_reload = true;
6451 arg_kill_who = optarg;
6455 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6456 log_error("Failed to parse signal string %s.", optarg);
6461 case ARG_NO_ASK_PASSWORD:
6462 arg_ask_password = false;
6466 arg_transport = BUS_TRANSPORT_REMOTE;
6471 arg_transport = BUS_TRANSPORT_MACHINE;
6480 if (safe_atou(optarg, &arg_lines) < 0) {
6481 log_error("Failed to parse lines '%s'", optarg);
6487 arg_output = output_mode_from_string(optarg);
6488 if (arg_output < 0) {
6489 log_error("Unknown output '%s'.", optarg);
6495 arg_ignore_inhibitors = true;
6503 const char *word, *state;
6506 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6509 s = strndup(word, size);
6513 if (strv_consume(&arg_states, s) < 0)
6520 if (geteuid() != 0) {
6521 log_error("--recursive requires root privileges.");
6525 arg_recursive = true;
6528 case ARG_PRESET_MODE:
6530 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6531 if (arg_preset_mode < 0) {
6532 log_error("Failed to parse preset mode: %s.", optarg);
6542 assert_not_reached("Unhandled option");
6545 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6546 log_error("Cannot access user instance remotely.");
6553 static int halt_parse_argv(int argc, char *argv[]) {
6562 static const struct option options[] = {
6563 { "help", no_argument, NULL, ARG_HELP },
6564 { "halt", no_argument, NULL, ARG_HALT },
6565 { "poweroff", no_argument, NULL, 'p' },
6566 { "reboot", no_argument, NULL, ARG_REBOOT },
6567 { "force", no_argument, NULL, 'f' },
6568 { "wtmp-only", no_argument, NULL, 'w' },
6569 { "no-wtmp", no_argument, NULL, 'd' },
6570 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6579 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6580 if (runlevel == '0' || runlevel == '6')
6583 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6591 arg_action = ACTION_HALT;
6595 if (arg_action != ACTION_REBOOT)
6596 arg_action = ACTION_POWEROFF;
6600 arg_action = ACTION_REBOOT;
6622 /* Compatibility nops */
6629 assert_not_reached("Unhandled option");
6632 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6633 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6636 } else if (optind < argc) {
6637 log_error("Too many arguments.");
6644 static int parse_time_spec(const char *t, usec_t *_u) {
6648 if (streq(t, "now"))
6650 else if (!strchr(t, ':')) {
6653 if (safe_atou64(t, &u) < 0)
6656 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6665 hour = strtol(t, &e, 10);
6666 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6669 minute = strtol(e+1, &e, 10);
6670 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6673 n = now(CLOCK_REALTIME);
6674 s = (time_t) (n / USEC_PER_SEC);
6676 assert_se(localtime_r(&s, &tm));
6678 tm.tm_hour = (int) hour;
6679 tm.tm_min = (int) minute;
6682 assert_se(s = mktime(&tm));
6684 *_u = (usec_t) s * USEC_PER_SEC;
6687 *_u += USEC_PER_DAY;
6693 static int shutdown_parse_argv(int argc, char *argv[]) {
6700 static const struct option options[] = {
6701 { "help", no_argument, NULL, ARG_HELP },
6702 { "halt", no_argument, NULL, 'H' },
6703 { "poweroff", no_argument, NULL, 'P' },
6704 { "reboot", no_argument, NULL, 'r' },
6705 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6706 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6715 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6723 arg_action = ACTION_HALT;
6727 arg_action = ACTION_POWEROFF;
6732 arg_action = ACTION_KEXEC;
6734 arg_action = ACTION_REBOOT;
6738 arg_action = ACTION_KEXEC;
6742 if (arg_action != ACTION_HALT)
6743 arg_action = ACTION_POWEROFF;
6758 /* Compatibility nops */
6762 arg_action = ACTION_CANCEL_SHUTDOWN;
6769 assert_not_reached("Unhandled option");
6772 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6773 r = parse_time_spec(argv[optind], &arg_when);
6775 log_error("Failed to parse time specification: %s", argv[optind]);
6779 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6781 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6782 /* No time argument for shutdown cancel */
6783 arg_wall = argv + optind;
6784 else if (argc > optind + 1)
6785 /* We skip the time argument */
6786 arg_wall = argv + optind + 1;
6793 static int telinit_parse_argv(int argc, char *argv[]) {
6800 static const struct option options[] = {
6801 { "help", no_argument, NULL, ARG_HELP },
6802 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6806 static const struct {
6810 { '0', ACTION_POWEROFF },
6811 { '6', ACTION_REBOOT },
6812 { '1', ACTION_RESCUE },
6813 { '2', ACTION_RUNLEVEL2 },
6814 { '3', ACTION_RUNLEVEL3 },
6815 { '4', ACTION_RUNLEVEL4 },
6816 { '5', ACTION_RUNLEVEL5 },
6817 { 's', ACTION_RESCUE },
6818 { 'S', ACTION_RESCUE },
6819 { 'q', ACTION_RELOAD },
6820 { 'Q', ACTION_RELOAD },
6821 { 'u', ACTION_REEXEC },
6822 { 'U', ACTION_REEXEC }
6831 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6846 assert_not_reached("Unhandled option");
6849 if (optind >= argc) {
6850 log_error("%s: required argument missing.",
6851 program_invocation_short_name);
6855 if (optind + 1 < argc) {
6856 log_error("Too many arguments.");
6860 if (strlen(argv[optind]) != 1) {
6861 log_error("Expected single character argument.");
6865 for (i = 0; i < ELEMENTSOF(table); i++)
6866 if (table[i].from == argv[optind][0])
6869 if (i >= ELEMENTSOF(table)) {
6870 log_error("Unknown command '%s'.", argv[optind]);
6874 arg_action = table[i].to;
6881 static int runlevel_parse_argv(int argc, char *argv[]) {
6887 static const struct option options[] = {
6888 { "help", no_argument, NULL, ARG_HELP },
6897 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6908 assert_not_reached("Unhandled option");
6911 if (optind < argc) {
6912 log_error("Too many arguments.");
6919 static int parse_argv(int argc, char *argv[]) {
6923 if (program_invocation_short_name) {
6925 if (strstr(program_invocation_short_name, "halt")) {
6926 arg_action = ACTION_HALT;
6927 return halt_parse_argv(argc, argv);
6928 } else if (strstr(program_invocation_short_name, "poweroff")) {
6929 arg_action = ACTION_POWEROFF;
6930 return halt_parse_argv(argc, argv);
6931 } else if (strstr(program_invocation_short_name, "reboot")) {
6933 arg_action = ACTION_KEXEC;
6935 arg_action = ACTION_REBOOT;
6936 return halt_parse_argv(argc, argv);
6937 } else if (strstr(program_invocation_short_name, "shutdown")) {
6938 arg_action = ACTION_POWEROFF;
6939 return shutdown_parse_argv(argc, argv);
6940 } else if (strstr(program_invocation_short_name, "init")) {
6942 if (sd_booted() > 0) {
6943 arg_action = _ACTION_INVALID;
6944 return telinit_parse_argv(argc, argv);
6946 /* Hmm, so some other init system is
6947 * running, we need to forward this
6948 * request to it. For now we simply
6949 * guess that it is Upstart. */
6951 execv(TELINIT, argv);
6953 log_error("Couldn't find an alternative telinit implementation to spawn.");
6957 } else if (strstr(program_invocation_short_name, "runlevel")) {
6958 arg_action = ACTION_RUNLEVEL;
6959 return runlevel_parse_argv(argc, argv);
6963 arg_action = ACTION_SYSTEMCTL;
6964 return systemctl_parse_argv(argc, argv);
6967 _pure_ static int action_to_runlevel(void) {
6969 static const char table[_ACTION_MAX] = {
6970 [ACTION_HALT] = '0',
6971 [ACTION_POWEROFF] = '0',
6972 [ACTION_REBOOT] = '6',
6973 [ACTION_RUNLEVEL2] = '2',
6974 [ACTION_RUNLEVEL3] = '3',
6975 [ACTION_RUNLEVEL4] = '4',
6976 [ACTION_RUNLEVEL5] = '5',
6977 [ACTION_RESCUE] = '1'
6980 assert(arg_action < _ACTION_MAX);
6982 return table[arg_action];
6985 static int talk_initctl(void) {
6987 struct init_request request = {
6988 .magic = INIT_MAGIC,
6990 .cmd = INIT_CMD_RUNLVL
6993 _cleanup_close_ int fd = -1;
6997 rl = action_to_runlevel();
7001 request.runlevel = rl;
7003 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7005 if (errno == ENOENT)
7008 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7012 r = loop_write(fd, &request, sizeof(request), false);
7014 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7019 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7021 static const struct {
7029 int (* const dispatch)(sd_bus *bus, char **args);
7035 { "list-units", MORE, 0, list_units },
7036 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7037 { "list-sockets", MORE, 1, list_sockets },
7038 { "list-timers", MORE, 1, list_timers },
7039 { "list-jobs", MORE, 1, list_jobs },
7040 { "list-machines", MORE, 1, list_machines },
7041 { "clear-jobs", EQUAL, 1, daemon_reload },
7042 { "cancel", MORE, 2, cancel_job },
7043 { "start", MORE, 2, start_unit },
7044 { "stop", MORE, 2, start_unit },
7045 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7046 { "reload", MORE, 2, start_unit },
7047 { "restart", MORE, 2, start_unit },
7048 { "try-restart", MORE, 2, start_unit },
7049 { "reload-or-restart", MORE, 2, start_unit },
7050 { "reload-or-try-restart", MORE, 2, start_unit },
7051 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7052 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7053 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7054 { "isolate", EQUAL, 2, start_unit },
7055 { "kill", MORE, 2, kill_unit },
7056 { "is-active", MORE, 2, check_unit_active },
7057 { "check", MORE, 2, check_unit_active },
7058 { "is-failed", MORE, 2, check_unit_failed },
7059 { "show", MORE, 1, show },
7060 { "cat", MORE, 2, cat, NOBUS },
7061 { "status", MORE, 1, show },
7062 { "help", MORE, 2, show },
7063 { "snapshot", LESS, 2, snapshot },
7064 { "delete", MORE, 2, delete_snapshot },
7065 { "daemon-reload", EQUAL, 1, daemon_reload },
7066 { "daemon-reexec", EQUAL, 1, daemon_reload },
7067 { "show-environment", EQUAL, 1, show_environment },
7068 { "set-environment", MORE, 2, set_environment },
7069 { "unset-environment", MORE, 2, set_environment },
7070 { "import-environment", MORE, 1, import_environment},
7071 { "halt", EQUAL, 1, start_special, FORCE },
7072 { "poweroff", EQUAL, 1, start_special, FORCE },
7073 { "reboot", EQUAL, 1, start_special, FORCE },
7074 { "kexec", EQUAL, 1, start_special },
7075 { "suspend", EQUAL, 1, start_special },
7076 { "hibernate", EQUAL, 1, start_special },
7077 { "hybrid-sleep", EQUAL, 1, start_special },
7078 { "default", EQUAL, 1, start_special },
7079 { "rescue", EQUAL, 1, start_special },
7080 { "emergency", EQUAL, 1, start_special },
7081 { "exit", EQUAL, 1, start_special },
7082 { "reset-failed", MORE, 1, reset_failed },
7083 { "enable", MORE, 2, enable_unit, NOBUS },
7084 { "disable", MORE, 2, enable_unit, NOBUS },
7085 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7086 { "reenable", MORE, 2, enable_unit, NOBUS },
7087 { "preset", MORE, 2, enable_unit, NOBUS },
7088 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7089 { "mask", MORE, 2, enable_unit, NOBUS },
7090 { "unmask", MORE, 2, enable_unit, NOBUS },
7091 { "link", MORE, 2, enable_unit, NOBUS },
7092 { "switch-root", MORE, 2, switch_root },
7093 { "list-dependencies", LESS, 2, list_dependencies },
7094 { "set-default", EQUAL, 2, set_default, NOBUS },
7095 { "get-default", EQUAL, 1, get_default, NOBUS },
7096 { "set-property", MORE, 3, set_property },
7097 { "is-system-running", EQUAL, 1, is_system_running },
7098 { "add-wants", MORE, 3, add_dependency, NOBUS },
7099 { "add-requires", MORE, 3, add_dependency, NOBUS },
7100 { "edit", MORE, 2, edit, NOBUS },
7109 left = argc - optind;
7111 /* Special rule: no arguments (left == 0) means "list-units" */
7113 if (streq(argv[optind], "help") && !argv[optind+1]) {
7114 log_error("This command expects one or more "
7115 "unit names. Did you mean --help?");
7119 for (; verb->verb; verb++)
7120 if (streq(argv[optind], verb->verb))
7123 log_error("Unknown operation '%s'.", argv[optind]);
7128 switch (verb->argc_cmp) {
7131 if (left != verb->argc) {
7132 log_error("Invalid number of arguments.");
7139 if (left < verb->argc) {
7140 log_error("Too few arguments.");
7147 if (left > verb->argc) {
7148 log_error("Too many arguments.");
7155 assert_not_reached("Unknown comparison operator.");
7158 /* Require a bus connection for all operations but
7160 if (verb->bus == NOBUS) {
7161 if (!bus && !avoid_bus()) {
7162 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7167 if (running_in_chroot() > 0) {
7168 log_info("Running in chroot, ignoring request.");
7172 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7173 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7178 return verb->dispatch(bus, argv + optind);
7181 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7183 struct sd_shutdown_command c = {
7190 union sockaddr_union sockaddr = {
7191 .un.sun_family = AF_UNIX,
7192 .un.sun_path = "/run/systemd/shutdownd",
7195 struct iovec iovec[2] = {{
7196 .iov_base = (char*) &c,
7197 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7200 struct msghdr msghdr = {
7201 .msg_name = &sockaddr,
7202 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7203 + strlen("/run/systemd/shutdownd"),
7208 _cleanup_close_ int fd;
7210 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7214 if (!isempty(message)) {
7215 iovec[1].iov_base = (char*) message;
7216 iovec[1].iov_len = strlen(message);
7217 msghdr.msg_iovlen++;
7220 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7226 static int reload_with_fallback(sd_bus *bus) {
7229 /* First, try systemd via D-Bus. */
7230 if (daemon_reload(bus, NULL) >= 0)
7234 /* Nothing else worked, so let's try signals */
7235 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7237 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7238 return log_error_errno(errno, "kill() failed: %m");
7243 static int start_with_fallback(sd_bus *bus) {
7246 /* First, try systemd via D-Bus. */
7247 if (start_unit(bus, NULL) >= 0)
7251 /* Nothing else worked, so let's try
7253 if (talk_initctl() > 0)
7256 log_error("Failed to talk to init daemon.");
7260 warn_wall(arg_action);
7264 static int halt_now(enum action a) {
7266 /* The kernel will automaticall flush ATA disks and suchlike
7267 * on reboot(), but the file systems need to be synce'd
7268 * explicitly in advance. */
7271 /* Make sure C-A-D is handled by the kernel from this point
7273 reboot(RB_ENABLE_CAD);
7278 log_info("Halting.");
7279 reboot(RB_HALT_SYSTEM);
7282 case ACTION_POWEROFF:
7283 log_info("Powering off.");
7284 reboot(RB_POWER_OFF);
7287 case ACTION_REBOOT: {
7288 _cleanup_free_ char *param = NULL;
7290 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7291 log_info("Rebooting with argument '%s'.", param);
7292 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7293 LINUX_REBOOT_CMD_RESTART2, param);
7296 log_info("Rebooting.");
7297 reboot(RB_AUTOBOOT);
7302 assert_not_reached("Unknown action.");
7306 static int halt_main(sd_bus *bus) {
7309 r = check_inhibitors(bus, arg_action);
7313 if (geteuid() != 0) {
7314 /* Try logind if we are a normal user and no special
7315 * mode applies. Maybe PolicyKit allows us to shutdown
7318 if (arg_when <= 0 &&
7321 (arg_action == ACTION_POWEROFF ||
7322 arg_action == ACTION_REBOOT)) {
7323 r = reboot_with_logind(bus, arg_action);
7328 log_error("Must be root.");
7333 _cleanup_free_ char *m;
7335 m = strv_join(arg_wall, " ");
7339 r = send_shutdownd(arg_when,
7340 arg_action == ACTION_HALT ? 'H' :
7341 arg_action == ACTION_POWEROFF ? 'P' :
7342 arg_action == ACTION_KEXEC ? 'K' :
7349 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7351 char date[FORMAT_TIMESTAMP_MAX];
7353 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7354 format_timestamp(date, sizeof(date), arg_when));
7359 if (!arg_dry && !arg_force)
7360 return start_with_fallback(bus);
7363 if (sd_booted() > 0)
7364 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7366 r = utmp_put_shutdown();
7368 log_warning_errno(r, "Failed to write utmp record: %m");
7375 r = halt_now(arg_action);
7376 log_error_errno(r, "Failed to reboot: %m");
7381 static int runlevel_main(void) {
7382 int r, runlevel, previous;
7384 r = utmp_get_runlevel(&runlevel, &previous);
7391 previous <= 0 ? 'N' : previous,
7392 runlevel <= 0 ? 'N' : runlevel);
7397 int main(int argc, char*argv[]) {
7398 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7401 setlocale(LC_ALL, "");
7402 log_parse_environment();
7405 /* Explicitly not on_tty() to avoid setting cached value.
7406 * This becomes relevant for piping output which might be
7408 original_stdout_is_tty = isatty(STDOUT_FILENO);
7410 r = parse_argv(argc, argv);
7414 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7415 * let's shortcut this */
7416 if (arg_action == ACTION_RUNLEVEL) {
7417 r = runlevel_main();
7421 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7422 log_info("Running in chroot, ignoring request.");
7427 /* Increase max number of open files to 16K if we can, we
7428 * might needs this when browsing journal files, which might
7429 * be split up into many files. */
7430 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7433 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7435 /* systemctl_main() will print an error message for the bus
7436 * connection, but only if it needs to */
7438 switch (arg_action) {
7440 case ACTION_SYSTEMCTL:
7441 r = systemctl_main(bus, argc, argv, r);
7445 case ACTION_POWEROFF:
7451 case ACTION_RUNLEVEL2:
7452 case ACTION_RUNLEVEL3:
7453 case ACTION_RUNLEVEL4:
7454 case ACTION_RUNLEVEL5:
7456 case ACTION_EMERGENCY:
7457 case ACTION_DEFAULT:
7458 r = start_with_fallback(bus);
7463 r = reload_with_fallback(bus);
7466 case ACTION_CANCEL_SHUTDOWN: {
7467 _cleanup_free_ char *m = NULL;
7470 m = strv_join(arg_wall, " ");
7477 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7479 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7483 case ACTION_RUNLEVEL:
7484 case _ACTION_INVALID:
7486 assert_not_reached("Unknown action");
7491 ask_password_agent_close();
7492 polkit_agent_close();
7494 strv_free(arg_types);
7495 strv_free(arg_states);
7496 strv_free(arg_properties);
7498 return r < 0 ? EXIT_FAILURE : r;