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_free_ char *unit = NULL;
2313 _cleanup_free_ char *path = NULL;
2314 _cleanup_strv_free_ char **dropins = NULL;
2316 unit = unit_dbus_path_from_name(unit_name);
2320 if (need_daemon_reload(bus, unit_name) > 0)
2321 warn_unit_file_changed(unit_name);
2323 r = sd_bus_get_property_string(
2325 "org.freedesktop.systemd1",
2327 "org.freedesktop.systemd1.Unit",
2332 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2334 r = sd_bus_get_property_strv(
2336 "org.freedesktop.systemd1",
2338 "org.freedesktop.systemd1.Unit",
2343 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2346 if (!isempty(path)) {
2347 *fragment_path = path;
2352 if (dropin_paths && !strv_isempty(dropins)) {
2353 *dropin_paths = dropins;
2358 _cleanup_set_free_ Set *names;
2360 names = set_new(NULL);
2364 r = set_put(names, unit_name);
2368 r = unit_file_find_path(lp, unit_name, fragment_path);
2373 _cleanup_free_ char *template;
2375 template = unit_name_template(unit_name);
2379 if (!streq(template, unit_name)) {
2380 r = unit_file_find_path(lp, template, fragment_path);
2387 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
2393 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2394 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2395 _cleanup_free_ char *n = NULL, *state = NULL;
2401 n = unit_name_mangle(name, MANGLE_NOGLOB);
2405 /* We don't use unit_dbus_path_from_name() directly since we
2406 * don't want to load the unit if it isn't loaded. */
2408 r = sd_bus_call_method(
2410 "org.freedesktop.systemd1",
2411 "/org/freedesktop/systemd1",
2412 "org.freedesktop.systemd1.Manager",
2423 r = sd_bus_message_read(reply, "o", &path);
2425 return bus_log_parse_error(r);
2427 r = sd_bus_get_property_string(
2429 "org.freedesktop.systemd1",
2431 "org.freedesktop.systemd1.Unit",
2444 return nulstr_contains(good_states, state);
2447 static int check_triggering_units(
2451 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2452 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2453 _cleanup_strv_free_ char **triggered_by = NULL;
2454 bool print_warning_label = true;
2458 n = unit_name_mangle(name, MANGLE_NOGLOB);
2462 path = unit_dbus_path_from_name(n);
2466 r = sd_bus_get_property_string(
2468 "org.freedesktop.systemd1",
2470 "org.freedesktop.systemd1.Unit",
2475 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2479 if (streq(state, "masked"))
2482 r = sd_bus_get_property_strv(
2484 "org.freedesktop.systemd1",
2486 "org.freedesktop.systemd1.Unit",
2491 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2495 STRV_FOREACH(i, triggered_by) {
2496 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2498 return log_error_errno(r, "Failed to check unit: %m");
2503 if (print_warning_label) {
2504 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2505 print_warning_label = false;
2508 log_warning(" %s", *i);
2514 static const struct {
2517 } unit_actions[] = {
2518 { "start", "StartUnit" },
2519 { "stop", "StopUnit" },
2520 { "condstop", "StopUnit" },
2521 { "reload", "ReloadUnit" },
2522 { "restart", "RestartUnit" },
2523 { "try-restart", "TryRestartUnit" },
2524 { "condrestart", "TryRestartUnit" },
2525 { "reload-or-restart", "ReloadOrRestartUnit" },
2526 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2527 { "condreload", "ReloadOrTryRestartUnit" },
2528 { "force-reload", "ReloadOrTryRestartUnit" }
2531 static const char *verb_to_method(const char *verb) {
2534 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2535 if (streq_ptr(unit_actions[i].verb, verb))
2536 return unit_actions[i].method;
2541 static const char *method_to_verb(const char *method) {
2544 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2545 if (streq_ptr(unit_actions[i].method, method))
2546 return unit_actions[i].verb;
2551 static int start_unit_one(
2556 sd_bus_error *error,
2557 BusWaitForJobs *w) {
2559 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2568 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2570 r = sd_bus_message_new_method_call(
2573 "org.freedesktop.systemd1",
2574 "/org/freedesktop/systemd1",
2575 "org.freedesktop.systemd1.Manager",
2578 return bus_log_create_error(r);
2580 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2582 return bus_log_create_error(r);
2584 r = sd_bus_message_append(m, "ss", name, mode);
2586 return bus_log_create_error(r);
2588 r = sd_bus_call(bus, m, 0, error, &reply);
2592 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2593 /* There's always a fallback possible for
2594 * legacy actions. */
2595 return -EADDRNOTAVAIL;
2597 verb = method_to_verb(method);
2599 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2603 r = sd_bus_message_read(reply, "o", &path);
2605 return bus_log_parse_error(r);
2607 if (need_daemon_reload(bus, name) > 0)
2608 warn_unit_file_changed(name);
2611 log_debug("Adding %s to the set", path);
2612 r = bus_wait_for_jobs_add(w, path);
2620 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2622 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2626 STRV_FOREACH(name, names) {
2630 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2632 t = unit_name_mangle(*name, MANGLE_GLOB);
2636 if (string_is_glob(t))
2637 r = strv_consume(&globs, t);
2639 r = strv_consume(&mangled, t);
2644 /* Query the manager only if any of the names are a glob, since
2645 * this is fairly expensive */
2646 if (!strv_isempty(globs)) {
2647 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2648 _cleanup_free_ UnitInfo *unit_infos = NULL;
2651 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2653 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2657 for (i = 0; i < r; i++)
2658 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2663 mangled = NULL; /* do not free */
2668 static const struct {
2672 } action_table[_ACTION_MAX] = {
2673 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2674 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2675 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2676 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2677 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2678 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2679 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2680 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2681 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2682 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2683 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2684 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2685 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2686 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2687 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2690 static enum action verb_to_action(const char *verb) {
2693 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2694 if (streq_ptr(action_table[i].verb, verb))
2697 return _ACTION_INVALID;
2700 static int start_unit(sd_bus *bus, char **args) {
2701 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2702 const char *method, *mode, *one_name, *suffix = NULL;
2703 _cleanup_strv_free_ char **names = NULL;
2709 ask_password_agent_open_if_enabled();
2710 polkit_agent_open_if_enabled();
2712 if (arg_action == ACTION_SYSTEMCTL) {
2714 method = verb_to_method(args[0]);
2715 action = verb_to_action(args[0]);
2717 if (streq(args[0], "isolate")) {
2721 mode = action_table[action].mode ?: arg_job_mode;
2723 one_name = action_table[action].target;
2725 assert(arg_action < ELEMENTSOF(action_table));
2726 assert(action_table[arg_action].target);
2728 method = "StartUnit";
2730 mode = action_table[arg_action].mode;
2731 one_name = action_table[arg_action].target;
2735 names = strv_new(one_name, NULL);
2737 r = expand_names(bus, args + 1, suffix, &names);
2739 log_error_errno(r, "Failed to expand names: %m");
2742 if (!arg_no_block) {
2743 r = bus_wait_for_jobs_new(bus, &w);
2745 return log_error_errno(r, "Could not watch jobs: %m");
2748 STRV_FOREACH(name, names) {
2749 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2752 q = start_unit_one(bus, method, *name, mode, &error, w);
2753 if (r >= 0 && q < 0)
2754 r = translate_bus_error_to_exit_status(q, &error);
2757 if (!arg_no_block) {
2760 q = bus_wait_for_jobs(w, arg_quiet);
2764 /* When stopping units, warn if they can still be triggered by
2765 * another active unit (socket, path, timer) */
2766 if (!arg_quiet && streq(method, "StopUnit"))
2767 STRV_FOREACH(name, names)
2768 check_triggering_units(bus, *name);
2774 /* Ask systemd-logind, which might grant access to unprivileged users
2775 * through PolicyKit */
2776 static int reboot_with_logind(sd_bus *bus, enum action a) {
2778 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2785 polkit_agent_open_if_enabled();
2793 case ACTION_POWEROFF:
2794 method = "PowerOff";
2797 case ACTION_SUSPEND:
2801 case ACTION_HIBERNATE:
2802 method = "Hibernate";
2805 case ACTION_HYBRID_SLEEP:
2806 method = "HybridSleep";
2813 r = sd_bus_call_method(
2815 "org.freedesktop.login1",
2816 "/org/freedesktop/login1",
2817 "org.freedesktop.login1.Manager",
2821 "b", arg_ask_password);
2823 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2831 static int check_inhibitors(sd_bus *bus, enum action a) {
2833 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2834 _cleanup_strv_free_ char **sessions = NULL;
2835 const char *what, *who, *why, *mode;
2844 if (arg_ignore_inhibitors || arg_force > 0)
2856 r = sd_bus_call_method(
2858 "org.freedesktop.login1",
2859 "/org/freedesktop/login1",
2860 "org.freedesktop.login1.Manager",
2866 /* If logind is not around, then there are no inhibitors... */
2869 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2871 return bus_log_parse_error(r);
2873 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2874 _cleanup_free_ char *comm = NULL, *user = NULL;
2875 _cleanup_strv_free_ char **sv = NULL;
2877 if (!streq(mode, "block"))
2880 sv = strv_split(what, ":");
2884 if (!strv_contains(sv,
2886 a == ACTION_POWEROFF ||
2887 a == ACTION_REBOOT ||
2888 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2891 get_process_comm(pid, &comm);
2892 user = uid_to_name(uid);
2894 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2895 who, pid, strna(comm), strna(user), why);
2900 return bus_log_parse_error(r);
2902 r = sd_bus_message_exit_container(reply);
2904 return bus_log_parse_error(r);
2906 /* Check for current sessions */
2907 sd_get_sessions(&sessions);
2908 STRV_FOREACH(s, sessions) {
2909 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2911 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2914 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2917 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2920 sd_session_get_tty(*s, &tty);
2921 sd_session_get_seat(*s, &seat);
2922 sd_session_get_service(*s, &service);
2923 user = uid_to_name(uid);
2925 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2932 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2933 action_table[a].verb);
2941 static int start_special(sd_bus *bus, char **args) {
2947 a = verb_to_action(args[0]);
2949 r = check_inhibitors(bus, a);
2953 if (arg_force >= 2 && geteuid() != 0) {
2954 log_error("Must be root.");
2958 if (a == ACTION_REBOOT) {
2959 r = update_reboot_param_file(args[1]);
2964 if (arg_force >= 2 &&
2965 (a == ACTION_HALT ||
2966 a == ACTION_POWEROFF ||
2967 a == ACTION_REBOOT))
2970 if (arg_force >= 1 &&
2971 (a == ACTION_HALT ||
2972 a == ACTION_POWEROFF ||
2973 a == ACTION_REBOOT ||
2974 a == ACTION_KEXEC ||
2976 return daemon_reload(bus, args);
2978 /* first try logind, to allow authentication with polkit */
2979 if (geteuid() != 0 &&
2980 (a == ACTION_POWEROFF ||
2981 a == ACTION_REBOOT ||
2982 a == ACTION_SUSPEND ||
2983 a == ACTION_HIBERNATE ||
2984 a == ACTION_HYBRID_SLEEP)) {
2985 r = reboot_with_logind(bus, a);
2986 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
2990 r = start_unit(bus, args);
2991 if (r == EXIT_SUCCESS)
2997 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2998 _cleanup_strv_free_ char **names = NULL;
3005 r = expand_names(bus, args, NULL, &names);
3007 return log_error_errno(r, "Failed to expand names: %m");
3009 STRV_FOREACH(name, names) {
3012 state = check_one_unit(bus, *name, good_states, arg_quiet);
3022 static int check_unit_active(sd_bus *bus, char **args) {
3023 /* According to LSB: 3, "program is not running" */
3024 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3027 static int check_unit_failed(sd_bus *bus, char **args) {
3028 return check_unit_generic(bus, 1, "failed\0", args + 1);
3031 static int kill_unit(sd_bus *bus, char **args) {
3032 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3033 _cleanup_strv_free_ char **names = NULL;
3040 polkit_agent_open_if_enabled();
3043 arg_kill_who = "all";
3045 r = expand_names(bus, args + 1, NULL, &names);
3047 log_error_errno(r, "Failed to expand names: %m");
3049 STRV_FOREACH(name, names) {
3050 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3052 q = sd_bus_message_new_method_call(
3055 "org.freedesktop.systemd1",
3056 "/org/freedesktop/systemd1",
3057 "org.freedesktop.systemd1.Manager",
3060 return bus_log_create_error(q);
3062 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3064 return bus_log_create_error(q);
3066 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3068 return bus_log_create_error(q);
3070 q = sd_bus_call(bus, m, 0, &error, NULL);
3072 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3081 typedef struct ExecStatusInfo {
3089 usec_t start_timestamp;
3090 usec_t exit_timestamp;
3095 LIST_FIELDS(struct ExecStatusInfo, exec);
3098 static void exec_status_info_free(ExecStatusInfo *i) {
3107 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3108 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3111 int32_t code, status;
3117 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3119 return bus_log_parse_error(r);
3123 r = sd_bus_message_read(m, "s", &path);
3125 return bus_log_parse_error(r);
3127 i->path = strdup(path);
3131 r = sd_bus_message_read_strv(m, &i->argv);
3133 return bus_log_parse_error(r);
3135 r = sd_bus_message_read(m,
3138 &start_timestamp, &start_timestamp_monotonic,
3139 &exit_timestamp, &exit_timestamp_monotonic,
3143 return bus_log_parse_error(r);
3146 i->start_timestamp = (usec_t) start_timestamp;
3147 i->exit_timestamp = (usec_t) exit_timestamp;
3148 i->pid = (pid_t) pid;
3152 r = sd_bus_message_exit_container(m);
3154 return bus_log_parse_error(r);
3159 typedef struct UnitStatusInfo {
3161 const char *load_state;
3162 const char *active_state;
3163 const char *sub_state;
3164 const char *unit_file_state;
3165 const char *unit_file_preset;
3167 const char *description;
3168 const char *following;
3170 char **documentation;
3172 const char *fragment_path;
3173 const char *source_path;
3174 const char *control_group;
3176 char **dropin_paths;
3178 const char *load_error;
3181 usec_t inactive_exit_timestamp;
3182 usec_t inactive_exit_timestamp_monotonic;
3183 usec_t active_enter_timestamp;
3184 usec_t active_exit_timestamp;
3185 usec_t inactive_enter_timestamp;
3187 bool need_daemon_reload;
3192 const char *status_text;
3193 const char *pid_file;
3197 usec_t start_timestamp;
3198 usec_t exit_timestamp;
3200 int exit_code, exit_status;
3202 usec_t condition_timestamp;
3203 bool condition_result;
3204 bool failed_condition_trigger;
3205 bool failed_condition_negate;
3206 const char *failed_condition;
3207 const char *failed_condition_parameter;
3209 usec_t assert_timestamp;
3211 bool failed_assert_trigger;
3212 bool failed_assert_negate;
3213 const char *failed_assert;
3214 const char *failed_assert_parameter;
3217 unsigned n_accepted;
3218 unsigned n_connections;
3221 /* Pairs of type, path */
3225 const char *sysfs_path;
3227 /* Mount, Automount */
3234 uint64_t memory_current;
3235 uint64_t memory_limit;
3237 LIST_HEAD(ExecStatusInfo, exec);
3240 static void print_status_info(
3245 const char *active_on, *active_off, *on, *off, *ss;
3247 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3248 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3254 /* This shows pretty information about a unit. See
3255 * print_property() for a low-level property printer */
3257 if (streq_ptr(i->active_state, "failed")) {
3258 active_on = ansi_highlight_red();
3259 active_off = ansi_highlight_off();
3260 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3261 active_on = ansi_highlight_green();
3262 active_off = ansi_highlight_off();
3264 active_on = active_off = "";
3266 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3268 if (i->description && !streq_ptr(i->id, i->description))
3269 printf(" - %s", i->description);
3274 printf(" Follow: unit currently follows state of %s\n", i->following);
3276 if (streq_ptr(i->load_state, "error")) {
3277 on = ansi_highlight_red();
3278 off = ansi_highlight_off();
3282 path = i->source_path ? i->source_path : i->fragment_path;
3285 printf(" Loaded: %s%s%s (Reason: %s)\n",
3286 on, strna(i->load_state), off, i->load_error);
3287 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3288 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3289 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3290 else if (path && !isempty(i->unit_file_state))
3291 printf(" Loaded: %s%s%s (%s; %s)\n",
3292 on, strna(i->load_state), off, path, i->unit_file_state);
3294 printf(" Loaded: %s%s%s (%s)\n",
3295 on, strna(i->load_state), off, path);
3297 printf(" Loaded: %s%s%s\n",
3298 on, strna(i->load_state), off);
3300 if (!strv_isempty(i->dropin_paths)) {
3301 _cleanup_free_ char *dir = NULL;
3305 STRV_FOREACH(dropin, i->dropin_paths) {
3306 if (! dir || last) {
3307 printf(dir ? " " : " Drop-In: ");
3312 if (path_get_parent(*dropin, &dir) < 0) {
3317 printf("%s\n %s", dir,
3318 draw_special_char(DRAW_TREE_RIGHT));
3321 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3323 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3327 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3329 printf(" Active: %s%s (%s)%s",
3330 active_on, strna(i->active_state), ss, active_off);
3332 printf(" Active: %s%s%s",
3333 active_on, strna(i->active_state), active_off);
3335 if (!isempty(i->result) && !streq(i->result, "success"))
3336 printf(" (Result: %s)", i->result);
3338 timestamp = (streq_ptr(i->active_state, "active") ||
3339 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3340 (streq_ptr(i->active_state, "inactive") ||
3341 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3342 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3343 i->active_exit_timestamp;
3345 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3346 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3349 printf(" since %s; %s\n", s2, s1);
3351 printf(" since %s\n", s2);
3355 if (!i->condition_result && i->condition_timestamp > 0) {
3356 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3357 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3359 printf("Condition: start %scondition failed%s at %s%s%s\n",
3360 ansi_highlight_yellow(), ansi_highlight_off(),
3361 s2, s1 ? "; " : "", s1 ? s1 : "");
3362 if (i->failed_condition_trigger)
3363 printf(" none of the trigger conditions were met\n");
3364 else if (i->failed_condition)
3365 printf(" %s=%s%s was not met\n",
3366 i->failed_condition,
3367 i->failed_condition_negate ? "!" : "",
3368 i->failed_condition_parameter);
3371 if (!i->assert_result && i->assert_timestamp > 0) {
3372 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3373 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3375 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3376 ansi_highlight_red(), ansi_highlight_off(),
3377 s2, s1 ? "; " : "", s1 ? s1 : "");
3378 if (i->failed_assert_trigger)
3379 printf(" none of the trigger assertions were met\n");
3380 else if (i->failed_assert)
3381 printf(" %s=%s%s was not met\n",
3383 i->failed_assert_negate ? "!" : "",
3384 i->failed_assert_parameter);
3388 printf(" Device: %s\n", i->sysfs_path);
3390 printf(" Where: %s\n", i->where);
3392 printf(" What: %s\n", i->what);
3394 STRV_FOREACH(t, i->documentation)
3395 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3397 STRV_FOREACH_PAIR(t, t2, i->listen)
3398 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3401 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3403 LIST_FOREACH(exec, p, i->exec) {
3404 _cleanup_free_ char *argv = NULL;
3407 /* Only show exited processes here */
3411 argv = strv_join(p->argv, " ");
3412 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3414 good = is_clean_exit_lsb(p->code, p->status, NULL);
3416 on = ansi_highlight_red();
3417 off = ansi_highlight_off();
3421 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3423 if (p->code == CLD_EXITED) {
3426 printf("status=%i", p->status);
3428 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3433 printf("signal=%s", signal_to_string(p->status));
3435 printf(")%s\n", off);
3437 if (i->main_pid == p->pid &&
3438 i->start_timestamp == p->start_timestamp &&
3439 i->exit_timestamp == p->start_timestamp)
3440 /* Let's not show this twice */
3443 if (p->pid == i->control_pid)
3447 if (i->main_pid > 0 || i->control_pid > 0) {
3448 if (i->main_pid > 0) {
3449 printf(" Main PID: "PID_FMT, i->main_pid);
3452 _cleanup_free_ char *comm = NULL;
3453 get_process_comm(i->main_pid, &comm);
3455 printf(" (%s)", comm);
3456 } else if (i->exit_code > 0) {
3457 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3459 if (i->exit_code == CLD_EXITED) {
3462 printf("status=%i", i->exit_status);
3464 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3469 printf("signal=%s", signal_to_string(i->exit_status));
3473 if (i->control_pid > 0)
3477 if (i->control_pid > 0) {
3478 _cleanup_free_ char *c = NULL;
3480 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3482 get_process_comm(i->control_pid, &c);
3491 printf(" Status: \"%s\"\n", i->status_text);
3492 if (i->status_errno > 0)
3493 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3495 if (i->memory_current != (uint64_t) -1) {
3496 char buf[FORMAT_BYTES_MAX];
3498 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3500 if (i->memory_limit != (uint64_t) -1)
3501 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3506 if (i->control_group &&
3507 (i->main_pid > 0 || i->control_pid > 0 ||
3508 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3511 printf(" CGroup: %s\n", i->control_group);
3513 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3516 static const char prefix[] = " ";
3519 if (c > sizeof(prefix) - 1)
3520 c -= sizeof(prefix) - 1;
3524 if (i->main_pid > 0)
3525 extra[k++] = i->main_pid;
3527 if (i->control_pid > 0)
3528 extra[k++] = i->control_pid;
3530 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3534 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3535 show_journal_by_unit(
3540 i->inactive_exit_timestamp_monotonic,
3543 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3544 SD_JOURNAL_LOCAL_ONLY,
3545 arg_scope == UNIT_FILE_SYSTEM,
3549 if (i->need_daemon_reload)
3550 warn_unit_file_changed(i->id);
3553 static void show_unit_help(UnitStatusInfo *i) {
3558 if (!i->documentation) {
3559 log_info("Documentation for %s not known.", i->id);
3563 STRV_FOREACH(p, i->documentation)
3564 if (startswith(*p, "man:"))
3565 show_man_page(*p + 4, false);
3567 log_info("Can't show: %s", *p);
3570 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3577 switch (contents[0]) {
3579 case SD_BUS_TYPE_STRING: {
3582 r = sd_bus_message_read(m, "s", &s);
3584 return bus_log_parse_error(r);
3587 if (streq(name, "Id"))
3589 else if (streq(name, "LoadState"))
3591 else if (streq(name, "ActiveState"))
3592 i->active_state = s;
3593 else if (streq(name, "SubState"))
3595 else if (streq(name, "Description"))
3597 else if (streq(name, "FragmentPath"))
3598 i->fragment_path = s;
3599 else if (streq(name, "SourcePath"))
3602 else if (streq(name, "DefaultControlGroup")) {
3604 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3606 i->control_group = e;
3609 else if (streq(name, "ControlGroup"))
3610 i->control_group = s;
3611 else if (streq(name, "StatusText"))
3613 else if (streq(name, "PIDFile"))
3615 else if (streq(name, "SysFSPath"))
3617 else if (streq(name, "Where"))
3619 else if (streq(name, "What"))
3621 else if (streq(name, "Following"))
3623 else if (streq(name, "UnitFileState"))
3624 i->unit_file_state = s;
3625 else if (streq(name, "UnitFilePreset"))
3626 i->unit_file_preset = s;
3627 else if (streq(name, "Result"))
3634 case SD_BUS_TYPE_BOOLEAN: {
3637 r = sd_bus_message_read(m, "b", &b);
3639 return bus_log_parse_error(r);
3641 if (streq(name, "Accept"))
3643 else if (streq(name, "NeedDaemonReload"))
3644 i->need_daemon_reload = b;
3645 else if (streq(name, "ConditionResult"))
3646 i->condition_result = b;
3647 else if (streq(name, "AssertResult"))
3648 i->assert_result = b;
3653 case SD_BUS_TYPE_UINT32: {
3656 r = sd_bus_message_read(m, "u", &u);
3658 return bus_log_parse_error(r);
3660 if (streq(name, "MainPID")) {
3662 i->main_pid = (pid_t) u;
3665 } else if (streq(name, "ControlPID"))
3666 i->control_pid = (pid_t) u;
3667 else if (streq(name, "ExecMainPID")) {
3669 i->main_pid = (pid_t) u;
3670 } else if (streq(name, "NAccepted"))
3672 else if (streq(name, "NConnections"))
3673 i->n_connections = u;
3678 case SD_BUS_TYPE_INT32: {
3681 r = sd_bus_message_read(m, "i", &j);
3683 return bus_log_parse_error(r);
3685 if (streq(name, "ExecMainCode"))
3686 i->exit_code = (int) j;
3687 else if (streq(name, "ExecMainStatus"))
3688 i->exit_status = (int) j;
3689 else if (streq(name, "StatusErrno"))
3690 i->status_errno = (int) j;
3695 case SD_BUS_TYPE_UINT64: {
3698 r = sd_bus_message_read(m, "t", &u);
3700 return bus_log_parse_error(r);
3702 if (streq(name, "ExecMainStartTimestamp"))
3703 i->start_timestamp = (usec_t) u;
3704 else if (streq(name, "ExecMainExitTimestamp"))
3705 i->exit_timestamp = (usec_t) u;
3706 else if (streq(name, "ActiveEnterTimestamp"))
3707 i->active_enter_timestamp = (usec_t) u;
3708 else if (streq(name, "InactiveEnterTimestamp"))
3709 i->inactive_enter_timestamp = (usec_t) u;
3710 else if (streq(name, "InactiveExitTimestamp"))
3711 i->inactive_exit_timestamp = (usec_t) u;
3712 else if (streq(name, "InactiveExitTimestampMonotonic"))
3713 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3714 else if (streq(name, "ActiveExitTimestamp"))
3715 i->active_exit_timestamp = (usec_t) u;
3716 else if (streq(name, "ConditionTimestamp"))
3717 i->condition_timestamp = (usec_t) u;
3718 else if (streq(name, "AssertTimestamp"))
3719 i->assert_timestamp = (usec_t) u;
3720 else if (streq(name, "MemoryCurrent"))
3721 i->memory_current = u;
3722 else if (streq(name, "MemoryLimit"))
3723 i->memory_limit = u;
3728 case SD_BUS_TYPE_ARRAY:
3730 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3731 _cleanup_free_ ExecStatusInfo *info = NULL;
3733 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3735 return bus_log_parse_error(r);
3737 info = new0(ExecStatusInfo, 1);
3741 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3743 info->name = strdup(name);
3747 LIST_PREPEND(exec, i->exec, info);
3749 info = new0(ExecStatusInfo, 1);
3755 return bus_log_parse_error(r);
3757 r = sd_bus_message_exit_container(m);
3759 return bus_log_parse_error(r);
3763 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3764 const char *type, *path;
3766 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3768 return bus_log_parse_error(r);
3770 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3772 r = strv_extend(&i->listen, type);
3776 r = strv_extend(&i->listen, path);
3781 return bus_log_parse_error(r);
3783 r = sd_bus_message_exit_container(m);
3785 return bus_log_parse_error(r);
3789 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3791 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3793 return bus_log_parse_error(r);
3795 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3797 r = sd_bus_message_read_strv(m, &i->documentation);
3799 return bus_log_parse_error(r);
3801 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3802 const char *cond, *param;
3803 int trigger, negate;
3806 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3808 return bus_log_parse_error(r);
3810 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3811 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3812 if (state < 0 && (!trigger || !i->failed_condition)) {
3813 i->failed_condition = cond;
3814 i->failed_condition_trigger = trigger;
3815 i->failed_condition_negate = negate;
3816 i->failed_condition_parameter = param;
3820 return bus_log_parse_error(r);
3822 r = sd_bus_message_exit_container(m);
3824 return bus_log_parse_error(r);
3826 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3827 const char *cond, *param;
3828 int trigger, negate;
3831 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3833 return bus_log_parse_error(r);
3835 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3836 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3837 if (state < 0 && (!trigger || !i->failed_assert)) {
3838 i->failed_assert = cond;
3839 i->failed_assert_trigger = trigger;
3840 i->failed_assert_negate = negate;
3841 i->failed_assert_parameter = param;
3845 return bus_log_parse_error(r);
3847 r = sd_bus_message_exit_container(m);
3849 return bus_log_parse_error(r);
3856 case SD_BUS_TYPE_STRUCT_BEGIN:
3858 if (streq(name, "LoadError")) {
3859 const char *n, *message;
3861 r = sd_bus_message_read(m, "(ss)", &n, &message);
3863 return bus_log_parse_error(r);
3865 if (!isempty(message))
3866 i->load_error = message;
3879 r = sd_bus_message_skip(m, contents);
3881 return bus_log_parse_error(r);
3886 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3892 /* This is a low-level property printer, see
3893 * print_status_info() for the nicer output */
3895 if (arg_properties && !strv_find(arg_properties, name)) {
3896 /* skip what we didn't read */
3897 r = sd_bus_message_skip(m, contents);
3901 switch (contents[0]) {
3903 case SD_BUS_TYPE_STRUCT_BEGIN:
3905 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3908 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3910 return bus_log_parse_error(r);
3913 printf("%s=%"PRIu32"\n", name, u);
3915 printf("%s=\n", name);
3919 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3922 r = sd_bus_message_read(m, "(so)", &s, NULL);
3924 return bus_log_parse_error(r);
3926 if (arg_all || !isempty(s))
3927 printf("%s=%s\n", name, s);
3931 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3932 const char *a = NULL, *b = NULL;
3934 r = sd_bus_message_read(m, "(ss)", &a, &b);
3936 return bus_log_parse_error(r);
3938 if (arg_all || !isempty(a) || !isempty(b))
3939 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3942 } else if (streq_ptr(name, "SystemCallFilter")) {
3943 _cleanup_strv_free_ char **l = NULL;
3946 r = sd_bus_message_enter_container(m, 'r', "bas");
3948 return bus_log_parse_error(r);
3950 r = sd_bus_message_read(m, "b", &whitelist);
3952 return bus_log_parse_error(r);
3954 r = sd_bus_message_read_strv(m, &l);
3956 return bus_log_parse_error(r);
3958 r = sd_bus_message_exit_container(m);
3960 return bus_log_parse_error(r);
3962 if (arg_all || whitelist || !strv_isempty(l)) {
3966 fputs(name, stdout);
3972 STRV_FOREACH(i, l) {
3980 fputc('\n', stdout);
3988 case SD_BUS_TYPE_ARRAY:
3990 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3994 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3996 return bus_log_parse_error(r);
3998 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3999 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4002 return bus_log_parse_error(r);
4004 r = sd_bus_message_exit_container(m);
4006 return bus_log_parse_error(r);
4010 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4011 const char *type, *path;
4013 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4015 return bus_log_parse_error(r);
4017 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4018 printf("%s=%s\n", type, path);
4020 return bus_log_parse_error(r);
4022 r = sd_bus_message_exit_container(m);
4024 return bus_log_parse_error(r);
4028 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4029 const char *type, *path;
4031 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4033 return bus_log_parse_error(r);
4035 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4036 printf("Listen%s=%s\n", type, path);
4038 return bus_log_parse_error(r);
4040 r = sd_bus_message_exit_container(m);
4042 return bus_log_parse_error(r);
4046 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4048 uint64_t value, next_elapse;
4050 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4052 return bus_log_parse_error(r);
4054 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4055 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4057 printf("%s={ value=%s ; next_elapse=%s }\n",
4059 format_timespan(timespan1, sizeof(timespan1), value, 0),
4060 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4063 return bus_log_parse_error(r);
4065 r = sd_bus_message_exit_container(m);
4067 return bus_log_parse_error(r);
4071 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4072 ExecStatusInfo info = {};
4074 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4076 return bus_log_parse_error(r);
4078 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4079 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4080 _cleanup_free_ char *tt;
4082 tt = strv_join(info.argv, " ");
4084 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",
4088 yes_no(info.ignore),
4089 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4090 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4092 sigchld_code_to_string(info.code),
4094 info.code == CLD_EXITED ? "" : "/",
4095 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4098 strv_free(info.argv);
4102 r = sd_bus_message_exit_container(m);
4104 return bus_log_parse_error(r);
4108 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4109 const char *path, *rwm;
4111 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4113 return bus_log_parse_error(r);
4115 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4116 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4118 return bus_log_parse_error(r);
4120 r = sd_bus_message_exit_container(m);
4122 return bus_log_parse_error(r);
4126 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4130 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4132 return bus_log_parse_error(r);
4134 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4135 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4137 return bus_log_parse_error(r);
4139 r = sd_bus_message_exit_container(m);
4141 return bus_log_parse_error(r);
4145 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4149 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4151 return bus_log_parse_error(r);
4153 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4154 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4156 return bus_log_parse_error(r);
4158 r = sd_bus_message_exit_container(m);
4160 return bus_log_parse_error(r);
4168 r = bus_print_property(name, m, arg_all);
4170 return bus_log_parse_error(r);
4173 r = sd_bus_message_skip(m, contents);
4175 return bus_log_parse_error(r);
4178 printf("%s=[unprintable]\n", name);
4184 static int show_one(
4188 bool show_properties,
4192 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4193 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4194 UnitStatusInfo info = {
4195 .memory_current = (uint64_t) -1,
4196 .memory_limit = (uint64_t) -1,
4204 log_debug("Showing one %s", path);
4206 r = sd_bus_call_method(
4208 "org.freedesktop.systemd1",
4210 "org.freedesktop.DBus.Properties",
4216 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4220 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4222 return bus_log_parse_error(r);
4229 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4230 const char *name, *contents;
4232 r = sd_bus_message_read(reply, "s", &name);
4234 return bus_log_parse_error(r);
4236 r = sd_bus_message_peek_type(reply, NULL, &contents);
4238 return bus_log_parse_error(r);
4240 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4242 return bus_log_parse_error(r);
4244 if (show_properties)
4245 r = print_property(name, reply, contents);
4247 r = status_property(name, reply, &info, contents);
4251 r = sd_bus_message_exit_container(reply);
4253 return bus_log_parse_error(r);
4255 r = sd_bus_message_exit_container(reply);
4257 return bus_log_parse_error(r);
4260 return bus_log_parse_error(r);
4262 r = sd_bus_message_exit_container(reply);
4264 return bus_log_parse_error(r);
4268 if (!show_properties) {
4269 if (streq(verb, "help"))
4270 show_unit_help(&info);
4272 print_status_info(&info, ellipsized);
4275 strv_free(info.documentation);
4276 strv_free(info.dropin_paths);
4277 strv_free(info.listen);
4279 if (!streq_ptr(info.active_state, "active") &&
4280 !streq_ptr(info.active_state, "reloading") &&
4281 streq(verb, "status")) {
4282 /* According to LSB: "program not running" */
4283 /* 0: program is running or service is OK
4284 * 1: program is dead and /run PID file exists
4285 * 2: program is dead and /run/lock lock file exists
4286 * 3: program is not running
4287 * 4: program or service status is unknown
4289 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4295 while ((p = info.exec)) {
4296 LIST_REMOVE(exec, info.exec, p);
4297 exec_status_info_free(p);
4303 static int get_unit_dbus_path_by_pid(
4308 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4309 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4313 r = sd_bus_call_method(
4315 "org.freedesktop.systemd1",
4316 "/org/freedesktop/systemd1",
4317 "org.freedesktop.systemd1.Manager",
4323 log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4327 r = sd_bus_message_read(reply, "o", &u);
4329 return bus_log_parse_error(r);
4339 static int show_all(
4342 bool show_properties,
4346 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4347 _cleanup_free_ UnitInfo *unit_infos = NULL;
4352 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4356 pager_open_if_enabled();
4360 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4362 for (u = unit_infos; u < unit_infos + c; u++) {
4363 _cleanup_free_ char *p = NULL;
4365 p = unit_dbus_path_from_name(u->id);
4369 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4372 else if (r > 0 && ret == 0)
4379 static int show_system_status(sd_bus *bus) {
4380 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4381 _cleanup_free_ char *hn = NULL;
4382 struct machine_info mi = {};
4383 const char *on, *off;
4386 hn = gethostname_malloc();
4390 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4392 return log_error_errno(r, "Failed to read server status: %m");
4394 if (streq_ptr(mi.state, "degraded")) {
4395 on = ansi_highlight_red();
4396 off = ansi_highlight_off();
4397 } else if (!streq_ptr(mi.state, "running")) {
4398 on = ansi_highlight_yellow();
4399 off = ansi_highlight_off();
4403 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4405 printf(" State: %s%s%s\n",
4406 on, strna(mi.state), off);
4408 printf(" Jobs: %u queued\n", mi.n_jobs);
4409 printf(" Failed: %u units\n", mi.n_failed_units);
4411 printf(" Since: %s; %s\n",
4412 format_timestamp(since2, sizeof(since2), mi.timestamp),
4413 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4415 printf(" CGroup: %s\n", mi.control_group ?: "/");
4416 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4417 static const char prefix[] = " ";
4421 if (c > sizeof(prefix) - 1)
4422 c -= sizeof(prefix) - 1;
4426 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4430 free(mi.control_group);
4435 static int show(sd_bus *bus, char **args) {
4436 bool show_properties, show_status, new_line = false;
4437 bool ellipsized = false;
4443 show_properties = streq(args[0], "show");
4444 show_status = streq(args[0], "status");
4446 if (show_properties)
4447 pager_open_if_enabled();
4449 /* If no argument is specified inspect the manager itself */
4451 if (show_properties && strv_length(args) <= 1)
4452 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4454 if (show_status && strv_length(args) <= 1) {
4456 pager_open_if_enabled();
4457 show_system_status(bus);
4461 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4463 _cleanup_free_ char **patterns = NULL;
4466 STRV_FOREACH(name, args + 1) {
4467 _cleanup_free_ char *unit = NULL;
4470 if (safe_atou32(*name, &id) < 0) {
4471 if (strv_push(&patterns, *name) < 0)
4475 } else if (show_properties) {
4476 /* Interpret as job id */
4477 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4481 /* Interpret as PID */
4482 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4489 r = show_one(args[0], bus, unit, show_properties,
4490 &new_line, &ellipsized);
4493 else if (r > 0 && ret == 0)
4497 if (!strv_isempty(patterns)) {
4498 _cleanup_strv_free_ char **names = NULL;
4500 r = expand_names(bus, patterns, NULL, &names);
4502 log_error_errno(r, "Failed to expand names: %m");
4504 STRV_FOREACH(name, names) {
4505 _cleanup_free_ char *unit;
4507 unit = unit_dbus_path_from_name(*name);
4511 r = show_one(args[0], bus, unit, show_properties,
4512 &new_line, &ellipsized);
4515 else if (r > 0 && ret == 0)
4521 if (ellipsized && !arg_quiet)
4522 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4527 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4531 assert(user_runtime);
4534 if (arg_scope == UNIT_FILE_USER) {
4535 r = user_config_home(user_home);
4537 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4539 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4541 r = user_runtime_dir(user_runtime);
4543 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4545 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4548 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4550 return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
4555 static int cat(sd_bus *bus, char **args) {
4556 _cleanup_free_ char *user_home = NULL;
4557 _cleanup_free_ char *user_runtime = NULL;
4558 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4559 _cleanup_strv_free_ char **names = NULL;
4561 bool first = true, avoid_bus_cache;
4567 log_error("Option --host cannot be used with 'cat'");
4571 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4575 r = expand_names(bus, args + 1, NULL, &names);
4577 log_error_errno(r, "Failed to expand names: %m");
4579 avoid_bus_cache = !bus || avoid_bus();
4581 pager_open_if_enabled();
4583 STRV_FOREACH(name, names) {
4584 _cleanup_free_ char *fragment_path = NULL;
4585 _cleanup_strv_free_ char **dropin_paths = NULL;
4588 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4592 log_warning("Unit %s does not have any files on disk", *name);
4601 if (fragment_path) {
4602 printf("%s# %s%s\n",
4603 ansi_highlight_blue(),
4605 ansi_highlight_off());
4608 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4610 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4615 STRV_FOREACH(path, dropin_paths) {
4616 printf("%s%s# %s%s\n",
4617 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4618 ansi_highlight_blue(),
4620 ansi_highlight_off());
4623 r = copy_file_fd(*path, STDOUT_FILENO, false);
4625 log_warning_errno(r, "Failed to cat %s: %m", *path);
4631 return r < 0 ? r : 0;
4634 static int set_property(sd_bus *bus, char **args) {
4635 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4636 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4637 _cleanup_free_ char *n = NULL;
4641 polkit_agent_open_if_enabled();
4643 r = sd_bus_message_new_method_call(
4646 "org.freedesktop.systemd1",
4647 "/org/freedesktop/systemd1",
4648 "org.freedesktop.systemd1.Manager",
4649 "SetUnitProperties");
4651 return bus_log_create_error(r);
4653 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4655 return bus_log_create_error(r);
4657 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4661 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4663 return bus_log_create_error(r);
4665 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4667 return bus_log_create_error(r);
4669 STRV_FOREACH(i, args + 2) {
4670 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4672 return bus_log_create_error(r);
4674 r = bus_append_unit_property_assignment(m, *i);
4678 r = sd_bus_message_close_container(m);
4680 return bus_log_create_error(r);
4683 r = sd_bus_message_close_container(m);
4685 return bus_log_create_error(r);
4687 r = sd_bus_call(bus, m, 0, &error, NULL);
4689 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4696 static int snapshot(sd_bus *bus, char **args) {
4697 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4698 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4699 _cleanup_free_ char *n = NULL, *id = NULL;
4703 polkit_agent_open_if_enabled();
4705 if (strv_length(args) > 1)
4706 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4712 r = sd_bus_message_new_method_call(
4715 "org.freedesktop.systemd1",
4716 "/org/freedesktop/systemd1",
4717 "org.freedesktop.systemd1.Manager",
4720 return bus_log_create_error(r);
4722 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4724 return bus_log_create_error(r);
4726 r = sd_bus_message_append(m, "sb", n, false);
4728 return bus_log_create_error(r);
4730 r = sd_bus_call(bus, m, 0, &error, &reply);
4732 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4736 r = sd_bus_message_read(reply, "o", &path);
4738 return bus_log_parse_error(r);
4740 r = sd_bus_get_property_string(
4742 "org.freedesktop.systemd1",
4744 "org.freedesktop.systemd1.Unit",
4749 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4759 static int delete_snapshot(sd_bus *bus, char **args) {
4760 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4761 _cleanup_strv_free_ char **names = NULL;
4767 polkit_agent_open_if_enabled();
4769 r = expand_names(bus, args + 1, ".snapshot", &names);
4771 log_error_errno(r, "Failed to expand names: %m");
4773 STRV_FOREACH(name, names) {
4774 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4777 q = sd_bus_message_new_method_call(
4780 "org.freedesktop.systemd1",
4781 "/org/freedesktop/systemd1",
4782 "org.freedesktop.systemd1.Manager",
4785 return bus_log_create_error(q);
4787 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4789 return bus_log_create_error(q);
4791 q = sd_bus_message_append(m, "s", *name);
4793 return bus_log_create_error(q);
4795 q = sd_bus_call(bus, m, 0, &error, NULL);
4797 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4806 static int daemon_reload(sd_bus *bus, char **args) {
4807 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4808 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4812 polkit_agent_open_if_enabled();
4814 if (arg_action == ACTION_RELOAD)
4816 else if (arg_action == ACTION_REEXEC)
4817 method = "Reexecute";
4819 assert(arg_action == ACTION_SYSTEMCTL);
4822 streq(args[0], "clear-jobs") ||
4823 streq(args[0], "cancel") ? "ClearJobs" :
4824 streq(args[0], "daemon-reexec") ? "Reexecute" :
4825 streq(args[0], "reset-failed") ? "ResetFailed" :
4826 streq(args[0], "halt") ? "Halt" :
4827 streq(args[0], "poweroff") ? "PowerOff" :
4828 streq(args[0], "reboot") ? "Reboot" :
4829 streq(args[0], "kexec") ? "KExec" :
4830 streq(args[0], "exit") ? "Exit" :
4831 /* "daemon-reload" */ "Reload";
4834 r = sd_bus_message_new_method_call(
4837 "org.freedesktop.systemd1",
4838 "/org/freedesktop/systemd1",
4839 "org.freedesktop.systemd1.Manager",
4842 return bus_log_create_error(r);
4844 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4846 return bus_log_create_error(r);
4848 r = sd_bus_call(bus, m, 0, &error, NULL);
4849 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4850 /* There's always a fallback possible for
4851 * legacy actions. */
4853 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4854 /* On reexecution, we expect a disconnect, not a
4858 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4860 return r < 0 ? r : 0;
4863 static int reset_failed(sd_bus *bus, char **args) {
4864 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4865 _cleanup_strv_free_ char **names = NULL;
4869 if (strv_length(args) <= 1)
4870 return daemon_reload(bus, args);
4872 polkit_agent_open_if_enabled();
4874 r = expand_names(bus, args + 1, NULL, &names);
4876 log_error_errno(r, "Failed to expand names: %m");
4878 STRV_FOREACH(name, names) {
4879 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4881 q = sd_bus_message_new_method_call(
4884 "org.freedesktop.systemd1",
4885 "/org/freedesktop/systemd1",
4886 "org.freedesktop.systemd1.Manager",
4889 return bus_log_create_error(q);
4891 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4893 return bus_log_create_error(q);
4895 q = sd_bus_message_append(m, "s", *name);
4897 return bus_log_create_error(q);
4899 q = sd_bus_call(bus, m, 0, &error, NULL);
4901 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4910 static int show_environment(sd_bus *bus, char **args) {
4911 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4912 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4916 pager_open_if_enabled();
4918 r = sd_bus_get_property(
4920 "org.freedesktop.systemd1",
4921 "/org/freedesktop/systemd1",
4922 "org.freedesktop.systemd1.Manager",
4928 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4932 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4934 return bus_log_parse_error(r);
4936 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4939 return bus_log_parse_error(r);
4941 r = sd_bus_message_exit_container(reply);
4943 return bus_log_parse_error(r);
4948 static int switch_root(sd_bus *bus, char **args) {
4949 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4950 _cleanup_free_ char *cmdline_init = NULL;
4951 const char *root, *init;
4955 l = strv_length(args);
4956 if (l < 2 || l > 3) {
4957 log_error("Wrong number of arguments.");
4966 r = parse_env_file("/proc/cmdline", WHITESPACE,
4967 "init", &cmdline_init,
4970 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4972 init = cmdline_init;
4979 const char *root_systemd_path = NULL, *root_init_path = NULL;
4981 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
4982 root_init_path = strjoina(root, "/", init);
4984 /* If the passed init is actually the same as the
4985 * systemd binary, then let's suppress it. */
4986 if (files_same(root_init_path, root_systemd_path) > 0)
4990 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4992 r = sd_bus_call_method(
4994 "org.freedesktop.systemd1",
4995 "/org/freedesktop/systemd1",
4996 "org.freedesktop.systemd1.Manager",
5002 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5009 static int set_environment(sd_bus *bus, char **args) {
5010 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5011 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5018 method = streq(args[0], "set-environment")
5020 : "UnsetEnvironment";
5022 r = sd_bus_message_new_method_call(
5025 "org.freedesktop.systemd1",
5026 "/org/freedesktop/systemd1",
5027 "org.freedesktop.systemd1.Manager",
5030 return bus_log_create_error(r);
5032 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5034 return bus_log_create_error(r);
5036 r = sd_bus_message_append_strv(m, args + 1);
5038 return bus_log_create_error(r);
5040 r = sd_bus_call(bus, m, 0, &error, NULL);
5042 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5049 static int import_environment(sd_bus *bus, char **args) {
5050 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5051 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5057 r = sd_bus_message_new_method_call(
5060 "org.freedesktop.systemd1",
5061 "/org/freedesktop/systemd1",
5062 "org.freedesktop.systemd1.Manager",
5065 return bus_log_create_error(r);
5067 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5069 return bus_log_create_error(r);
5071 if (strv_isempty(args + 1))
5072 r = sd_bus_message_append_strv(m, environ);
5076 r = sd_bus_message_open_container(m, 'a', "s");
5078 return bus_log_create_error(r);
5080 STRV_FOREACH(a, args + 1) {
5082 if (!env_name_is_valid(*a)) {
5083 log_error("Not a valid environment variable name: %s", *a);
5087 STRV_FOREACH(b, environ) {
5090 eq = startswith(*b, *a);
5091 if (eq && *eq == '=') {
5093 r = sd_bus_message_append(m, "s", *b);
5095 return bus_log_create_error(r);
5102 r = sd_bus_message_close_container(m);
5105 return bus_log_create_error(r);
5107 r = sd_bus_call(bus, m, 0, &error, NULL);
5109 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5116 static int enable_sysv_units(const char *verb, char **args) {
5119 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5121 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5123 if (arg_scope != UNIT_FILE_SYSTEM)
5126 if (!streq(verb, "enable") &&
5127 !streq(verb, "disable") &&
5128 !streq(verb, "is-enabled"))
5131 /* Processes all SysV units, and reshuffles the array so that
5132 * afterwards only the native units remain */
5134 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5141 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5142 bool found_native = false, found_sysv;
5144 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5152 if (!endswith(name, ".service"))
5155 if (path_is_absolute(name))
5158 STRV_FOREACH(k, paths.unit_path) {
5159 _cleanup_free_ char *path = NULL;
5161 path = path_join(arg_root, *k, name);
5165 found_native = access(path, F_OK) >= 0;
5173 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5177 p[strlen(p) - strlen(".service")] = 0;
5178 found_sysv = access(p, F_OK) >= 0;
5182 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5184 if (!isempty(arg_root))
5185 argv[c++] = q = strappend("--root=", arg_root);
5187 argv[c++] = basename(p);
5189 streq(verb, "enable") ? "on" :
5190 streq(verb, "disable") ? "off" : "--level=5";
5193 l = strv_join((char**)argv, " ");
5197 log_info("Executing %s", l);
5201 return log_error_errno(errno, "Failed to fork: %m");
5202 else if (pid == 0) {
5205 execv(argv[0], (char**) argv);
5206 _exit(EXIT_FAILURE);
5209 j = wait_for_terminate(pid, &status);
5211 log_error_errno(r, "Failed to wait for child: %m");
5215 if (status.si_code == CLD_EXITED) {
5216 if (streq(verb, "is-enabled")) {
5217 if (status.si_status == 0) {
5226 } else if (status.si_status != 0)
5231 /* Remove this entry, so that we don't try enabling it as native unit */
5234 assert(args[f] == name);
5235 strv_remove(args, name);
5242 static int mangle_names(char **original_names, char ***mangled_names) {
5243 char **i, **l, **name;
5245 l = new(char*, strv_length(original_names) + 1);
5250 STRV_FOREACH(name, original_names) {
5252 /* When enabling units qualified path names are OK,
5253 * too, hence allow them explicitly. */
5258 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5274 static int enable_unit(sd_bus *bus, char **args) {
5275 _cleanup_strv_free_ char **names = NULL;
5276 const char *verb = args[0];
5277 UnitFileChange *changes = NULL;
5278 unsigned n_changes = 0;
5279 int carries_install_info = -1;
5285 r = mangle_names(args+1, &names);
5289 r = enable_sysv_units(verb, names);
5293 /* If the operation was fully executed by the SysV compat,
5294 * let's finish early */
5295 if (strv_isempty(names))
5298 if (!bus || avoid_bus()) {
5299 if (streq(verb, "enable")) {
5300 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5301 carries_install_info = r;
5302 } else if (streq(verb, "disable"))
5303 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5304 else if (streq(verb, "reenable")) {
5305 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5306 carries_install_info = r;
5307 } else if (streq(verb, "link"))
5308 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5309 else if (streq(verb, "preset")) {
5310 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5311 carries_install_info = r;
5312 } else if (streq(verb, "mask"))
5313 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5314 else if (streq(verb, "unmask"))
5315 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5317 assert_not_reached("Unknown verb");
5320 log_error_errno(r, "Operation failed: %m");
5325 dump_unit_file_changes(changes, n_changes);
5329 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5330 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5331 int expect_carries_install_info = false;
5332 bool send_force = true, send_preset_mode = false;
5335 polkit_agent_open_if_enabled();
5337 if (streq(verb, "enable")) {
5338 method = "EnableUnitFiles";
5339 expect_carries_install_info = true;
5340 } else if (streq(verb, "disable")) {
5341 method = "DisableUnitFiles";
5343 } else if (streq(verb, "reenable")) {
5344 method = "ReenableUnitFiles";
5345 expect_carries_install_info = true;
5346 } else if (streq(verb, "link"))
5347 method = "LinkUnitFiles";
5348 else if (streq(verb, "preset")) {
5350 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5351 method = "PresetUnitFilesWithMode";
5352 send_preset_mode = true;
5354 method = "PresetUnitFiles";
5356 expect_carries_install_info = true;
5357 } else if (streq(verb, "mask"))
5358 method = "MaskUnitFiles";
5359 else if (streq(verb, "unmask")) {
5360 method = "UnmaskUnitFiles";
5363 assert_not_reached("Unknown verb");
5365 r = sd_bus_message_new_method_call(
5368 "org.freedesktop.systemd1",
5369 "/org/freedesktop/systemd1",
5370 "org.freedesktop.systemd1.Manager",
5373 return bus_log_create_error(r);
5375 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5377 return bus_log_create_error(r);
5379 r = sd_bus_message_append_strv(m, names);
5381 return bus_log_create_error(r);
5383 if (send_preset_mode) {
5384 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5386 return bus_log_create_error(r);
5389 r = sd_bus_message_append(m, "b", arg_runtime);
5391 return bus_log_create_error(r);
5394 r = sd_bus_message_append(m, "b", arg_force);
5396 return bus_log_create_error(r);
5399 r = sd_bus_call(bus, m, 0, &error, &reply);
5401 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5405 if (expect_carries_install_info) {
5406 r = sd_bus_message_read(reply, "b", &carries_install_info);
5408 return bus_log_parse_error(r);
5411 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5415 /* Try to reload if enabled */
5417 r = daemon_reload(bus, args);
5422 if (carries_install_info == 0)
5423 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5424 "using systemctl.\n"
5425 "Possible reasons for having this kind of units are:\n"
5426 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5427 " .wants/ or .requires/ directory.\n"
5428 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5429 " a requirement dependency on it.\n"
5430 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5431 " D-Bus, udev, scripted systemctl call, ...).\n");
5434 unit_file_changes_free(changes, n_changes);
5439 static int add_dependency(sd_bus *bus, char **args) {
5440 _cleanup_strv_free_ char **names = NULL;
5441 _cleanup_free_ char *target = NULL;
5442 const char *verb = args[0];
5449 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5453 r = mangle_names(args+2, &names);
5457 if (streq(verb, "add-wants"))
5459 else if (streq(verb, "add-requires"))
5460 dep = UNIT_REQUIRES;
5462 assert_not_reached("Unknown verb");
5464 if (!bus || avoid_bus()) {
5465 UnitFileChange *changes = NULL;
5466 unsigned n_changes = 0;
5468 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5471 return log_error_errno(r, "Can't add dependency: %m");
5474 dump_unit_file_changes(changes, n_changes);
5476 unit_file_changes_free(changes, n_changes);
5479 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5480 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5482 polkit_agent_open_if_enabled();
5484 r = sd_bus_message_new_method_call(
5487 "org.freedesktop.systemd1",
5488 "/org/freedesktop/systemd1",
5489 "org.freedesktop.systemd1.Manager",
5490 "AddDependencyUnitFiles");
5492 return bus_log_create_error(r);
5494 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5496 return bus_log_create_error(r);
5498 r = sd_bus_message_append_strv(m, names);
5500 return bus_log_create_error(r);
5502 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5504 return bus_log_create_error(r);
5506 r = sd_bus_call(bus, m, 0, &error, &reply);
5508 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5512 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5517 r = daemon_reload(bus, args);
5525 static int preset_all(sd_bus *bus, char **args) {
5526 UnitFileChange *changes = NULL;
5527 unsigned n_changes = 0;
5530 if (!bus || avoid_bus()) {
5532 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5534 log_error_errno(r, "Operation failed: %m");
5539 dump_unit_file_changes(changes, n_changes);
5544 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5545 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5547 polkit_agent_open_if_enabled();
5549 r = sd_bus_message_new_method_call(
5552 "org.freedesktop.systemd1",
5553 "/org/freedesktop/systemd1",
5554 "org.freedesktop.systemd1.Manager",
5555 "PresetAllUnitFiles");
5557 return bus_log_create_error(r);
5559 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5561 return bus_log_create_error(r);
5563 r = sd_bus_message_append(
5566 unit_file_preset_mode_to_string(arg_preset_mode),
5570 return bus_log_create_error(r);
5572 r = sd_bus_call(bus, m, 0, &error, &reply);
5574 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5578 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5583 r = daemon_reload(bus, args);
5589 unit_file_changes_free(changes, n_changes);
5594 static int unit_is_enabled(sd_bus *bus, char **args) {
5596 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5597 _cleanup_strv_free_ char **names = NULL;
5602 r = mangle_names(args+1, &names);
5606 r = enable_sysv_units(args[0], names);
5612 if (!bus || avoid_bus()) {
5614 STRV_FOREACH(name, names) {
5615 UnitFileState state;
5617 state = unit_file_get_state(arg_scope, arg_root, *name);
5619 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5621 if (state == UNIT_FILE_ENABLED ||
5622 state == UNIT_FILE_ENABLED_RUNTIME ||
5623 state == UNIT_FILE_STATIC ||
5624 state == UNIT_FILE_INDIRECT)
5628 puts(unit_file_state_to_string(state));
5632 STRV_FOREACH(name, names) {
5633 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5636 r = sd_bus_call_method(
5638 "org.freedesktop.systemd1",
5639 "/org/freedesktop/systemd1",
5640 "org.freedesktop.systemd1.Manager",
5646 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5650 r = sd_bus_message_read(reply, "s", &s);
5652 return bus_log_parse_error(r);
5654 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5665 static int is_system_running(sd_bus *bus, char **args) {
5666 _cleanup_free_ char *state = NULL;
5669 r = sd_bus_get_property_string(
5671 "org.freedesktop.systemd1",
5672 "/org/freedesktop/systemd1",
5673 "org.freedesktop.systemd1.Manager",
5686 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5689 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5694 assert(original_path);
5697 r = tempfn_random(new_path, &t);
5699 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5701 r = mkdir_parents(new_path, 0755);
5703 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5708 r = copy_file(original_path, t, 0, 0644, 0);
5712 log_error_errno(r, "Failed to create temporary file %s: %m", t);
5717 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5727 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5728 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5730 switch (arg_scope) {
5731 case UNIT_FILE_SYSTEM:
5732 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5734 run = path_join(arg_root, "/run/systemd/system/", name);
5736 case UNIT_FILE_GLOBAL:
5737 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5739 run = path_join(arg_root, "/run/systemd/user/", name);
5741 case UNIT_FILE_USER:
5743 assert(user_runtime);
5745 path = path_join(arg_root, user_home, name);
5747 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5750 run = path_join(arg_root, user_runtime, name);
5754 assert_not_reached("Invalid scope");
5756 if (!path || (arg_runtime && !run))
5760 if (access(path, F_OK) >= 0)
5761 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5763 if (path2 && access(path2, F_OK) >= 0)
5764 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5777 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) {
5778 char *tmp_new_path, *ending;
5783 assert(ret_new_path);
5784 assert(ret_tmp_path);
5786 ending = strjoina(unit_name, ".d/override.conf");
5787 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5791 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5797 *ret_new_path = tmp_new_path;
5798 *ret_tmp_path = tmp_tmp_path;
5803 static int unit_file_create_copy(const char *unit_name,
5804 const char *fragment_path,
5805 const char *user_home,
5806 const char *user_runtime,
5807 char **ret_new_path,
5808 char **ret_tmp_path) {
5813 assert(fragment_path);
5815 assert(ret_new_path);
5816 assert(ret_tmp_path);
5818 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5822 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5825 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);
5830 if (response != 'y') {
5831 log_warning("%s ignored", unit_name);
5837 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5839 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5844 *ret_new_path = tmp_new_path;
5845 *ret_tmp_path = tmp_tmp_path;
5850 static int run_editor(char **paths) {
5858 log_error_errno(errno, "Failed to fork: %m");
5864 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5866 char **tmp_path, **original_path, **p;
5870 argc = strv_length(paths)/2 + 1;
5871 args = newa(const char*, argc + 1);
5874 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5875 args[i] = *tmp_path;
5880 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5881 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5882 * we try to execute well known editors
5884 editor = getenv("SYSTEMD_EDITOR");
5886 editor = getenv("EDITOR");
5888 editor = getenv("VISUAL");
5890 if (!isempty(editor)) {
5892 execvp(editor, (char* const*) args);
5895 STRV_FOREACH(p, backup_editors) {
5897 execvp(*p, (char* const*) args);
5898 /* We do not fail if the editor doesn't exist
5899 * because we want to try each one of them before
5902 if (errno != ENOENT) {
5903 log_error("Failed to execute %s: %m", editor);
5904 _exit(EXIT_FAILURE);
5908 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5909 _exit(EXIT_FAILURE);
5912 r = wait_for_terminate_and_warn("editor", pid, true);
5914 return log_error_errno(r, "Failed to wait for child: %m");
5919 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5920 _cleanup_free_ char *user_home = NULL;
5921 _cleanup_free_ char *user_runtime = NULL;
5922 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5923 bool avoid_bus_cache;
5930 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5934 avoid_bus_cache = !bus || avoid_bus();
5936 STRV_FOREACH(name, names) {
5937 _cleanup_free_ char *path = NULL;
5938 char *new_path, *tmp_path;
5940 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5943 else if (r == 0 || !path)
5944 // FIXME: support units with path==NULL (no FragmentPath)
5945 return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
5948 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5950 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5954 r = strv_push_pair(paths, new_path, tmp_path);
5962 static int edit(sd_bus *bus, char **args) {
5963 _cleanup_strv_free_ char **names = NULL;
5964 _cleanup_strv_free_ char **paths = NULL;
5965 char **original, **tmp;
5971 log_error("Cannot edit units if we are not on a tty");
5975 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5976 log_error("Cannot remotely edit units");
5980 r = expand_names(bus, args + 1, NULL, &names);
5982 return log_error_errno(r, "Failed to expand names: %m");
5985 log_error("No unit name found by expanding names");
5989 r = find_paths_to_edit(bus, names, &paths);
5993 if (strv_isempty(paths)) {
5994 log_error("Cannot find any units to edit");
5998 r = run_editor(paths);
6002 STRV_FOREACH_PAIR(original, tmp, paths) {
6003 /* If the temporary file is empty we ignore it.
6004 * It's useful if the user wants to cancel its modification
6006 if (null_or_empty_path(*tmp)) {
6007 log_warning("Edition of %s canceled: temporary file empty", *original);
6010 r = rename(*tmp, *original);
6012 r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
6017 if (!arg_no_reload && bus && !avoid_bus())
6018 r = daemon_reload(bus, args);
6021 STRV_FOREACH_PAIR(original, tmp, paths)
6022 unlink_noerrno(*tmp);
6027 static void systemctl_help(void) {
6029 pager_open_if_enabled();
6031 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6032 "Query or send control commands to the systemd manager.\n\n"
6033 " -h --help Show this help\n"
6034 " --version Show package version\n"
6035 " --system Connect to system manager\n"
6036 " --user Connect to user service manager\n"
6037 " -H --host=[USER@]HOST\n"
6038 " Operate on remote host\n"
6039 " -M --machine=CONTAINER\n"
6040 " Operate on local container\n"
6041 " -t --type=TYPE List units of a particular type\n"
6042 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6043 " -p --property=NAME Show only properties by this name\n"
6044 " -a --all Show all loaded units/properties, including dead/empty\n"
6045 " ones. To list all units installed on the system, use\n"
6046 " the 'list-unit-files' command instead.\n"
6047 " -l --full Don't ellipsize unit names on output\n"
6048 " -r --recursive Show unit list of host and local containers\n"
6049 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6050 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6051 " queueing a new job\n"
6052 " --show-types When showing sockets, explicitly show their type\n"
6053 " -i --ignore-inhibitors\n"
6054 " When shutting down or sleeping, ignore inhibitors\n"
6055 " --kill-who=WHO Who to send signal to\n"
6056 " -s --signal=SIGNAL Which signal to send\n"
6057 " -q --quiet Suppress output\n"
6058 " --no-block Do not wait until operation finished\n"
6059 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6060 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6061 " --no-legend Do not print a legend (column headers and hints)\n"
6062 " --no-pager Do not pipe output into a pager\n"
6063 " --no-ask-password\n"
6064 " Do not ask for system passwords\n"
6065 " --global Enable/disable unit files globally\n"
6066 " --runtime Enable unit files only temporarily until next reboot\n"
6067 " -f --force When enabling unit files, override existing symlinks\n"
6068 " When shutting down, execute action immediately\n"
6069 " --preset-mode= Apply only enable, only disable, or all presets\n"
6070 " --root=PATH Enable unit files in the specified root directory\n"
6071 " -n --lines=INTEGER Number of journal entries to show\n"
6072 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6073 " short-precise, short-monotonic, verbose,\n"
6074 " export, json, json-pretty, json-sse, cat)\n"
6075 " --plain Print unit dependencies as a list instead of a tree\n\n"
6077 " list-units [PATTERN...] List loaded units\n"
6078 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6079 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6080 " start NAME... Start (activate) one or more units\n"
6081 " stop NAME... Stop (deactivate) one or more units\n"
6082 " reload NAME... Reload one or more units\n"
6083 " restart NAME... Start or restart one or more units\n"
6084 " try-restart NAME... Restart one or more units if active\n"
6085 " reload-or-restart NAME... Reload one or more units if possible,\n"
6086 " otherwise start or restart\n"
6087 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6088 " otherwise restart if active\n"
6089 " isolate NAME Start one unit and stop all others\n"
6090 " kill NAME... Send signal to processes of a unit\n"
6091 " is-active PATTERN... Check whether units are active\n"
6092 " is-failed PATTERN... Check whether units are failed\n"
6093 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6094 " show [PATTERN...|JOB...] Show properties of one or more\n"
6095 " units/jobs or the manager\n"
6096 " cat PATTERN... Show files and drop-ins of one or more units\n"
6097 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6098 " help PATTERN...|PID... Show manual for one or more units\n"
6099 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6101 " list-dependencies [NAME] Recursively show units which are required\n"
6102 " or wanted by this unit or by which this\n"
6103 " unit is required or wanted\n\n"
6104 "Unit File Commands:\n"
6105 " list-unit-files [PATTERN...] List installed unit files\n"
6106 " enable NAME... Enable one or more unit files\n"
6107 " disable NAME... Disable one or more unit files\n"
6108 " reenable NAME... Reenable one or more unit files\n"
6109 " preset NAME... Enable/disable one or more unit files\n"
6110 " based on preset configuration\n"
6111 " preset-all Enable/disable all unit files based on\n"
6112 " preset configuration\n"
6113 " is-enabled NAME... Check whether unit files are enabled\n"
6114 " mask NAME... Mask one or more units\n"
6115 " unmask NAME... Unmask one or more units\n"
6116 " link PATH... Link one or more units files into\n"
6117 " the search path\n"
6118 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6119 " on specified one or more units\n"
6120 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6121 " on specified one or more units\n"
6122 " edit NAME... Edit one or more unit files\n"
6123 " get-default Get the name of the default target\n"
6124 " set-default NAME Set the default target\n\n"
6125 "Machine Commands:\n"
6126 " list-machines [PATTERN...] List local containers and host\n\n"
6128 " list-jobs [PATTERN...] List jobs\n"
6129 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6130 "Snapshot Commands:\n"
6131 " snapshot [NAME] Create a snapshot\n"
6132 " delete NAME... Remove one or more snapshots\n\n"
6133 "Environment Commands:\n"
6134 " show-environment Dump environment\n"
6135 " set-environment NAME=VALUE... Set one or more environment variables\n"
6136 " unset-environment NAME... Unset one or more environment variables\n"
6137 " import-environment [NAME...] Import all or some environment variables\n\n"
6138 "Manager Lifecycle Commands:\n"
6139 " daemon-reload Reload systemd manager configuration\n"
6140 " daemon-reexec Reexecute systemd manager\n\n"
6141 "System Commands:\n"
6142 " is-system-running Check whether system is fully running\n"
6143 " default Enter system default mode\n"
6144 " rescue Enter system rescue mode\n"
6145 " emergency Enter system emergency mode\n"
6146 " halt Shut down and halt the system\n"
6147 " poweroff Shut down and power-off the system\n"
6148 " reboot [ARG] Shut down and reboot the system\n"
6149 " kexec Shut down and reboot the system with kexec\n"
6150 " exit Request user instance exit\n"
6151 " switch-root ROOT [INIT] Change to a different root file system\n"
6152 " suspend Suspend the system\n"
6153 " hibernate Hibernate the system\n"
6154 " hybrid-sleep Hibernate and suspend the system\n",
6155 program_invocation_short_name);
6158 static void halt_help(void) {
6159 printf("%s [OPTIONS...]%s\n\n"
6160 "%s the system.\n\n"
6161 " --help Show this help\n"
6162 " --halt Halt the machine\n"
6163 " -p --poweroff Switch off the machine\n"
6164 " --reboot Reboot the machine\n"
6165 " -f --force Force immediate halt/power-off/reboot\n"
6166 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6167 " -d --no-wtmp Don't write wtmp record\n"
6168 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6169 program_invocation_short_name,
6170 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6171 arg_action == ACTION_REBOOT ? "Reboot" :
6172 arg_action == ACTION_POWEROFF ? "Power off" :
6176 static void shutdown_help(void) {
6177 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6178 "Shut down the system.\n\n"
6179 " --help Show this help\n"
6180 " -H --halt Halt the machine\n"
6181 " -P --poweroff Power-off the machine\n"
6182 " -r --reboot Reboot the machine\n"
6183 " -h Equivalent to --poweroff, overridden by --halt\n"
6184 " -k Don't halt/power-off/reboot, just send warnings\n"
6185 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6186 " -c Cancel a pending shutdown\n",
6187 program_invocation_short_name);
6190 static void telinit_help(void) {
6191 printf("%s [OPTIONS...] {COMMAND}\n\n"
6192 "Send control commands to the init daemon.\n\n"
6193 " --help Show this help\n"
6194 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6196 " 0 Power-off the machine\n"
6197 " 6 Reboot the machine\n"
6198 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6199 " 1, s, S Enter rescue mode\n"
6200 " q, Q Reload init daemon configuration\n"
6201 " u, U Reexecute init daemon\n",
6202 program_invocation_short_name);
6205 static void runlevel_help(void) {
6206 printf("%s [OPTIONS...]\n\n"
6207 "Prints the previous and current runlevel of the init system.\n\n"
6208 " --help Show this help\n",
6209 program_invocation_short_name);
6212 static void help_types(void) {
6217 puts("Available unit types:");
6218 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6219 t = unit_type_to_string(i);
6225 static int systemctl_parse_argv(int argc, char *argv[]) {
6234 ARG_IGNORE_DEPENDENCIES,
6246 ARG_NO_ASK_PASSWORD,
6256 static const struct option options[] = {
6257 { "help", no_argument, NULL, 'h' },
6258 { "version", no_argument, NULL, ARG_VERSION },
6259 { "type", required_argument, NULL, 't' },
6260 { "property", required_argument, NULL, 'p' },
6261 { "all", no_argument, NULL, 'a' },
6262 { "reverse", no_argument, NULL, ARG_REVERSE },
6263 { "after", no_argument, NULL, ARG_AFTER },
6264 { "before", no_argument, NULL, ARG_BEFORE },
6265 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6266 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6267 { "full", no_argument, NULL, 'l' },
6268 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6269 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6270 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6271 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6272 { "ignore-inhibitors", no_argument, NULL, 'i' },
6273 { "user", no_argument, NULL, ARG_USER },
6274 { "system", no_argument, NULL, ARG_SYSTEM },
6275 { "global", no_argument, NULL, ARG_GLOBAL },
6276 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6277 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6278 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6279 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6280 { "quiet", no_argument, NULL, 'q' },
6281 { "root", required_argument, NULL, ARG_ROOT },
6282 { "force", no_argument, NULL, ARG_FORCE },
6283 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6284 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6285 { "signal", required_argument, NULL, 's' },
6286 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6287 { "host", required_argument, NULL, 'H' },
6288 { "machine", required_argument, NULL, 'M' },
6289 { "runtime", no_argument, NULL, ARG_RUNTIME },
6290 { "lines", required_argument, NULL, 'n' },
6291 { "output", required_argument, NULL, 'o' },
6292 { "plain", no_argument, NULL, ARG_PLAIN },
6293 { "state", required_argument, NULL, ARG_STATE },
6294 { "recursive", no_argument, NULL, 'r' },
6295 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6304 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6313 puts(PACKAGE_STRING);
6314 puts(SYSTEMD_FEATURES);
6318 const char *word, *state;
6321 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6322 _cleanup_free_ char *type;
6324 type = strndup(word, size);
6328 if (streq(type, "help")) {
6333 if (unit_type_from_string(type) >= 0) {
6334 if (strv_push(&arg_types, type))
6340 /* It's much nicer to use --state= for
6341 * load states, but let's support this
6342 * in --types= too for compatibility
6343 * with old versions */
6344 if (unit_load_state_from_string(optarg) >= 0) {
6345 if (strv_push(&arg_states, type) < 0)
6351 log_error("Unknown unit type or load state '%s'.", type);
6352 log_info("Use -t help to see a list of allowed values.");
6360 /* Make sure that if the empty property list
6361 was specified, we won't show any properties. */
6362 if (isempty(optarg) && !arg_properties) {
6363 arg_properties = new0(char*, 1);
6364 if (!arg_properties)
6367 const char *word, *state;
6370 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6373 prop = strndup(word, size);
6377 if (strv_consume(&arg_properties, prop) < 0)
6382 /* If the user asked for a particular
6383 * property, show it to him, even if it is
6395 arg_dependency = DEPENDENCY_REVERSE;
6399 arg_dependency = DEPENDENCY_AFTER;
6403 arg_dependency = DEPENDENCY_BEFORE;
6406 case ARG_SHOW_TYPES:
6407 arg_show_types = true;
6411 arg_job_mode = optarg;
6415 arg_job_mode = "fail";
6418 case ARG_IRREVERSIBLE:
6419 arg_job_mode = "replace-irreversibly";
6422 case ARG_IGNORE_DEPENDENCIES:
6423 arg_job_mode = "ignore-dependencies";
6427 arg_scope = UNIT_FILE_USER;
6431 arg_scope = UNIT_FILE_SYSTEM;
6435 arg_scope = UNIT_FILE_GLOBAL;
6439 arg_no_block = true;
6443 arg_no_legend = true;
6447 arg_no_pager = true;
6463 if (strv_extend(&arg_states, "failed") < 0)
6481 arg_no_reload = true;
6485 arg_kill_who = optarg;
6489 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6490 log_error("Failed to parse signal string %s.", optarg);
6495 case ARG_NO_ASK_PASSWORD:
6496 arg_ask_password = false;
6500 arg_transport = BUS_TRANSPORT_REMOTE;
6505 arg_transport = BUS_TRANSPORT_MACHINE;
6514 if (safe_atou(optarg, &arg_lines) < 0) {
6515 log_error("Failed to parse lines '%s'", optarg);
6521 arg_output = output_mode_from_string(optarg);
6522 if (arg_output < 0) {
6523 log_error("Unknown output '%s'.", optarg);
6529 arg_ignore_inhibitors = true;
6537 const char *word, *state;
6540 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6543 s = strndup(word, size);
6547 if (strv_consume(&arg_states, s) < 0)
6554 if (geteuid() != 0) {
6555 log_error("--recursive requires root privileges.");
6559 arg_recursive = true;
6562 case ARG_PRESET_MODE:
6564 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6565 if (arg_preset_mode < 0) {
6566 log_error("Failed to parse preset mode: %s.", optarg);
6576 assert_not_reached("Unhandled option");
6579 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6580 log_error("Cannot access user instance remotely.");
6587 static int halt_parse_argv(int argc, char *argv[]) {
6596 static const struct option options[] = {
6597 { "help", no_argument, NULL, ARG_HELP },
6598 { "halt", no_argument, NULL, ARG_HALT },
6599 { "poweroff", no_argument, NULL, 'p' },
6600 { "reboot", no_argument, NULL, ARG_REBOOT },
6601 { "force", no_argument, NULL, 'f' },
6602 { "wtmp-only", no_argument, NULL, 'w' },
6603 { "no-wtmp", no_argument, NULL, 'd' },
6604 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6613 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6614 if (runlevel == '0' || runlevel == '6')
6617 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6625 arg_action = ACTION_HALT;
6629 if (arg_action != ACTION_REBOOT)
6630 arg_action = ACTION_POWEROFF;
6634 arg_action = ACTION_REBOOT;
6656 /* Compatibility nops */
6663 assert_not_reached("Unhandled option");
6666 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6667 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6670 } else if (optind < argc) {
6671 log_error("Too many arguments.");
6678 static int parse_time_spec(const char *t, usec_t *_u) {
6682 if (streq(t, "now"))
6684 else if (!strchr(t, ':')) {
6687 if (safe_atou64(t, &u) < 0)
6690 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6699 hour = strtol(t, &e, 10);
6700 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6703 minute = strtol(e+1, &e, 10);
6704 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6707 n = now(CLOCK_REALTIME);
6708 s = (time_t) (n / USEC_PER_SEC);
6710 assert_se(localtime_r(&s, &tm));
6712 tm.tm_hour = (int) hour;
6713 tm.tm_min = (int) minute;
6716 assert_se(s = mktime(&tm));
6718 *_u = (usec_t) s * USEC_PER_SEC;
6721 *_u += USEC_PER_DAY;
6727 static int shutdown_parse_argv(int argc, char *argv[]) {
6734 static const struct option options[] = {
6735 { "help", no_argument, NULL, ARG_HELP },
6736 { "halt", no_argument, NULL, 'H' },
6737 { "poweroff", no_argument, NULL, 'P' },
6738 { "reboot", no_argument, NULL, 'r' },
6739 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6740 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6749 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6757 arg_action = ACTION_HALT;
6761 arg_action = ACTION_POWEROFF;
6766 arg_action = ACTION_KEXEC;
6768 arg_action = ACTION_REBOOT;
6772 arg_action = ACTION_KEXEC;
6776 if (arg_action != ACTION_HALT)
6777 arg_action = ACTION_POWEROFF;
6792 /* Compatibility nops */
6796 arg_action = ACTION_CANCEL_SHUTDOWN;
6803 assert_not_reached("Unhandled option");
6806 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6807 r = parse_time_spec(argv[optind], &arg_when);
6809 log_error("Failed to parse time specification: %s", argv[optind]);
6813 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6815 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6816 /* No time argument for shutdown cancel */
6817 arg_wall = argv + optind;
6818 else if (argc > optind + 1)
6819 /* We skip the time argument */
6820 arg_wall = argv + optind + 1;
6827 static int telinit_parse_argv(int argc, char *argv[]) {
6834 static const struct option options[] = {
6835 { "help", no_argument, NULL, ARG_HELP },
6836 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6840 static const struct {
6844 { '0', ACTION_POWEROFF },
6845 { '6', ACTION_REBOOT },
6846 { '1', ACTION_RESCUE },
6847 { '2', ACTION_RUNLEVEL2 },
6848 { '3', ACTION_RUNLEVEL3 },
6849 { '4', ACTION_RUNLEVEL4 },
6850 { '5', ACTION_RUNLEVEL5 },
6851 { 's', ACTION_RESCUE },
6852 { 'S', ACTION_RESCUE },
6853 { 'q', ACTION_RELOAD },
6854 { 'Q', ACTION_RELOAD },
6855 { 'u', ACTION_REEXEC },
6856 { 'U', ACTION_REEXEC }
6865 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6880 assert_not_reached("Unhandled option");
6883 if (optind >= argc) {
6884 log_error("%s: required argument missing.",
6885 program_invocation_short_name);
6889 if (optind + 1 < argc) {
6890 log_error("Too many arguments.");
6894 if (strlen(argv[optind]) != 1) {
6895 log_error("Expected single character argument.");
6899 for (i = 0; i < ELEMENTSOF(table); i++)
6900 if (table[i].from == argv[optind][0])
6903 if (i >= ELEMENTSOF(table)) {
6904 log_error("Unknown command '%s'.", argv[optind]);
6908 arg_action = table[i].to;
6915 static int runlevel_parse_argv(int argc, char *argv[]) {
6921 static const struct option options[] = {
6922 { "help", no_argument, NULL, ARG_HELP },
6931 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6942 assert_not_reached("Unhandled option");
6945 if (optind < argc) {
6946 log_error("Too many arguments.");
6953 static int parse_argv(int argc, char *argv[]) {
6957 if (program_invocation_short_name) {
6959 if (strstr(program_invocation_short_name, "halt")) {
6960 arg_action = ACTION_HALT;
6961 return halt_parse_argv(argc, argv);
6962 } else if (strstr(program_invocation_short_name, "poweroff")) {
6963 arg_action = ACTION_POWEROFF;
6964 return halt_parse_argv(argc, argv);
6965 } else if (strstr(program_invocation_short_name, "reboot")) {
6967 arg_action = ACTION_KEXEC;
6969 arg_action = ACTION_REBOOT;
6970 return halt_parse_argv(argc, argv);
6971 } else if (strstr(program_invocation_short_name, "shutdown")) {
6972 arg_action = ACTION_POWEROFF;
6973 return shutdown_parse_argv(argc, argv);
6974 } else if (strstr(program_invocation_short_name, "init")) {
6976 if (sd_booted() > 0) {
6977 arg_action = _ACTION_INVALID;
6978 return telinit_parse_argv(argc, argv);
6980 /* Hmm, so some other init system is
6981 * running, we need to forward this
6982 * request to it. For now we simply
6983 * guess that it is Upstart. */
6985 execv(TELINIT, argv);
6987 log_error("Couldn't find an alternative telinit implementation to spawn.");
6991 } else if (strstr(program_invocation_short_name, "runlevel")) {
6992 arg_action = ACTION_RUNLEVEL;
6993 return runlevel_parse_argv(argc, argv);
6997 arg_action = ACTION_SYSTEMCTL;
6998 return systemctl_parse_argv(argc, argv);
7001 _pure_ static int action_to_runlevel(void) {
7003 static const char table[_ACTION_MAX] = {
7004 [ACTION_HALT] = '0',
7005 [ACTION_POWEROFF] = '0',
7006 [ACTION_REBOOT] = '6',
7007 [ACTION_RUNLEVEL2] = '2',
7008 [ACTION_RUNLEVEL3] = '3',
7009 [ACTION_RUNLEVEL4] = '4',
7010 [ACTION_RUNLEVEL5] = '5',
7011 [ACTION_RESCUE] = '1'
7014 assert(arg_action < _ACTION_MAX);
7016 return table[arg_action];
7019 static int talk_initctl(void) {
7021 struct init_request request = {
7022 .magic = INIT_MAGIC,
7024 .cmd = INIT_CMD_RUNLVL
7027 _cleanup_close_ int fd = -1;
7031 rl = action_to_runlevel();
7035 request.runlevel = rl;
7037 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7039 if (errno == ENOENT)
7042 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7046 r = loop_write(fd, &request, sizeof(request), false);
7048 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7053 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7055 static const struct {
7063 int (* const dispatch)(sd_bus *bus, char **args);
7069 { "list-units", MORE, 0, list_units },
7070 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7071 { "list-sockets", MORE, 1, list_sockets },
7072 { "list-timers", MORE, 1, list_timers },
7073 { "list-jobs", MORE, 1, list_jobs },
7074 { "list-machines", MORE, 1, list_machines },
7075 { "clear-jobs", EQUAL, 1, daemon_reload },
7076 { "cancel", MORE, 2, cancel_job },
7077 { "start", MORE, 2, start_unit },
7078 { "stop", MORE, 2, start_unit },
7079 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7080 { "reload", MORE, 2, start_unit },
7081 { "restart", MORE, 2, start_unit },
7082 { "try-restart", MORE, 2, start_unit },
7083 { "reload-or-restart", MORE, 2, start_unit },
7084 { "reload-or-try-restart", MORE, 2, start_unit },
7085 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7086 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7087 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7088 { "isolate", EQUAL, 2, start_unit },
7089 { "kill", MORE, 2, kill_unit },
7090 { "is-active", MORE, 2, check_unit_active },
7091 { "check", MORE, 2, check_unit_active },
7092 { "is-failed", MORE, 2, check_unit_failed },
7093 { "show", MORE, 1, show },
7094 { "cat", MORE, 2, cat, NOBUS },
7095 { "status", MORE, 1, show },
7096 { "help", MORE, 2, show },
7097 { "snapshot", LESS, 2, snapshot },
7098 { "delete", MORE, 2, delete_snapshot },
7099 { "daemon-reload", EQUAL, 1, daemon_reload },
7100 { "daemon-reexec", EQUAL, 1, daemon_reload },
7101 { "show-environment", EQUAL, 1, show_environment },
7102 { "set-environment", MORE, 2, set_environment },
7103 { "unset-environment", MORE, 2, set_environment },
7104 { "import-environment", MORE, 1, import_environment},
7105 { "halt", EQUAL, 1, start_special, FORCE },
7106 { "poweroff", EQUAL, 1, start_special, FORCE },
7107 { "reboot", MORE, 1, start_special, FORCE },
7108 { "kexec", EQUAL, 1, start_special },
7109 { "suspend", EQUAL, 1, start_special },
7110 { "hibernate", EQUAL, 1, start_special },
7111 { "hybrid-sleep", EQUAL, 1, start_special },
7112 { "default", EQUAL, 1, start_special },
7113 { "rescue", EQUAL, 1, start_special },
7114 { "emergency", EQUAL, 1, start_special },
7115 { "exit", EQUAL, 1, start_special },
7116 { "reset-failed", MORE, 1, reset_failed },
7117 { "enable", MORE, 2, enable_unit, NOBUS },
7118 { "disable", MORE, 2, enable_unit, NOBUS },
7119 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7120 { "reenable", MORE, 2, enable_unit, NOBUS },
7121 { "preset", MORE, 2, enable_unit, NOBUS },
7122 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7123 { "mask", MORE, 2, enable_unit, NOBUS },
7124 { "unmask", MORE, 2, enable_unit, NOBUS },
7125 { "link", MORE, 2, enable_unit, NOBUS },
7126 { "switch-root", MORE, 2, switch_root },
7127 { "list-dependencies", LESS, 2, list_dependencies },
7128 { "set-default", EQUAL, 2, set_default, NOBUS },
7129 { "get-default", EQUAL, 1, get_default, NOBUS },
7130 { "set-property", MORE, 3, set_property },
7131 { "is-system-running", EQUAL, 1, is_system_running },
7132 { "add-wants", MORE, 3, add_dependency, NOBUS },
7133 { "add-requires", MORE, 3, add_dependency, NOBUS },
7134 { "edit", MORE, 2, edit, NOBUS },
7143 left = argc - optind;
7145 /* Special rule: no arguments (left == 0) means "list-units" */
7147 if (streq(argv[optind], "help") && !argv[optind+1]) {
7148 log_error("This command expects one or more "
7149 "unit names. Did you mean --help?");
7153 for (; verb->verb; verb++)
7154 if (streq(argv[optind], verb->verb))
7157 log_error("Unknown operation '%s'.", argv[optind]);
7162 switch (verb->argc_cmp) {
7165 if (left != verb->argc) {
7166 log_error("Invalid number of arguments.");
7173 if (left < verb->argc) {
7174 log_error("Too few arguments.");
7181 if (left > verb->argc) {
7182 log_error("Too many arguments.");
7189 assert_not_reached("Unknown comparison operator.");
7192 /* Require a bus connection for all operations but
7194 if (verb->bus == NOBUS) {
7195 if (!bus && !avoid_bus()) {
7196 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7201 if (running_in_chroot() > 0) {
7202 log_info("Running in chroot, ignoring request.");
7206 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7207 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7212 return verb->dispatch(bus, argv + optind);
7215 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7217 struct sd_shutdown_command c = {
7224 union sockaddr_union sockaddr = {
7225 .un.sun_family = AF_UNIX,
7226 .un.sun_path = "/run/systemd/shutdownd",
7229 struct iovec iovec[2] = {{
7230 .iov_base = (char*) &c,
7231 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7234 struct msghdr msghdr = {
7235 .msg_name = &sockaddr,
7236 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7237 + strlen("/run/systemd/shutdownd"),
7242 _cleanup_close_ int fd;
7244 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7248 if (!isempty(message)) {
7249 iovec[1].iov_base = (char*) message;
7250 iovec[1].iov_len = strlen(message);
7251 msghdr.msg_iovlen++;
7254 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7260 static int reload_with_fallback(sd_bus *bus) {
7263 /* First, try systemd via D-Bus. */
7264 if (daemon_reload(bus, NULL) >= 0)
7268 /* Nothing else worked, so let's try signals */
7269 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7271 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7272 return log_error_errno(errno, "kill() failed: %m");
7277 static int start_with_fallback(sd_bus *bus) {
7280 /* First, try systemd via D-Bus. */
7281 if (start_unit(bus, NULL) >= 0)
7285 /* Nothing else worked, so let's try
7287 if (talk_initctl() > 0)
7290 log_error("Failed to talk to init daemon.");
7294 warn_wall(arg_action);
7298 static int halt_now(enum action a) {
7300 /* The kernel will automaticall flush ATA disks and suchlike
7301 * on reboot(), but the file systems need to be synce'd
7302 * explicitly in advance. */
7305 /* Make sure C-A-D is handled by the kernel from this point
7307 reboot(RB_ENABLE_CAD);
7312 log_info("Halting.");
7313 reboot(RB_HALT_SYSTEM);
7316 case ACTION_POWEROFF:
7317 log_info("Powering off.");
7318 reboot(RB_POWER_OFF);
7321 case ACTION_REBOOT: {
7322 _cleanup_free_ char *param = NULL;
7324 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7325 log_info("Rebooting with argument '%s'.", param);
7326 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7327 LINUX_REBOOT_CMD_RESTART2, param);
7330 log_info("Rebooting.");
7331 reboot(RB_AUTOBOOT);
7336 assert_not_reached("Unknown action.");
7340 static int halt_main(sd_bus *bus) {
7343 r = check_inhibitors(bus, arg_action);
7347 if (geteuid() != 0) {
7348 /* Try logind if we are a normal user and no special
7349 * mode applies. Maybe PolicyKit allows us to shutdown
7352 if (arg_when <= 0 &&
7355 (arg_action == ACTION_POWEROFF ||
7356 arg_action == ACTION_REBOOT)) {
7357 r = reboot_with_logind(bus, arg_action);
7362 log_error("Must be root.");
7367 _cleanup_free_ char *m;
7369 m = strv_join(arg_wall, " ");
7373 r = send_shutdownd(arg_when,
7374 arg_action == ACTION_HALT ? 'H' :
7375 arg_action == ACTION_POWEROFF ? 'P' :
7376 arg_action == ACTION_KEXEC ? 'K' :
7383 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7385 char date[FORMAT_TIMESTAMP_MAX];
7387 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7388 format_timestamp(date, sizeof(date), arg_when));
7393 if (!arg_dry && !arg_force)
7394 return start_with_fallback(bus);
7397 if (sd_booted() > 0)
7398 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7400 r = utmp_put_shutdown();
7402 log_warning_errno(r, "Failed to write utmp record: %m");
7409 r = halt_now(arg_action);
7410 log_error_errno(r, "Failed to reboot: %m");
7415 static int runlevel_main(void) {
7416 int r, runlevel, previous;
7418 r = utmp_get_runlevel(&runlevel, &previous);
7425 previous <= 0 ? 'N' : previous,
7426 runlevel <= 0 ? 'N' : runlevel);
7431 int main(int argc, char*argv[]) {
7432 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7435 setlocale(LC_ALL, "");
7436 log_parse_environment();
7439 /* Explicitly not on_tty() to avoid setting cached value.
7440 * This becomes relevant for piping output which might be
7442 original_stdout_is_tty = isatty(STDOUT_FILENO);
7444 r = parse_argv(argc, argv);
7448 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7449 * let's shortcut this */
7450 if (arg_action == ACTION_RUNLEVEL) {
7451 r = runlevel_main();
7455 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7456 log_info("Running in chroot, ignoring request.");
7461 /* Increase max number of open files to 16K if we can, we
7462 * might needs this when browsing journal files, which might
7463 * be split up into many files. */
7464 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7467 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7469 /* systemctl_main() will print an error message for the bus
7470 * connection, but only if it needs to */
7472 switch (arg_action) {
7474 case ACTION_SYSTEMCTL:
7475 r = systemctl_main(bus, argc, argv, r);
7479 case ACTION_POWEROFF:
7485 case ACTION_RUNLEVEL2:
7486 case ACTION_RUNLEVEL3:
7487 case ACTION_RUNLEVEL4:
7488 case ACTION_RUNLEVEL5:
7490 case ACTION_EMERGENCY:
7491 case ACTION_DEFAULT:
7492 r = start_with_fallback(bus);
7497 r = reload_with_fallback(bus);
7500 case ACTION_CANCEL_SHUTDOWN: {
7501 _cleanup_free_ char *m = NULL;
7504 m = strv_join(arg_wall, " ");
7511 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7513 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7517 case ACTION_RUNLEVEL:
7518 case _ACTION_INVALID:
7520 assert_not_reached("Unknown action");
7525 ask_password_agent_close();
7526 polkit_agent_close();
7528 strv_free(arg_types);
7529 strv_free(arg_states);
7530 strv_free(arg_properties);
7532 return r < 0 ? EXIT_FAILURE : r;