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") && !arg_plain) {
438 on_loaded = ansi_highlight_red();
439 on_circle = ansi_highlight_yellow();
440 off_loaded = off_circle = ansi_highlight_off();
442 } else if (streq(u->active_state, "failed") && !arg_plain) {
443 on_circle = on_active = ansi_highlight_red();
444 off_circle = off_active = ansi_highlight_off();
449 j = strjoin(u->machine, ":", u->id, NULL);
458 e = ellipsize(id, id_len, 33);
466 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
468 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
469 on_active, id_len, id, off_active,
470 on_loaded, load_len, u->load_state, off_loaded,
471 on_active, active_len, u->active_state,
472 sub_len, u->sub_state, off_active,
473 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
476 printf("%.*s\n", desc_len, u->description);
478 printf("%s\n", u->description);
481 if (!arg_no_legend) {
482 const char *on, *off;
486 "LOAD = Reflects whether the unit definition was properly loaded.\n"
487 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
488 "SUB = The low-level unit activation state, values depend on unit type.");
489 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
490 on = ansi_highlight();
491 off = ansi_highlight_off();
493 on = ansi_highlight_red();
494 off = ansi_highlight_off();
498 printf("%s%u loaded units listed.%s\n"
499 "To show all installed unit files use 'systemctl list-unit-files'.\n",
502 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
503 "To show all installed unit files use 'systemctl list-unit-files'.\n",
510 static int get_unit_list(
514 UnitInfo **unit_infos,
516 sd_bus_message **_reply) {
518 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
519 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
520 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
529 r = sd_bus_message_new_method_call(
532 "org.freedesktop.systemd1",
533 "/org/freedesktop/systemd1",
534 "org.freedesktop.systemd1.Manager",
535 "ListUnitsFiltered");
538 return bus_log_create_error(r);
540 r = sd_bus_message_append_strv(m, arg_states);
542 return bus_log_create_error(r);
544 r = sd_bus_call(bus, m, 0, &error, &reply);
546 log_error("Failed to list units: %s", bus_error_message(&error, r));
550 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
552 return bus_log_parse_error(r);
554 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
557 if (!output_show_unit(&u, patterns))
560 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
563 (*unit_infos)[c++] = u;
566 return bus_log_parse_error(r);
568 r = sd_bus_message_exit_container(reply);
570 return bus_log_parse_error(r);
578 static void message_set_freep(Set **set) {
581 while ((m = set_steal_first(*set)))
582 sd_bus_message_unref(m);
587 static int get_unit_list_recursive(
590 UnitInfo **_unit_infos,
594 _cleanup_free_ UnitInfo *unit_infos = NULL;
595 _cleanup_(message_set_freep) Set *replies;
596 sd_bus_message *reply;
604 replies = set_new(NULL);
608 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
612 r = set_put(replies, reply);
614 sd_bus_message_unref(reply);
619 _cleanup_strv_free_ char **machines = NULL;
622 r = sd_get_machine_names(&machines);
626 STRV_FOREACH(i, machines) {
627 _cleanup_bus_close_unref_ sd_bus *container = NULL;
630 r = sd_bus_open_system_machine(&container, *i);
632 log_error_errno(r, "Failed to connect to container %s: %m", *i);
636 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
642 r = set_put(replies, reply);
644 sd_bus_message_unref(reply);
649 *_machines = machines;
654 *_unit_infos = unit_infos;
663 static int list_units(sd_bus *bus, char **args) {
664 _cleanup_free_ UnitInfo *unit_infos = NULL;
665 _cleanup_(message_set_freep) Set *replies = NULL;
666 _cleanup_strv_free_ char **machines = NULL;
669 pager_open_if_enabled();
671 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
675 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
676 return output_units_list(unit_infos, r);
679 static int get_triggered_units(
684 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
687 r = sd_bus_get_property_strv(
689 "org.freedesktop.systemd1",
691 "org.freedesktop.systemd1.Unit",
697 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
702 static int get_listening(
704 const char* unit_path,
707 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
708 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
709 const char *type, *path;
712 r = sd_bus_get_property(
714 "org.freedesktop.systemd1",
716 "org.freedesktop.systemd1.Socket",
722 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
726 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
728 return bus_log_parse_error(r);
730 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
732 r = strv_extend(listening, type);
736 r = strv_extend(listening, path);
743 return bus_log_parse_error(r);
745 r = sd_bus_message_exit_container(reply);
747 return bus_log_parse_error(r);
759 /* Note: triggered is a list here, although it almost certainly
760 * will always be one unit. Nevertheless, dbus API allows for multiple
761 * values, so let's follow that. */
764 /* The strv above is shared. free is set only in the first one. */
768 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
774 if (!a->machine && b->machine)
776 if (a->machine && !b->machine)
778 if (a->machine && b->machine) {
779 o = strcasecmp(a->machine, b->machine);
784 o = strcmp(a->path, b->path);
786 o = strcmp(a->type, b->type);
791 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
792 struct socket_info *s;
793 unsigned pathlen = strlen("LISTEN"),
794 typelen = strlen("TYPE") * arg_show_types,
795 socklen = strlen("UNIT"),
796 servlen = strlen("ACTIVATES");
797 const char *on, *off;
799 for (s = socket_infos; s < socket_infos + cs; s++) {
803 socklen = MAX(socklen, strlen(s->id));
805 typelen = MAX(typelen, strlen(s->type));
806 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
808 STRV_FOREACH(a, s->triggered)
809 tmp += strlen(*a) + 2*(a != s->triggered);
810 servlen = MAX(servlen, tmp);
815 printf("%-*s %-*.*s%-*s %s\n",
817 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
821 for (s = socket_infos; s < socket_infos + cs; s++) {
822 _cleanup_free_ char *j = NULL;
827 j = strjoin(s->machine, ":", s->path, NULL);
835 printf("%-*s %-*s %-*s",
836 pathlen, path, typelen, s->type, socklen, s->id);
839 pathlen, path, socklen, s->id);
840 STRV_FOREACH(a, s->triggered)
842 a == s->triggered ? "" : ",", *a);
846 on = ansi_highlight();
847 off = ansi_highlight_off();
851 on = ansi_highlight_red();
852 off = ansi_highlight_off();
855 if (!arg_no_legend) {
856 printf("%s%u sockets listed.%s\n", on, cs, off);
858 printf("Pass --all to see loaded but inactive sockets, too.\n");
864 static int list_sockets(sd_bus *bus, char **args) {
865 _cleanup_(message_set_freep) Set *replies = NULL;
866 _cleanup_strv_free_ char **machines = NULL;
867 _cleanup_free_ UnitInfo *unit_infos = NULL;
868 _cleanup_free_ struct socket_info *socket_infos = NULL;
870 struct socket_info *s;
875 pager_open_if_enabled();
877 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
881 for (u = unit_infos; u < unit_infos + n; u++) {
882 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
885 if (!endswith(u->id, ".socket"))
888 r = get_triggered_units(bus, u->unit_path, &triggered);
892 c = get_listening(bus, u->unit_path, &listening);
898 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
903 for (i = 0; i < c; i++)
904 socket_infos[cs + i] = (struct socket_info) {
905 .machine = u->machine,
907 .type = listening[i*2],
908 .path = listening[i*2 + 1],
909 .triggered = triggered,
910 .own_triggered = i==0,
913 /* from this point on we will cleanup those socket_infos */
916 listening = triggered = NULL; /* avoid cleanup */
919 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
920 (__compar_fn_t) socket_info_compare);
922 output_sockets_list(socket_infos, cs);
925 assert(cs == 0 || socket_infos);
926 for (s = socket_infos; s < socket_infos + cs; s++) {
929 if (s->own_triggered)
930 strv_free(s->triggered);
936 static int get_next_elapse(
939 dual_timestamp *next) {
941 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
949 r = sd_bus_get_property_trivial(
951 "org.freedesktop.systemd1",
953 "org.freedesktop.systemd1.Timer",
954 "NextElapseUSecMonotonic",
959 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
963 r = sd_bus_get_property_trivial(
965 "org.freedesktop.systemd1",
967 "org.freedesktop.systemd1.Timer",
968 "NextElapseUSecRealtime",
973 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
981 static int get_last_trigger(
986 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
993 r = sd_bus_get_property_trivial(
995 "org.freedesktop.systemd1",
997 "org.freedesktop.systemd1.Timer",
1003 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1011 const char* machine;
1014 usec_t last_trigger;
1018 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1024 if (!a->machine && b->machine)
1026 if (a->machine && !b->machine)
1028 if (a->machine && b->machine) {
1029 o = strcasecmp(a->machine, b->machine);
1034 if (a->next_elapse < b->next_elapse)
1036 if (a->next_elapse > b->next_elapse)
1039 return strcmp(a->id, b->id);
1042 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1043 struct timer_info *t;
1045 nextlen = strlen("NEXT"),
1046 leftlen = strlen("LEFT"),
1047 lastlen = strlen("LAST"),
1048 passedlen = strlen("PASSED"),
1049 unitlen = strlen("UNIT"),
1050 activatelen = strlen("ACTIVATES");
1052 const char *on, *off;
1054 assert(timer_infos || n == 0);
1056 for (t = timer_infos; t < timer_infos + n; t++) {
1060 if (t->next_elapse > 0) {
1061 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1063 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1064 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1066 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1067 leftlen = MAX(leftlen, strlen(trel));
1070 if (t->last_trigger > 0) {
1071 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1073 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1074 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1076 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1077 passedlen = MAX(passedlen, strlen(trel));
1080 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1082 STRV_FOREACH(a, t->triggered)
1083 ul += strlen(*a) + 2*(a != t->triggered);
1085 activatelen = MAX(activatelen, ul);
1090 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1094 passedlen, "PASSED",
1098 for (t = timer_infos; t < timer_infos + n; t++) {
1099 _cleanup_free_ char *j = NULL;
1101 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1102 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1105 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1106 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1108 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1109 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1112 j = strjoin(t->machine, ":", t->id, NULL);
1119 printf("%-*s %-*s %-*s %-*s %-*s",
1120 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1122 STRV_FOREACH(a, t->triggered)
1124 a == t->triggered ? "" : ",", *a);
1128 on = ansi_highlight();
1129 off = ansi_highlight_off();
1133 on = ansi_highlight_red();
1134 off = ansi_highlight_off();
1137 if (!arg_no_legend) {
1138 printf("%s%u timers listed.%s\n", on, n, off);
1140 printf("Pass --all to see loaded but inactive timers, too.\n");
1146 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1152 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1155 if (next->monotonic > nw->monotonic)
1156 converted = nw->realtime + (next->monotonic - nw->monotonic);
1158 converted = nw->realtime - (nw->monotonic - next->monotonic);
1160 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1161 next_elapse = MIN(converted, next->realtime);
1163 next_elapse = converted;
1166 next_elapse = next->realtime;
1171 static int list_timers(sd_bus *bus, char **args) {
1172 _cleanup_(message_set_freep) Set *replies = NULL;
1173 _cleanup_strv_free_ char **machines = NULL;
1174 _cleanup_free_ struct timer_info *timer_infos = NULL;
1175 _cleanup_free_ UnitInfo *unit_infos = NULL;
1176 struct timer_info *t;
1183 pager_open_if_enabled();
1185 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1189 dual_timestamp_get(&nw);
1191 for (u = unit_infos; u < unit_infos + n; u++) {
1192 _cleanup_strv_free_ char **triggered = NULL;
1193 dual_timestamp next = {};
1196 if (!endswith(u->id, ".timer"))
1199 r = get_triggered_units(bus, u->unit_path, &triggered);
1203 r = get_next_elapse(bus, u->unit_path, &next);
1207 get_last_trigger(bus, u->unit_path, &last);
1209 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1214 m = calc_next_elapse(&nw, &next);
1216 timer_infos[c++] = (struct timer_info) {
1217 .machine = u->machine,
1220 .last_trigger = last,
1221 .triggered = triggered,
1224 triggered = NULL; /* avoid cleanup */
1227 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1228 (__compar_fn_t) timer_info_compare);
1230 output_timers_list(timer_infos, c);
1233 for (t = timer_infos; t < timer_infos + c; t++)
1234 strv_free(t->triggered);
1239 static int compare_unit_file_list(const void *a, const void *b) {
1240 const char *d1, *d2;
1241 const UnitFileList *u = a, *v = b;
1243 d1 = strrchr(u->path, '.');
1244 d2 = strrchr(v->path, '.');
1249 r = strcasecmp(d1, d2);
1254 return strcasecmp(basename(u->path), basename(v->path));
1257 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1258 if (!strv_isempty(patterns)) {
1261 STRV_FOREACH(pattern, patterns)
1262 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1268 if (!strv_isempty(arg_types)) {
1271 dot = strrchr(u->path, '.');
1275 if (!strv_find(arg_types, dot+1))
1279 if (!strv_isempty(arg_states)) {
1280 if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
1287 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1288 unsigned max_id_len, id_cols, state_cols;
1289 const UnitFileList *u;
1291 max_id_len = strlen("UNIT FILE");
1292 state_cols = strlen("STATE");
1294 for (u = units; u < units + c; u++) {
1295 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1296 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1300 unsigned basic_cols;
1302 id_cols = MIN(max_id_len, 25u);
1303 basic_cols = 1 + id_cols + state_cols;
1304 if (basic_cols < (unsigned) columns())
1305 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1307 id_cols = max_id_len;
1310 printf("%-*s %-*s\n",
1311 id_cols, "UNIT FILE",
1312 state_cols, "STATE");
1314 for (u = units; u < units + c; u++) {
1315 _cleanup_free_ char *e = NULL;
1316 const char *on, *off;
1319 if (u->state == UNIT_FILE_MASKED ||
1320 u->state == UNIT_FILE_MASKED_RUNTIME ||
1321 u->state == UNIT_FILE_DISABLED ||
1322 u->state == UNIT_FILE_INVALID) {
1323 on = ansi_highlight_red();
1324 off = ansi_highlight_off();
1325 } else if (u->state == UNIT_FILE_ENABLED) {
1326 on = ansi_highlight_green();
1327 off = ansi_highlight_off();
1331 id = basename(u->path);
1333 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1335 printf("%-*s %s%-*s%s\n",
1336 id_cols, e ? e : id,
1337 on, state_cols, unit_file_state_to_string(u->state), off);
1341 printf("\n%u unit files listed.\n", c);
1344 static int list_unit_files(sd_bus *bus, char **args) {
1345 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1346 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1347 _cleanup_free_ UnitFileList *units = NULL;
1355 pager_open_if_enabled();
1363 h = hashmap_new(&string_hash_ops);
1367 r = unit_file_get_list(arg_scope, arg_root, h);
1369 unit_file_list_free(h);
1370 log_error_errno(r, "Failed to get unit file list: %m");
1374 n_units = hashmap_size(h);
1376 units = new(UnitFileList, n_units);
1377 if (!units && n_units > 0) {
1378 unit_file_list_free(h);
1382 HASHMAP_FOREACH(u, h, i) {
1383 if (!output_show_unit_file(u, strv_skip_first(args)))
1390 assert(c <= n_units);
1393 r = sd_bus_call_method(
1395 "org.freedesktop.systemd1",
1396 "/org/freedesktop/systemd1",
1397 "org.freedesktop.systemd1.Manager",
1403 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1407 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1409 return bus_log_parse_error(r);
1411 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1413 if (!GREEDY_REALLOC(units, size, c + 1))
1416 units[c] = (struct UnitFileList) {
1418 unit_file_state_from_string(state)
1421 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1426 return bus_log_parse_error(r);
1428 r = sd_bus_message_exit_container(reply);
1430 return bus_log_parse_error(r);
1433 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1434 output_unit_file_list(units, c);
1437 for (unit = units; unit < units + c; unit++)
1444 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1445 _cleanup_free_ char *n = NULL;
1446 size_t max_len = MAX(columns(),20u);
1452 for (i = level - 1; i >= 0; i--) {
1454 if (len > max_len - 3 && !arg_full) {
1455 printf("%s...\n",max_len % 2 ? "" : " ");
1458 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1462 if (len > max_len - 3 && !arg_full) {
1463 printf("%s...\n",max_len % 2 ? "" : " ");
1467 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1471 printf("%s\n", name);
1475 n = ellipsize(name, max_len-len, 100);
1483 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1485 static const char *dependencies[_DEPENDENCY_MAX] = {
1486 [DEPENDENCY_FORWARD] = "Requires\0"
1487 "RequiresOverridable\0"
1489 "RequisiteOverridable\0"
1492 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1493 "RequiredByOverridable\0"
1497 [DEPENDENCY_AFTER] = "After\0",
1498 [DEPENDENCY_BEFORE] = "Before\0",
1501 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1502 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1503 _cleanup_strv_free_ char **ret = NULL;
1504 _cleanup_free_ char *path = NULL;
1510 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1512 path = unit_dbus_path_from_name(name);
1516 r = sd_bus_call_method(
1518 "org.freedesktop.systemd1",
1520 "org.freedesktop.DBus.Properties",
1524 "s", "org.freedesktop.systemd1.Unit");
1526 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1530 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1532 return bus_log_parse_error(r);
1534 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1537 r = sd_bus_message_read(reply, "s", &prop);
1539 return bus_log_parse_error(r);
1541 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1542 r = sd_bus_message_skip(reply, "v");
1544 return bus_log_parse_error(r);
1547 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1549 return bus_log_parse_error(r);
1551 r = bus_message_read_strv_extend(reply, &ret);
1553 return bus_log_parse_error(r);
1555 r = sd_bus_message_exit_container(reply);
1557 return bus_log_parse_error(r);
1560 r = sd_bus_message_exit_container(reply);
1562 return bus_log_parse_error(r);
1566 return bus_log_parse_error(r);
1568 r = sd_bus_message_exit_container(reply);
1570 return bus_log_parse_error(r);
1578 static int list_dependencies_compare(const void *_a, const void *_b) {
1579 const char **a = (const char**) _a, **b = (const char**) _b;
1581 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1583 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1586 return strcasecmp(*a, *b);
1589 static int list_dependencies_one(
1594 unsigned int branches) {
1596 _cleanup_strv_free_ char **deps = NULL;
1604 r = strv_extend(units, name);
1608 r = list_dependencies_get_dependencies(bus, name, &deps);
1612 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1614 STRV_FOREACH(c, deps) {
1615 if (strv_contains(*units, *c)) {
1617 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1630 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1631 on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
1632 printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1635 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1639 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1640 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1647 strv_remove(*units, name);
1652 static int list_dependencies(sd_bus *bus, char **args) {
1653 _cleanup_strv_free_ char **units = NULL;
1654 _cleanup_free_ char *unit = NULL;
1660 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1665 u = SPECIAL_DEFAULT_TARGET;
1667 pager_open_if_enabled();
1671 return list_dependencies_one(bus, u, 0, &units, 0);
1674 struct machine_info {
1678 char *control_group;
1679 uint32_t n_failed_units;
1684 static const struct bus_properties_map machine_info_property_map[] = {
1685 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1686 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1687 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1688 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1689 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1693 static void free_machines_list(struct machine_info *machine_infos, int n) {
1699 for (i = 0; i < n; i++) {
1700 free(machine_infos[i].name);
1701 free(machine_infos[i].state);
1702 free(machine_infos[i].control_group);
1705 free(machine_infos);
1708 static int compare_machine_info(const void *a, const void *b) {
1709 const struct machine_info *u = a, *v = b;
1711 if (u->is_host != v->is_host)
1712 return u->is_host > v->is_host ? -1 : 1;
1714 return strcasecmp(u->name, v->name);
1717 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1718 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1724 r = sd_bus_open_system_machine(&container, mi->name);
1731 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1738 static bool output_show_machine(const char *name, char **patterns) {
1743 if (strv_isempty(patterns))
1746 STRV_FOREACH(i, patterns)
1747 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1753 static int get_machine_list(
1755 struct machine_info **_machine_infos,
1758 struct machine_info *machine_infos = NULL;
1759 _cleanup_strv_free_ char **m = NULL;
1760 _cleanup_free_ char *hn = NULL;
1765 hn = gethostname_malloc();
1769 if (output_show_machine(hn, patterns)) {
1770 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1773 machine_infos[c].is_host = true;
1774 machine_infos[c].name = hn;
1777 get_machine_properties(bus, &machine_infos[c]);
1781 sd_get_machine_names(&m);
1782 STRV_FOREACH(i, m) {
1783 _cleanup_free_ char *class = NULL;
1785 if (!output_show_machine(*i, patterns))
1788 sd_machine_get_class(*i, &class);
1789 if (!streq_ptr(class, "container"))
1792 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1793 free_machines_list(machine_infos, c);
1797 machine_infos[c].is_host = false;
1798 machine_infos[c].name = strdup(*i);
1799 if (!machine_infos[c].name) {
1800 free_machines_list(machine_infos, c);
1804 get_machine_properties(NULL, &machine_infos[c]);
1808 *_machine_infos = machine_infos;
1812 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1813 struct machine_info *m;
1816 namelen = sizeof("NAME") - 1,
1817 statelen = sizeof("STATE") - 1,
1818 failedlen = sizeof("FAILED") - 1,
1819 jobslen = sizeof("JOBS") - 1;
1821 assert(machine_infos || n == 0);
1823 for (m = machine_infos; m < machine_infos + n; m++) {
1824 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1825 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1826 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1827 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1829 if (!arg_plain && !streq_ptr(m->state, "running"))
1833 if (!arg_no_legend) {
1837 printf("%-*s %-*s %-*s %-*s\n",
1840 failedlen, "FAILED",
1844 for (m = machine_infos; m < machine_infos + n; m++) {
1845 const char *on_state = "", *off_state = "";
1846 const char *on_failed = "", *off_failed = "";
1847 bool circle = false;
1849 if (streq_ptr(m->state, "degraded")) {
1850 on_state = ansi_highlight_red();
1851 off_state = ansi_highlight_off();
1853 } else if (!streq_ptr(m->state, "running")) {
1854 on_state = ansi_highlight_yellow();
1855 off_state = ansi_highlight_off();
1859 if (m->n_failed_units > 0) {
1860 on_failed = ansi_highlight_red();
1861 off_failed = ansi_highlight_off();
1863 on_failed = off_failed = "";
1866 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1869 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1870 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1871 on_state, statelen, strna(m->state), off_state,
1872 on_failed, failedlen, m->n_failed_units, off_failed,
1873 jobslen, m->n_jobs);
1875 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1876 namelen, strna(m->name),
1877 on_state, statelen, strna(m->state), off_state,
1878 on_failed, failedlen, m->n_failed_units, off_failed,
1879 jobslen, m->n_jobs);
1883 printf("\n%u machines listed.\n", n);
1886 static int list_machines(sd_bus *bus, char **args) {
1887 struct machine_info *machine_infos = NULL;
1892 if (geteuid() != 0) {
1893 log_error("Must be root.");
1897 pager_open_if_enabled();
1899 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1903 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1904 output_machines_list(machine_infos, r);
1905 free_machines_list(machine_infos, r);
1910 static int get_default(sd_bus *bus, char **args) {
1911 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1912 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1913 _cleanup_free_ char *_path = NULL;
1917 if (!bus || avoid_bus()) {
1918 r = unit_file_get_default(arg_scope, arg_root, &_path);
1920 return log_error_errno(r, "Failed to get default target: %m");
1924 r = sd_bus_call_method(
1926 "org.freedesktop.systemd1",
1927 "/org/freedesktop/systemd1",
1928 "org.freedesktop.systemd1.Manager",
1934 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1938 r = sd_bus_message_read(reply, "s", &path);
1940 return bus_log_parse_error(r);
1944 printf("%s\n", path);
1949 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1952 assert(changes || n_changes == 0);
1954 for (i = 0; i < n_changes; i++) {
1955 if (changes[i].type == UNIT_FILE_SYMLINK)
1956 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1958 log_info("Removed symlink %s.", changes[i].path);
1962 static int set_default(sd_bus *bus, char **args) {
1963 _cleanup_free_ char *unit = NULL;
1964 UnitFileChange *changes = NULL;
1965 unsigned n_changes = 0;
1968 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1972 if (!bus || avoid_bus()) {
1973 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1975 return log_error_errno(r, "Failed to set default target: %m");
1978 dump_unit_file_changes(changes, n_changes);
1982 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1983 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1985 r = sd_bus_message_new_method_call(
1988 "org.freedesktop.systemd1",
1989 "/org/freedesktop/systemd1",
1990 "org.freedesktop.systemd1.Manager",
1991 "SetDefaultTarget");
1993 return bus_log_create_error(r);
1995 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
1997 return bus_log_create_error(r);
1999 r = sd_bus_message_append(m, "sb", unit, 1);
2001 return bus_log_create_error(r);
2003 r = sd_bus_call(bus, m, 0, &error, &reply);
2005 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2009 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
2013 /* Try to reload if enabled */
2015 r = daemon_reload(bus, args);
2020 unit_file_changes_free(changes, n_changes);
2027 const char *name, *type, *state;
2030 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2031 unsigned id_len, unit_len, type_len, state_len;
2032 const struct job_info *j;
2033 const char *on, *off;
2034 bool shorten = false;
2036 assert(n == 0 || jobs);
2039 if (!arg_no_legend) {
2040 on = ansi_highlight_green();
2041 off = ansi_highlight_off();
2043 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2048 pager_open_if_enabled();
2050 id_len = strlen("JOB");
2051 unit_len = strlen("UNIT");
2052 type_len = strlen("TYPE");
2053 state_len = strlen("STATE");
2055 for (j = jobs; j < jobs + n; j++) {
2056 uint32_t id = j->id;
2057 assert(j->name && j->type && j->state);
2059 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2060 unit_len = MAX(unit_len, strlen(j->name));
2061 type_len = MAX(type_len, strlen(j->type));
2062 state_len = MAX(state_len, strlen(j->state));
2065 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2066 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2071 printf("%*s %-*s %-*s %-*s\n",
2075 state_len, "STATE");
2077 for (j = jobs; j < jobs + n; j++) {
2078 _cleanup_free_ char *e = NULL;
2080 if (streq(j->state, "running")) {
2081 on = ansi_highlight();
2082 off = ansi_highlight_off();
2086 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2087 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2089 on, unit_len, e ? e : j->name, off,
2091 on, state_len, j->state, off);
2094 if (!arg_no_legend) {
2095 on = ansi_highlight();
2096 off = ansi_highlight_off();
2098 printf("\n%s%u jobs listed%s.\n", on, n, off);
2102 static bool output_show_job(struct job_info *job, char **patterns) {
2107 if (strv_isempty(patterns))
2110 STRV_FOREACH(pattern, patterns)
2111 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2116 static int list_jobs(sd_bus *bus, char **args) {
2117 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2118 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2119 const char *name, *type, *state, *job_path, *unit_path;
2120 _cleanup_free_ struct job_info *jobs = NULL;
2125 bool skipped = false;
2127 r = sd_bus_call_method(
2129 "org.freedesktop.systemd1",
2130 "/org/freedesktop/systemd1",
2131 "org.freedesktop.systemd1.Manager",
2137 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2141 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2143 return bus_log_parse_error(r);
2145 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2146 struct job_info job = { id, name, type, state };
2148 if (!output_show_job(&job, strv_skip_first(args))) {
2153 if (!GREEDY_REALLOC(jobs, size, c + 1))
2159 return bus_log_parse_error(r);
2161 r = sd_bus_message_exit_container(reply);
2163 return bus_log_parse_error(r);
2165 output_jobs_list(jobs, c, skipped);
2169 static int cancel_job(sd_bus *bus, char **args) {
2170 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2176 if (strv_length(args) <= 1)
2177 return daemon_reload(bus, args);
2179 STRV_FOREACH(name, args+1) {
2180 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2184 q = safe_atou32(*name, &id);
2186 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2188 q = sd_bus_message_new_method_call(
2191 "org.freedesktop.systemd1",
2192 "/org/freedesktop/systemd1",
2193 "org.freedesktop.systemd1.Manager",
2196 return bus_log_create_error(q);
2198 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2200 return bus_log_create_error(1);
2202 q = sd_bus_message_append(m, "u", id);
2204 return bus_log_create_error(q);
2206 q = sd_bus_call(bus, m, 0, &error, NULL);
2208 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2217 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2218 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2222 /* We ignore all errors here, since this is used to show a
2225 /* We don't use unit_dbus_path_from_name() directly since we
2226 * don't want to load the unit if it isn't loaded. */
2228 r = sd_bus_call_method(
2230 "org.freedesktop.systemd1",
2231 "/org/freedesktop/systemd1",
2232 "org.freedesktop.systemd1.Manager",
2240 r = sd_bus_message_read(reply, "o", &path);
2244 r = sd_bus_get_property_trivial(
2246 "org.freedesktop.systemd1",
2248 "org.freedesktop.systemd1.Unit",
2258 static void warn_unit_file_changed(const char *name) {
2259 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2260 ansi_highlight_red(),
2261 ansi_highlight_off(),
2263 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2266 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2273 STRV_FOREACH(p, lp->unit_path) {
2274 _cleanup_free_ char *path;
2276 path = path_join(arg_root, *p, unit_name);
2280 if (access(path, F_OK) == 0) {
2290 static int unit_find_paths(sd_bus *bus,
2291 const char *unit_name,
2292 bool avoid_bus_cache,
2294 char **fragment_path,
2295 char ***dropin_paths) {
2297 _cleanup_free_ char *path = NULL;
2298 _cleanup_strv_free_ char **dropins = NULL;
2302 * Finds where the unit is defined on disk. Returns 0 if the unit
2303 * is not found. Returns 1 if it is found, and sets
2304 * - the path to the unit in *path, if it exists on disk,
2305 * - and a strv of existing drop-ins in *dropins,
2306 * if the arg is not NULL and any dropins were found.
2310 assert(fragment_path);
2313 if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2314 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2315 _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
2316 _cleanup_free_ char *unit = NULL;
2317 char *unit_load_error_name, *unit_load_error_message;
2319 unit = unit_dbus_path_from_name(unit_name);
2323 if (need_daemon_reload(bus, unit_name) > 0)
2324 warn_unit_file_changed(unit_name);
2326 r = sd_bus_get_property(
2328 "org.freedesktop.systemd1",
2330 "org.freedesktop.systemd1.Unit",
2336 return log_error_errno(r, "Failed to get LoadError: %s", bus_error_message(&error, r));
2338 r = sd_bus_message_read(
2341 &unit_load_error_name,
2342 &unit_load_error_message);
2344 return bus_log_parse_error(r);
2346 if (!isempty(unit_load_error_name)) {
2347 log_error("Unit %s is not loaded: %s", unit_name, unit_load_error_message);
2351 r = sd_bus_get_property_string(
2353 "org.freedesktop.systemd1",
2355 "org.freedesktop.systemd1.Unit",
2360 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2363 r = sd_bus_get_property_strv(
2365 "org.freedesktop.systemd1",
2367 "org.freedesktop.systemd1.Unit",
2372 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2375 _cleanup_set_free_ Set *names;
2377 names = set_new(NULL);
2381 r = set_put(names, unit_name);
2385 r = unit_file_find_path(lp, unit_name, &path);
2390 _cleanup_free_ char *template;
2392 template = unit_name_template(unit_name);
2396 if (!streq(template, unit_name)) {
2397 r = unit_file_find_path(lp, template, &path);
2404 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
2412 if (!isempty(path)) {
2413 *fragment_path = path;
2418 if (dropin_paths && !strv_isempty(dropins)) {
2419 *dropin_paths = dropins;
2425 log_error("No files found for %s.", unit_name);
2430 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2431 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2432 _cleanup_free_ char *n = NULL, *state = NULL;
2438 n = unit_name_mangle(name, MANGLE_NOGLOB);
2442 /* We don't use unit_dbus_path_from_name() directly since we
2443 * don't want to load the unit if it isn't loaded. */
2445 r = sd_bus_call_method(
2447 "org.freedesktop.systemd1",
2448 "/org/freedesktop/systemd1",
2449 "org.freedesktop.systemd1.Manager",
2460 r = sd_bus_message_read(reply, "o", &path);
2462 return bus_log_parse_error(r);
2464 r = sd_bus_get_property_string(
2466 "org.freedesktop.systemd1",
2468 "org.freedesktop.systemd1.Unit",
2481 return nulstr_contains(good_states, state);
2484 static int check_triggering_units(
2488 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2489 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2490 _cleanup_strv_free_ char **triggered_by = NULL;
2491 bool print_warning_label = true;
2495 n = unit_name_mangle(name, MANGLE_NOGLOB);
2499 path = unit_dbus_path_from_name(n);
2503 r = sd_bus_get_property_string(
2505 "org.freedesktop.systemd1",
2507 "org.freedesktop.systemd1.Unit",
2512 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2516 if (streq(state, "masked"))
2519 r = sd_bus_get_property_strv(
2521 "org.freedesktop.systemd1",
2523 "org.freedesktop.systemd1.Unit",
2528 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2532 STRV_FOREACH(i, triggered_by) {
2533 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2535 return log_error_errno(r, "Failed to check unit: %m");
2540 if (print_warning_label) {
2541 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2542 print_warning_label = false;
2545 log_warning(" %s", *i);
2551 static const struct {
2554 } unit_actions[] = {
2555 { "start", "StartUnit" },
2556 { "stop", "StopUnit" },
2557 { "condstop", "StopUnit" },
2558 { "reload", "ReloadUnit" },
2559 { "restart", "RestartUnit" },
2560 { "try-restart", "TryRestartUnit" },
2561 { "condrestart", "TryRestartUnit" },
2562 { "reload-or-restart", "ReloadOrRestartUnit" },
2563 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2564 { "condreload", "ReloadOrTryRestartUnit" },
2565 { "force-reload", "ReloadOrTryRestartUnit" }
2568 static const char *verb_to_method(const char *verb) {
2571 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2572 if (streq_ptr(unit_actions[i].verb, verb))
2573 return unit_actions[i].method;
2578 static const char *method_to_verb(const char *method) {
2581 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2582 if (streq_ptr(unit_actions[i].method, method))
2583 return unit_actions[i].verb;
2588 static int start_unit_one(
2593 sd_bus_error *error,
2594 BusWaitForJobs *w) {
2596 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2605 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2607 r = sd_bus_message_new_method_call(
2610 "org.freedesktop.systemd1",
2611 "/org/freedesktop/systemd1",
2612 "org.freedesktop.systemd1.Manager",
2615 return bus_log_create_error(r);
2617 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2619 return bus_log_create_error(r);
2621 r = sd_bus_message_append(m, "ss", name, mode);
2623 return bus_log_create_error(r);
2625 r = sd_bus_call(bus, m, 0, error, &reply);
2629 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2630 /* There's always a fallback possible for
2631 * legacy actions. */
2632 return -EADDRNOTAVAIL;
2634 verb = method_to_verb(method);
2636 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2640 r = sd_bus_message_read(reply, "o", &path);
2642 return bus_log_parse_error(r);
2644 if (need_daemon_reload(bus, name) > 0)
2645 warn_unit_file_changed(name);
2648 log_debug("Adding %s to the set", path);
2649 r = bus_wait_for_jobs_add(w, path);
2657 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2659 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2663 STRV_FOREACH(name, names) {
2667 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2669 t = unit_name_mangle(*name, MANGLE_GLOB);
2673 if (string_is_glob(t))
2674 r = strv_consume(&globs, t);
2676 r = strv_consume(&mangled, t);
2681 /* Query the manager only if any of the names are a glob, since
2682 * this is fairly expensive */
2683 if (!strv_isempty(globs)) {
2684 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2685 _cleanup_free_ UnitInfo *unit_infos = NULL;
2688 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2690 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2694 for (i = 0; i < r; i++)
2695 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2700 mangled = NULL; /* do not free */
2705 static const struct {
2709 } action_table[_ACTION_MAX] = {
2710 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2711 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2712 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2713 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2714 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2715 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2716 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2717 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2718 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2719 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2720 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2721 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2722 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2723 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2724 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2727 static enum action verb_to_action(const char *verb) {
2730 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2731 if (streq_ptr(action_table[i].verb, verb))
2734 return _ACTION_INVALID;
2737 static int start_unit(sd_bus *bus, char **args) {
2738 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2739 const char *method, *mode, *one_name, *suffix = NULL;
2740 _cleanup_strv_free_ char **names = NULL;
2746 ask_password_agent_open_if_enabled();
2747 polkit_agent_open_if_enabled();
2749 if (arg_action == ACTION_SYSTEMCTL) {
2751 method = verb_to_method(args[0]);
2752 action = verb_to_action(args[0]);
2754 if (streq(args[0], "isolate")) {
2758 mode = action_table[action].mode ?: arg_job_mode;
2760 one_name = action_table[action].target;
2762 assert(arg_action < ELEMENTSOF(action_table));
2763 assert(action_table[arg_action].target);
2765 method = "StartUnit";
2767 mode = action_table[arg_action].mode;
2768 one_name = action_table[arg_action].target;
2772 names = strv_new(one_name, NULL);
2774 r = expand_names(bus, args + 1, suffix, &names);
2776 log_error_errno(r, "Failed to expand names: %m");
2779 if (!arg_no_block) {
2780 r = bus_wait_for_jobs_new(bus, &w);
2782 return log_error_errno(r, "Could not watch jobs: %m");
2785 STRV_FOREACH(name, names) {
2786 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2789 q = start_unit_one(bus, method, *name, mode, &error, w);
2790 if (r >= 0 && q < 0)
2791 r = translate_bus_error_to_exit_status(q, &error);
2794 if (!arg_no_block) {
2797 q = bus_wait_for_jobs(w, arg_quiet);
2801 /* When stopping units, warn if they can still be triggered by
2802 * another active unit (socket, path, timer) */
2803 if (!arg_quiet && streq(method, "StopUnit"))
2804 STRV_FOREACH(name, names)
2805 check_triggering_units(bus, *name);
2811 /* Ask systemd-logind, which might grant access to unprivileged users
2812 * through PolicyKit */
2813 static int reboot_with_logind(sd_bus *bus, enum action a) {
2815 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2822 polkit_agent_open_if_enabled();
2830 case ACTION_POWEROFF:
2831 method = "PowerOff";
2834 case ACTION_SUSPEND:
2838 case ACTION_HIBERNATE:
2839 method = "Hibernate";
2842 case ACTION_HYBRID_SLEEP:
2843 method = "HybridSleep";
2850 r = sd_bus_call_method(
2852 "org.freedesktop.login1",
2853 "/org/freedesktop/login1",
2854 "org.freedesktop.login1.Manager",
2858 "b", arg_ask_password);
2860 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2868 static int check_inhibitors(sd_bus *bus, enum action a) {
2870 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2871 _cleanup_strv_free_ char **sessions = NULL;
2872 const char *what, *who, *why, *mode;
2881 if (arg_ignore_inhibitors || arg_force > 0)
2893 r = sd_bus_call_method(
2895 "org.freedesktop.login1",
2896 "/org/freedesktop/login1",
2897 "org.freedesktop.login1.Manager",
2903 /* If logind is not around, then there are no inhibitors... */
2906 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2908 return bus_log_parse_error(r);
2910 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2911 _cleanup_free_ char *comm = NULL, *user = NULL;
2912 _cleanup_strv_free_ char **sv = NULL;
2914 if (!streq(mode, "block"))
2917 sv = strv_split(what, ":");
2921 if (!strv_contains(sv,
2923 a == ACTION_POWEROFF ||
2924 a == ACTION_REBOOT ||
2925 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2928 get_process_comm(pid, &comm);
2929 user = uid_to_name(uid);
2931 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2932 who, pid, strna(comm), strna(user), why);
2937 return bus_log_parse_error(r);
2939 r = sd_bus_message_exit_container(reply);
2941 return bus_log_parse_error(r);
2943 /* Check for current sessions */
2944 sd_get_sessions(&sessions);
2945 STRV_FOREACH(s, sessions) {
2946 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2948 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2951 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2954 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2957 sd_session_get_tty(*s, &tty);
2958 sd_session_get_seat(*s, &seat);
2959 sd_session_get_service(*s, &service);
2960 user = uid_to_name(uid);
2962 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2969 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2970 action_table[a].verb);
2978 static int start_special(sd_bus *bus, char **args) {
2984 a = verb_to_action(args[0]);
2986 r = check_inhibitors(bus, a);
2990 if (arg_force >= 2 && geteuid() != 0) {
2991 log_error("Must be root.");
2995 if (a == ACTION_REBOOT && args[1]) {
2996 r = update_reboot_param_file(args[1]);
3001 if (arg_force >= 2 &&
3002 (a == ACTION_HALT ||
3003 a == ACTION_POWEROFF ||
3004 a == ACTION_REBOOT))
3007 if (arg_force >= 1 &&
3008 (a == ACTION_HALT ||
3009 a == ACTION_POWEROFF ||
3010 a == ACTION_REBOOT ||
3011 a == ACTION_KEXEC ||
3013 return daemon_reload(bus, args);
3015 /* first try logind, to allow authentication with polkit */
3016 if (geteuid() != 0 &&
3017 (a == ACTION_POWEROFF ||
3018 a == ACTION_REBOOT ||
3019 a == ACTION_SUSPEND ||
3020 a == ACTION_HIBERNATE ||
3021 a == ACTION_HYBRID_SLEEP)) {
3022 r = reboot_with_logind(bus, a);
3023 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
3027 r = start_unit(bus, args);
3028 if (r == EXIT_SUCCESS)
3034 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3035 _cleanup_strv_free_ char **names = NULL;
3042 r = expand_names(bus, args, NULL, &names);
3044 return log_error_errno(r, "Failed to expand names: %m");
3046 STRV_FOREACH(name, names) {
3049 state = check_one_unit(bus, *name, good_states, arg_quiet);
3059 static int check_unit_active(sd_bus *bus, char **args) {
3060 /* According to LSB: 3, "program is not running" */
3061 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3064 static int check_unit_failed(sd_bus *bus, char **args) {
3065 return check_unit_generic(bus, 1, "failed\0", args + 1);
3068 static int kill_unit(sd_bus *bus, char **args) {
3069 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3070 _cleanup_strv_free_ char **names = NULL;
3077 polkit_agent_open_if_enabled();
3080 arg_kill_who = "all";
3082 r = expand_names(bus, args + 1, NULL, &names);
3084 log_error_errno(r, "Failed to expand names: %m");
3086 STRV_FOREACH(name, names) {
3087 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3089 q = sd_bus_message_new_method_call(
3092 "org.freedesktop.systemd1",
3093 "/org/freedesktop/systemd1",
3094 "org.freedesktop.systemd1.Manager",
3097 return bus_log_create_error(q);
3099 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3101 return bus_log_create_error(q);
3103 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3105 return bus_log_create_error(q);
3107 q = sd_bus_call(bus, m, 0, &error, NULL);
3109 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3118 typedef struct ExecStatusInfo {
3126 usec_t start_timestamp;
3127 usec_t exit_timestamp;
3132 LIST_FIELDS(struct ExecStatusInfo, exec);
3135 static void exec_status_info_free(ExecStatusInfo *i) {
3144 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3145 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3148 int32_t code, status;
3154 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3156 return bus_log_parse_error(r);
3160 r = sd_bus_message_read(m, "s", &path);
3162 return bus_log_parse_error(r);
3164 i->path = strdup(path);
3168 r = sd_bus_message_read_strv(m, &i->argv);
3170 return bus_log_parse_error(r);
3172 r = sd_bus_message_read(m,
3175 &start_timestamp, &start_timestamp_monotonic,
3176 &exit_timestamp, &exit_timestamp_monotonic,
3180 return bus_log_parse_error(r);
3183 i->start_timestamp = (usec_t) start_timestamp;
3184 i->exit_timestamp = (usec_t) exit_timestamp;
3185 i->pid = (pid_t) pid;
3189 r = sd_bus_message_exit_container(m);
3191 return bus_log_parse_error(r);
3196 typedef struct UnitStatusInfo {
3198 const char *load_state;
3199 const char *active_state;
3200 const char *sub_state;
3201 const char *unit_file_state;
3202 const char *unit_file_preset;
3204 const char *description;
3205 const char *following;
3207 char **documentation;
3209 const char *fragment_path;
3210 const char *source_path;
3211 const char *control_group;
3213 char **dropin_paths;
3215 const char *load_error;
3218 usec_t inactive_exit_timestamp;
3219 usec_t inactive_exit_timestamp_monotonic;
3220 usec_t active_enter_timestamp;
3221 usec_t active_exit_timestamp;
3222 usec_t inactive_enter_timestamp;
3224 bool need_daemon_reload;
3229 const char *status_text;
3230 const char *pid_file;
3234 usec_t start_timestamp;
3235 usec_t exit_timestamp;
3237 int exit_code, exit_status;
3239 usec_t condition_timestamp;
3240 bool condition_result;
3241 bool failed_condition_trigger;
3242 bool failed_condition_negate;
3243 const char *failed_condition;
3244 const char *failed_condition_parameter;
3246 usec_t assert_timestamp;
3248 bool failed_assert_trigger;
3249 bool failed_assert_negate;
3250 const char *failed_assert;
3251 const char *failed_assert_parameter;
3254 unsigned n_accepted;
3255 unsigned n_connections;
3258 /* Pairs of type, path */
3262 const char *sysfs_path;
3264 /* Mount, Automount */
3271 uint64_t memory_current;
3272 uint64_t memory_limit;
3274 LIST_HEAD(ExecStatusInfo, exec);
3277 static void print_status_info(
3282 const char *active_on, *active_off, *on, *off, *ss;
3284 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3285 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3291 /* This shows pretty information about a unit. See
3292 * print_property() for a low-level property printer */
3294 if (streq_ptr(i->active_state, "failed")) {
3295 active_on = ansi_highlight_red();
3296 active_off = ansi_highlight_off();
3297 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3298 active_on = ansi_highlight_green();
3299 active_off = ansi_highlight_off();
3301 active_on = active_off = "";
3303 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3305 if (i->description && !streq_ptr(i->id, i->description))
3306 printf(" - %s", i->description);
3311 printf(" Follow: unit currently follows state of %s\n", i->following);
3313 if (streq_ptr(i->load_state, "error")) {
3314 on = ansi_highlight_red();
3315 off = ansi_highlight_off();
3319 path = i->source_path ? i->source_path : i->fragment_path;
3322 printf(" Loaded: %s%s%s (Reason: %s)\n",
3323 on, strna(i->load_state), off, i->load_error);
3324 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3325 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3326 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3327 else if (path && !isempty(i->unit_file_state))
3328 printf(" Loaded: %s%s%s (%s; %s)\n",
3329 on, strna(i->load_state), off, path, i->unit_file_state);
3331 printf(" Loaded: %s%s%s (%s)\n",
3332 on, strna(i->load_state), off, path);
3334 printf(" Loaded: %s%s%s\n",
3335 on, strna(i->load_state), off);
3337 if (!strv_isempty(i->dropin_paths)) {
3338 _cleanup_free_ char *dir = NULL;
3342 STRV_FOREACH(dropin, i->dropin_paths) {
3343 if (! dir || last) {
3344 printf(dir ? " " : " Drop-In: ");
3349 if (path_get_parent(*dropin, &dir) < 0) {
3354 printf("%s\n %s", dir,
3355 draw_special_char(DRAW_TREE_RIGHT));
3358 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3360 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3364 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3366 printf(" Active: %s%s (%s)%s",
3367 active_on, strna(i->active_state), ss, active_off);
3369 printf(" Active: %s%s%s",
3370 active_on, strna(i->active_state), active_off);
3372 if (!isempty(i->result) && !streq(i->result, "success"))
3373 printf(" (Result: %s)", i->result);
3375 timestamp = (streq_ptr(i->active_state, "active") ||
3376 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3377 (streq_ptr(i->active_state, "inactive") ||
3378 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3379 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3380 i->active_exit_timestamp;
3382 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3383 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3386 printf(" since %s; %s\n", s2, s1);
3388 printf(" since %s\n", s2);
3392 if (!i->condition_result && i->condition_timestamp > 0) {
3393 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3394 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3396 printf("Condition: start %scondition failed%s at %s%s%s\n",
3397 ansi_highlight_yellow(), ansi_highlight_off(),
3398 s2, s1 ? "; " : "", s1 ? s1 : "");
3399 if (i->failed_condition_trigger)
3400 printf(" none of the trigger conditions were met\n");
3401 else if (i->failed_condition)
3402 printf(" %s=%s%s was not met\n",
3403 i->failed_condition,
3404 i->failed_condition_negate ? "!" : "",
3405 i->failed_condition_parameter);
3408 if (!i->assert_result && i->assert_timestamp > 0) {
3409 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3410 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3412 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3413 ansi_highlight_red(), ansi_highlight_off(),
3414 s2, s1 ? "; " : "", s1 ? s1 : "");
3415 if (i->failed_assert_trigger)
3416 printf(" none of the trigger assertions were met\n");
3417 else if (i->failed_assert)
3418 printf(" %s=%s%s was not met\n",
3420 i->failed_assert_negate ? "!" : "",
3421 i->failed_assert_parameter);
3425 printf(" Device: %s\n", i->sysfs_path);
3427 printf(" Where: %s\n", i->where);
3429 printf(" What: %s\n", i->what);
3431 STRV_FOREACH(t, i->documentation)
3432 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3434 STRV_FOREACH_PAIR(t, t2, i->listen)
3435 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3438 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3440 LIST_FOREACH(exec, p, i->exec) {
3441 _cleanup_free_ char *argv = NULL;
3444 /* Only show exited processes here */
3448 argv = strv_join(p->argv, " ");
3449 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3451 good = is_clean_exit_lsb(p->code, p->status, NULL);
3453 on = ansi_highlight_red();
3454 off = ansi_highlight_off();
3458 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3460 if (p->code == CLD_EXITED) {
3463 printf("status=%i", p->status);
3465 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3470 printf("signal=%s", signal_to_string(p->status));
3472 printf(")%s\n", off);
3474 if (i->main_pid == p->pid &&
3475 i->start_timestamp == p->start_timestamp &&
3476 i->exit_timestamp == p->start_timestamp)
3477 /* Let's not show this twice */
3480 if (p->pid == i->control_pid)
3484 if (i->main_pid > 0 || i->control_pid > 0) {
3485 if (i->main_pid > 0) {
3486 printf(" Main PID: "PID_FMT, i->main_pid);
3489 _cleanup_free_ char *comm = NULL;
3490 get_process_comm(i->main_pid, &comm);
3492 printf(" (%s)", comm);
3493 } else if (i->exit_code > 0) {
3494 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3496 if (i->exit_code == CLD_EXITED) {
3499 printf("status=%i", i->exit_status);
3501 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3506 printf("signal=%s", signal_to_string(i->exit_status));
3510 if (i->control_pid > 0)
3514 if (i->control_pid > 0) {
3515 _cleanup_free_ char *c = NULL;
3517 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3519 get_process_comm(i->control_pid, &c);
3528 printf(" Status: \"%s\"\n", i->status_text);
3529 if (i->status_errno > 0)
3530 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3532 if (i->memory_current != (uint64_t) -1) {
3533 char buf[FORMAT_BYTES_MAX];
3535 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3537 if (i->memory_limit != (uint64_t) -1)
3538 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3543 if (i->control_group &&
3544 (i->main_pid > 0 || i->control_pid > 0 ||
3545 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3548 printf(" CGroup: %s\n", i->control_group);
3550 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3553 static const char prefix[] = " ";
3556 if (c > sizeof(prefix) - 1)
3557 c -= sizeof(prefix) - 1;
3561 if (i->main_pid > 0)
3562 extra[k++] = i->main_pid;
3564 if (i->control_pid > 0)
3565 extra[k++] = i->control_pid;
3567 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3571 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3572 show_journal_by_unit(
3577 i->inactive_exit_timestamp_monotonic,
3580 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3581 SD_JOURNAL_LOCAL_ONLY,
3582 arg_scope == UNIT_FILE_SYSTEM,
3586 if (i->need_daemon_reload)
3587 warn_unit_file_changed(i->id);
3590 static void show_unit_help(UnitStatusInfo *i) {
3595 if (!i->documentation) {
3596 log_info("Documentation for %s not known.", i->id);
3600 STRV_FOREACH(p, i->documentation)
3601 if (startswith(*p, "man:"))
3602 show_man_page(*p + 4, false);
3604 log_info("Can't show: %s", *p);
3607 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3614 switch (contents[0]) {
3616 case SD_BUS_TYPE_STRING: {
3619 r = sd_bus_message_read(m, "s", &s);
3621 return bus_log_parse_error(r);
3624 if (streq(name, "Id"))
3626 else if (streq(name, "LoadState"))
3628 else if (streq(name, "ActiveState"))
3629 i->active_state = s;
3630 else if (streq(name, "SubState"))
3632 else if (streq(name, "Description"))
3634 else if (streq(name, "FragmentPath"))
3635 i->fragment_path = s;
3636 else if (streq(name, "SourcePath"))
3639 else if (streq(name, "DefaultControlGroup")) {
3641 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3643 i->control_group = e;
3646 else if (streq(name, "ControlGroup"))
3647 i->control_group = s;
3648 else if (streq(name, "StatusText"))
3650 else if (streq(name, "PIDFile"))
3652 else if (streq(name, "SysFSPath"))
3654 else if (streq(name, "Where"))
3656 else if (streq(name, "What"))
3658 else if (streq(name, "Following"))
3660 else if (streq(name, "UnitFileState"))
3661 i->unit_file_state = s;
3662 else if (streq(name, "UnitFilePreset"))
3663 i->unit_file_preset = s;
3664 else if (streq(name, "Result"))
3671 case SD_BUS_TYPE_BOOLEAN: {
3674 r = sd_bus_message_read(m, "b", &b);
3676 return bus_log_parse_error(r);
3678 if (streq(name, "Accept"))
3680 else if (streq(name, "NeedDaemonReload"))
3681 i->need_daemon_reload = b;
3682 else if (streq(name, "ConditionResult"))
3683 i->condition_result = b;
3684 else if (streq(name, "AssertResult"))
3685 i->assert_result = b;
3690 case SD_BUS_TYPE_UINT32: {
3693 r = sd_bus_message_read(m, "u", &u);
3695 return bus_log_parse_error(r);
3697 if (streq(name, "MainPID")) {
3699 i->main_pid = (pid_t) u;
3702 } else if (streq(name, "ControlPID"))
3703 i->control_pid = (pid_t) u;
3704 else if (streq(name, "ExecMainPID")) {
3706 i->main_pid = (pid_t) u;
3707 } else if (streq(name, "NAccepted"))
3709 else if (streq(name, "NConnections"))
3710 i->n_connections = u;
3715 case SD_BUS_TYPE_INT32: {
3718 r = sd_bus_message_read(m, "i", &j);
3720 return bus_log_parse_error(r);
3722 if (streq(name, "ExecMainCode"))
3723 i->exit_code = (int) j;
3724 else if (streq(name, "ExecMainStatus"))
3725 i->exit_status = (int) j;
3726 else if (streq(name, "StatusErrno"))
3727 i->status_errno = (int) j;
3732 case SD_BUS_TYPE_UINT64: {
3735 r = sd_bus_message_read(m, "t", &u);
3737 return bus_log_parse_error(r);
3739 if (streq(name, "ExecMainStartTimestamp"))
3740 i->start_timestamp = (usec_t) u;
3741 else if (streq(name, "ExecMainExitTimestamp"))
3742 i->exit_timestamp = (usec_t) u;
3743 else if (streq(name, "ActiveEnterTimestamp"))
3744 i->active_enter_timestamp = (usec_t) u;
3745 else if (streq(name, "InactiveEnterTimestamp"))
3746 i->inactive_enter_timestamp = (usec_t) u;
3747 else if (streq(name, "InactiveExitTimestamp"))
3748 i->inactive_exit_timestamp = (usec_t) u;
3749 else if (streq(name, "InactiveExitTimestampMonotonic"))
3750 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3751 else if (streq(name, "ActiveExitTimestamp"))
3752 i->active_exit_timestamp = (usec_t) u;
3753 else if (streq(name, "ConditionTimestamp"))
3754 i->condition_timestamp = (usec_t) u;
3755 else if (streq(name, "AssertTimestamp"))
3756 i->assert_timestamp = (usec_t) u;
3757 else if (streq(name, "MemoryCurrent"))
3758 i->memory_current = u;
3759 else if (streq(name, "MemoryLimit"))
3760 i->memory_limit = u;
3765 case SD_BUS_TYPE_ARRAY:
3767 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3768 _cleanup_free_ ExecStatusInfo *info = NULL;
3770 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3772 return bus_log_parse_error(r);
3774 info = new0(ExecStatusInfo, 1);
3778 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3780 info->name = strdup(name);
3784 LIST_PREPEND(exec, i->exec, info);
3786 info = new0(ExecStatusInfo, 1);
3792 return bus_log_parse_error(r);
3794 r = sd_bus_message_exit_container(m);
3796 return bus_log_parse_error(r);
3800 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3801 const char *type, *path;
3803 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3805 return bus_log_parse_error(r);
3807 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3809 r = strv_extend(&i->listen, type);
3813 r = strv_extend(&i->listen, path);
3818 return bus_log_parse_error(r);
3820 r = sd_bus_message_exit_container(m);
3822 return bus_log_parse_error(r);
3826 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3828 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3830 return bus_log_parse_error(r);
3832 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3834 r = sd_bus_message_read_strv(m, &i->documentation);
3836 return bus_log_parse_error(r);
3838 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3839 const char *cond, *param;
3840 int trigger, negate;
3843 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3845 return bus_log_parse_error(r);
3847 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3848 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3849 if (state < 0 && (!trigger || !i->failed_condition)) {
3850 i->failed_condition = cond;
3851 i->failed_condition_trigger = trigger;
3852 i->failed_condition_negate = negate;
3853 i->failed_condition_parameter = param;
3857 return bus_log_parse_error(r);
3859 r = sd_bus_message_exit_container(m);
3861 return bus_log_parse_error(r);
3863 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3864 const char *cond, *param;
3865 int trigger, negate;
3868 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3870 return bus_log_parse_error(r);
3872 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3873 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3874 if (state < 0 && (!trigger || !i->failed_assert)) {
3875 i->failed_assert = cond;
3876 i->failed_assert_trigger = trigger;
3877 i->failed_assert_negate = negate;
3878 i->failed_assert_parameter = param;
3882 return bus_log_parse_error(r);
3884 r = sd_bus_message_exit_container(m);
3886 return bus_log_parse_error(r);
3893 case SD_BUS_TYPE_STRUCT_BEGIN:
3895 if (streq(name, "LoadError")) {
3896 const char *n, *message;
3898 r = sd_bus_message_read(m, "(ss)", &n, &message);
3900 return bus_log_parse_error(r);
3902 if (!isempty(message))
3903 i->load_error = message;
3916 r = sd_bus_message_skip(m, contents);
3918 return bus_log_parse_error(r);
3923 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3929 /* This is a low-level property printer, see
3930 * print_status_info() for the nicer output */
3932 if (arg_properties && !strv_find(arg_properties, name)) {
3933 /* skip what we didn't read */
3934 r = sd_bus_message_skip(m, contents);
3938 switch (contents[0]) {
3940 case SD_BUS_TYPE_STRUCT_BEGIN:
3942 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3945 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3947 return bus_log_parse_error(r);
3950 printf("%s=%"PRIu32"\n", name, u);
3952 printf("%s=\n", name);
3956 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3959 r = sd_bus_message_read(m, "(so)", &s, NULL);
3961 return bus_log_parse_error(r);
3963 if (arg_all || !isempty(s))
3964 printf("%s=%s\n", name, s);
3968 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3969 const char *a = NULL, *b = NULL;
3971 r = sd_bus_message_read(m, "(ss)", &a, &b);
3973 return bus_log_parse_error(r);
3975 if (arg_all || !isempty(a) || !isempty(b))
3976 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3979 } else if (streq_ptr(name, "SystemCallFilter")) {
3980 _cleanup_strv_free_ char **l = NULL;
3983 r = sd_bus_message_enter_container(m, 'r', "bas");
3985 return bus_log_parse_error(r);
3987 r = sd_bus_message_read(m, "b", &whitelist);
3989 return bus_log_parse_error(r);
3991 r = sd_bus_message_read_strv(m, &l);
3993 return bus_log_parse_error(r);
3995 r = sd_bus_message_exit_container(m);
3997 return bus_log_parse_error(r);
3999 if (arg_all || whitelist || !strv_isempty(l)) {
4003 fputs(name, stdout);
4009 STRV_FOREACH(i, l) {
4017 fputc('\n', stdout);
4025 case SD_BUS_TYPE_ARRAY:
4027 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4031 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4033 return bus_log_parse_error(r);
4035 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4036 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4039 return bus_log_parse_error(r);
4041 r = sd_bus_message_exit_container(m);
4043 return bus_log_parse_error(r);
4047 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4048 const char *type, *path;
4050 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4052 return bus_log_parse_error(r);
4054 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4055 printf("%s=%s\n", type, path);
4057 return bus_log_parse_error(r);
4059 r = sd_bus_message_exit_container(m);
4061 return bus_log_parse_error(r);
4065 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4066 const char *type, *path;
4068 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4070 return bus_log_parse_error(r);
4072 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4073 printf("Listen%s=%s\n", type, path);
4075 return bus_log_parse_error(r);
4077 r = sd_bus_message_exit_container(m);
4079 return bus_log_parse_error(r);
4083 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4085 uint64_t value, next_elapse;
4087 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4089 return bus_log_parse_error(r);
4091 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4092 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4094 printf("%s={ value=%s ; next_elapse=%s }\n",
4096 format_timespan(timespan1, sizeof(timespan1), value, 0),
4097 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4100 return bus_log_parse_error(r);
4102 r = sd_bus_message_exit_container(m);
4104 return bus_log_parse_error(r);
4108 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4109 ExecStatusInfo info = {};
4111 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4113 return bus_log_parse_error(r);
4115 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4116 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4117 _cleanup_free_ char *tt;
4119 tt = strv_join(info.argv, " ");
4121 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",
4125 yes_no(info.ignore),
4126 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4127 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4129 sigchld_code_to_string(info.code),
4131 info.code == CLD_EXITED ? "" : "/",
4132 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4135 strv_free(info.argv);
4139 r = sd_bus_message_exit_container(m);
4141 return bus_log_parse_error(r);
4145 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4146 const char *path, *rwm;
4148 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4150 return bus_log_parse_error(r);
4152 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4153 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4155 return bus_log_parse_error(r);
4157 r = sd_bus_message_exit_container(m);
4159 return bus_log_parse_error(r);
4163 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4167 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4169 return bus_log_parse_error(r);
4171 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4172 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4174 return bus_log_parse_error(r);
4176 r = sd_bus_message_exit_container(m);
4178 return bus_log_parse_error(r);
4182 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4186 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4188 return bus_log_parse_error(r);
4190 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4191 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4193 return bus_log_parse_error(r);
4195 r = sd_bus_message_exit_container(m);
4197 return bus_log_parse_error(r);
4205 r = bus_print_property(name, m, arg_all);
4207 return bus_log_parse_error(r);
4210 r = sd_bus_message_skip(m, contents);
4212 return bus_log_parse_error(r);
4215 printf("%s=[unprintable]\n", name);
4221 static int show_one(
4225 bool show_properties,
4229 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4230 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4231 UnitStatusInfo info = {
4232 .memory_current = (uint64_t) -1,
4233 .memory_limit = (uint64_t) -1,
4241 log_debug("Showing one %s", path);
4243 r = sd_bus_call_method(
4245 "org.freedesktop.systemd1",
4247 "org.freedesktop.DBus.Properties",
4253 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4257 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4259 return bus_log_parse_error(r);
4266 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4267 const char *name, *contents;
4269 r = sd_bus_message_read(reply, "s", &name);
4271 return bus_log_parse_error(r);
4273 r = sd_bus_message_peek_type(reply, NULL, &contents);
4275 return bus_log_parse_error(r);
4277 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4279 return bus_log_parse_error(r);
4281 if (show_properties)
4282 r = print_property(name, reply, contents);
4284 r = status_property(name, reply, &info, contents);
4288 r = sd_bus_message_exit_container(reply);
4290 return bus_log_parse_error(r);
4292 r = sd_bus_message_exit_container(reply);
4294 return bus_log_parse_error(r);
4297 return bus_log_parse_error(r);
4299 r = sd_bus_message_exit_container(reply);
4301 return bus_log_parse_error(r);
4305 if (!show_properties) {
4306 if (streq(verb, "help"))
4307 show_unit_help(&info);
4309 print_status_info(&info, ellipsized);
4312 strv_free(info.documentation);
4313 strv_free(info.dropin_paths);
4314 strv_free(info.listen);
4316 if (!streq_ptr(info.active_state, "active") &&
4317 !streq_ptr(info.active_state, "reloading") &&
4318 streq(verb, "status")) {
4319 /* According to LSB: "program not running" */
4320 /* 0: program is running or service is OK
4321 * 1: program is dead and /run PID file exists
4322 * 2: program is dead and /run/lock lock file exists
4323 * 3: program is not running
4324 * 4: program or service status is unknown
4326 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4332 while ((p = info.exec)) {
4333 LIST_REMOVE(exec, info.exec, p);
4334 exec_status_info_free(p);
4340 static int get_unit_dbus_path_by_pid(
4345 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4346 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4350 r = sd_bus_call_method(
4352 "org.freedesktop.systemd1",
4353 "/org/freedesktop/systemd1",
4354 "org.freedesktop.systemd1.Manager",
4360 log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4364 r = sd_bus_message_read(reply, "o", &u);
4366 return bus_log_parse_error(r);
4376 static int show_all(
4379 bool show_properties,
4383 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4384 _cleanup_free_ UnitInfo *unit_infos = NULL;
4389 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4393 pager_open_if_enabled();
4397 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4399 for (u = unit_infos; u < unit_infos + c; u++) {
4400 _cleanup_free_ char *p = NULL;
4402 p = unit_dbus_path_from_name(u->id);
4406 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4409 else if (r > 0 && ret == 0)
4416 static int show_system_status(sd_bus *bus) {
4417 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4418 _cleanup_free_ char *hn = NULL;
4419 struct machine_info mi = {};
4420 const char *on, *off;
4423 hn = gethostname_malloc();
4427 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4429 return log_error_errno(r, "Failed to read server status: %m");
4431 if (streq_ptr(mi.state, "degraded")) {
4432 on = ansi_highlight_red();
4433 off = ansi_highlight_off();
4434 } else if (!streq_ptr(mi.state, "running")) {
4435 on = ansi_highlight_yellow();
4436 off = ansi_highlight_off();
4440 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4442 printf(" State: %s%s%s\n",
4443 on, strna(mi.state), off);
4445 printf(" Jobs: %u queued\n", mi.n_jobs);
4446 printf(" Failed: %u units\n", mi.n_failed_units);
4448 printf(" Since: %s; %s\n",
4449 format_timestamp(since2, sizeof(since2), mi.timestamp),
4450 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4452 printf(" CGroup: %s\n", mi.control_group ?: "/");
4453 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4454 static const char prefix[] = " ";
4458 if (c > sizeof(prefix) - 1)
4459 c -= sizeof(prefix) - 1;
4463 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4467 free(mi.control_group);
4472 static int show(sd_bus *bus, char **args) {
4473 bool show_properties, show_status, new_line = false;
4474 bool ellipsized = false;
4480 show_properties = streq(args[0], "show");
4481 show_status = streq(args[0], "status");
4483 if (show_properties)
4484 pager_open_if_enabled();
4486 /* If no argument is specified inspect the manager itself */
4488 if (show_properties && strv_length(args) <= 1)
4489 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4491 if (show_status && strv_length(args) <= 1) {
4493 pager_open_if_enabled();
4494 show_system_status(bus);
4498 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4500 _cleanup_free_ char **patterns = NULL;
4503 STRV_FOREACH(name, args + 1) {
4504 _cleanup_free_ char *unit = NULL;
4507 if (safe_atou32(*name, &id) < 0) {
4508 if (strv_push(&patterns, *name) < 0)
4512 } else if (show_properties) {
4513 /* Interpret as job id */
4514 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4518 /* Interpret as PID */
4519 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4526 r = show_one(args[0], bus, unit, show_properties,
4527 &new_line, &ellipsized);
4530 else if (r > 0 && ret == 0)
4534 if (!strv_isempty(patterns)) {
4535 _cleanup_strv_free_ char **names = NULL;
4537 r = expand_names(bus, patterns, NULL, &names);
4539 log_error_errno(r, "Failed to expand names: %m");
4541 STRV_FOREACH(name, names) {
4542 _cleanup_free_ char *unit;
4544 unit = unit_dbus_path_from_name(*name);
4548 r = show_one(args[0], bus, unit, show_properties,
4549 &new_line, &ellipsized);
4552 else if (r > 0 && ret == 0)
4558 if (ellipsized && !arg_quiet)
4559 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4564 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4568 assert(user_runtime);
4571 if (arg_scope == UNIT_FILE_USER) {
4572 r = user_config_home(user_home);
4574 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4576 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4578 r = user_runtime_dir(user_runtime);
4580 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4582 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4585 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4587 return log_error_errno(r, "Failed to query unit lookup paths: %m");
4592 static int cat(sd_bus *bus, char **args) {
4593 _cleanup_free_ char *user_home = NULL;
4594 _cleanup_free_ char *user_runtime = NULL;
4595 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4596 _cleanup_strv_free_ char **names = NULL;
4598 bool first = true, avoid_bus_cache;
4603 if (arg_transport != BUS_TRANSPORT_LOCAL) {
4604 log_error("Cannot remotely cat units");
4608 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4612 r = expand_names(bus, args + 1, NULL, &names);
4614 return log_error_errno(r, "Failed to expand names: %m");
4616 avoid_bus_cache = !bus || avoid_bus();
4618 pager_open_if_enabled();
4620 STRV_FOREACH(name, names) {
4621 _cleanup_free_ char *fragment_path = NULL;
4622 _cleanup_strv_free_ char **dropin_paths = NULL;
4625 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4636 if (fragment_path) {
4637 printf("%s# %s%s\n",
4638 ansi_highlight_blue(),
4640 ansi_highlight_off());
4643 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4645 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4650 STRV_FOREACH(path, dropin_paths) {
4651 printf("%s%s# %s%s\n",
4652 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4653 ansi_highlight_blue(),
4655 ansi_highlight_off());
4658 r = copy_file_fd(*path, STDOUT_FILENO, false);
4660 log_warning_errno(r, "Failed to cat %s: %m", *path);
4666 return r < 0 ? r : 0;
4669 static int set_property(sd_bus *bus, char **args) {
4670 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4671 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4672 _cleanup_free_ char *n = NULL;
4676 polkit_agent_open_if_enabled();
4678 r = sd_bus_message_new_method_call(
4681 "org.freedesktop.systemd1",
4682 "/org/freedesktop/systemd1",
4683 "org.freedesktop.systemd1.Manager",
4684 "SetUnitProperties");
4686 return bus_log_create_error(r);
4688 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4690 return bus_log_create_error(r);
4692 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4696 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4698 return bus_log_create_error(r);
4700 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4702 return bus_log_create_error(r);
4704 STRV_FOREACH(i, args + 2) {
4705 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4707 return bus_log_create_error(r);
4709 r = bus_append_unit_property_assignment(m, *i);
4713 r = sd_bus_message_close_container(m);
4715 return bus_log_create_error(r);
4718 r = sd_bus_message_close_container(m);
4720 return bus_log_create_error(r);
4722 r = sd_bus_call(bus, m, 0, &error, NULL);
4724 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4731 static int snapshot(sd_bus *bus, char **args) {
4732 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4733 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4734 _cleanup_free_ char *n = NULL, *id = NULL;
4738 polkit_agent_open_if_enabled();
4740 if (strv_length(args) > 1)
4741 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4747 r = sd_bus_message_new_method_call(
4750 "org.freedesktop.systemd1",
4751 "/org/freedesktop/systemd1",
4752 "org.freedesktop.systemd1.Manager",
4755 return bus_log_create_error(r);
4757 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4759 return bus_log_create_error(r);
4761 r = sd_bus_message_append(m, "sb", n, false);
4763 return bus_log_create_error(r);
4765 r = sd_bus_call(bus, m, 0, &error, &reply);
4767 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4771 r = sd_bus_message_read(reply, "o", &path);
4773 return bus_log_parse_error(r);
4775 r = sd_bus_get_property_string(
4777 "org.freedesktop.systemd1",
4779 "org.freedesktop.systemd1.Unit",
4784 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4794 static int delete_snapshot(sd_bus *bus, char **args) {
4795 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4796 _cleanup_strv_free_ char **names = NULL;
4802 polkit_agent_open_if_enabled();
4804 r = expand_names(bus, args + 1, ".snapshot", &names);
4806 log_error_errno(r, "Failed to expand names: %m");
4808 STRV_FOREACH(name, names) {
4809 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4812 q = sd_bus_message_new_method_call(
4815 "org.freedesktop.systemd1",
4816 "/org/freedesktop/systemd1",
4817 "org.freedesktop.systemd1.Manager",
4820 return bus_log_create_error(q);
4822 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4824 return bus_log_create_error(q);
4826 q = sd_bus_message_append(m, "s", *name);
4828 return bus_log_create_error(q);
4830 q = sd_bus_call(bus, m, 0, &error, NULL);
4832 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4841 static int daemon_reload(sd_bus *bus, char **args) {
4842 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4843 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4847 polkit_agent_open_if_enabled();
4849 if (arg_action == ACTION_RELOAD)
4851 else if (arg_action == ACTION_REEXEC)
4852 method = "Reexecute";
4854 assert(arg_action == ACTION_SYSTEMCTL);
4857 streq(args[0], "clear-jobs") ||
4858 streq(args[0], "cancel") ? "ClearJobs" :
4859 streq(args[0], "daemon-reexec") ? "Reexecute" :
4860 streq(args[0], "reset-failed") ? "ResetFailed" :
4861 streq(args[0], "halt") ? "Halt" :
4862 streq(args[0], "poweroff") ? "PowerOff" :
4863 streq(args[0], "reboot") ? "Reboot" :
4864 streq(args[0], "kexec") ? "KExec" :
4865 streq(args[0], "exit") ? "Exit" :
4866 /* "daemon-reload" */ "Reload";
4869 r = sd_bus_message_new_method_call(
4872 "org.freedesktop.systemd1",
4873 "/org/freedesktop/systemd1",
4874 "org.freedesktop.systemd1.Manager",
4877 return bus_log_create_error(r);
4879 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4881 return bus_log_create_error(r);
4883 r = sd_bus_call(bus, m, 0, &error, NULL);
4884 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4885 /* There's always a fallback possible for
4886 * legacy actions. */
4888 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4889 /* On reexecution, we expect a disconnect, not a
4893 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4895 return r < 0 ? r : 0;
4898 static int reset_failed(sd_bus *bus, char **args) {
4899 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4900 _cleanup_strv_free_ char **names = NULL;
4904 if (strv_length(args) <= 1)
4905 return daemon_reload(bus, args);
4907 polkit_agent_open_if_enabled();
4909 r = expand_names(bus, args + 1, NULL, &names);
4911 log_error_errno(r, "Failed to expand names: %m");
4913 STRV_FOREACH(name, names) {
4914 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4916 q = sd_bus_message_new_method_call(
4919 "org.freedesktop.systemd1",
4920 "/org/freedesktop/systemd1",
4921 "org.freedesktop.systemd1.Manager",
4924 return bus_log_create_error(q);
4926 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4928 return bus_log_create_error(q);
4930 q = sd_bus_message_append(m, "s", *name);
4932 return bus_log_create_error(q);
4934 q = sd_bus_call(bus, m, 0, &error, NULL);
4936 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4945 static int show_environment(sd_bus *bus, char **args) {
4946 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4947 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4951 pager_open_if_enabled();
4953 r = sd_bus_get_property(
4955 "org.freedesktop.systemd1",
4956 "/org/freedesktop/systemd1",
4957 "org.freedesktop.systemd1.Manager",
4963 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4967 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4969 return bus_log_parse_error(r);
4971 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4974 return bus_log_parse_error(r);
4976 r = sd_bus_message_exit_container(reply);
4978 return bus_log_parse_error(r);
4983 static int switch_root(sd_bus *bus, char **args) {
4984 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4985 _cleanup_free_ char *cmdline_init = NULL;
4986 const char *root, *init;
4990 l = strv_length(args);
4991 if (l < 2 || l > 3) {
4992 log_error("Wrong number of arguments.");
5001 r = parse_env_file("/proc/cmdline", WHITESPACE,
5002 "init", &cmdline_init,
5005 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5007 init = cmdline_init;
5014 const char *root_systemd_path = NULL, *root_init_path = NULL;
5016 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
5017 root_init_path = strjoina(root, "/", init);
5019 /* If the passed init is actually the same as the
5020 * systemd binary, then let's suppress it. */
5021 if (files_same(root_init_path, root_systemd_path) > 0)
5025 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5027 r = sd_bus_call_method(
5029 "org.freedesktop.systemd1",
5030 "/org/freedesktop/systemd1",
5031 "org.freedesktop.systemd1.Manager",
5037 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5044 static int set_environment(sd_bus *bus, char **args) {
5045 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5046 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5053 method = streq(args[0], "set-environment")
5055 : "UnsetEnvironment";
5057 r = sd_bus_message_new_method_call(
5060 "org.freedesktop.systemd1",
5061 "/org/freedesktop/systemd1",
5062 "org.freedesktop.systemd1.Manager",
5065 return bus_log_create_error(r);
5067 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5069 return bus_log_create_error(r);
5071 r = sd_bus_message_append_strv(m, args + 1);
5073 return bus_log_create_error(r);
5075 r = sd_bus_call(bus, m, 0, &error, NULL);
5077 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5084 static int import_environment(sd_bus *bus, char **args) {
5085 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5086 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5092 r = sd_bus_message_new_method_call(
5095 "org.freedesktop.systemd1",
5096 "/org/freedesktop/systemd1",
5097 "org.freedesktop.systemd1.Manager",
5100 return bus_log_create_error(r);
5102 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5104 return bus_log_create_error(r);
5106 if (strv_isempty(args + 1))
5107 r = sd_bus_message_append_strv(m, environ);
5111 r = sd_bus_message_open_container(m, 'a', "s");
5113 return bus_log_create_error(r);
5115 STRV_FOREACH(a, args + 1) {
5117 if (!env_name_is_valid(*a)) {
5118 log_error("Not a valid environment variable name: %s", *a);
5122 STRV_FOREACH(b, environ) {
5125 eq = startswith(*b, *a);
5126 if (eq && *eq == '=') {
5128 r = sd_bus_message_append(m, "s", *b);
5130 return bus_log_create_error(r);
5137 r = sd_bus_message_close_container(m);
5140 return bus_log_create_error(r);
5142 r = sd_bus_call(bus, m, 0, &error, NULL);
5144 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5151 static int enable_sysv_units(const char *verb, char **args) {
5154 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5156 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5158 if (arg_scope != UNIT_FILE_SYSTEM)
5161 if (!streq(verb, "enable") &&
5162 !streq(verb, "disable") &&
5163 !streq(verb, "is-enabled"))
5166 /* Processes all SysV units, and reshuffles the array so that
5167 * afterwards only the native units remain */
5169 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5176 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5177 bool found_native = false, found_sysv;
5179 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5187 if (!endswith(name, ".service"))
5190 if (path_is_absolute(name))
5193 STRV_FOREACH(k, paths.unit_path) {
5194 _cleanup_free_ char *path = NULL;
5196 path = path_join(arg_root, *k, name);
5200 found_native = access(path, F_OK) >= 0;
5208 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5212 p[strlen(p) - strlen(".service")] = 0;
5213 found_sysv = access(p, F_OK) >= 0;
5217 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5219 if (!isempty(arg_root))
5220 argv[c++] = q = strappend("--root=", arg_root);
5222 argv[c++] = basename(p);
5224 streq(verb, "enable") ? "on" :
5225 streq(verb, "disable") ? "off" : "--level=5";
5228 l = strv_join((char**)argv, " ");
5232 log_info("Executing %s", l);
5236 return log_error_errno(errno, "Failed to fork: %m");
5237 else if (pid == 0) {
5240 execv(argv[0], (char**) argv);
5241 _exit(EXIT_FAILURE);
5244 j = wait_for_terminate(pid, &status);
5246 log_error_errno(r, "Failed to wait for child: %m");
5250 if (status.si_code == CLD_EXITED) {
5251 if (streq(verb, "is-enabled")) {
5252 if (status.si_status == 0) {
5261 } else if (status.si_status != 0)
5266 /* Remove this entry, so that we don't try enabling it as native unit */
5269 assert(args[f] == name);
5270 strv_remove(args, name);
5277 static int mangle_names(char **original_names, char ***mangled_names) {
5278 char **i, **l, **name;
5280 l = new(char*, strv_length(original_names) + 1);
5285 STRV_FOREACH(name, original_names) {
5287 /* When enabling units qualified path names are OK,
5288 * too, hence allow them explicitly. */
5293 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5309 static int enable_unit(sd_bus *bus, char **args) {
5310 _cleanup_strv_free_ char **names = NULL;
5311 const char *verb = args[0];
5312 UnitFileChange *changes = NULL;
5313 unsigned n_changes = 0;
5314 int carries_install_info = -1;
5320 r = mangle_names(args+1, &names);
5324 r = enable_sysv_units(verb, names);
5328 /* If the operation was fully executed by the SysV compat,
5329 * let's finish early */
5330 if (strv_isempty(names))
5333 if (!bus || avoid_bus()) {
5334 if (streq(verb, "enable")) {
5335 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5336 carries_install_info = r;
5337 } else if (streq(verb, "disable"))
5338 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5339 else if (streq(verb, "reenable")) {
5340 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5341 carries_install_info = r;
5342 } else if (streq(verb, "link"))
5343 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5344 else if (streq(verb, "preset")) {
5345 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5346 carries_install_info = r;
5347 } else if (streq(verb, "mask"))
5348 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5349 else if (streq(verb, "unmask"))
5350 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5352 assert_not_reached("Unknown verb");
5355 log_error_errno(r, "Operation failed: %m");
5360 dump_unit_file_changes(changes, n_changes);
5364 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5365 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5366 int expect_carries_install_info = false;
5367 bool send_force = true, send_preset_mode = false;
5370 polkit_agent_open_if_enabled();
5372 if (streq(verb, "enable")) {
5373 method = "EnableUnitFiles";
5374 expect_carries_install_info = true;
5375 } else if (streq(verb, "disable")) {
5376 method = "DisableUnitFiles";
5378 } else if (streq(verb, "reenable")) {
5379 method = "ReenableUnitFiles";
5380 expect_carries_install_info = true;
5381 } else if (streq(verb, "link"))
5382 method = "LinkUnitFiles";
5383 else if (streq(verb, "preset")) {
5385 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5386 method = "PresetUnitFilesWithMode";
5387 send_preset_mode = true;
5389 method = "PresetUnitFiles";
5391 expect_carries_install_info = true;
5392 } else if (streq(verb, "mask"))
5393 method = "MaskUnitFiles";
5394 else if (streq(verb, "unmask")) {
5395 method = "UnmaskUnitFiles";
5398 assert_not_reached("Unknown verb");
5400 r = sd_bus_message_new_method_call(
5403 "org.freedesktop.systemd1",
5404 "/org/freedesktop/systemd1",
5405 "org.freedesktop.systemd1.Manager",
5408 return bus_log_create_error(r);
5410 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5412 return bus_log_create_error(r);
5414 r = sd_bus_message_append_strv(m, names);
5416 return bus_log_create_error(r);
5418 if (send_preset_mode) {
5419 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5421 return bus_log_create_error(r);
5424 r = sd_bus_message_append(m, "b", arg_runtime);
5426 return bus_log_create_error(r);
5429 r = sd_bus_message_append(m, "b", arg_force);
5431 return bus_log_create_error(r);
5434 r = sd_bus_call(bus, m, 0, &error, &reply);
5436 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5440 if (expect_carries_install_info) {
5441 r = sd_bus_message_read(reply, "b", &carries_install_info);
5443 return bus_log_parse_error(r);
5446 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5450 /* Try to reload if enabled */
5452 r = daemon_reload(bus, args);
5457 if (carries_install_info == 0)
5458 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5459 "using systemctl.\n"
5460 "Possible reasons for having this kind of units are:\n"
5461 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5462 " .wants/ or .requires/ directory.\n"
5463 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5464 " a requirement dependency on it.\n"
5465 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5466 " D-Bus, udev, scripted systemctl call, ...).\n");
5469 unit_file_changes_free(changes, n_changes);
5474 static int add_dependency(sd_bus *bus, char **args) {
5475 _cleanup_strv_free_ char **names = NULL;
5476 _cleanup_free_ char *target = NULL;
5477 const char *verb = args[0];
5484 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5488 r = mangle_names(args+2, &names);
5492 if (streq(verb, "add-wants"))
5494 else if (streq(verb, "add-requires"))
5495 dep = UNIT_REQUIRES;
5497 assert_not_reached("Unknown verb");
5499 if (!bus || avoid_bus()) {
5500 UnitFileChange *changes = NULL;
5501 unsigned n_changes = 0;
5503 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5506 return log_error_errno(r, "Can't add dependency: %m");
5509 dump_unit_file_changes(changes, n_changes);
5511 unit_file_changes_free(changes, n_changes);
5514 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5515 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5517 polkit_agent_open_if_enabled();
5519 r = sd_bus_message_new_method_call(
5522 "org.freedesktop.systemd1",
5523 "/org/freedesktop/systemd1",
5524 "org.freedesktop.systemd1.Manager",
5525 "AddDependencyUnitFiles");
5527 return bus_log_create_error(r);
5529 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5531 return bus_log_create_error(r);
5533 r = sd_bus_message_append_strv(m, names);
5535 return bus_log_create_error(r);
5537 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5539 return bus_log_create_error(r);
5541 r = sd_bus_call(bus, m, 0, &error, &reply);
5543 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5547 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5552 r = daemon_reload(bus, args);
5560 static int preset_all(sd_bus *bus, char **args) {
5561 UnitFileChange *changes = NULL;
5562 unsigned n_changes = 0;
5565 if (!bus || avoid_bus()) {
5567 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5569 log_error_errno(r, "Operation failed: %m");
5574 dump_unit_file_changes(changes, n_changes);
5579 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5580 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5582 polkit_agent_open_if_enabled();
5584 r = sd_bus_message_new_method_call(
5587 "org.freedesktop.systemd1",
5588 "/org/freedesktop/systemd1",
5589 "org.freedesktop.systemd1.Manager",
5590 "PresetAllUnitFiles");
5592 return bus_log_create_error(r);
5594 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5596 return bus_log_create_error(r);
5598 r = sd_bus_message_append(
5601 unit_file_preset_mode_to_string(arg_preset_mode),
5605 return bus_log_create_error(r);
5607 r = sd_bus_call(bus, m, 0, &error, &reply);
5609 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5613 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5618 r = daemon_reload(bus, args);
5624 unit_file_changes_free(changes, n_changes);
5629 static int unit_is_enabled(sd_bus *bus, char **args) {
5631 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5632 _cleanup_strv_free_ char **names = NULL;
5637 r = mangle_names(args+1, &names);
5641 r = enable_sysv_units(args[0], names);
5647 if (!bus || avoid_bus()) {
5649 STRV_FOREACH(name, names) {
5650 UnitFileState state;
5652 state = unit_file_get_state(arg_scope, arg_root, *name);
5654 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5656 if (state == UNIT_FILE_ENABLED ||
5657 state == UNIT_FILE_ENABLED_RUNTIME ||
5658 state == UNIT_FILE_STATIC ||
5659 state == UNIT_FILE_INDIRECT)
5663 puts(unit_file_state_to_string(state));
5667 STRV_FOREACH(name, names) {
5668 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5671 r = sd_bus_call_method(
5673 "org.freedesktop.systemd1",
5674 "/org/freedesktop/systemd1",
5675 "org.freedesktop.systemd1.Manager",
5681 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5685 r = sd_bus_message_read(reply, "s", &s);
5687 return bus_log_parse_error(r);
5689 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5700 static int is_system_running(sd_bus *bus, char **args) {
5701 _cleanup_free_ char *state = NULL;
5704 r = sd_bus_get_property_string(
5706 "org.freedesktop.systemd1",
5707 "/org/freedesktop/systemd1",
5708 "org.freedesktop.systemd1.Manager",
5721 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5724 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5729 assert(original_path);
5732 r = tempfn_random(new_path, &t);
5734 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5736 r = mkdir_parents(new_path, 0755);
5738 log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5743 r = copy_file(original_path, t, 0, 0644, 0);
5747 log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5752 log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5762 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5763 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5765 switch (arg_scope) {
5766 case UNIT_FILE_SYSTEM:
5767 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5769 run = path_join(arg_root, "/run/systemd/system/", name);
5771 case UNIT_FILE_GLOBAL:
5772 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5774 run = path_join(arg_root, "/run/systemd/user/", name);
5776 case UNIT_FILE_USER:
5778 assert(user_runtime);
5780 path = path_join(arg_root, user_home, name);
5782 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5785 run = path_join(arg_root, user_runtime, name);
5789 assert_not_reached("Invalid scope");
5791 if (!path || (arg_runtime && !run))
5795 if (access(path, F_OK) >= 0)
5796 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5798 if (path2 && access(path2, F_OK) >= 0)
5799 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5812 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) {
5813 char *tmp_new_path, *ending;
5818 assert(ret_new_path);
5819 assert(ret_tmp_path);
5821 ending = strjoina(unit_name, ".d/override.conf");
5822 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5826 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5832 *ret_new_path = tmp_new_path;
5833 *ret_tmp_path = tmp_tmp_path;
5838 static int unit_file_create_copy(const char *unit_name,
5839 const char *fragment_path,
5840 const char *user_home,
5841 const char *user_runtime,
5842 char **ret_new_path,
5843 char **ret_tmp_path) {
5848 assert(fragment_path);
5850 assert(ret_new_path);
5851 assert(ret_tmp_path);
5853 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5857 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5860 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5865 if (response != 'y') {
5866 log_warning("%s ignored", unit_name);
5872 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5874 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
5879 *ret_new_path = tmp_new_path;
5880 *ret_tmp_path = tmp_tmp_path;
5885 static int run_editor(char **paths) {
5893 log_error_errno(errno, "Failed to fork: %m");
5899 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5901 char **tmp_path, **original_path, **p;
5905 argc = strv_length(paths)/2 + 1;
5906 args = newa(const char*, argc + 1);
5909 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5910 args[i] = *tmp_path;
5915 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5916 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5917 * we try to execute well known editors
5919 editor = getenv("SYSTEMD_EDITOR");
5921 editor = getenv("EDITOR");
5923 editor = getenv("VISUAL");
5925 if (!isempty(editor)) {
5927 execvp(editor, (char* const*) args);
5930 STRV_FOREACH(p, backup_editors) {
5932 execvp(*p, (char* const*) args);
5933 /* We do not fail if the editor doesn't exist
5934 * because we want to try each one of them before
5937 if (errno != ENOENT) {
5938 log_error("Failed to execute %s: %m", editor);
5939 _exit(EXIT_FAILURE);
5943 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5944 _exit(EXIT_FAILURE);
5947 r = wait_for_terminate_and_warn("editor", pid, true);
5949 return log_error_errno(r, "Failed to wait for child: %m");
5954 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5955 _cleanup_free_ char *user_home = NULL;
5956 _cleanup_free_ char *user_runtime = NULL;
5957 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5958 bool avoid_bus_cache;
5965 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5969 avoid_bus_cache = !bus || avoid_bus();
5971 STRV_FOREACH(name, names) {
5972 _cleanup_free_ char *path = NULL;
5973 char *new_path, *tmp_path;
5975 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5981 // FIXME: support units with path==NULL (no FragmentPath)
5982 log_error("No fragment exists for %s.", *name);
5987 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5989 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5993 r = strv_push_pair(paths, new_path, tmp_path);
6001 static int edit(sd_bus *bus, char **args) {
6002 _cleanup_strv_free_ char **names = NULL;
6003 _cleanup_strv_free_ char **paths = NULL;
6004 char **original, **tmp;
6010 log_error("Cannot edit units if not on a tty");
6014 if (arg_transport != BUS_TRANSPORT_LOCAL) {
6015 log_error("Cannot remotely edit units");
6019 r = expand_names(bus, args + 1, NULL, &names);
6021 return log_error_errno(r, "Failed to expand names: %m");
6023 r = find_paths_to_edit(bus, names, &paths);
6027 if (strv_isempty(paths))
6030 r = run_editor(paths);
6034 STRV_FOREACH_PAIR(original, tmp, paths) {
6035 /* If the temporary file is empty we ignore it.
6036 * It's useful if the user wants to cancel its modification
6038 if (null_or_empty_path(*tmp)) {
6039 log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
6042 r = rename(*tmp, *original);
6044 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
6049 if (!arg_no_reload && bus && !avoid_bus())
6050 r = daemon_reload(bus, args);
6053 STRV_FOREACH_PAIR(original, tmp, paths)
6054 unlink_noerrno(*tmp);
6059 static void systemctl_help(void) {
6061 pager_open_if_enabled();
6063 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6064 "Query or send control commands to the systemd manager.\n\n"
6065 " -h --help Show this help\n"
6066 " --version Show package version\n"
6067 " --system Connect to system manager\n"
6068 " --user Connect to user service manager\n"
6069 " -H --host=[USER@]HOST\n"
6070 " Operate on remote host\n"
6071 " -M --machine=CONTAINER\n"
6072 " Operate on local container\n"
6073 " -t --type=TYPE List units of a particular type\n"
6074 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6075 " -p --property=NAME Show only properties by this name\n"
6076 " -a --all Show all loaded units/properties, including dead/empty\n"
6077 " ones. To list all units installed on the system, use\n"
6078 " the 'list-unit-files' command instead.\n"
6079 " -l --full Don't ellipsize unit names on output\n"
6080 " -r --recursive Show unit list of host and local containers\n"
6081 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6082 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6083 " queueing a new job\n"
6084 " --show-types When showing sockets, explicitly show their type\n"
6085 " -i --ignore-inhibitors\n"
6086 " When shutting down or sleeping, ignore inhibitors\n"
6087 " --kill-who=WHO Who to send signal to\n"
6088 " -s --signal=SIGNAL Which signal to send\n"
6089 " -q --quiet Suppress output\n"
6090 " --no-block Do not wait until operation finished\n"
6091 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6092 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6093 " --no-legend Do not print a legend (column headers and hints)\n"
6094 " --no-pager Do not pipe output into a pager\n"
6095 " --no-ask-password\n"
6096 " Do not ask for system passwords\n"
6097 " --global Enable/disable unit files globally\n"
6098 " --runtime Enable unit files only temporarily until next reboot\n"
6099 " -f --force When enabling unit files, override existing symlinks\n"
6100 " When shutting down, execute action immediately\n"
6101 " --preset-mode= Apply only enable, only disable, or all presets\n"
6102 " --root=PATH Enable unit files in the specified root directory\n"
6103 " -n --lines=INTEGER Number of journal entries to show\n"
6104 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6105 " short-precise, short-monotonic, verbose,\n"
6106 " export, json, json-pretty, json-sse, cat)\n"
6107 " --plain Print unit dependencies as a list instead of a tree\n\n"
6109 " list-units [PATTERN...] List loaded units\n"
6110 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6111 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6112 " start NAME... Start (activate) one or more units\n"
6113 " stop NAME... Stop (deactivate) one or more units\n"
6114 " reload NAME... Reload one or more units\n"
6115 " restart NAME... Start or restart one or more units\n"
6116 " try-restart NAME... Restart one or more units if active\n"
6117 " reload-or-restart NAME... Reload one or more units if possible,\n"
6118 " otherwise start or restart\n"
6119 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6120 " otherwise restart if active\n"
6121 " isolate NAME Start one unit and stop all others\n"
6122 " kill NAME... Send signal to processes of a unit\n"
6123 " is-active PATTERN... Check whether units are active\n"
6124 " is-failed PATTERN... Check whether units are failed\n"
6125 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6126 " show [PATTERN...|JOB...] Show properties of one or more\n"
6127 " units/jobs or the manager\n"
6128 " cat PATTERN... Show files and drop-ins of one or more units\n"
6129 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6130 " help PATTERN...|PID... Show manual for one or more units\n"
6131 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6133 " list-dependencies [NAME] Recursively show units which are required\n"
6134 " or wanted by this unit or by which this\n"
6135 " unit is required or wanted\n\n"
6136 "Unit File Commands:\n"
6137 " list-unit-files [PATTERN...] List installed unit files\n"
6138 " enable NAME... Enable one or more unit files\n"
6139 " disable NAME... Disable one or more unit files\n"
6140 " reenable NAME... Reenable one or more unit files\n"
6141 " preset NAME... Enable/disable one or more unit files\n"
6142 " based on preset configuration\n"
6143 " preset-all Enable/disable all unit files based on\n"
6144 " preset configuration\n"
6145 " is-enabled NAME... Check whether unit files are enabled\n"
6146 " mask NAME... Mask one or more units\n"
6147 " unmask NAME... Unmask one or more units\n"
6148 " link PATH... Link one or more units files into\n"
6149 " the search path\n"
6150 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6151 " on specified one or more units\n"
6152 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6153 " on specified one or more units\n"
6154 " edit NAME... Edit one or more unit files\n"
6155 " get-default Get the name of the default target\n"
6156 " set-default NAME Set the default target\n\n"
6157 "Machine Commands:\n"
6158 " list-machines [PATTERN...] List local containers and host\n\n"
6160 " list-jobs [PATTERN...] List jobs\n"
6161 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6162 "Snapshot Commands:\n"
6163 " snapshot [NAME] Create a snapshot\n"
6164 " delete NAME... Remove one or more snapshots\n\n"
6165 "Environment Commands:\n"
6166 " show-environment Dump environment\n"
6167 " set-environment NAME=VALUE... Set one or more environment variables\n"
6168 " unset-environment NAME... Unset one or more environment variables\n"
6169 " import-environment [NAME...] Import all or some environment variables\n\n"
6170 "Manager Lifecycle Commands:\n"
6171 " daemon-reload Reload systemd manager configuration\n"
6172 " daemon-reexec Reexecute systemd manager\n\n"
6173 "System Commands:\n"
6174 " is-system-running Check whether system is fully running\n"
6175 " default Enter system default mode\n"
6176 " rescue Enter system rescue mode\n"
6177 " emergency Enter system emergency mode\n"
6178 " halt Shut down and halt the system\n"
6179 " poweroff Shut down and power-off the system\n"
6180 " reboot [ARG] Shut down and reboot the system\n"
6181 " kexec Shut down and reboot the system with kexec\n"
6182 " exit Request user instance exit\n"
6183 " switch-root ROOT [INIT] Change to a different root file system\n"
6184 " suspend Suspend the system\n"
6185 " hibernate Hibernate the system\n"
6186 " hybrid-sleep Hibernate and suspend the system\n",
6187 program_invocation_short_name);
6190 static void halt_help(void) {
6191 printf("%s [OPTIONS...]%s\n\n"
6192 "%s the system.\n\n"
6193 " --help Show this help\n"
6194 " --halt Halt the machine\n"
6195 " -p --poweroff Switch off the machine\n"
6196 " --reboot Reboot the machine\n"
6197 " -f --force Force immediate halt/power-off/reboot\n"
6198 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6199 " -d --no-wtmp Don't write wtmp record\n"
6200 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6201 program_invocation_short_name,
6202 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6203 arg_action == ACTION_REBOOT ? "Reboot" :
6204 arg_action == ACTION_POWEROFF ? "Power off" :
6208 static void shutdown_help(void) {
6209 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6210 "Shut down the system.\n\n"
6211 " --help Show this help\n"
6212 " -H --halt Halt the machine\n"
6213 " -P --poweroff Power-off the machine\n"
6214 " -r --reboot Reboot the machine\n"
6215 " -h Equivalent to --poweroff, overridden by --halt\n"
6216 " -k Don't halt/power-off/reboot, just send warnings\n"
6217 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6218 " -c Cancel a pending shutdown\n",
6219 program_invocation_short_name);
6222 static void telinit_help(void) {
6223 printf("%s [OPTIONS...] {COMMAND}\n\n"
6224 "Send control commands to the init daemon.\n\n"
6225 " --help Show this help\n"
6226 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6228 " 0 Power-off the machine\n"
6229 " 6 Reboot the machine\n"
6230 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6231 " 1, s, S Enter rescue mode\n"
6232 " q, Q Reload init daemon configuration\n"
6233 " u, U Reexecute init daemon\n",
6234 program_invocation_short_name);
6237 static void runlevel_help(void) {
6238 printf("%s [OPTIONS...]\n\n"
6239 "Prints the previous and current runlevel of the init system.\n\n"
6240 " --help Show this help\n",
6241 program_invocation_short_name);
6244 static void help_types(void) {
6249 puts("Available unit types:");
6250 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6251 t = unit_type_to_string(i);
6257 static int systemctl_parse_argv(int argc, char *argv[]) {
6266 ARG_IGNORE_DEPENDENCIES,
6278 ARG_NO_ASK_PASSWORD,
6288 static const struct option options[] = {
6289 { "help", no_argument, NULL, 'h' },
6290 { "version", no_argument, NULL, ARG_VERSION },
6291 { "type", required_argument, NULL, 't' },
6292 { "property", required_argument, NULL, 'p' },
6293 { "all", no_argument, NULL, 'a' },
6294 { "reverse", no_argument, NULL, ARG_REVERSE },
6295 { "after", no_argument, NULL, ARG_AFTER },
6296 { "before", no_argument, NULL, ARG_BEFORE },
6297 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6298 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6299 { "full", no_argument, NULL, 'l' },
6300 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6301 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6302 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6303 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6304 { "ignore-inhibitors", no_argument, NULL, 'i' },
6305 { "user", no_argument, NULL, ARG_USER },
6306 { "system", no_argument, NULL, ARG_SYSTEM },
6307 { "global", no_argument, NULL, ARG_GLOBAL },
6308 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6309 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6310 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6311 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6312 { "quiet", no_argument, NULL, 'q' },
6313 { "root", required_argument, NULL, ARG_ROOT },
6314 { "force", no_argument, NULL, ARG_FORCE },
6315 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6316 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6317 { "signal", required_argument, NULL, 's' },
6318 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6319 { "host", required_argument, NULL, 'H' },
6320 { "machine", required_argument, NULL, 'M' },
6321 { "runtime", no_argument, NULL, ARG_RUNTIME },
6322 { "lines", required_argument, NULL, 'n' },
6323 { "output", required_argument, NULL, 'o' },
6324 { "plain", no_argument, NULL, ARG_PLAIN },
6325 { "state", required_argument, NULL, ARG_STATE },
6326 { "recursive", no_argument, NULL, 'r' },
6327 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6336 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6345 puts(PACKAGE_STRING);
6346 puts(SYSTEMD_FEATURES);
6350 const char *word, *state;
6353 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6354 _cleanup_free_ char *type;
6356 type = strndup(word, size);
6360 if (streq(type, "help")) {
6365 if (unit_type_from_string(type) >= 0) {
6366 if (strv_push(&arg_types, type))
6372 /* It's much nicer to use --state= for
6373 * load states, but let's support this
6374 * in --types= too for compatibility
6375 * with old versions */
6376 if (unit_load_state_from_string(optarg) >= 0) {
6377 if (strv_push(&arg_states, type) < 0)
6383 log_error("Unknown unit type or load state '%s'.", type);
6384 log_info("Use -t help to see a list of allowed values.");
6392 /* Make sure that if the empty property list
6393 was specified, we won't show any properties. */
6394 if (isempty(optarg) && !arg_properties) {
6395 arg_properties = new0(char*, 1);
6396 if (!arg_properties)
6399 const char *word, *state;
6402 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6405 prop = strndup(word, size);
6409 if (strv_consume(&arg_properties, prop) < 0)
6414 /* If the user asked for a particular
6415 * property, show it to him, even if it is
6427 arg_dependency = DEPENDENCY_REVERSE;
6431 arg_dependency = DEPENDENCY_AFTER;
6435 arg_dependency = DEPENDENCY_BEFORE;
6438 case ARG_SHOW_TYPES:
6439 arg_show_types = true;
6443 arg_job_mode = optarg;
6447 arg_job_mode = "fail";
6450 case ARG_IRREVERSIBLE:
6451 arg_job_mode = "replace-irreversibly";
6454 case ARG_IGNORE_DEPENDENCIES:
6455 arg_job_mode = "ignore-dependencies";
6459 arg_scope = UNIT_FILE_USER;
6463 arg_scope = UNIT_FILE_SYSTEM;
6467 arg_scope = UNIT_FILE_GLOBAL;
6471 arg_no_block = true;
6475 arg_no_legend = true;
6479 arg_no_pager = true;
6495 if (strv_extend(&arg_states, "failed") < 0)
6513 arg_no_reload = true;
6517 arg_kill_who = optarg;
6521 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6522 log_error("Failed to parse signal string %s.", optarg);
6527 case ARG_NO_ASK_PASSWORD:
6528 arg_ask_password = false;
6532 arg_transport = BUS_TRANSPORT_REMOTE;
6537 arg_transport = BUS_TRANSPORT_MACHINE;
6546 if (safe_atou(optarg, &arg_lines) < 0) {
6547 log_error("Failed to parse lines '%s'", optarg);
6553 arg_output = output_mode_from_string(optarg);
6554 if (arg_output < 0) {
6555 log_error("Unknown output '%s'.", optarg);
6561 arg_ignore_inhibitors = true;
6569 const char *word, *state;
6572 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6575 s = strndup(word, size);
6579 if (strv_consume(&arg_states, s) < 0)
6586 if (geteuid() != 0) {
6587 log_error("--recursive requires root privileges.");
6591 arg_recursive = true;
6594 case ARG_PRESET_MODE:
6596 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6597 if (arg_preset_mode < 0) {
6598 log_error("Failed to parse preset mode: %s.", optarg);
6608 assert_not_reached("Unhandled option");
6611 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6612 log_error("Cannot access user instance remotely.");
6619 static int halt_parse_argv(int argc, char *argv[]) {
6628 static const struct option options[] = {
6629 { "help", no_argument, NULL, ARG_HELP },
6630 { "halt", no_argument, NULL, ARG_HALT },
6631 { "poweroff", no_argument, NULL, 'p' },
6632 { "reboot", no_argument, NULL, ARG_REBOOT },
6633 { "force", no_argument, NULL, 'f' },
6634 { "wtmp-only", no_argument, NULL, 'w' },
6635 { "no-wtmp", no_argument, NULL, 'd' },
6636 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6645 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6646 if (runlevel == '0' || runlevel == '6')
6649 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6657 arg_action = ACTION_HALT;
6661 if (arg_action != ACTION_REBOOT)
6662 arg_action = ACTION_POWEROFF;
6666 arg_action = ACTION_REBOOT;
6688 /* Compatibility nops */
6695 assert_not_reached("Unhandled option");
6698 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6699 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6702 } else if (optind < argc) {
6703 log_error("Too many arguments.");
6710 static int parse_time_spec(const char *t, usec_t *_u) {
6714 if (streq(t, "now"))
6716 else if (!strchr(t, ':')) {
6719 if (safe_atou64(t, &u) < 0)
6722 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6731 hour = strtol(t, &e, 10);
6732 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6735 minute = strtol(e+1, &e, 10);
6736 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6739 n = now(CLOCK_REALTIME);
6740 s = (time_t) (n / USEC_PER_SEC);
6742 assert_se(localtime_r(&s, &tm));
6744 tm.tm_hour = (int) hour;
6745 tm.tm_min = (int) minute;
6748 assert_se(s = mktime(&tm));
6750 *_u = (usec_t) s * USEC_PER_SEC;
6753 *_u += USEC_PER_DAY;
6759 static int shutdown_parse_argv(int argc, char *argv[]) {
6766 static const struct option options[] = {
6767 { "help", no_argument, NULL, ARG_HELP },
6768 { "halt", no_argument, NULL, 'H' },
6769 { "poweroff", no_argument, NULL, 'P' },
6770 { "reboot", no_argument, NULL, 'r' },
6771 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6772 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6781 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6789 arg_action = ACTION_HALT;
6793 arg_action = ACTION_POWEROFF;
6798 arg_action = ACTION_KEXEC;
6800 arg_action = ACTION_REBOOT;
6804 arg_action = ACTION_KEXEC;
6808 if (arg_action != ACTION_HALT)
6809 arg_action = ACTION_POWEROFF;
6824 /* Compatibility nops */
6828 arg_action = ACTION_CANCEL_SHUTDOWN;
6835 assert_not_reached("Unhandled option");
6838 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6839 r = parse_time_spec(argv[optind], &arg_when);
6841 log_error("Failed to parse time specification: %s", argv[optind]);
6845 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6847 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6848 /* No time argument for shutdown cancel */
6849 arg_wall = argv + optind;
6850 else if (argc > optind + 1)
6851 /* We skip the time argument */
6852 arg_wall = argv + optind + 1;
6859 static int telinit_parse_argv(int argc, char *argv[]) {
6866 static const struct option options[] = {
6867 { "help", no_argument, NULL, ARG_HELP },
6868 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6872 static const struct {
6876 { '0', ACTION_POWEROFF },
6877 { '6', ACTION_REBOOT },
6878 { '1', ACTION_RESCUE },
6879 { '2', ACTION_RUNLEVEL2 },
6880 { '3', ACTION_RUNLEVEL3 },
6881 { '4', ACTION_RUNLEVEL4 },
6882 { '5', ACTION_RUNLEVEL5 },
6883 { 's', ACTION_RESCUE },
6884 { 'S', ACTION_RESCUE },
6885 { 'q', ACTION_RELOAD },
6886 { 'Q', ACTION_RELOAD },
6887 { 'u', ACTION_REEXEC },
6888 { 'U', ACTION_REEXEC }
6897 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6912 assert_not_reached("Unhandled option");
6915 if (optind >= argc) {
6916 log_error("%s: required argument missing.",
6917 program_invocation_short_name);
6921 if (optind + 1 < argc) {
6922 log_error("Too many arguments.");
6926 if (strlen(argv[optind]) != 1) {
6927 log_error("Expected single character argument.");
6931 for (i = 0; i < ELEMENTSOF(table); i++)
6932 if (table[i].from == argv[optind][0])
6935 if (i >= ELEMENTSOF(table)) {
6936 log_error("Unknown command '%s'.", argv[optind]);
6940 arg_action = table[i].to;
6947 static int runlevel_parse_argv(int argc, char *argv[]) {
6953 static const struct option options[] = {
6954 { "help", no_argument, NULL, ARG_HELP },
6963 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6974 assert_not_reached("Unhandled option");
6977 if (optind < argc) {
6978 log_error("Too many arguments.");
6985 static int parse_argv(int argc, char *argv[]) {
6989 if (program_invocation_short_name) {
6991 if (strstr(program_invocation_short_name, "halt")) {
6992 arg_action = ACTION_HALT;
6993 return halt_parse_argv(argc, argv);
6994 } else if (strstr(program_invocation_short_name, "poweroff")) {
6995 arg_action = ACTION_POWEROFF;
6996 return halt_parse_argv(argc, argv);
6997 } else if (strstr(program_invocation_short_name, "reboot")) {
6999 arg_action = ACTION_KEXEC;
7001 arg_action = ACTION_REBOOT;
7002 return halt_parse_argv(argc, argv);
7003 } else if (strstr(program_invocation_short_name, "shutdown")) {
7004 arg_action = ACTION_POWEROFF;
7005 return shutdown_parse_argv(argc, argv);
7006 } else if (strstr(program_invocation_short_name, "init")) {
7008 if (sd_booted() > 0) {
7009 arg_action = _ACTION_INVALID;
7010 return telinit_parse_argv(argc, argv);
7012 /* Hmm, so some other init system is
7013 * running, we need to forward this
7014 * request to it. For now we simply
7015 * guess that it is Upstart. */
7017 execv(TELINIT, argv);
7019 log_error("Couldn't find an alternative telinit implementation to spawn.");
7023 } else if (strstr(program_invocation_short_name, "runlevel")) {
7024 arg_action = ACTION_RUNLEVEL;
7025 return runlevel_parse_argv(argc, argv);
7029 arg_action = ACTION_SYSTEMCTL;
7030 return systemctl_parse_argv(argc, argv);
7033 _pure_ static int action_to_runlevel(void) {
7035 static const char table[_ACTION_MAX] = {
7036 [ACTION_HALT] = '0',
7037 [ACTION_POWEROFF] = '0',
7038 [ACTION_REBOOT] = '6',
7039 [ACTION_RUNLEVEL2] = '2',
7040 [ACTION_RUNLEVEL3] = '3',
7041 [ACTION_RUNLEVEL4] = '4',
7042 [ACTION_RUNLEVEL5] = '5',
7043 [ACTION_RESCUE] = '1'
7046 assert(arg_action < _ACTION_MAX);
7048 return table[arg_action];
7051 static int talk_initctl(void) {
7053 struct init_request request = {
7054 .magic = INIT_MAGIC,
7056 .cmd = INIT_CMD_RUNLVL
7059 _cleanup_close_ int fd = -1;
7063 rl = action_to_runlevel();
7067 request.runlevel = rl;
7069 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7071 if (errno == ENOENT)
7074 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7078 r = loop_write(fd, &request, sizeof(request), false);
7080 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7085 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7087 static const struct {
7095 int (* const dispatch)(sd_bus *bus, char **args);
7101 { "list-units", MORE, 0, list_units },
7102 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7103 { "list-sockets", MORE, 1, list_sockets },
7104 { "list-timers", MORE, 1, list_timers },
7105 { "list-jobs", MORE, 1, list_jobs },
7106 { "list-machines", MORE, 1, list_machines },
7107 { "clear-jobs", EQUAL, 1, daemon_reload },
7108 { "cancel", MORE, 2, cancel_job },
7109 { "start", MORE, 2, start_unit },
7110 { "stop", MORE, 2, start_unit },
7111 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7112 { "reload", MORE, 2, start_unit },
7113 { "restart", MORE, 2, start_unit },
7114 { "try-restart", MORE, 2, start_unit },
7115 { "reload-or-restart", MORE, 2, start_unit },
7116 { "reload-or-try-restart", MORE, 2, start_unit },
7117 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7118 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7119 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7120 { "isolate", EQUAL, 2, start_unit },
7121 { "kill", MORE, 2, kill_unit },
7122 { "is-active", MORE, 2, check_unit_active },
7123 { "check", MORE, 2, check_unit_active },
7124 { "is-failed", MORE, 2, check_unit_failed },
7125 { "show", MORE, 1, show },
7126 { "cat", MORE, 2, cat, NOBUS },
7127 { "status", MORE, 1, show },
7128 { "help", MORE, 2, show },
7129 { "snapshot", LESS, 2, snapshot },
7130 { "delete", MORE, 2, delete_snapshot },
7131 { "daemon-reload", EQUAL, 1, daemon_reload },
7132 { "daemon-reexec", EQUAL, 1, daemon_reload },
7133 { "show-environment", EQUAL, 1, show_environment },
7134 { "set-environment", MORE, 2, set_environment },
7135 { "unset-environment", MORE, 2, set_environment },
7136 { "import-environment", MORE, 1, import_environment},
7137 { "halt", EQUAL, 1, start_special, FORCE },
7138 { "poweroff", EQUAL, 1, start_special, FORCE },
7139 { "reboot", MORE, 1, start_special, FORCE },
7140 { "kexec", EQUAL, 1, start_special },
7141 { "suspend", EQUAL, 1, start_special },
7142 { "hibernate", EQUAL, 1, start_special },
7143 { "hybrid-sleep", EQUAL, 1, start_special },
7144 { "default", EQUAL, 1, start_special },
7145 { "rescue", EQUAL, 1, start_special },
7146 { "emergency", EQUAL, 1, start_special },
7147 { "exit", EQUAL, 1, start_special },
7148 { "reset-failed", MORE, 1, reset_failed },
7149 { "enable", MORE, 2, enable_unit, NOBUS },
7150 { "disable", MORE, 2, enable_unit, NOBUS },
7151 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7152 { "reenable", MORE, 2, enable_unit, NOBUS },
7153 { "preset", MORE, 2, enable_unit, NOBUS },
7154 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7155 { "mask", MORE, 2, enable_unit, NOBUS },
7156 { "unmask", MORE, 2, enable_unit, NOBUS },
7157 { "link", MORE, 2, enable_unit, NOBUS },
7158 { "switch-root", MORE, 2, switch_root },
7159 { "list-dependencies", LESS, 2, list_dependencies },
7160 { "set-default", EQUAL, 2, set_default, NOBUS },
7161 { "get-default", EQUAL, 1, get_default, NOBUS },
7162 { "set-property", MORE, 3, set_property },
7163 { "is-system-running", EQUAL, 1, is_system_running },
7164 { "add-wants", MORE, 3, add_dependency, NOBUS },
7165 { "add-requires", MORE, 3, add_dependency, NOBUS },
7166 { "edit", MORE, 2, edit, NOBUS },
7175 left = argc - optind;
7177 /* Special rule: no arguments (left == 0) means "list-units" */
7179 if (streq(argv[optind], "help") && !argv[optind+1]) {
7180 log_error("This command expects one or more "
7181 "unit names. Did you mean --help?");
7185 for (; verb->verb; verb++)
7186 if (streq(argv[optind], verb->verb))
7189 log_error("Unknown operation '%s'.", argv[optind]);
7194 switch (verb->argc_cmp) {
7197 if (left != verb->argc) {
7198 log_error("Invalid number of arguments.");
7205 if (left < verb->argc) {
7206 log_error("Too few arguments.");
7213 if (left > verb->argc) {
7214 log_error("Too many arguments.");
7221 assert_not_reached("Unknown comparison operator.");
7224 /* Require a bus connection for all operations but
7226 if (verb->bus == NOBUS) {
7227 if (!bus && !avoid_bus()) {
7228 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7233 if (running_in_chroot() > 0) {
7234 log_info("Running in chroot, ignoring request.");
7238 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7239 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7244 return verb->dispatch(bus, argv + optind);
7247 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7249 struct sd_shutdown_command c = {
7256 union sockaddr_union sockaddr = {
7257 .un.sun_family = AF_UNIX,
7258 .un.sun_path = "/run/systemd/shutdownd",
7261 struct iovec iovec[2] = {{
7262 .iov_base = (char*) &c,
7263 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7266 struct msghdr msghdr = {
7267 .msg_name = &sockaddr,
7268 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7269 + strlen("/run/systemd/shutdownd"),
7274 _cleanup_close_ int fd;
7276 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7280 if (!isempty(message)) {
7281 iovec[1].iov_base = (char*) message;
7282 iovec[1].iov_len = strlen(message);
7283 msghdr.msg_iovlen++;
7286 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7292 static int reload_with_fallback(sd_bus *bus) {
7295 /* First, try systemd via D-Bus. */
7296 if (daemon_reload(bus, NULL) >= 0)
7300 /* Nothing else worked, so let's try signals */
7301 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7303 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7304 return log_error_errno(errno, "kill() failed: %m");
7309 static int start_with_fallback(sd_bus *bus) {
7312 /* First, try systemd via D-Bus. */
7313 if (start_unit(bus, NULL) >= 0)
7317 /* Nothing else worked, so let's try
7319 if (talk_initctl() > 0)
7322 log_error("Failed to talk to init daemon.");
7326 warn_wall(arg_action);
7330 static int halt_now(enum action a) {
7332 /* The kernel will automaticall flush ATA disks and suchlike
7333 * on reboot(), but the file systems need to be synce'd
7334 * explicitly in advance. */
7337 /* Make sure C-A-D is handled by the kernel from this point
7339 reboot(RB_ENABLE_CAD);
7344 log_info("Halting.");
7345 reboot(RB_HALT_SYSTEM);
7348 case ACTION_POWEROFF:
7349 log_info("Powering off.");
7350 reboot(RB_POWER_OFF);
7353 case ACTION_REBOOT: {
7354 _cleanup_free_ char *param = NULL;
7356 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7357 log_info("Rebooting with argument '%s'.", param);
7358 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7359 LINUX_REBOOT_CMD_RESTART2, param);
7362 log_info("Rebooting.");
7363 reboot(RB_AUTOBOOT);
7368 assert_not_reached("Unknown action.");
7372 static int halt_main(sd_bus *bus) {
7375 r = check_inhibitors(bus, arg_action);
7379 if (geteuid() != 0) {
7380 /* Try logind if we are a normal user and no special
7381 * mode applies. Maybe PolicyKit allows us to shutdown
7384 if (arg_when <= 0 &&
7387 (arg_action == ACTION_POWEROFF ||
7388 arg_action == ACTION_REBOOT)) {
7389 r = reboot_with_logind(bus, arg_action);
7394 log_error("Must be root.");
7399 _cleanup_free_ char *m;
7401 m = strv_join(arg_wall, " ");
7405 r = send_shutdownd(arg_when,
7406 arg_action == ACTION_HALT ? 'H' :
7407 arg_action == ACTION_POWEROFF ? 'P' :
7408 arg_action == ACTION_KEXEC ? 'K' :
7415 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7417 char date[FORMAT_TIMESTAMP_MAX];
7419 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7420 format_timestamp(date, sizeof(date), arg_when));
7425 if (!arg_dry && !arg_force)
7426 return start_with_fallback(bus);
7429 if (sd_booted() > 0)
7430 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7432 r = utmp_put_shutdown();
7434 log_warning_errno(r, "Failed to write utmp record: %m");
7441 r = halt_now(arg_action);
7442 log_error_errno(r, "Failed to reboot: %m");
7447 static int runlevel_main(void) {
7448 int r, runlevel, previous;
7450 r = utmp_get_runlevel(&runlevel, &previous);
7457 previous <= 0 ? 'N' : previous,
7458 runlevel <= 0 ? 'N' : runlevel);
7463 int main(int argc, char*argv[]) {
7464 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7467 setlocale(LC_ALL, "");
7468 log_parse_environment();
7471 /* Explicitly not on_tty() to avoid setting cached value.
7472 * This becomes relevant for piping output which might be
7474 original_stdout_is_tty = isatty(STDOUT_FILENO);
7476 r = parse_argv(argc, argv);
7480 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7481 * let's shortcut this */
7482 if (arg_action == ACTION_RUNLEVEL) {
7483 r = runlevel_main();
7487 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7488 log_info("Running in chroot, ignoring request.");
7493 /* Increase max number of open files to 16K if we can, we
7494 * might needs this when browsing journal files, which might
7495 * be split up into many files. */
7496 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7499 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7501 /* systemctl_main() will print an error message for the bus
7502 * connection, but only if it needs to */
7504 switch (arg_action) {
7506 case ACTION_SYSTEMCTL:
7507 r = systemctl_main(bus, argc, argv, r);
7511 case ACTION_POWEROFF:
7517 case ACTION_RUNLEVEL2:
7518 case ACTION_RUNLEVEL3:
7519 case ACTION_RUNLEVEL4:
7520 case ACTION_RUNLEVEL5:
7522 case ACTION_EMERGENCY:
7523 case ACTION_DEFAULT:
7524 r = start_with_fallback(bus);
7529 r = reload_with_fallback(bus);
7532 case ACTION_CANCEL_SHUTDOWN: {
7533 _cleanup_free_ char *m = NULL;
7536 m = strv_join(arg_wall, " ");
7543 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7545 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7549 case ACTION_RUNLEVEL:
7550 case _ACTION_INVALID:
7552 assert_not_reached("Unknown action");
7557 ask_password_agent_close();
7558 polkit_agent_close();
7560 strv_free(arg_types);
7561 strv_free(arg_states);
7562 strv_free(arg_properties);
7564 return r < 0 ? EXIT_FAILURE : r;