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) {
2299 * Finds where the unit is defined on disk. Returns 0 if the unit
2300 * is not found. Returns 1 if it is found, and sets
2301 * - the path to the unit in *path, if it exists on disk,
2302 * - and a strv of existing drop-ins in *dropins,
2303 * if the arg is not NULL and any dropins were found.
2307 assert(fragment_path);
2310 if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2311 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2312 _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
2313 _cleanup_free_ char *unit = NULL;
2314 _cleanup_free_ char *path = NULL;
2315 _cleanup_strv_free_ char **dropins = NULL;
2316 _cleanup_strv_free_ char **load_error = 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));
2362 r = sd_bus_get_property_strv(
2364 "org.freedesktop.systemd1",
2366 "org.freedesktop.systemd1.Unit",
2371 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2374 if (!isempty(path)) {
2375 *fragment_path = path;
2380 if (dropin_paths && !strv_isempty(dropins)) {
2381 *dropin_paths = dropins;
2386 _cleanup_set_free_ Set *names;
2388 names = set_new(NULL);
2392 r = set_put(names, unit_name);
2396 r = unit_file_find_path(lp, unit_name, fragment_path);
2401 _cleanup_free_ char *template;
2403 template = unit_name_template(unit_name);
2407 if (!streq(template, unit_name)) {
2408 r = unit_file_find_path(lp, template, fragment_path);
2415 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
2419 log_error("No files found for %s.", unit_name);
2424 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2425 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2426 _cleanup_free_ char *n = NULL, *state = NULL;
2432 n = unit_name_mangle(name, MANGLE_NOGLOB);
2436 /* We don't use unit_dbus_path_from_name() directly since we
2437 * don't want to load the unit if it isn't loaded. */
2439 r = sd_bus_call_method(
2441 "org.freedesktop.systemd1",
2442 "/org/freedesktop/systemd1",
2443 "org.freedesktop.systemd1.Manager",
2454 r = sd_bus_message_read(reply, "o", &path);
2456 return bus_log_parse_error(r);
2458 r = sd_bus_get_property_string(
2460 "org.freedesktop.systemd1",
2462 "org.freedesktop.systemd1.Unit",
2475 return nulstr_contains(good_states, state);
2478 static int check_triggering_units(
2482 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2483 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2484 _cleanup_strv_free_ char **triggered_by = NULL;
2485 bool print_warning_label = true;
2489 n = unit_name_mangle(name, MANGLE_NOGLOB);
2493 path = unit_dbus_path_from_name(n);
2497 r = sd_bus_get_property_string(
2499 "org.freedesktop.systemd1",
2501 "org.freedesktop.systemd1.Unit",
2506 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2510 if (streq(state, "masked"))
2513 r = sd_bus_get_property_strv(
2515 "org.freedesktop.systemd1",
2517 "org.freedesktop.systemd1.Unit",
2522 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2526 STRV_FOREACH(i, triggered_by) {
2527 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2529 return log_error_errno(r, "Failed to check unit: %m");
2534 if (print_warning_label) {
2535 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2536 print_warning_label = false;
2539 log_warning(" %s", *i);
2545 static const struct {
2548 } unit_actions[] = {
2549 { "start", "StartUnit" },
2550 { "stop", "StopUnit" },
2551 { "condstop", "StopUnit" },
2552 { "reload", "ReloadUnit" },
2553 { "restart", "RestartUnit" },
2554 { "try-restart", "TryRestartUnit" },
2555 { "condrestart", "TryRestartUnit" },
2556 { "reload-or-restart", "ReloadOrRestartUnit" },
2557 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2558 { "condreload", "ReloadOrTryRestartUnit" },
2559 { "force-reload", "ReloadOrTryRestartUnit" }
2562 static const char *verb_to_method(const char *verb) {
2565 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2566 if (streq_ptr(unit_actions[i].verb, verb))
2567 return unit_actions[i].method;
2572 static const char *method_to_verb(const char *method) {
2575 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2576 if (streq_ptr(unit_actions[i].method, method))
2577 return unit_actions[i].verb;
2582 static int start_unit_one(
2587 sd_bus_error *error,
2588 BusWaitForJobs *w) {
2590 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2599 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2601 r = sd_bus_message_new_method_call(
2604 "org.freedesktop.systemd1",
2605 "/org/freedesktop/systemd1",
2606 "org.freedesktop.systemd1.Manager",
2609 return bus_log_create_error(r);
2611 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2613 return bus_log_create_error(r);
2615 r = sd_bus_message_append(m, "ss", name, mode);
2617 return bus_log_create_error(r);
2619 r = sd_bus_call(bus, m, 0, error, &reply);
2623 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2624 /* There's always a fallback possible for
2625 * legacy actions. */
2626 return -EADDRNOTAVAIL;
2628 verb = method_to_verb(method);
2630 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2634 r = sd_bus_message_read(reply, "o", &path);
2636 return bus_log_parse_error(r);
2638 if (need_daemon_reload(bus, name) > 0)
2639 warn_unit_file_changed(name);
2642 log_debug("Adding %s to the set", path);
2643 r = bus_wait_for_jobs_add(w, path);
2651 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2653 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2657 STRV_FOREACH(name, names) {
2661 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2663 t = unit_name_mangle(*name, MANGLE_GLOB);
2667 if (string_is_glob(t))
2668 r = strv_consume(&globs, t);
2670 r = strv_consume(&mangled, t);
2675 /* Query the manager only if any of the names are a glob, since
2676 * this is fairly expensive */
2677 if (!strv_isempty(globs)) {
2678 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2679 _cleanup_free_ UnitInfo *unit_infos = NULL;
2682 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2684 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2688 for (i = 0; i < r; i++)
2689 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2694 mangled = NULL; /* do not free */
2699 static const struct {
2703 } action_table[_ACTION_MAX] = {
2704 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2705 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2706 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2707 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2708 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2709 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2710 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2711 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2712 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2713 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2714 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2715 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2716 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2717 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2718 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2721 static enum action verb_to_action(const char *verb) {
2724 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2725 if (streq_ptr(action_table[i].verb, verb))
2728 return _ACTION_INVALID;
2731 static int start_unit(sd_bus *bus, char **args) {
2732 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2733 const char *method, *mode, *one_name, *suffix = NULL;
2734 _cleanup_strv_free_ char **names = NULL;
2740 ask_password_agent_open_if_enabled();
2741 polkit_agent_open_if_enabled();
2743 if (arg_action == ACTION_SYSTEMCTL) {
2745 method = verb_to_method(args[0]);
2746 action = verb_to_action(args[0]);
2748 if (streq(args[0], "isolate")) {
2752 mode = action_table[action].mode ?: arg_job_mode;
2754 one_name = action_table[action].target;
2756 assert(arg_action < ELEMENTSOF(action_table));
2757 assert(action_table[arg_action].target);
2759 method = "StartUnit";
2761 mode = action_table[arg_action].mode;
2762 one_name = action_table[arg_action].target;
2766 names = strv_new(one_name, NULL);
2768 r = expand_names(bus, args + 1, suffix, &names);
2770 log_error_errno(r, "Failed to expand names: %m");
2773 if (!arg_no_block) {
2774 r = bus_wait_for_jobs_new(bus, &w);
2776 return log_error_errno(r, "Could not watch jobs: %m");
2779 STRV_FOREACH(name, names) {
2780 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2783 q = start_unit_one(bus, method, *name, mode, &error, w);
2784 if (r >= 0 && q < 0)
2785 r = translate_bus_error_to_exit_status(q, &error);
2788 if (!arg_no_block) {
2791 q = bus_wait_for_jobs(w, arg_quiet);
2795 /* When stopping units, warn if they can still be triggered by
2796 * another active unit (socket, path, timer) */
2797 if (!arg_quiet && streq(method, "StopUnit"))
2798 STRV_FOREACH(name, names)
2799 check_triggering_units(bus, *name);
2805 /* Ask systemd-logind, which might grant access to unprivileged users
2806 * through PolicyKit */
2807 static int reboot_with_logind(sd_bus *bus, enum action a) {
2809 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2816 polkit_agent_open_if_enabled();
2824 case ACTION_POWEROFF:
2825 method = "PowerOff";
2828 case ACTION_SUSPEND:
2832 case ACTION_HIBERNATE:
2833 method = "Hibernate";
2836 case ACTION_HYBRID_SLEEP:
2837 method = "HybridSleep";
2844 r = sd_bus_call_method(
2846 "org.freedesktop.login1",
2847 "/org/freedesktop/login1",
2848 "org.freedesktop.login1.Manager",
2852 "b", arg_ask_password);
2854 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2862 static int check_inhibitors(sd_bus *bus, enum action a) {
2864 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2865 _cleanup_strv_free_ char **sessions = NULL;
2866 const char *what, *who, *why, *mode;
2875 if (arg_ignore_inhibitors || arg_force > 0)
2887 r = sd_bus_call_method(
2889 "org.freedesktop.login1",
2890 "/org/freedesktop/login1",
2891 "org.freedesktop.login1.Manager",
2897 /* If logind is not around, then there are no inhibitors... */
2900 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2902 return bus_log_parse_error(r);
2904 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2905 _cleanup_free_ char *comm = NULL, *user = NULL;
2906 _cleanup_strv_free_ char **sv = NULL;
2908 if (!streq(mode, "block"))
2911 sv = strv_split(what, ":");
2915 if (!strv_contains(sv,
2917 a == ACTION_POWEROFF ||
2918 a == ACTION_REBOOT ||
2919 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2922 get_process_comm(pid, &comm);
2923 user = uid_to_name(uid);
2925 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2926 who, pid, strna(comm), strna(user), why);
2931 return bus_log_parse_error(r);
2933 r = sd_bus_message_exit_container(reply);
2935 return bus_log_parse_error(r);
2937 /* Check for current sessions */
2938 sd_get_sessions(&sessions);
2939 STRV_FOREACH(s, sessions) {
2940 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2942 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2945 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2948 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2951 sd_session_get_tty(*s, &tty);
2952 sd_session_get_seat(*s, &seat);
2953 sd_session_get_service(*s, &service);
2954 user = uid_to_name(uid);
2956 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2963 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2964 action_table[a].verb);
2972 static int start_special(sd_bus *bus, char **args) {
2978 a = verb_to_action(args[0]);
2980 r = check_inhibitors(bus, a);
2984 if (arg_force >= 2 && geteuid() != 0) {
2985 log_error("Must be root.");
2989 if (a == ACTION_REBOOT) {
2990 r = update_reboot_param_file(args[1]);
2995 if (arg_force >= 2 &&
2996 (a == ACTION_HALT ||
2997 a == ACTION_POWEROFF ||
2998 a == ACTION_REBOOT))
3001 if (arg_force >= 1 &&
3002 (a == ACTION_HALT ||
3003 a == ACTION_POWEROFF ||
3004 a == ACTION_REBOOT ||
3005 a == ACTION_KEXEC ||
3007 return daemon_reload(bus, args);
3009 /* first try logind, to allow authentication with polkit */
3010 if (geteuid() != 0 &&
3011 (a == ACTION_POWEROFF ||
3012 a == ACTION_REBOOT ||
3013 a == ACTION_SUSPEND ||
3014 a == ACTION_HIBERNATE ||
3015 a == ACTION_HYBRID_SLEEP)) {
3016 r = reboot_with_logind(bus, a);
3017 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
3021 r = start_unit(bus, args);
3022 if (r == EXIT_SUCCESS)
3028 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3029 _cleanup_strv_free_ char **names = NULL;
3036 r = expand_names(bus, args, NULL, &names);
3038 return log_error_errno(r, "Failed to expand names: %m");
3040 STRV_FOREACH(name, names) {
3043 state = check_one_unit(bus, *name, good_states, arg_quiet);
3053 static int check_unit_active(sd_bus *bus, char **args) {
3054 /* According to LSB: 3, "program is not running" */
3055 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3058 static int check_unit_failed(sd_bus *bus, char **args) {
3059 return check_unit_generic(bus, 1, "failed\0", args + 1);
3062 static int kill_unit(sd_bus *bus, char **args) {
3063 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3064 _cleanup_strv_free_ char **names = NULL;
3071 polkit_agent_open_if_enabled();
3074 arg_kill_who = "all";
3076 r = expand_names(bus, args + 1, NULL, &names);
3078 log_error_errno(r, "Failed to expand names: %m");
3080 STRV_FOREACH(name, names) {
3081 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3083 q = sd_bus_message_new_method_call(
3086 "org.freedesktop.systemd1",
3087 "/org/freedesktop/systemd1",
3088 "org.freedesktop.systemd1.Manager",
3091 return bus_log_create_error(q);
3093 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3095 return bus_log_create_error(q);
3097 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3099 return bus_log_create_error(q);
3101 q = sd_bus_call(bus, m, 0, &error, NULL);
3103 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3112 typedef struct ExecStatusInfo {
3120 usec_t start_timestamp;
3121 usec_t exit_timestamp;
3126 LIST_FIELDS(struct ExecStatusInfo, exec);
3129 static void exec_status_info_free(ExecStatusInfo *i) {
3138 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3139 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3142 int32_t code, status;
3148 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3150 return bus_log_parse_error(r);
3154 r = sd_bus_message_read(m, "s", &path);
3156 return bus_log_parse_error(r);
3158 i->path = strdup(path);
3162 r = sd_bus_message_read_strv(m, &i->argv);
3164 return bus_log_parse_error(r);
3166 r = sd_bus_message_read(m,
3169 &start_timestamp, &start_timestamp_monotonic,
3170 &exit_timestamp, &exit_timestamp_monotonic,
3174 return bus_log_parse_error(r);
3177 i->start_timestamp = (usec_t) start_timestamp;
3178 i->exit_timestamp = (usec_t) exit_timestamp;
3179 i->pid = (pid_t) pid;
3183 r = sd_bus_message_exit_container(m);
3185 return bus_log_parse_error(r);
3190 typedef struct UnitStatusInfo {
3192 const char *load_state;
3193 const char *active_state;
3194 const char *sub_state;
3195 const char *unit_file_state;
3196 const char *unit_file_preset;
3198 const char *description;
3199 const char *following;
3201 char **documentation;
3203 const char *fragment_path;
3204 const char *source_path;
3205 const char *control_group;
3207 char **dropin_paths;
3209 const char *load_error;
3212 usec_t inactive_exit_timestamp;
3213 usec_t inactive_exit_timestamp_monotonic;
3214 usec_t active_enter_timestamp;
3215 usec_t active_exit_timestamp;
3216 usec_t inactive_enter_timestamp;
3218 bool need_daemon_reload;
3223 const char *status_text;
3224 const char *pid_file;
3228 usec_t start_timestamp;
3229 usec_t exit_timestamp;
3231 int exit_code, exit_status;
3233 usec_t condition_timestamp;
3234 bool condition_result;
3235 bool failed_condition_trigger;
3236 bool failed_condition_negate;
3237 const char *failed_condition;
3238 const char *failed_condition_parameter;
3240 usec_t assert_timestamp;
3242 bool failed_assert_trigger;
3243 bool failed_assert_negate;
3244 const char *failed_assert;
3245 const char *failed_assert_parameter;
3248 unsigned n_accepted;
3249 unsigned n_connections;
3252 /* Pairs of type, path */
3256 const char *sysfs_path;
3258 /* Mount, Automount */
3265 uint64_t memory_current;
3266 uint64_t memory_limit;
3268 LIST_HEAD(ExecStatusInfo, exec);
3271 static void print_status_info(
3276 const char *active_on, *active_off, *on, *off, *ss;
3278 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3279 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3285 /* This shows pretty information about a unit. See
3286 * print_property() for a low-level property printer */
3288 if (streq_ptr(i->active_state, "failed")) {
3289 active_on = ansi_highlight_red();
3290 active_off = ansi_highlight_off();
3291 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3292 active_on = ansi_highlight_green();
3293 active_off = ansi_highlight_off();
3295 active_on = active_off = "";
3297 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3299 if (i->description && !streq_ptr(i->id, i->description))
3300 printf(" - %s", i->description);
3305 printf(" Follow: unit currently follows state of %s\n", i->following);
3307 if (streq_ptr(i->load_state, "error")) {
3308 on = ansi_highlight_red();
3309 off = ansi_highlight_off();
3313 path = i->source_path ? i->source_path : i->fragment_path;
3316 printf(" Loaded: %s%s%s (Reason: %s)\n",
3317 on, strna(i->load_state), off, i->load_error);
3318 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3319 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3320 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3321 else if (path && !isempty(i->unit_file_state))
3322 printf(" Loaded: %s%s%s (%s; %s)\n",
3323 on, strna(i->load_state), off, path, i->unit_file_state);
3325 printf(" Loaded: %s%s%s (%s)\n",
3326 on, strna(i->load_state), off, path);
3328 printf(" Loaded: %s%s%s\n",
3329 on, strna(i->load_state), off);
3331 if (!strv_isempty(i->dropin_paths)) {
3332 _cleanup_free_ char *dir = NULL;
3336 STRV_FOREACH(dropin, i->dropin_paths) {
3337 if (! dir || last) {
3338 printf(dir ? " " : " Drop-In: ");
3343 if (path_get_parent(*dropin, &dir) < 0) {
3348 printf("%s\n %s", dir,
3349 draw_special_char(DRAW_TREE_RIGHT));
3352 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3354 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3358 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3360 printf(" Active: %s%s (%s)%s",
3361 active_on, strna(i->active_state), ss, active_off);
3363 printf(" Active: %s%s%s",
3364 active_on, strna(i->active_state), active_off);
3366 if (!isempty(i->result) && !streq(i->result, "success"))
3367 printf(" (Result: %s)", i->result);
3369 timestamp = (streq_ptr(i->active_state, "active") ||
3370 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3371 (streq_ptr(i->active_state, "inactive") ||
3372 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3373 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3374 i->active_exit_timestamp;
3376 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3377 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3380 printf(" since %s; %s\n", s2, s1);
3382 printf(" since %s\n", s2);
3386 if (!i->condition_result && i->condition_timestamp > 0) {
3387 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3388 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3390 printf("Condition: start %scondition failed%s at %s%s%s\n",
3391 ansi_highlight_yellow(), ansi_highlight_off(),
3392 s2, s1 ? "; " : "", s1 ? s1 : "");
3393 if (i->failed_condition_trigger)
3394 printf(" none of the trigger conditions were met\n");
3395 else if (i->failed_condition)
3396 printf(" %s=%s%s was not met\n",
3397 i->failed_condition,
3398 i->failed_condition_negate ? "!" : "",
3399 i->failed_condition_parameter);
3402 if (!i->assert_result && i->assert_timestamp > 0) {
3403 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3404 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3406 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3407 ansi_highlight_red(), ansi_highlight_off(),
3408 s2, s1 ? "; " : "", s1 ? s1 : "");
3409 if (i->failed_assert_trigger)
3410 printf(" none of the trigger assertions were met\n");
3411 else if (i->failed_assert)
3412 printf(" %s=%s%s was not met\n",
3414 i->failed_assert_negate ? "!" : "",
3415 i->failed_assert_parameter);
3419 printf(" Device: %s\n", i->sysfs_path);
3421 printf(" Where: %s\n", i->where);
3423 printf(" What: %s\n", i->what);
3425 STRV_FOREACH(t, i->documentation)
3426 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3428 STRV_FOREACH_PAIR(t, t2, i->listen)
3429 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3432 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3434 LIST_FOREACH(exec, p, i->exec) {
3435 _cleanup_free_ char *argv = NULL;
3438 /* Only show exited processes here */
3442 argv = strv_join(p->argv, " ");
3443 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3445 good = is_clean_exit_lsb(p->code, p->status, NULL);
3447 on = ansi_highlight_red();
3448 off = ansi_highlight_off();
3452 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3454 if (p->code == CLD_EXITED) {
3457 printf("status=%i", p->status);
3459 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3464 printf("signal=%s", signal_to_string(p->status));
3466 printf(")%s\n", off);
3468 if (i->main_pid == p->pid &&
3469 i->start_timestamp == p->start_timestamp &&
3470 i->exit_timestamp == p->start_timestamp)
3471 /* Let's not show this twice */
3474 if (p->pid == i->control_pid)
3478 if (i->main_pid > 0 || i->control_pid > 0) {
3479 if (i->main_pid > 0) {
3480 printf(" Main PID: "PID_FMT, i->main_pid);
3483 _cleanup_free_ char *comm = NULL;
3484 get_process_comm(i->main_pid, &comm);
3486 printf(" (%s)", comm);
3487 } else if (i->exit_code > 0) {
3488 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3490 if (i->exit_code == CLD_EXITED) {
3493 printf("status=%i", i->exit_status);
3495 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3500 printf("signal=%s", signal_to_string(i->exit_status));
3504 if (i->control_pid > 0)
3508 if (i->control_pid > 0) {
3509 _cleanup_free_ char *c = NULL;
3511 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3513 get_process_comm(i->control_pid, &c);
3522 printf(" Status: \"%s\"\n", i->status_text);
3523 if (i->status_errno > 0)
3524 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3526 if (i->memory_current != (uint64_t) -1) {
3527 char buf[FORMAT_BYTES_MAX];
3529 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3531 if (i->memory_limit != (uint64_t) -1)
3532 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3537 if (i->control_group &&
3538 (i->main_pid > 0 || i->control_pid > 0 ||
3539 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3542 printf(" CGroup: %s\n", i->control_group);
3544 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3547 static const char prefix[] = " ";
3550 if (c > sizeof(prefix) - 1)
3551 c -= sizeof(prefix) - 1;
3555 if (i->main_pid > 0)
3556 extra[k++] = i->main_pid;
3558 if (i->control_pid > 0)
3559 extra[k++] = i->control_pid;
3561 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3565 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3566 show_journal_by_unit(
3571 i->inactive_exit_timestamp_monotonic,
3574 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3575 SD_JOURNAL_LOCAL_ONLY,
3576 arg_scope == UNIT_FILE_SYSTEM,
3580 if (i->need_daemon_reload)
3581 warn_unit_file_changed(i->id);
3584 static void show_unit_help(UnitStatusInfo *i) {
3589 if (!i->documentation) {
3590 log_info("Documentation for %s not known.", i->id);
3594 STRV_FOREACH(p, i->documentation)
3595 if (startswith(*p, "man:"))
3596 show_man_page(*p + 4, false);
3598 log_info("Can't show: %s", *p);
3601 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3608 switch (contents[0]) {
3610 case SD_BUS_TYPE_STRING: {
3613 r = sd_bus_message_read(m, "s", &s);
3615 return bus_log_parse_error(r);
3618 if (streq(name, "Id"))
3620 else if (streq(name, "LoadState"))
3622 else if (streq(name, "ActiveState"))
3623 i->active_state = s;
3624 else if (streq(name, "SubState"))
3626 else if (streq(name, "Description"))
3628 else if (streq(name, "FragmentPath"))
3629 i->fragment_path = s;
3630 else if (streq(name, "SourcePath"))
3633 else if (streq(name, "DefaultControlGroup")) {
3635 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3637 i->control_group = e;
3640 else if (streq(name, "ControlGroup"))
3641 i->control_group = s;
3642 else if (streq(name, "StatusText"))
3644 else if (streq(name, "PIDFile"))
3646 else if (streq(name, "SysFSPath"))
3648 else if (streq(name, "Where"))
3650 else if (streq(name, "What"))
3652 else if (streq(name, "Following"))
3654 else if (streq(name, "UnitFileState"))
3655 i->unit_file_state = s;
3656 else if (streq(name, "UnitFilePreset"))
3657 i->unit_file_preset = s;
3658 else if (streq(name, "Result"))
3665 case SD_BUS_TYPE_BOOLEAN: {
3668 r = sd_bus_message_read(m, "b", &b);
3670 return bus_log_parse_error(r);
3672 if (streq(name, "Accept"))
3674 else if (streq(name, "NeedDaemonReload"))
3675 i->need_daemon_reload = b;
3676 else if (streq(name, "ConditionResult"))
3677 i->condition_result = b;
3678 else if (streq(name, "AssertResult"))
3679 i->assert_result = b;
3684 case SD_BUS_TYPE_UINT32: {
3687 r = sd_bus_message_read(m, "u", &u);
3689 return bus_log_parse_error(r);
3691 if (streq(name, "MainPID")) {
3693 i->main_pid = (pid_t) u;
3696 } else if (streq(name, "ControlPID"))
3697 i->control_pid = (pid_t) u;
3698 else if (streq(name, "ExecMainPID")) {
3700 i->main_pid = (pid_t) u;
3701 } else if (streq(name, "NAccepted"))
3703 else if (streq(name, "NConnections"))
3704 i->n_connections = u;
3709 case SD_BUS_TYPE_INT32: {
3712 r = sd_bus_message_read(m, "i", &j);
3714 return bus_log_parse_error(r);
3716 if (streq(name, "ExecMainCode"))
3717 i->exit_code = (int) j;
3718 else if (streq(name, "ExecMainStatus"))
3719 i->exit_status = (int) j;
3720 else if (streq(name, "StatusErrno"))
3721 i->status_errno = (int) j;
3726 case SD_BUS_TYPE_UINT64: {
3729 r = sd_bus_message_read(m, "t", &u);
3731 return bus_log_parse_error(r);
3733 if (streq(name, "ExecMainStartTimestamp"))
3734 i->start_timestamp = (usec_t) u;
3735 else if (streq(name, "ExecMainExitTimestamp"))
3736 i->exit_timestamp = (usec_t) u;
3737 else if (streq(name, "ActiveEnterTimestamp"))
3738 i->active_enter_timestamp = (usec_t) u;
3739 else if (streq(name, "InactiveEnterTimestamp"))
3740 i->inactive_enter_timestamp = (usec_t) u;
3741 else if (streq(name, "InactiveExitTimestamp"))
3742 i->inactive_exit_timestamp = (usec_t) u;
3743 else if (streq(name, "InactiveExitTimestampMonotonic"))
3744 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3745 else if (streq(name, "ActiveExitTimestamp"))
3746 i->active_exit_timestamp = (usec_t) u;
3747 else if (streq(name, "ConditionTimestamp"))
3748 i->condition_timestamp = (usec_t) u;
3749 else if (streq(name, "AssertTimestamp"))
3750 i->assert_timestamp = (usec_t) u;
3751 else if (streq(name, "MemoryCurrent"))
3752 i->memory_current = u;
3753 else if (streq(name, "MemoryLimit"))
3754 i->memory_limit = u;
3759 case SD_BUS_TYPE_ARRAY:
3761 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3762 _cleanup_free_ ExecStatusInfo *info = NULL;
3764 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3766 return bus_log_parse_error(r);
3768 info = new0(ExecStatusInfo, 1);
3772 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3774 info->name = strdup(name);
3778 LIST_PREPEND(exec, i->exec, info);
3780 info = new0(ExecStatusInfo, 1);
3786 return bus_log_parse_error(r);
3788 r = sd_bus_message_exit_container(m);
3790 return bus_log_parse_error(r);
3794 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3795 const char *type, *path;
3797 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3799 return bus_log_parse_error(r);
3801 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3803 r = strv_extend(&i->listen, type);
3807 r = strv_extend(&i->listen, path);
3812 return bus_log_parse_error(r);
3814 r = sd_bus_message_exit_container(m);
3816 return bus_log_parse_error(r);
3820 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3822 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3824 return bus_log_parse_error(r);
3826 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3828 r = sd_bus_message_read_strv(m, &i->documentation);
3830 return bus_log_parse_error(r);
3832 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3833 const char *cond, *param;
3834 int trigger, negate;
3837 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3839 return bus_log_parse_error(r);
3841 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3842 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3843 if (state < 0 && (!trigger || !i->failed_condition)) {
3844 i->failed_condition = cond;
3845 i->failed_condition_trigger = trigger;
3846 i->failed_condition_negate = negate;
3847 i->failed_condition_parameter = param;
3851 return bus_log_parse_error(r);
3853 r = sd_bus_message_exit_container(m);
3855 return bus_log_parse_error(r);
3857 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3858 const char *cond, *param;
3859 int trigger, negate;
3862 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3864 return bus_log_parse_error(r);
3866 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3867 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3868 if (state < 0 && (!trigger || !i->failed_assert)) {
3869 i->failed_assert = cond;
3870 i->failed_assert_trigger = trigger;
3871 i->failed_assert_negate = negate;
3872 i->failed_assert_parameter = param;
3876 return bus_log_parse_error(r);
3878 r = sd_bus_message_exit_container(m);
3880 return bus_log_parse_error(r);
3887 case SD_BUS_TYPE_STRUCT_BEGIN:
3889 if (streq(name, "LoadError")) {
3890 const char *n, *message;
3892 r = sd_bus_message_read(m, "(ss)", &n, &message);
3894 return bus_log_parse_error(r);
3896 if (!isempty(message))
3897 i->load_error = message;
3910 r = sd_bus_message_skip(m, contents);
3912 return bus_log_parse_error(r);
3917 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3923 /* This is a low-level property printer, see
3924 * print_status_info() for the nicer output */
3926 if (arg_properties && !strv_find(arg_properties, name)) {
3927 /* skip what we didn't read */
3928 r = sd_bus_message_skip(m, contents);
3932 switch (contents[0]) {
3934 case SD_BUS_TYPE_STRUCT_BEGIN:
3936 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3939 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3941 return bus_log_parse_error(r);
3944 printf("%s=%"PRIu32"\n", name, u);
3946 printf("%s=\n", name);
3950 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3953 r = sd_bus_message_read(m, "(so)", &s, NULL);
3955 return bus_log_parse_error(r);
3957 if (arg_all || !isempty(s))
3958 printf("%s=%s\n", name, s);
3962 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3963 const char *a = NULL, *b = NULL;
3965 r = sd_bus_message_read(m, "(ss)", &a, &b);
3967 return bus_log_parse_error(r);
3969 if (arg_all || !isempty(a) || !isempty(b))
3970 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3973 } else if (streq_ptr(name, "SystemCallFilter")) {
3974 _cleanup_strv_free_ char **l = NULL;
3977 r = sd_bus_message_enter_container(m, 'r', "bas");
3979 return bus_log_parse_error(r);
3981 r = sd_bus_message_read(m, "b", &whitelist);
3983 return bus_log_parse_error(r);
3985 r = sd_bus_message_read_strv(m, &l);
3987 return bus_log_parse_error(r);
3989 r = sd_bus_message_exit_container(m);
3991 return bus_log_parse_error(r);
3993 if (arg_all || whitelist || !strv_isempty(l)) {
3997 fputs(name, stdout);
4003 STRV_FOREACH(i, l) {
4011 fputc('\n', stdout);
4019 case SD_BUS_TYPE_ARRAY:
4021 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4025 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4027 return bus_log_parse_error(r);
4029 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4030 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4033 return bus_log_parse_error(r);
4035 r = sd_bus_message_exit_container(m);
4037 return bus_log_parse_error(r);
4041 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4042 const char *type, *path;
4044 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4046 return bus_log_parse_error(r);
4048 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4049 printf("%s=%s\n", type, path);
4051 return bus_log_parse_error(r);
4053 r = sd_bus_message_exit_container(m);
4055 return bus_log_parse_error(r);
4059 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4060 const char *type, *path;
4062 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4064 return bus_log_parse_error(r);
4066 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4067 printf("Listen%s=%s\n", type, path);
4069 return bus_log_parse_error(r);
4071 r = sd_bus_message_exit_container(m);
4073 return bus_log_parse_error(r);
4077 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4079 uint64_t value, next_elapse;
4081 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4083 return bus_log_parse_error(r);
4085 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4086 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4088 printf("%s={ value=%s ; next_elapse=%s }\n",
4090 format_timespan(timespan1, sizeof(timespan1), value, 0),
4091 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4094 return bus_log_parse_error(r);
4096 r = sd_bus_message_exit_container(m);
4098 return bus_log_parse_error(r);
4102 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4103 ExecStatusInfo info = {};
4105 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4107 return bus_log_parse_error(r);
4109 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4110 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4111 _cleanup_free_ char *tt;
4113 tt = strv_join(info.argv, " ");
4115 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",
4119 yes_no(info.ignore),
4120 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4121 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4123 sigchld_code_to_string(info.code),
4125 info.code == CLD_EXITED ? "" : "/",
4126 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4129 strv_free(info.argv);
4133 r = sd_bus_message_exit_container(m);
4135 return bus_log_parse_error(r);
4139 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4140 const char *path, *rwm;
4142 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4144 return bus_log_parse_error(r);
4146 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4147 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4149 return bus_log_parse_error(r);
4151 r = sd_bus_message_exit_container(m);
4153 return bus_log_parse_error(r);
4157 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4161 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4163 return bus_log_parse_error(r);
4165 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4166 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4168 return bus_log_parse_error(r);
4170 r = sd_bus_message_exit_container(m);
4172 return bus_log_parse_error(r);
4176 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4180 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4182 return bus_log_parse_error(r);
4184 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4185 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4187 return bus_log_parse_error(r);
4189 r = sd_bus_message_exit_container(m);
4191 return bus_log_parse_error(r);
4199 r = bus_print_property(name, m, arg_all);
4201 return bus_log_parse_error(r);
4204 r = sd_bus_message_skip(m, contents);
4206 return bus_log_parse_error(r);
4209 printf("%s=[unprintable]\n", name);
4215 static int show_one(
4219 bool show_properties,
4223 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4224 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4225 UnitStatusInfo info = {
4226 .memory_current = (uint64_t) -1,
4227 .memory_limit = (uint64_t) -1,
4235 log_debug("Showing one %s", path);
4237 r = sd_bus_call_method(
4239 "org.freedesktop.systemd1",
4241 "org.freedesktop.DBus.Properties",
4247 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4251 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4253 return bus_log_parse_error(r);
4260 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4261 const char *name, *contents;
4263 r = sd_bus_message_read(reply, "s", &name);
4265 return bus_log_parse_error(r);
4267 r = sd_bus_message_peek_type(reply, NULL, &contents);
4269 return bus_log_parse_error(r);
4271 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4273 return bus_log_parse_error(r);
4275 if (show_properties)
4276 r = print_property(name, reply, contents);
4278 r = status_property(name, reply, &info, contents);
4282 r = sd_bus_message_exit_container(reply);
4284 return bus_log_parse_error(r);
4286 r = sd_bus_message_exit_container(reply);
4288 return bus_log_parse_error(r);
4291 return bus_log_parse_error(r);
4293 r = sd_bus_message_exit_container(reply);
4295 return bus_log_parse_error(r);
4299 if (!show_properties) {
4300 if (streq(verb, "help"))
4301 show_unit_help(&info);
4303 print_status_info(&info, ellipsized);
4306 strv_free(info.documentation);
4307 strv_free(info.dropin_paths);
4308 strv_free(info.listen);
4310 if (!streq_ptr(info.active_state, "active") &&
4311 !streq_ptr(info.active_state, "reloading") &&
4312 streq(verb, "status")) {
4313 /* According to LSB: "program not running" */
4314 /* 0: program is running or service is OK
4315 * 1: program is dead and /run PID file exists
4316 * 2: program is dead and /run/lock lock file exists
4317 * 3: program is not running
4318 * 4: program or service status is unknown
4320 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4326 while ((p = info.exec)) {
4327 LIST_REMOVE(exec, info.exec, p);
4328 exec_status_info_free(p);
4334 static int get_unit_dbus_path_by_pid(
4339 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4340 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4344 r = sd_bus_call_method(
4346 "org.freedesktop.systemd1",
4347 "/org/freedesktop/systemd1",
4348 "org.freedesktop.systemd1.Manager",
4354 log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4358 r = sd_bus_message_read(reply, "o", &u);
4360 return bus_log_parse_error(r);
4370 static int show_all(
4373 bool show_properties,
4377 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4378 _cleanup_free_ UnitInfo *unit_infos = NULL;
4383 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4387 pager_open_if_enabled();
4391 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4393 for (u = unit_infos; u < unit_infos + c; u++) {
4394 _cleanup_free_ char *p = NULL;
4396 p = unit_dbus_path_from_name(u->id);
4400 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4403 else if (r > 0 && ret == 0)
4410 static int show_system_status(sd_bus *bus) {
4411 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4412 _cleanup_free_ char *hn = NULL;
4413 struct machine_info mi = {};
4414 const char *on, *off;
4417 hn = gethostname_malloc();
4421 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4423 return log_error_errno(r, "Failed to read server status: %m");
4425 if (streq_ptr(mi.state, "degraded")) {
4426 on = ansi_highlight_red();
4427 off = ansi_highlight_off();
4428 } else if (!streq_ptr(mi.state, "running")) {
4429 on = ansi_highlight_yellow();
4430 off = ansi_highlight_off();
4434 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4436 printf(" State: %s%s%s\n",
4437 on, strna(mi.state), off);
4439 printf(" Jobs: %u queued\n", mi.n_jobs);
4440 printf(" Failed: %u units\n", mi.n_failed_units);
4442 printf(" Since: %s; %s\n",
4443 format_timestamp(since2, sizeof(since2), mi.timestamp),
4444 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4446 printf(" CGroup: %s\n", mi.control_group ?: "/");
4447 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4448 static const char prefix[] = " ";
4452 if (c > sizeof(prefix) - 1)
4453 c -= sizeof(prefix) - 1;
4457 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4461 free(mi.control_group);
4466 static int show(sd_bus *bus, char **args) {
4467 bool show_properties, show_status, new_line = false;
4468 bool ellipsized = false;
4474 show_properties = streq(args[0], "show");
4475 show_status = streq(args[0], "status");
4477 if (show_properties)
4478 pager_open_if_enabled();
4480 /* If no argument is specified inspect the manager itself */
4482 if (show_properties && strv_length(args) <= 1)
4483 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4485 if (show_status && strv_length(args) <= 1) {
4487 pager_open_if_enabled();
4488 show_system_status(bus);
4492 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4494 _cleanup_free_ char **patterns = NULL;
4497 STRV_FOREACH(name, args + 1) {
4498 _cleanup_free_ char *unit = NULL;
4501 if (safe_atou32(*name, &id) < 0) {
4502 if (strv_push(&patterns, *name) < 0)
4506 } else if (show_properties) {
4507 /* Interpret as job id */
4508 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4512 /* Interpret as PID */
4513 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4520 r = show_one(args[0], bus, unit, show_properties,
4521 &new_line, &ellipsized);
4524 else if (r > 0 && ret == 0)
4528 if (!strv_isempty(patterns)) {
4529 _cleanup_strv_free_ char **names = NULL;
4531 r = expand_names(bus, patterns, NULL, &names);
4533 log_error_errno(r, "Failed to expand names: %m");
4535 STRV_FOREACH(name, names) {
4536 _cleanup_free_ char *unit;
4538 unit = unit_dbus_path_from_name(*name);
4542 r = show_one(args[0], bus, unit, show_properties,
4543 &new_line, &ellipsized);
4546 else if (r > 0 && ret == 0)
4552 if (ellipsized && !arg_quiet)
4553 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4558 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4562 assert(user_runtime);
4565 if (arg_scope == UNIT_FILE_USER) {
4566 r = user_config_home(user_home);
4568 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4570 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4572 r = user_runtime_dir(user_runtime);
4574 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4576 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4579 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4581 return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
4586 static int cat(sd_bus *bus, char **args) {
4587 _cleanup_free_ char *user_home = NULL;
4588 _cleanup_free_ char *user_runtime = NULL;
4589 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4590 _cleanup_strv_free_ char **names = NULL;
4592 bool first = true, avoid_bus_cache;
4598 log_error("Option --host cannot be used with 'cat'");
4602 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4606 r = expand_names(bus, args + 1, NULL, &names);
4608 log_error_errno(r, "Failed to expand names: %m");
4610 avoid_bus_cache = !bus || avoid_bus();
4612 pager_open_if_enabled();
4614 STRV_FOREACH(name, names) {
4615 _cleanup_free_ char *fragment_path = NULL;
4616 _cleanup_strv_free_ char **dropin_paths = NULL;
4619 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4630 if (fragment_path) {
4631 printf("%s# %s%s\n",
4632 ansi_highlight_blue(),
4634 ansi_highlight_off());
4637 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4639 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4644 STRV_FOREACH(path, dropin_paths) {
4645 printf("%s%s# %s%s\n",
4646 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4647 ansi_highlight_blue(),
4649 ansi_highlight_off());
4652 r = copy_file_fd(*path, STDOUT_FILENO, false);
4654 log_warning_errno(r, "Failed to cat %s: %m", *path);
4660 return r < 0 ? r : 0;
4663 static int set_property(sd_bus *bus, char **args) {
4664 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4665 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4666 _cleanup_free_ char *n = NULL;
4670 polkit_agent_open_if_enabled();
4672 r = sd_bus_message_new_method_call(
4675 "org.freedesktop.systemd1",
4676 "/org/freedesktop/systemd1",
4677 "org.freedesktop.systemd1.Manager",
4678 "SetUnitProperties");
4680 return bus_log_create_error(r);
4682 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4684 return bus_log_create_error(r);
4686 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4690 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4692 return bus_log_create_error(r);
4694 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4696 return bus_log_create_error(r);
4698 STRV_FOREACH(i, args + 2) {
4699 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4701 return bus_log_create_error(r);
4703 r = bus_append_unit_property_assignment(m, *i);
4707 r = sd_bus_message_close_container(m);
4709 return bus_log_create_error(r);
4712 r = sd_bus_message_close_container(m);
4714 return bus_log_create_error(r);
4716 r = sd_bus_call(bus, m, 0, &error, NULL);
4718 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4725 static int snapshot(sd_bus *bus, char **args) {
4726 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4727 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4728 _cleanup_free_ char *n = NULL, *id = NULL;
4732 polkit_agent_open_if_enabled();
4734 if (strv_length(args) > 1)
4735 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4741 r = sd_bus_message_new_method_call(
4744 "org.freedesktop.systemd1",
4745 "/org/freedesktop/systemd1",
4746 "org.freedesktop.systemd1.Manager",
4749 return bus_log_create_error(r);
4751 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4753 return bus_log_create_error(r);
4755 r = sd_bus_message_append(m, "sb", n, false);
4757 return bus_log_create_error(r);
4759 r = sd_bus_call(bus, m, 0, &error, &reply);
4761 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4765 r = sd_bus_message_read(reply, "o", &path);
4767 return bus_log_parse_error(r);
4769 r = sd_bus_get_property_string(
4771 "org.freedesktop.systemd1",
4773 "org.freedesktop.systemd1.Unit",
4778 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4788 static int delete_snapshot(sd_bus *bus, char **args) {
4789 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4790 _cleanup_strv_free_ char **names = NULL;
4796 polkit_agent_open_if_enabled();
4798 r = expand_names(bus, args + 1, ".snapshot", &names);
4800 log_error_errno(r, "Failed to expand names: %m");
4802 STRV_FOREACH(name, names) {
4803 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4806 q = sd_bus_message_new_method_call(
4809 "org.freedesktop.systemd1",
4810 "/org/freedesktop/systemd1",
4811 "org.freedesktop.systemd1.Manager",
4814 return bus_log_create_error(q);
4816 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4818 return bus_log_create_error(q);
4820 q = sd_bus_message_append(m, "s", *name);
4822 return bus_log_create_error(q);
4824 q = sd_bus_call(bus, m, 0, &error, NULL);
4826 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4835 static int daemon_reload(sd_bus *bus, char **args) {
4836 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4837 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4841 polkit_agent_open_if_enabled();
4843 if (arg_action == ACTION_RELOAD)
4845 else if (arg_action == ACTION_REEXEC)
4846 method = "Reexecute";
4848 assert(arg_action == ACTION_SYSTEMCTL);
4851 streq(args[0], "clear-jobs") ||
4852 streq(args[0], "cancel") ? "ClearJobs" :
4853 streq(args[0], "daemon-reexec") ? "Reexecute" :
4854 streq(args[0], "reset-failed") ? "ResetFailed" :
4855 streq(args[0], "halt") ? "Halt" :
4856 streq(args[0], "poweroff") ? "PowerOff" :
4857 streq(args[0], "reboot") ? "Reboot" :
4858 streq(args[0], "kexec") ? "KExec" :
4859 streq(args[0], "exit") ? "Exit" :
4860 /* "daemon-reload" */ "Reload";
4863 r = sd_bus_message_new_method_call(
4866 "org.freedesktop.systemd1",
4867 "/org/freedesktop/systemd1",
4868 "org.freedesktop.systemd1.Manager",
4871 return bus_log_create_error(r);
4873 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4875 return bus_log_create_error(r);
4877 r = sd_bus_call(bus, m, 0, &error, NULL);
4878 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4879 /* There's always a fallback possible for
4880 * legacy actions. */
4882 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4883 /* On reexecution, we expect a disconnect, not a
4887 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4889 return r < 0 ? r : 0;
4892 static int reset_failed(sd_bus *bus, char **args) {
4893 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4894 _cleanup_strv_free_ char **names = NULL;
4898 if (strv_length(args) <= 1)
4899 return daemon_reload(bus, args);
4901 polkit_agent_open_if_enabled();
4903 r = expand_names(bus, args + 1, NULL, &names);
4905 log_error_errno(r, "Failed to expand names: %m");
4907 STRV_FOREACH(name, names) {
4908 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4910 q = sd_bus_message_new_method_call(
4913 "org.freedesktop.systemd1",
4914 "/org/freedesktop/systemd1",
4915 "org.freedesktop.systemd1.Manager",
4918 return bus_log_create_error(q);
4920 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4922 return bus_log_create_error(q);
4924 q = sd_bus_message_append(m, "s", *name);
4926 return bus_log_create_error(q);
4928 q = sd_bus_call(bus, m, 0, &error, NULL);
4930 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4939 static int show_environment(sd_bus *bus, char **args) {
4940 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4941 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4945 pager_open_if_enabled();
4947 r = sd_bus_get_property(
4949 "org.freedesktop.systemd1",
4950 "/org/freedesktop/systemd1",
4951 "org.freedesktop.systemd1.Manager",
4957 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4961 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4963 return bus_log_parse_error(r);
4965 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4968 return bus_log_parse_error(r);
4970 r = sd_bus_message_exit_container(reply);
4972 return bus_log_parse_error(r);
4977 static int switch_root(sd_bus *bus, char **args) {
4978 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4979 _cleanup_free_ char *cmdline_init = NULL;
4980 const char *root, *init;
4984 l = strv_length(args);
4985 if (l < 2 || l > 3) {
4986 log_error("Wrong number of arguments.");
4995 r = parse_env_file("/proc/cmdline", WHITESPACE,
4996 "init", &cmdline_init,
4999 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5001 init = cmdline_init;
5008 const char *root_systemd_path = NULL, *root_init_path = NULL;
5010 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
5011 root_init_path = strjoina(root, "/", init);
5013 /* If the passed init is actually the same as the
5014 * systemd binary, then let's suppress it. */
5015 if (files_same(root_init_path, root_systemd_path) > 0)
5019 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5021 r = sd_bus_call_method(
5023 "org.freedesktop.systemd1",
5024 "/org/freedesktop/systemd1",
5025 "org.freedesktop.systemd1.Manager",
5031 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5038 static int set_environment(sd_bus *bus, char **args) {
5039 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5040 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5047 method = streq(args[0], "set-environment")
5049 : "UnsetEnvironment";
5051 r = sd_bus_message_new_method_call(
5054 "org.freedesktop.systemd1",
5055 "/org/freedesktop/systemd1",
5056 "org.freedesktop.systemd1.Manager",
5059 return bus_log_create_error(r);
5061 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5063 return bus_log_create_error(r);
5065 r = sd_bus_message_append_strv(m, args + 1);
5067 return bus_log_create_error(r);
5069 r = sd_bus_call(bus, m, 0, &error, NULL);
5071 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5078 static int import_environment(sd_bus *bus, char **args) {
5079 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5080 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5086 r = sd_bus_message_new_method_call(
5089 "org.freedesktop.systemd1",
5090 "/org/freedesktop/systemd1",
5091 "org.freedesktop.systemd1.Manager",
5094 return bus_log_create_error(r);
5096 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5098 return bus_log_create_error(r);
5100 if (strv_isempty(args + 1))
5101 r = sd_bus_message_append_strv(m, environ);
5105 r = sd_bus_message_open_container(m, 'a', "s");
5107 return bus_log_create_error(r);
5109 STRV_FOREACH(a, args + 1) {
5111 if (!env_name_is_valid(*a)) {
5112 log_error("Not a valid environment variable name: %s", *a);
5116 STRV_FOREACH(b, environ) {
5119 eq = startswith(*b, *a);
5120 if (eq && *eq == '=') {
5122 r = sd_bus_message_append(m, "s", *b);
5124 return bus_log_create_error(r);
5131 r = sd_bus_message_close_container(m);
5134 return bus_log_create_error(r);
5136 r = sd_bus_call(bus, m, 0, &error, NULL);
5138 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5145 static int enable_sysv_units(const char *verb, char **args) {
5148 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5150 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5152 if (arg_scope != UNIT_FILE_SYSTEM)
5155 if (!streq(verb, "enable") &&
5156 !streq(verb, "disable") &&
5157 !streq(verb, "is-enabled"))
5160 /* Processes all SysV units, and reshuffles the array so that
5161 * afterwards only the native units remain */
5163 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5170 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5171 bool found_native = false, found_sysv;
5173 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5181 if (!endswith(name, ".service"))
5184 if (path_is_absolute(name))
5187 STRV_FOREACH(k, paths.unit_path) {
5188 _cleanup_free_ char *path = NULL;
5190 path = path_join(arg_root, *k, name);
5194 found_native = access(path, F_OK) >= 0;
5202 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5206 p[strlen(p) - strlen(".service")] = 0;
5207 found_sysv = access(p, F_OK) >= 0;
5211 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5213 if (!isempty(arg_root))
5214 argv[c++] = q = strappend("--root=", arg_root);
5216 argv[c++] = basename(p);
5218 streq(verb, "enable") ? "on" :
5219 streq(verb, "disable") ? "off" : "--level=5";
5222 l = strv_join((char**)argv, " ");
5226 log_info("Executing %s", l);
5230 return log_error_errno(errno, "Failed to fork: %m");
5231 else if (pid == 0) {
5234 execv(argv[0], (char**) argv);
5235 _exit(EXIT_FAILURE);
5238 j = wait_for_terminate(pid, &status);
5240 log_error_errno(r, "Failed to wait for child: %m");
5244 if (status.si_code == CLD_EXITED) {
5245 if (streq(verb, "is-enabled")) {
5246 if (status.si_status == 0) {
5255 } else if (status.si_status != 0)
5260 /* Remove this entry, so that we don't try enabling it as native unit */
5263 assert(args[f] == name);
5264 strv_remove(args, name);
5271 static int mangle_names(char **original_names, char ***mangled_names) {
5272 char **i, **l, **name;
5274 l = new(char*, strv_length(original_names) + 1);
5279 STRV_FOREACH(name, original_names) {
5281 /* When enabling units qualified path names are OK,
5282 * too, hence allow them explicitly. */
5287 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5303 static int enable_unit(sd_bus *bus, char **args) {
5304 _cleanup_strv_free_ char **names = NULL;
5305 const char *verb = args[0];
5306 UnitFileChange *changes = NULL;
5307 unsigned n_changes = 0;
5308 int carries_install_info = -1;
5314 r = mangle_names(args+1, &names);
5318 r = enable_sysv_units(verb, names);
5322 /* If the operation was fully executed by the SysV compat,
5323 * let's finish early */
5324 if (strv_isempty(names))
5327 if (!bus || avoid_bus()) {
5328 if (streq(verb, "enable")) {
5329 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5330 carries_install_info = r;
5331 } else if (streq(verb, "disable"))
5332 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5333 else if (streq(verb, "reenable")) {
5334 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5335 carries_install_info = r;
5336 } else if (streq(verb, "link"))
5337 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5338 else if (streq(verb, "preset")) {
5339 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5340 carries_install_info = r;
5341 } else if (streq(verb, "mask"))
5342 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5343 else if (streq(verb, "unmask"))
5344 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5346 assert_not_reached("Unknown verb");
5349 log_error_errno(r, "Operation failed: %m");
5354 dump_unit_file_changes(changes, n_changes);
5358 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5359 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5360 int expect_carries_install_info = false;
5361 bool send_force = true, send_preset_mode = false;
5364 polkit_agent_open_if_enabled();
5366 if (streq(verb, "enable")) {
5367 method = "EnableUnitFiles";
5368 expect_carries_install_info = true;
5369 } else if (streq(verb, "disable")) {
5370 method = "DisableUnitFiles";
5372 } else if (streq(verb, "reenable")) {
5373 method = "ReenableUnitFiles";
5374 expect_carries_install_info = true;
5375 } else if (streq(verb, "link"))
5376 method = "LinkUnitFiles";
5377 else if (streq(verb, "preset")) {
5379 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5380 method = "PresetUnitFilesWithMode";
5381 send_preset_mode = true;
5383 method = "PresetUnitFiles";
5385 expect_carries_install_info = true;
5386 } else if (streq(verb, "mask"))
5387 method = "MaskUnitFiles";
5388 else if (streq(verb, "unmask")) {
5389 method = "UnmaskUnitFiles";
5392 assert_not_reached("Unknown verb");
5394 r = sd_bus_message_new_method_call(
5397 "org.freedesktop.systemd1",
5398 "/org/freedesktop/systemd1",
5399 "org.freedesktop.systemd1.Manager",
5402 return bus_log_create_error(r);
5404 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5406 return bus_log_create_error(r);
5408 r = sd_bus_message_append_strv(m, names);
5410 return bus_log_create_error(r);
5412 if (send_preset_mode) {
5413 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5415 return bus_log_create_error(r);
5418 r = sd_bus_message_append(m, "b", arg_runtime);
5420 return bus_log_create_error(r);
5423 r = sd_bus_message_append(m, "b", arg_force);
5425 return bus_log_create_error(r);
5428 r = sd_bus_call(bus, m, 0, &error, &reply);
5430 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5434 if (expect_carries_install_info) {
5435 r = sd_bus_message_read(reply, "b", &carries_install_info);
5437 return bus_log_parse_error(r);
5440 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5444 /* Try to reload if enabled */
5446 r = daemon_reload(bus, args);
5451 if (carries_install_info == 0)
5452 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5453 "using systemctl.\n"
5454 "Possible reasons for having this kind of units are:\n"
5455 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5456 " .wants/ or .requires/ directory.\n"
5457 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5458 " a requirement dependency on it.\n"
5459 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5460 " D-Bus, udev, scripted systemctl call, ...).\n");
5463 unit_file_changes_free(changes, n_changes);
5468 static int add_dependency(sd_bus *bus, char **args) {
5469 _cleanup_strv_free_ char **names = NULL;
5470 _cleanup_free_ char *target = NULL;
5471 const char *verb = args[0];
5478 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5482 r = mangle_names(args+2, &names);
5486 if (streq(verb, "add-wants"))
5488 else if (streq(verb, "add-requires"))
5489 dep = UNIT_REQUIRES;
5491 assert_not_reached("Unknown verb");
5493 if (!bus || avoid_bus()) {
5494 UnitFileChange *changes = NULL;
5495 unsigned n_changes = 0;
5497 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5500 return log_error_errno(r, "Can't add dependency: %m");
5503 dump_unit_file_changes(changes, n_changes);
5505 unit_file_changes_free(changes, n_changes);
5508 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5509 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5511 polkit_agent_open_if_enabled();
5513 r = sd_bus_message_new_method_call(
5516 "org.freedesktop.systemd1",
5517 "/org/freedesktop/systemd1",
5518 "org.freedesktop.systemd1.Manager",
5519 "AddDependencyUnitFiles");
5521 return bus_log_create_error(r);
5523 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5525 return bus_log_create_error(r);
5527 r = sd_bus_message_append_strv(m, names);
5529 return bus_log_create_error(r);
5531 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5533 return bus_log_create_error(r);
5535 r = sd_bus_call(bus, m, 0, &error, &reply);
5537 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5541 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5546 r = daemon_reload(bus, args);
5554 static int preset_all(sd_bus *bus, char **args) {
5555 UnitFileChange *changes = NULL;
5556 unsigned n_changes = 0;
5559 if (!bus || avoid_bus()) {
5561 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5563 log_error_errno(r, "Operation failed: %m");
5568 dump_unit_file_changes(changes, n_changes);
5573 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5574 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5576 polkit_agent_open_if_enabled();
5578 r = sd_bus_message_new_method_call(
5581 "org.freedesktop.systemd1",
5582 "/org/freedesktop/systemd1",
5583 "org.freedesktop.systemd1.Manager",
5584 "PresetAllUnitFiles");
5586 return bus_log_create_error(r);
5588 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5590 return bus_log_create_error(r);
5592 r = sd_bus_message_append(
5595 unit_file_preset_mode_to_string(arg_preset_mode),
5599 return bus_log_create_error(r);
5601 r = sd_bus_call(bus, m, 0, &error, &reply);
5603 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5607 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5612 r = daemon_reload(bus, args);
5618 unit_file_changes_free(changes, n_changes);
5623 static int unit_is_enabled(sd_bus *bus, char **args) {
5625 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5626 _cleanup_strv_free_ char **names = NULL;
5631 r = mangle_names(args+1, &names);
5635 r = enable_sysv_units(args[0], names);
5641 if (!bus || avoid_bus()) {
5643 STRV_FOREACH(name, names) {
5644 UnitFileState state;
5646 state = unit_file_get_state(arg_scope, arg_root, *name);
5648 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5650 if (state == UNIT_FILE_ENABLED ||
5651 state == UNIT_FILE_ENABLED_RUNTIME ||
5652 state == UNIT_FILE_STATIC ||
5653 state == UNIT_FILE_INDIRECT)
5657 puts(unit_file_state_to_string(state));
5661 STRV_FOREACH(name, names) {
5662 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5665 r = sd_bus_call_method(
5667 "org.freedesktop.systemd1",
5668 "/org/freedesktop/systemd1",
5669 "org.freedesktop.systemd1.Manager",
5675 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5679 r = sd_bus_message_read(reply, "s", &s);
5681 return bus_log_parse_error(r);
5683 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5694 static int is_system_running(sd_bus *bus, char **args) {
5695 _cleanup_free_ char *state = NULL;
5698 r = sd_bus_get_property_string(
5700 "org.freedesktop.systemd1",
5701 "/org/freedesktop/systemd1",
5702 "org.freedesktop.systemd1.Manager",
5715 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5718 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5723 assert(original_path);
5726 r = tempfn_random(new_path, &t);
5728 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5730 r = mkdir_parents(new_path, 0755);
5732 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5737 r = copy_file(original_path, t, 0, 0644, 0);
5741 log_error_errno(r, "Failed to create temporary file %s: %m", t);
5746 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5756 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5757 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5759 switch (arg_scope) {
5760 case UNIT_FILE_SYSTEM:
5761 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5763 run = path_join(arg_root, "/run/systemd/system/", name);
5765 case UNIT_FILE_GLOBAL:
5766 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5768 run = path_join(arg_root, "/run/systemd/user/", name);
5770 case UNIT_FILE_USER:
5772 assert(user_runtime);
5774 path = path_join(arg_root, user_home, name);
5776 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5779 run = path_join(arg_root, user_runtime, name);
5783 assert_not_reached("Invalid scope");
5785 if (!path || (arg_runtime && !run))
5789 if (access(path, F_OK) >= 0)
5790 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5792 if (path2 && access(path2, F_OK) >= 0)
5793 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5806 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) {
5807 char *tmp_new_path, *ending;
5812 assert(ret_new_path);
5813 assert(ret_tmp_path);
5815 ending = strjoina(unit_name, ".d/override.conf");
5816 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5820 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5826 *ret_new_path = tmp_new_path;
5827 *ret_tmp_path = tmp_tmp_path;
5832 static int unit_file_create_copy(const char *unit_name,
5833 const char *fragment_path,
5834 const char *user_home,
5835 const char *user_runtime,
5836 char **ret_new_path,
5837 char **ret_tmp_path) {
5842 assert(fragment_path);
5844 assert(ret_new_path);
5845 assert(ret_tmp_path);
5847 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5851 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5854 r = ask_char(&response, "yn", "%s already exists, are you sure to overwrite it with %s? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5859 if (response != 'y') {
5860 log_warning("%s ignored", unit_name);
5866 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5868 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5873 *ret_new_path = tmp_new_path;
5874 *ret_tmp_path = tmp_tmp_path;
5879 static int run_editor(char **paths) {
5887 log_error_errno(errno, "Failed to fork: %m");
5893 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5895 char **tmp_path, **original_path, **p;
5899 argc = strv_length(paths)/2 + 1;
5900 args = newa(const char*, argc + 1);
5903 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5904 args[i] = *tmp_path;
5909 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5910 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5911 * we try to execute well known editors
5913 editor = getenv("SYSTEMD_EDITOR");
5915 editor = getenv("EDITOR");
5917 editor = getenv("VISUAL");
5919 if (!isempty(editor)) {
5921 execvp(editor, (char* const*) args);
5924 STRV_FOREACH(p, backup_editors) {
5926 execvp(*p, (char* const*) args);
5927 /* We do not fail if the editor doesn't exist
5928 * because we want to try each one of them before
5931 if (errno != ENOENT) {
5932 log_error("Failed to execute %s: %m", editor);
5933 _exit(EXIT_FAILURE);
5937 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5938 _exit(EXIT_FAILURE);
5941 r = wait_for_terminate_and_warn("editor", pid, true);
5943 return log_error_errno(r, "Failed to wait for child: %m");
5948 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5949 _cleanup_free_ char *user_home = NULL;
5950 _cleanup_free_ char *user_runtime = NULL;
5951 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5952 bool avoid_bus_cache;
5959 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5963 avoid_bus_cache = !bus || avoid_bus();
5965 STRV_FOREACH(name, names) {
5966 _cleanup_free_ char *path = NULL;
5967 char *new_path, *tmp_path;
5969 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5975 // FIXME: support units with path==NULL (no FragmentPath)
5976 log_error("No fragment exists for %s.", *name);
5981 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5983 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5987 r = strv_push_pair(paths, new_path, tmp_path);
5995 static int edit(sd_bus *bus, char **args) {
5996 _cleanup_strv_free_ char **names = NULL;
5997 _cleanup_strv_free_ char **paths = NULL;
5998 char **original, **tmp;
6004 log_error("Cannot edit units if we are not on a tty");
6008 if (arg_transport != BUS_TRANSPORT_LOCAL) {
6009 log_error("Cannot remotely edit units");
6013 r = expand_names(bus, args + 1, NULL, &names);
6015 return log_error_errno(r, "Failed to expand names: %m");
6017 r = find_paths_to_edit(bus, names, &paths);
6021 if (strv_isempty(paths))
6024 r = run_editor(paths);
6028 STRV_FOREACH_PAIR(original, tmp, paths) {
6029 /* If the temporary file is empty we ignore it.
6030 * It's useful if the user wants to cancel its modification
6032 if (null_or_empty_path(*tmp)) {
6033 log_warning("Edition of %s canceled: temporary file empty", *original);
6036 r = rename(*tmp, *original);
6038 r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
6043 if (!arg_no_reload && bus && !avoid_bus())
6044 r = daemon_reload(bus, args);
6047 STRV_FOREACH_PAIR(original, tmp, paths)
6048 unlink_noerrno(*tmp);
6053 static void systemctl_help(void) {
6055 pager_open_if_enabled();
6057 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6058 "Query or send control commands to the systemd manager.\n\n"
6059 " -h --help Show this help\n"
6060 " --version Show package version\n"
6061 " --system Connect to system manager\n"
6062 " --user Connect to user service manager\n"
6063 " -H --host=[USER@]HOST\n"
6064 " Operate on remote host\n"
6065 " -M --machine=CONTAINER\n"
6066 " Operate on local container\n"
6067 " -t --type=TYPE List units of a particular type\n"
6068 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6069 " -p --property=NAME Show only properties by this name\n"
6070 " -a --all Show all loaded units/properties, including dead/empty\n"
6071 " ones. To list all units installed on the system, use\n"
6072 " the 'list-unit-files' command instead.\n"
6073 " -l --full Don't ellipsize unit names on output\n"
6074 " -r --recursive Show unit list of host and local containers\n"
6075 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6076 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6077 " queueing a new job\n"
6078 " --show-types When showing sockets, explicitly show their type\n"
6079 " -i --ignore-inhibitors\n"
6080 " When shutting down or sleeping, ignore inhibitors\n"
6081 " --kill-who=WHO Who to send signal to\n"
6082 " -s --signal=SIGNAL Which signal to send\n"
6083 " -q --quiet Suppress output\n"
6084 " --no-block Do not wait until operation finished\n"
6085 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6086 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6087 " --no-legend Do not print a legend (column headers and hints)\n"
6088 " --no-pager Do not pipe output into a pager\n"
6089 " --no-ask-password\n"
6090 " Do not ask for system passwords\n"
6091 " --global Enable/disable unit files globally\n"
6092 " --runtime Enable unit files only temporarily until next reboot\n"
6093 " -f --force When enabling unit files, override existing symlinks\n"
6094 " When shutting down, execute action immediately\n"
6095 " --preset-mode= Apply only enable, only disable, or all presets\n"
6096 " --root=PATH Enable unit files in the specified root directory\n"
6097 " -n --lines=INTEGER Number of journal entries to show\n"
6098 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6099 " short-precise, short-monotonic, verbose,\n"
6100 " export, json, json-pretty, json-sse, cat)\n"
6101 " --plain Print unit dependencies as a list instead of a tree\n\n"
6103 " list-units [PATTERN...] List loaded units\n"
6104 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6105 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6106 " start NAME... Start (activate) one or more units\n"
6107 " stop NAME... Stop (deactivate) one or more units\n"
6108 " reload NAME... Reload one or more units\n"
6109 " restart NAME... Start or restart one or more units\n"
6110 " try-restart NAME... Restart one or more units if active\n"
6111 " reload-or-restart NAME... Reload one or more units if possible,\n"
6112 " otherwise start or restart\n"
6113 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6114 " otherwise restart if active\n"
6115 " isolate NAME Start one unit and stop all others\n"
6116 " kill NAME... Send signal to processes of a unit\n"
6117 " is-active PATTERN... Check whether units are active\n"
6118 " is-failed PATTERN... Check whether units are failed\n"
6119 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6120 " show [PATTERN...|JOB...] Show properties of one or more\n"
6121 " units/jobs or the manager\n"
6122 " cat PATTERN... Show files and drop-ins of one or more units\n"
6123 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6124 " help PATTERN...|PID... Show manual for one or more units\n"
6125 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6127 " list-dependencies [NAME] Recursively show units which are required\n"
6128 " or wanted by this unit or by which this\n"
6129 " unit is required or wanted\n\n"
6130 "Unit File Commands:\n"
6131 " list-unit-files [PATTERN...] List installed unit files\n"
6132 " enable NAME... Enable one or more unit files\n"
6133 " disable NAME... Disable one or more unit files\n"
6134 " reenable NAME... Reenable one or more unit files\n"
6135 " preset NAME... Enable/disable one or more unit files\n"
6136 " based on preset configuration\n"
6137 " preset-all Enable/disable all unit files based on\n"
6138 " preset configuration\n"
6139 " is-enabled NAME... Check whether unit files are enabled\n"
6140 " mask NAME... Mask one or more units\n"
6141 " unmask NAME... Unmask one or more units\n"
6142 " link PATH... Link one or more units files into\n"
6143 " the search path\n"
6144 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6145 " on specified one or more units\n"
6146 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6147 " on specified one or more units\n"
6148 " edit NAME... Edit one or more unit files\n"
6149 " get-default Get the name of the default target\n"
6150 " set-default NAME Set the default target\n\n"
6151 "Machine Commands:\n"
6152 " list-machines [PATTERN...] List local containers and host\n\n"
6154 " list-jobs [PATTERN...] List jobs\n"
6155 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6156 "Snapshot Commands:\n"
6157 " snapshot [NAME] Create a snapshot\n"
6158 " delete NAME... Remove one or more snapshots\n\n"
6159 "Environment Commands:\n"
6160 " show-environment Dump environment\n"
6161 " set-environment NAME=VALUE... Set one or more environment variables\n"
6162 " unset-environment NAME... Unset one or more environment variables\n"
6163 " import-environment [NAME...] Import all or some environment variables\n\n"
6164 "Manager Lifecycle Commands:\n"
6165 " daemon-reload Reload systemd manager configuration\n"
6166 " daemon-reexec Reexecute systemd manager\n\n"
6167 "System Commands:\n"
6168 " is-system-running Check whether system is fully running\n"
6169 " default Enter system default mode\n"
6170 " rescue Enter system rescue mode\n"
6171 " emergency Enter system emergency mode\n"
6172 " halt Shut down and halt the system\n"
6173 " poweroff Shut down and power-off the system\n"
6174 " reboot [ARG] Shut down and reboot the system\n"
6175 " kexec Shut down and reboot the system with kexec\n"
6176 " exit Request user instance exit\n"
6177 " switch-root ROOT [INIT] Change to a different root file system\n"
6178 " suspend Suspend the system\n"
6179 " hibernate Hibernate the system\n"
6180 " hybrid-sleep Hibernate and suspend the system\n",
6181 program_invocation_short_name);
6184 static void halt_help(void) {
6185 printf("%s [OPTIONS...]%s\n\n"
6186 "%s the system.\n\n"
6187 " --help Show this help\n"
6188 " --halt Halt the machine\n"
6189 " -p --poweroff Switch off the machine\n"
6190 " --reboot Reboot the machine\n"
6191 " -f --force Force immediate halt/power-off/reboot\n"
6192 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6193 " -d --no-wtmp Don't write wtmp record\n"
6194 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6195 program_invocation_short_name,
6196 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6197 arg_action == ACTION_REBOOT ? "Reboot" :
6198 arg_action == ACTION_POWEROFF ? "Power off" :
6202 static void shutdown_help(void) {
6203 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6204 "Shut down the system.\n\n"
6205 " --help Show this help\n"
6206 " -H --halt Halt the machine\n"
6207 " -P --poweroff Power-off the machine\n"
6208 " -r --reboot Reboot the machine\n"
6209 " -h Equivalent to --poweroff, overridden by --halt\n"
6210 " -k Don't halt/power-off/reboot, just send warnings\n"
6211 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6212 " -c Cancel a pending shutdown\n",
6213 program_invocation_short_name);
6216 static void telinit_help(void) {
6217 printf("%s [OPTIONS...] {COMMAND}\n\n"
6218 "Send control commands to the init daemon.\n\n"
6219 " --help Show this help\n"
6220 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6222 " 0 Power-off the machine\n"
6223 " 6 Reboot the machine\n"
6224 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6225 " 1, s, S Enter rescue mode\n"
6226 " q, Q Reload init daemon configuration\n"
6227 " u, U Reexecute init daemon\n",
6228 program_invocation_short_name);
6231 static void runlevel_help(void) {
6232 printf("%s [OPTIONS...]\n\n"
6233 "Prints the previous and current runlevel of the init system.\n\n"
6234 " --help Show this help\n",
6235 program_invocation_short_name);
6238 static void help_types(void) {
6243 puts("Available unit types:");
6244 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6245 t = unit_type_to_string(i);
6251 static int systemctl_parse_argv(int argc, char *argv[]) {
6260 ARG_IGNORE_DEPENDENCIES,
6272 ARG_NO_ASK_PASSWORD,
6282 static const struct option options[] = {
6283 { "help", no_argument, NULL, 'h' },
6284 { "version", no_argument, NULL, ARG_VERSION },
6285 { "type", required_argument, NULL, 't' },
6286 { "property", required_argument, NULL, 'p' },
6287 { "all", no_argument, NULL, 'a' },
6288 { "reverse", no_argument, NULL, ARG_REVERSE },
6289 { "after", no_argument, NULL, ARG_AFTER },
6290 { "before", no_argument, NULL, ARG_BEFORE },
6291 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6292 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6293 { "full", no_argument, NULL, 'l' },
6294 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6295 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6296 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6297 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6298 { "ignore-inhibitors", no_argument, NULL, 'i' },
6299 { "user", no_argument, NULL, ARG_USER },
6300 { "system", no_argument, NULL, ARG_SYSTEM },
6301 { "global", no_argument, NULL, ARG_GLOBAL },
6302 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6303 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6304 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6305 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6306 { "quiet", no_argument, NULL, 'q' },
6307 { "root", required_argument, NULL, ARG_ROOT },
6308 { "force", no_argument, NULL, ARG_FORCE },
6309 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6310 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6311 { "signal", required_argument, NULL, 's' },
6312 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6313 { "host", required_argument, NULL, 'H' },
6314 { "machine", required_argument, NULL, 'M' },
6315 { "runtime", no_argument, NULL, ARG_RUNTIME },
6316 { "lines", required_argument, NULL, 'n' },
6317 { "output", required_argument, NULL, 'o' },
6318 { "plain", no_argument, NULL, ARG_PLAIN },
6319 { "state", required_argument, NULL, ARG_STATE },
6320 { "recursive", no_argument, NULL, 'r' },
6321 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6330 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6339 puts(PACKAGE_STRING);
6340 puts(SYSTEMD_FEATURES);
6344 const char *word, *state;
6347 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6348 _cleanup_free_ char *type;
6350 type = strndup(word, size);
6354 if (streq(type, "help")) {
6359 if (unit_type_from_string(type) >= 0) {
6360 if (strv_push(&arg_types, type))
6366 /* It's much nicer to use --state= for
6367 * load states, but let's support this
6368 * in --types= too for compatibility
6369 * with old versions */
6370 if (unit_load_state_from_string(optarg) >= 0) {
6371 if (strv_push(&arg_states, type) < 0)
6377 log_error("Unknown unit type or load state '%s'.", type);
6378 log_info("Use -t help to see a list of allowed values.");
6386 /* Make sure that if the empty property list
6387 was specified, we won't show any properties. */
6388 if (isempty(optarg) && !arg_properties) {
6389 arg_properties = new0(char*, 1);
6390 if (!arg_properties)
6393 const char *word, *state;
6396 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6399 prop = strndup(word, size);
6403 if (strv_consume(&arg_properties, prop) < 0)
6408 /* If the user asked for a particular
6409 * property, show it to him, even if it is
6421 arg_dependency = DEPENDENCY_REVERSE;
6425 arg_dependency = DEPENDENCY_AFTER;
6429 arg_dependency = DEPENDENCY_BEFORE;
6432 case ARG_SHOW_TYPES:
6433 arg_show_types = true;
6437 arg_job_mode = optarg;
6441 arg_job_mode = "fail";
6444 case ARG_IRREVERSIBLE:
6445 arg_job_mode = "replace-irreversibly";
6448 case ARG_IGNORE_DEPENDENCIES:
6449 arg_job_mode = "ignore-dependencies";
6453 arg_scope = UNIT_FILE_USER;
6457 arg_scope = UNIT_FILE_SYSTEM;
6461 arg_scope = UNIT_FILE_GLOBAL;
6465 arg_no_block = true;
6469 arg_no_legend = true;
6473 arg_no_pager = true;
6489 if (strv_extend(&arg_states, "failed") < 0)
6507 arg_no_reload = true;
6511 arg_kill_who = optarg;
6515 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6516 log_error("Failed to parse signal string %s.", optarg);
6521 case ARG_NO_ASK_PASSWORD:
6522 arg_ask_password = false;
6526 arg_transport = BUS_TRANSPORT_REMOTE;
6531 arg_transport = BUS_TRANSPORT_MACHINE;
6540 if (safe_atou(optarg, &arg_lines) < 0) {
6541 log_error("Failed to parse lines '%s'", optarg);
6547 arg_output = output_mode_from_string(optarg);
6548 if (arg_output < 0) {
6549 log_error("Unknown output '%s'.", optarg);
6555 arg_ignore_inhibitors = true;
6563 const char *word, *state;
6566 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6569 s = strndup(word, size);
6573 if (strv_consume(&arg_states, s) < 0)
6580 if (geteuid() != 0) {
6581 log_error("--recursive requires root privileges.");
6585 arg_recursive = true;
6588 case ARG_PRESET_MODE:
6590 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6591 if (arg_preset_mode < 0) {
6592 log_error("Failed to parse preset mode: %s.", optarg);
6602 assert_not_reached("Unhandled option");
6605 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6606 log_error("Cannot access user instance remotely.");
6613 static int halt_parse_argv(int argc, char *argv[]) {
6622 static const struct option options[] = {
6623 { "help", no_argument, NULL, ARG_HELP },
6624 { "halt", no_argument, NULL, ARG_HALT },
6625 { "poweroff", no_argument, NULL, 'p' },
6626 { "reboot", no_argument, NULL, ARG_REBOOT },
6627 { "force", no_argument, NULL, 'f' },
6628 { "wtmp-only", no_argument, NULL, 'w' },
6629 { "no-wtmp", no_argument, NULL, 'd' },
6630 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6639 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6640 if (runlevel == '0' || runlevel == '6')
6643 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6651 arg_action = ACTION_HALT;
6655 if (arg_action != ACTION_REBOOT)
6656 arg_action = ACTION_POWEROFF;
6660 arg_action = ACTION_REBOOT;
6682 /* Compatibility nops */
6689 assert_not_reached("Unhandled option");
6692 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6693 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6696 } else if (optind < argc) {
6697 log_error("Too many arguments.");
6704 static int parse_time_spec(const char *t, usec_t *_u) {
6708 if (streq(t, "now"))
6710 else if (!strchr(t, ':')) {
6713 if (safe_atou64(t, &u) < 0)
6716 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6725 hour = strtol(t, &e, 10);
6726 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6729 minute = strtol(e+1, &e, 10);
6730 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6733 n = now(CLOCK_REALTIME);
6734 s = (time_t) (n / USEC_PER_SEC);
6736 assert_se(localtime_r(&s, &tm));
6738 tm.tm_hour = (int) hour;
6739 tm.tm_min = (int) minute;
6742 assert_se(s = mktime(&tm));
6744 *_u = (usec_t) s * USEC_PER_SEC;
6747 *_u += USEC_PER_DAY;
6753 static int shutdown_parse_argv(int argc, char *argv[]) {
6760 static const struct option options[] = {
6761 { "help", no_argument, NULL, ARG_HELP },
6762 { "halt", no_argument, NULL, 'H' },
6763 { "poweroff", no_argument, NULL, 'P' },
6764 { "reboot", no_argument, NULL, 'r' },
6765 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6766 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6775 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6783 arg_action = ACTION_HALT;
6787 arg_action = ACTION_POWEROFF;
6792 arg_action = ACTION_KEXEC;
6794 arg_action = ACTION_REBOOT;
6798 arg_action = ACTION_KEXEC;
6802 if (arg_action != ACTION_HALT)
6803 arg_action = ACTION_POWEROFF;
6818 /* Compatibility nops */
6822 arg_action = ACTION_CANCEL_SHUTDOWN;
6829 assert_not_reached("Unhandled option");
6832 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6833 r = parse_time_spec(argv[optind], &arg_when);
6835 log_error("Failed to parse time specification: %s", argv[optind]);
6839 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6841 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6842 /* No time argument for shutdown cancel */
6843 arg_wall = argv + optind;
6844 else if (argc > optind + 1)
6845 /* We skip the time argument */
6846 arg_wall = argv + optind + 1;
6853 static int telinit_parse_argv(int argc, char *argv[]) {
6860 static const struct option options[] = {
6861 { "help", no_argument, NULL, ARG_HELP },
6862 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6866 static const struct {
6870 { '0', ACTION_POWEROFF },
6871 { '6', ACTION_REBOOT },
6872 { '1', ACTION_RESCUE },
6873 { '2', ACTION_RUNLEVEL2 },
6874 { '3', ACTION_RUNLEVEL3 },
6875 { '4', ACTION_RUNLEVEL4 },
6876 { '5', ACTION_RUNLEVEL5 },
6877 { 's', ACTION_RESCUE },
6878 { 'S', ACTION_RESCUE },
6879 { 'q', ACTION_RELOAD },
6880 { 'Q', ACTION_RELOAD },
6881 { 'u', ACTION_REEXEC },
6882 { 'U', ACTION_REEXEC }
6891 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6906 assert_not_reached("Unhandled option");
6909 if (optind >= argc) {
6910 log_error("%s: required argument missing.",
6911 program_invocation_short_name);
6915 if (optind + 1 < argc) {
6916 log_error("Too many arguments.");
6920 if (strlen(argv[optind]) != 1) {
6921 log_error("Expected single character argument.");
6925 for (i = 0; i < ELEMENTSOF(table); i++)
6926 if (table[i].from == argv[optind][0])
6929 if (i >= ELEMENTSOF(table)) {
6930 log_error("Unknown command '%s'.", argv[optind]);
6934 arg_action = table[i].to;
6941 static int runlevel_parse_argv(int argc, char *argv[]) {
6947 static const struct option options[] = {
6948 { "help", no_argument, NULL, ARG_HELP },
6957 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6968 assert_not_reached("Unhandled option");
6971 if (optind < argc) {
6972 log_error("Too many arguments.");
6979 static int parse_argv(int argc, char *argv[]) {
6983 if (program_invocation_short_name) {
6985 if (strstr(program_invocation_short_name, "halt")) {
6986 arg_action = ACTION_HALT;
6987 return halt_parse_argv(argc, argv);
6988 } else if (strstr(program_invocation_short_name, "poweroff")) {
6989 arg_action = ACTION_POWEROFF;
6990 return halt_parse_argv(argc, argv);
6991 } else if (strstr(program_invocation_short_name, "reboot")) {
6993 arg_action = ACTION_KEXEC;
6995 arg_action = ACTION_REBOOT;
6996 return halt_parse_argv(argc, argv);
6997 } else if (strstr(program_invocation_short_name, "shutdown")) {
6998 arg_action = ACTION_POWEROFF;
6999 return shutdown_parse_argv(argc, argv);
7000 } else if (strstr(program_invocation_short_name, "init")) {
7002 if (sd_booted() > 0) {
7003 arg_action = _ACTION_INVALID;
7004 return telinit_parse_argv(argc, argv);
7006 /* Hmm, so some other init system is
7007 * running, we need to forward this
7008 * request to it. For now we simply
7009 * guess that it is Upstart. */
7011 execv(TELINIT, argv);
7013 log_error("Couldn't find an alternative telinit implementation to spawn.");
7017 } else if (strstr(program_invocation_short_name, "runlevel")) {
7018 arg_action = ACTION_RUNLEVEL;
7019 return runlevel_parse_argv(argc, argv);
7023 arg_action = ACTION_SYSTEMCTL;
7024 return systemctl_parse_argv(argc, argv);
7027 _pure_ static int action_to_runlevel(void) {
7029 static const char table[_ACTION_MAX] = {
7030 [ACTION_HALT] = '0',
7031 [ACTION_POWEROFF] = '0',
7032 [ACTION_REBOOT] = '6',
7033 [ACTION_RUNLEVEL2] = '2',
7034 [ACTION_RUNLEVEL3] = '3',
7035 [ACTION_RUNLEVEL4] = '4',
7036 [ACTION_RUNLEVEL5] = '5',
7037 [ACTION_RESCUE] = '1'
7040 assert(arg_action < _ACTION_MAX);
7042 return table[arg_action];
7045 static int talk_initctl(void) {
7047 struct init_request request = {
7048 .magic = INIT_MAGIC,
7050 .cmd = INIT_CMD_RUNLVL
7053 _cleanup_close_ int fd = -1;
7057 rl = action_to_runlevel();
7061 request.runlevel = rl;
7063 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7065 if (errno == ENOENT)
7068 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7072 r = loop_write(fd, &request, sizeof(request), false);
7074 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7079 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7081 static const struct {
7089 int (* const dispatch)(sd_bus *bus, char **args);
7095 { "list-units", MORE, 0, list_units },
7096 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7097 { "list-sockets", MORE, 1, list_sockets },
7098 { "list-timers", MORE, 1, list_timers },
7099 { "list-jobs", MORE, 1, list_jobs },
7100 { "list-machines", MORE, 1, list_machines },
7101 { "clear-jobs", EQUAL, 1, daemon_reload },
7102 { "cancel", MORE, 2, cancel_job },
7103 { "start", MORE, 2, start_unit },
7104 { "stop", MORE, 2, start_unit },
7105 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7106 { "reload", MORE, 2, start_unit },
7107 { "restart", MORE, 2, start_unit },
7108 { "try-restart", MORE, 2, start_unit },
7109 { "reload-or-restart", MORE, 2, start_unit },
7110 { "reload-or-try-restart", MORE, 2, start_unit },
7111 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7112 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7113 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7114 { "isolate", EQUAL, 2, start_unit },
7115 { "kill", MORE, 2, kill_unit },
7116 { "is-active", MORE, 2, check_unit_active },
7117 { "check", MORE, 2, check_unit_active },
7118 { "is-failed", MORE, 2, check_unit_failed },
7119 { "show", MORE, 1, show },
7120 { "cat", MORE, 2, cat, NOBUS },
7121 { "status", MORE, 1, show },
7122 { "help", MORE, 2, show },
7123 { "snapshot", LESS, 2, snapshot },
7124 { "delete", MORE, 2, delete_snapshot },
7125 { "daemon-reload", EQUAL, 1, daemon_reload },
7126 { "daemon-reexec", EQUAL, 1, daemon_reload },
7127 { "show-environment", EQUAL, 1, show_environment },
7128 { "set-environment", MORE, 2, set_environment },
7129 { "unset-environment", MORE, 2, set_environment },
7130 { "import-environment", MORE, 1, import_environment},
7131 { "halt", EQUAL, 1, start_special, FORCE },
7132 { "poweroff", EQUAL, 1, start_special, FORCE },
7133 { "reboot", MORE, 1, start_special, FORCE },
7134 { "kexec", EQUAL, 1, start_special },
7135 { "suspend", EQUAL, 1, start_special },
7136 { "hibernate", EQUAL, 1, start_special },
7137 { "hybrid-sleep", EQUAL, 1, start_special },
7138 { "default", EQUAL, 1, start_special },
7139 { "rescue", EQUAL, 1, start_special },
7140 { "emergency", EQUAL, 1, start_special },
7141 { "exit", EQUAL, 1, start_special },
7142 { "reset-failed", MORE, 1, reset_failed },
7143 { "enable", MORE, 2, enable_unit, NOBUS },
7144 { "disable", MORE, 2, enable_unit, NOBUS },
7145 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7146 { "reenable", MORE, 2, enable_unit, NOBUS },
7147 { "preset", MORE, 2, enable_unit, NOBUS },
7148 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7149 { "mask", MORE, 2, enable_unit, NOBUS },
7150 { "unmask", MORE, 2, enable_unit, NOBUS },
7151 { "link", MORE, 2, enable_unit, NOBUS },
7152 { "switch-root", MORE, 2, switch_root },
7153 { "list-dependencies", LESS, 2, list_dependencies },
7154 { "set-default", EQUAL, 2, set_default, NOBUS },
7155 { "get-default", EQUAL, 1, get_default, NOBUS },
7156 { "set-property", MORE, 3, set_property },
7157 { "is-system-running", EQUAL, 1, is_system_running },
7158 { "add-wants", MORE, 3, add_dependency, NOBUS },
7159 { "add-requires", MORE, 3, add_dependency, NOBUS },
7160 { "edit", MORE, 2, edit, NOBUS },
7169 left = argc - optind;
7171 /* Special rule: no arguments (left == 0) means "list-units" */
7173 if (streq(argv[optind], "help") && !argv[optind+1]) {
7174 log_error("This command expects one or more "
7175 "unit names. Did you mean --help?");
7179 for (; verb->verb; verb++)
7180 if (streq(argv[optind], verb->verb))
7183 log_error("Unknown operation '%s'.", argv[optind]);
7188 switch (verb->argc_cmp) {
7191 if (left != verb->argc) {
7192 log_error("Invalid number of arguments.");
7199 if (left < verb->argc) {
7200 log_error("Too few arguments.");
7207 if (left > verb->argc) {
7208 log_error("Too many arguments.");
7215 assert_not_reached("Unknown comparison operator.");
7218 /* Require a bus connection for all operations but
7220 if (verb->bus == NOBUS) {
7221 if (!bus && !avoid_bus()) {
7222 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7227 if (running_in_chroot() > 0) {
7228 log_info("Running in chroot, ignoring request.");
7232 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7233 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7238 return verb->dispatch(bus, argv + optind);
7241 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7243 struct sd_shutdown_command c = {
7250 union sockaddr_union sockaddr = {
7251 .un.sun_family = AF_UNIX,
7252 .un.sun_path = "/run/systemd/shutdownd",
7255 struct iovec iovec[2] = {{
7256 .iov_base = (char*) &c,
7257 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7260 struct msghdr msghdr = {
7261 .msg_name = &sockaddr,
7262 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7263 + strlen("/run/systemd/shutdownd"),
7268 _cleanup_close_ int fd;
7270 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7274 if (!isempty(message)) {
7275 iovec[1].iov_base = (char*) message;
7276 iovec[1].iov_len = strlen(message);
7277 msghdr.msg_iovlen++;
7280 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7286 static int reload_with_fallback(sd_bus *bus) {
7289 /* First, try systemd via D-Bus. */
7290 if (daemon_reload(bus, NULL) >= 0)
7294 /* Nothing else worked, so let's try signals */
7295 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7297 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7298 return log_error_errno(errno, "kill() failed: %m");
7303 static int start_with_fallback(sd_bus *bus) {
7306 /* First, try systemd via D-Bus. */
7307 if (start_unit(bus, NULL) >= 0)
7311 /* Nothing else worked, so let's try
7313 if (talk_initctl() > 0)
7316 log_error("Failed to talk to init daemon.");
7320 warn_wall(arg_action);
7324 static int halt_now(enum action a) {
7326 /* The kernel will automaticall flush ATA disks and suchlike
7327 * on reboot(), but the file systems need to be synce'd
7328 * explicitly in advance. */
7331 /* Make sure C-A-D is handled by the kernel from this point
7333 reboot(RB_ENABLE_CAD);
7338 log_info("Halting.");
7339 reboot(RB_HALT_SYSTEM);
7342 case ACTION_POWEROFF:
7343 log_info("Powering off.");
7344 reboot(RB_POWER_OFF);
7347 case ACTION_REBOOT: {
7348 _cleanup_free_ char *param = NULL;
7350 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7351 log_info("Rebooting with argument '%s'.", param);
7352 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7353 LINUX_REBOOT_CMD_RESTART2, param);
7356 log_info("Rebooting.");
7357 reboot(RB_AUTOBOOT);
7362 assert_not_reached("Unknown action.");
7366 static int halt_main(sd_bus *bus) {
7369 r = check_inhibitors(bus, arg_action);
7373 if (geteuid() != 0) {
7374 /* Try logind if we are a normal user and no special
7375 * mode applies. Maybe PolicyKit allows us to shutdown
7378 if (arg_when <= 0 &&
7381 (arg_action == ACTION_POWEROFF ||
7382 arg_action == ACTION_REBOOT)) {
7383 r = reboot_with_logind(bus, arg_action);
7388 log_error("Must be root.");
7393 _cleanup_free_ char *m;
7395 m = strv_join(arg_wall, " ");
7399 r = send_shutdownd(arg_when,
7400 arg_action == ACTION_HALT ? 'H' :
7401 arg_action == ACTION_POWEROFF ? 'P' :
7402 arg_action == ACTION_KEXEC ? 'K' :
7409 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7411 char date[FORMAT_TIMESTAMP_MAX];
7413 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7414 format_timestamp(date, sizeof(date), arg_when));
7419 if (!arg_dry && !arg_force)
7420 return start_with_fallback(bus);
7423 if (sd_booted() > 0)
7424 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7426 r = utmp_put_shutdown();
7428 log_warning_errno(r, "Failed to write utmp record: %m");
7435 r = halt_now(arg_action);
7436 log_error_errno(r, "Failed to reboot: %m");
7441 static int runlevel_main(void) {
7442 int r, runlevel, previous;
7444 r = utmp_get_runlevel(&runlevel, &previous);
7451 previous <= 0 ? 'N' : previous,
7452 runlevel <= 0 ? 'N' : runlevel);
7457 int main(int argc, char*argv[]) {
7458 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7461 setlocale(LC_ALL, "");
7462 log_parse_environment();
7465 /* Explicitly not on_tty() to avoid setting cached value.
7466 * This becomes relevant for piping output which might be
7468 original_stdout_is_tty = isatty(STDOUT_FILENO);
7470 r = parse_argv(argc, argv);
7474 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7475 * let's shortcut this */
7476 if (arg_action == ACTION_RUNLEVEL) {
7477 r = runlevel_main();
7481 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7482 log_info("Running in chroot, ignoring request.");
7487 /* Increase max number of open files to 16K if we can, we
7488 * might needs this when browsing journal files, which might
7489 * be split up into many files. */
7490 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7493 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7495 /* systemctl_main() will print an error message for the bus
7496 * connection, but only if it needs to */
7498 switch (arg_action) {
7500 case ACTION_SYSTEMCTL:
7501 r = systemctl_main(bus, argc, argv, r);
7505 case ACTION_POWEROFF:
7511 case ACTION_RUNLEVEL2:
7512 case ACTION_RUNLEVEL3:
7513 case ACTION_RUNLEVEL4:
7514 case ACTION_RUNLEVEL5:
7516 case ACTION_EMERGENCY:
7517 case ACTION_DEFAULT:
7518 r = start_with_fallback(bus);
7523 r = reload_with_fallback(bus);
7526 case ACTION_CANCEL_SHUTDOWN: {
7527 _cleanup_free_ char *m = NULL;
7530 m = strv_join(arg_wall, " ");
7537 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7539 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7543 case ACTION_RUNLEVEL:
7544 case _ACTION_INVALID:
7546 assert_not_reached("Unknown action");
7551 ask_password_agent_close();
7552 polkit_agent_close();
7554 strv_free(arg_types);
7555 strv_free(arg_states);
7556 strv_free(arg_properties);
7558 return r < 0 ? EXIT_FAILURE : r;