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();
180 static void polkit_agent_open_if_enabled(void) {
182 /* Open the polkit agent as a child process if necessary */
184 if (!arg_ask_password)
187 if (arg_scope != UNIT_FILE_SYSTEM)
190 if (arg_transport != BUS_TRANSPORT_LOCAL)
197 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
200 if (!sd_bus_error_is_set(error))
203 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
204 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
205 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
206 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
207 return EXIT_NOPERMISSION;
209 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
210 return EXIT_NOTINSTALLED;
212 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
213 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
214 return EXIT_NOTIMPLEMENTED;
216 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
217 return EXIT_NOTCONFIGURED;
225 static void warn_wall(enum action a) {
226 static const char *table[_ACTION_MAX] = {
227 [ACTION_HALT] = "The system is going down for system halt NOW!",
228 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
229 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
230 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
231 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
232 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
233 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
240 _cleanup_free_ char *p;
242 p = strv_join(arg_wall, " ");
249 utmp_wall(p, NULL, NULL);
257 utmp_wall(table[a], NULL, NULL);
260 static bool avoid_bus(void) {
262 if (running_in_chroot() > 0)
265 if (sd_booted() <= 0)
268 if (!isempty(arg_root))
271 if (arg_scope == UNIT_FILE_GLOBAL)
277 static int compare_unit_info(const void *a, const void *b) {
278 const UnitInfo *u = a, *v = b;
282 /* First, order by machine */
283 if (!u->machine && v->machine)
285 if (u->machine && !v->machine)
287 if (u->machine && v->machine) {
288 r = strcasecmp(u->machine, v->machine);
293 /* Second, order by unit type */
294 d1 = strrchr(u->id, '.');
295 d2 = strrchr(v->id, '.');
297 r = strcasecmp(d1, d2);
302 /* Third, order by name */
303 return strcasecmp(u->id, v->id);
306 static bool output_show_unit(const UnitInfo *u, char **patterns) {
307 if (!strv_isempty(patterns)) {
310 STRV_FOREACH(pattern, patterns)
311 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
320 dot = strrchr(u->id, '.');
324 if (!strv_find(arg_types, dot+1))
334 if (streq(u->active_state, "inactive") || u->following[0])
340 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
341 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
343 unsigned n_shown = 0;
346 max_id_len = strlen("UNIT");
347 load_len = strlen("LOAD");
348 active_len = strlen("ACTIVE");
349 sub_len = strlen("SUB");
350 job_len = strlen("JOB");
353 for (u = unit_infos; u < unit_infos + c; u++) {
354 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
355 load_len = MAX(load_len, strlen(u->load_state));
356 active_len = MAX(active_len, strlen(u->active_state));
357 sub_len = MAX(sub_len, strlen(u->sub_state));
359 if (u->job_id != 0) {
360 job_len = MAX(job_len, strlen(u->job_type));
364 if (!arg_no_legend &&
365 (streq(u->active_state, "failed") ||
366 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
370 if (!arg_full && original_stdout_is_tty) {
373 id_len = MIN(max_id_len, 25u);
374 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
377 basic_len += job_len + 1;
379 if (basic_len < (unsigned) columns()) {
380 unsigned extra_len, incr;
381 extra_len = columns() - basic_len;
383 /* Either UNIT already got 25, or is fully satisfied.
384 * Grant up to 25 to DESC now. */
385 incr = MIN(extra_len, 25u);
389 /* split the remaining space between UNIT and DESC,
390 * but do not give UNIT more than it needs. */
392 incr = MIN(extra_len / 2, max_id_len - id_len);
394 desc_len += extra_len - incr;
400 for (u = unit_infos; u < unit_infos + c; u++) {
401 _cleanup_free_ char *e = NULL, *j = NULL;
402 const char *on_loaded = "", *off_loaded = "";
403 const char *on_active = "", *off_active = "";
404 const char *on_circle = "", *off_circle = "";
408 if (!n_shown && !arg_no_legend) {
413 printf("%-*s %-*s %-*s %-*s ",
416 active_len, "ACTIVE",
420 printf("%-*s ", job_len, "JOB");
422 if (!arg_full && arg_no_pager)
423 printf("%.*s\n", desc_len, "DESCRIPTION");
425 printf("%s\n", "DESCRIPTION");
430 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
431 on_loaded = ansi_highlight_red();
432 on_circle = ansi_highlight_yellow();
433 off_loaded = off_circle = ansi_highlight_off();
437 if (streq(u->active_state, "failed")) {
438 on_circle = on_active = ansi_highlight_red();
439 off_circle = off_active = ansi_highlight_off();
444 j = strjoin(u->machine, ":", u->id, NULL);
453 e = ellipsize(id, id_len, 33);
461 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
463 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
464 on_active, id_len, id, off_active,
465 on_loaded, load_len, u->load_state, off_loaded,
466 on_active, active_len, u->active_state,
467 sub_len, u->sub_state, off_active,
468 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
471 printf("%.*s\n", desc_len, u->description);
473 printf("%s\n", u->description);
476 if (!arg_no_legend) {
477 const char *on, *off;
481 "LOAD = Reflects whether the unit definition was properly loaded.\n"
482 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
483 "SUB = The low-level unit activation state, values depend on unit type.");
484 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
485 on = ansi_highlight();
486 off = ansi_highlight_off();
488 on = ansi_highlight_red();
489 off = ansi_highlight_off();
493 printf("%s%u loaded units listed.%s\n"
494 "To show all installed unit files use 'systemctl list-unit-files'.\n",
497 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
498 "To show all installed unit files use 'systemctl list-unit-files'.\n",
505 static int get_unit_list(
509 UnitInfo **unit_infos,
511 sd_bus_message **_reply) {
513 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
514 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
515 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
524 r = sd_bus_message_new_method_call(
527 "org.freedesktop.systemd1",
528 "/org/freedesktop/systemd1",
529 "org.freedesktop.systemd1.Manager",
530 "ListUnitsFiltered");
533 return bus_log_create_error(r);
535 r = sd_bus_message_append_strv(m, arg_states);
537 return bus_log_create_error(r);
539 r = sd_bus_call(bus, m, 0, &error, &reply);
541 log_error("Failed to list units: %s", bus_error_message(&error, r));
545 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
547 return bus_log_parse_error(r);
549 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
552 if (!output_show_unit(&u, patterns))
555 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
558 (*unit_infos)[c++] = u;
561 return bus_log_parse_error(r);
563 r = sd_bus_message_exit_container(reply);
565 return bus_log_parse_error(r);
573 static void message_set_freep(Set **set) {
576 while ((m = set_steal_first(*set)))
577 sd_bus_message_unref(m);
582 static int get_unit_list_recursive(
585 UnitInfo **_unit_infos,
589 _cleanup_free_ UnitInfo *unit_infos = NULL;
590 _cleanup_(message_set_freep) Set *replies;
591 sd_bus_message *reply;
599 replies = set_new(NULL);
603 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
607 r = set_put(replies, reply);
609 sd_bus_message_unref(reply);
614 _cleanup_strv_free_ char **machines = NULL;
617 r = sd_get_machine_names(&machines);
621 STRV_FOREACH(i, machines) {
622 _cleanup_bus_close_unref_ sd_bus *container = NULL;
625 r = sd_bus_open_system_machine(&container, *i);
627 log_error_errno(r, "Failed to connect to container %s: %m", *i);
631 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
637 r = set_put(replies, reply);
639 sd_bus_message_unref(reply);
644 *_machines = machines;
649 *_unit_infos = unit_infos;
658 static int list_units(sd_bus *bus, char **args) {
659 _cleanup_free_ UnitInfo *unit_infos = NULL;
660 _cleanup_(message_set_freep) Set *replies = NULL;
661 _cleanup_strv_free_ char **machines = NULL;
664 pager_open_if_enabled();
666 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
670 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
671 return output_units_list(unit_infos, r);
674 static int get_triggered_units(
679 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
682 r = sd_bus_get_property_strv(
684 "org.freedesktop.systemd1",
686 "org.freedesktop.systemd1.Unit",
692 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
697 static int get_listening(
699 const char* unit_path,
702 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
703 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
704 const char *type, *path;
707 r = sd_bus_get_property(
709 "org.freedesktop.systemd1",
711 "org.freedesktop.systemd1.Socket",
717 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
721 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
723 return bus_log_parse_error(r);
725 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
727 r = strv_extend(listening, type);
731 r = strv_extend(listening, path);
738 return bus_log_parse_error(r);
740 r = sd_bus_message_exit_container(reply);
742 return bus_log_parse_error(r);
754 /* Note: triggered is a list here, although it almost certainly
755 * will always be one unit. Nevertheless, dbus API allows for multiple
756 * values, so let's follow that. */
759 /* The strv above is shared. free is set only in the first one. */
763 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
769 if (!a->machine && b->machine)
771 if (a->machine && !b->machine)
773 if (a->machine && b->machine) {
774 o = strcasecmp(a->machine, b->machine);
779 o = strcmp(a->path, b->path);
781 o = strcmp(a->type, b->type);
786 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
787 struct socket_info *s;
788 unsigned pathlen = strlen("LISTEN"),
789 typelen = strlen("TYPE") * arg_show_types,
790 socklen = strlen("UNIT"),
791 servlen = strlen("ACTIVATES");
792 const char *on, *off;
794 for (s = socket_infos; s < socket_infos + cs; s++) {
798 socklen = MAX(socklen, strlen(s->id));
800 typelen = MAX(typelen, strlen(s->type));
801 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
803 STRV_FOREACH(a, s->triggered)
804 tmp += strlen(*a) + 2*(a != s->triggered);
805 servlen = MAX(servlen, tmp);
810 printf("%-*s %-*.*s%-*s %s\n",
812 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
816 for (s = socket_infos; s < socket_infos + cs; s++) {
817 _cleanup_free_ char *j = NULL;
822 j = strjoin(s->machine, ":", s->path, NULL);
830 printf("%-*s %-*s %-*s",
831 pathlen, path, typelen, s->type, socklen, s->id);
834 pathlen, path, socklen, s->id);
835 STRV_FOREACH(a, s->triggered)
837 a == s->triggered ? "" : ",", *a);
841 on = ansi_highlight();
842 off = ansi_highlight_off();
846 on = ansi_highlight_red();
847 off = ansi_highlight_off();
850 if (!arg_no_legend) {
851 printf("%s%u sockets listed.%s\n", on, cs, off);
853 printf("Pass --all to see loaded but inactive sockets, too.\n");
859 static int list_sockets(sd_bus *bus, char **args) {
860 _cleanup_(message_set_freep) Set *replies = NULL;
861 _cleanup_strv_free_ char **machines = NULL;
862 _cleanup_free_ UnitInfo *unit_infos = NULL;
863 _cleanup_free_ struct socket_info *socket_infos = NULL;
865 struct socket_info *s;
870 pager_open_if_enabled();
872 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
876 for (u = unit_infos; u < unit_infos + n; u++) {
877 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
880 if (!endswith(u->id, ".socket"))
883 r = get_triggered_units(bus, u->unit_path, &triggered);
887 c = get_listening(bus, u->unit_path, &listening);
893 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
898 for (i = 0; i < c; i++)
899 socket_infos[cs + i] = (struct socket_info) {
900 .machine = u->machine,
902 .type = listening[i*2],
903 .path = listening[i*2 + 1],
904 .triggered = triggered,
905 .own_triggered = i==0,
908 /* from this point on we will cleanup those socket_infos */
911 listening = triggered = NULL; /* avoid cleanup */
914 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
915 (__compar_fn_t) socket_info_compare);
917 output_sockets_list(socket_infos, cs);
920 assert(cs == 0 || socket_infos);
921 for (s = socket_infos; s < socket_infos + cs; s++) {
924 if (s->own_triggered)
925 strv_free(s->triggered);
931 static int get_next_elapse(
934 dual_timestamp *next) {
936 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
944 r = sd_bus_get_property_trivial(
946 "org.freedesktop.systemd1",
948 "org.freedesktop.systemd1.Timer",
949 "NextElapseUSecMonotonic",
954 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
958 r = sd_bus_get_property_trivial(
960 "org.freedesktop.systemd1",
962 "org.freedesktop.systemd1.Timer",
963 "NextElapseUSecRealtime",
968 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
976 static int get_last_trigger(
981 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
988 r = sd_bus_get_property_trivial(
990 "org.freedesktop.systemd1",
992 "org.freedesktop.systemd1.Timer",
998 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1006 const char* machine;
1009 usec_t last_trigger;
1013 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1019 if (!a->machine && b->machine)
1021 if (a->machine && !b->machine)
1023 if (a->machine && b->machine) {
1024 o = strcasecmp(a->machine, b->machine);
1029 if (a->next_elapse < b->next_elapse)
1031 if (a->next_elapse > b->next_elapse)
1034 return strcmp(a->id, b->id);
1037 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1038 struct timer_info *t;
1040 nextlen = strlen("NEXT"),
1041 leftlen = strlen("LEFT"),
1042 lastlen = strlen("LAST"),
1043 passedlen = strlen("PASSED"),
1044 unitlen = strlen("UNIT"),
1045 activatelen = strlen("ACTIVATES");
1047 const char *on, *off;
1049 assert(timer_infos || n == 0);
1051 for (t = timer_infos; t < timer_infos + n; t++) {
1055 if (t->next_elapse > 0) {
1056 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1058 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1059 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1061 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1062 leftlen = MAX(leftlen, strlen(trel));
1065 if (t->last_trigger > 0) {
1066 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1068 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1069 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1071 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1072 passedlen = MAX(passedlen, strlen(trel));
1075 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1077 STRV_FOREACH(a, t->triggered)
1078 ul += strlen(*a) + 2*(a != t->triggered);
1080 activatelen = MAX(activatelen, ul);
1085 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1089 passedlen, "PASSED",
1093 for (t = timer_infos; t < timer_infos + n; t++) {
1094 _cleanup_free_ char *j = NULL;
1096 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1097 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1100 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1101 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1103 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1104 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1107 j = strjoin(t->machine, ":", t->id, NULL);
1114 printf("%-*s %-*s %-*s %-*s %-*s",
1115 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1117 STRV_FOREACH(a, t->triggered)
1119 a == t->triggered ? "" : ",", *a);
1123 on = ansi_highlight();
1124 off = ansi_highlight_off();
1128 on = ansi_highlight_red();
1129 off = ansi_highlight_off();
1132 if (!arg_no_legend) {
1133 printf("%s%u timers listed.%s\n", on, n, off);
1135 printf("Pass --all to see loaded but inactive timers, too.\n");
1141 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1147 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1150 if (next->monotonic > nw->monotonic)
1151 converted = nw->realtime + (next->monotonic - nw->monotonic);
1153 converted = nw->realtime - (nw->monotonic - next->monotonic);
1155 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1156 next_elapse = MIN(converted, next->realtime);
1158 next_elapse = converted;
1161 next_elapse = next->realtime;
1166 static int list_timers(sd_bus *bus, char **args) {
1167 _cleanup_(message_set_freep) Set *replies = NULL;
1168 _cleanup_strv_free_ char **machines = NULL;
1169 _cleanup_free_ struct timer_info *timer_infos = NULL;
1170 _cleanup_free_ UnitInfo *unit_infos = NULL;
1171 struct timer_info *t;
1178 pager_open_if_enabled();
1180 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1184 dual_timestamp_get(&nw);
1186 for (u = unit_infos; u < unit_infos + n; u++) {
1187 _cleanup_strv_free_ char **triggered = NULL;
1188 dual_timestamp next = {};
1191 if (!endswith(u->id, ".timer"))
1194 r = get_triggered_units(bus, u->unit_path, &triggered);
1198 r = get_next_elapse(bus, u->unit_path, &next);
1202 get_last_trigger(bus, u->unit_path, &last);
1204 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1209 m = calc_next_elapse(&nw, &next);
1211 timer_infos[c++] = (struct timer_info) {
1212 .machine = u->machine,
1215 .last_trigger = last,
1216 .triggered = triggered,
1219 triggered = NULL; /* avoid cleanup */
1222 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1223 (__compar_fn_t) timer_info_compare);
1225 output_timers_list(timer_infos, c);
1228 for (t = timer_infos; t < timer_infos + c; t++)
1229 strv_free(t->triggered);
1234 static int compare_unit_file_list(const void *a, const void *b) {
1235 const char *d1, *d2;
1236 const UnitFileList *u = a, *v = b;
1238 d1 = strrchr(u->path, '.');
1239 d2 = strrchr(v->path, '.');
1244 r = strcasecmp(d1, d2);
1249 return strcasecmp(basename(u->path), basename(v->path));
1252 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1253 if (!strv_isempty(patterns)) {
1256 STRV_FOREACH(pattern, patterns)
1257 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1263 if (!strv_isempty(arg_types)) {
1266 dot = strrchr(u->path, '.');
1270 if (!strv_find(arg_types, dot+1))
1274 if (!strv_isempty(arg_states)) {
1275 if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
1282 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1283 unsigned max_id_len, id_cols, state_cols;
1284 const UnitFileList *u;
1286 max_id_len = strlen("UNIT FILE");
1287 state_cols = strlen("STATE");
1289 for (u = units; u < units + c; u++) {
1290 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1291 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1295 unsigned basic_cols;
1297 id_cols = MIN(max_id_len, 25u);
1298 basic_cols = 1 + id_cols + state_cols;
1299 if (basic_cols < (unsigned) columns())
1300 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1302 id_cols = max_id_len;
1305 printf("%-*s %-*s\n",
1306 id_cols, "UNIT FILE",
1307 state_cols, "STATE");
1309 for (u = units; u < units + c; u++) {
1310 _cleanup_free_ char *e = NULL;
1311 const char *on, *off;
1314 if (u->state == UNIT_FILE_MASKED ||
1315 u->state == UNIT_FILE_MASKED_RUNTIME ||
1316 u->state == UNIT_FILE_DISABLED ||
1317 u->state == UNIT_FILE_INVALID) {
1318 on = ansi_highlight_red();
1319 off = ansi_highlight_off();
1320 } else if (u->state == UNIT_FILE_ENABLED) {
1321 on = ansi_highlight_green();
1322 off = ansi_highlight_off();
1326 id = basename(u->path);
1328 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1330 printf("%-*s %s%-*s%s\n",
1331 id_cols, e ? e : id,
1332 on, state_cols, unit_file_state_to_string(u->state), off);
1336 printf("\n%u unit files listed.\n", c);
1339 static int list_unit_files(sd_bus *bus, char **args) {
1340 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1341 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1342 _cleanup_free_ UnitFileList *units = NULL;
1350 pager_open_if_enabled();
1358 h = hashmap_new(&string_hash_ops);
1362 r = unit_file_get_list(arg_scope, arg_root, h);
1364 unit_file_list_free(h);
1365 log_error_errno(r, "Failed to get unit file list: %m");
1369 n_units = hashmap_size(h);
1371 units = new(UnitFileList, n_units);
1372 if (!units && n_units > 0) {
1373 unit_file_list_free(h);
1377 HASHMAP_FOREACH(u, h, i) {
1378 if (!output_show_unit_file(u, strv_skip_first(args)))
1385 assert(c <= n_units);
1388 r = sd_bus_call_method(
1390 "org.freedesktop.systemd1",
1391 "/org/freedesktop/systemd1",
1392 "org.freedesktop.systemd1.Manager",
1398 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1402 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1404 return bus_log_parse_error(r);
1406 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1408 if (!GREEDY_REALLOC(units, size, c + 1))
1411 units[c] = (struct UnitFileList) {
1413 unit_file_state_from_string(state)
1416 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1421 return bus_log_parse_error(r);
1423 r = sd_bus_message_exit_container(reply);
1425 return bus_log_parse_error(r);
1428 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1429 output_unit_file_list(units, c);
1432 for (unit = units; unit < units + c; unit++)
1439 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1440 _cleanup_free_ char *n = NULL;
1441 size_t max_len = MAX(columns(),20u);
1447 for (i = level - 1; i >= 0; i--) {
1449 if (len > max_len - 3 && !arg_full) {
1450 printf("%s...\n",max_len % 2 ? "" : " ");
1453 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1457 if (len > max_len - 3 && !arg_full) {
1458 printf("%s...\n",max_len % 2 ? "" : " ");
1462 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1466 printf("%s\n", name);
1470 n = ellipsize(name, max_len-len, 100);
1478 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1480 static const char *dependencies[_DEPENDENCY_MAX] = {
1481 [DEPENDENCY_FORWARD] = "Requires\0"
1482 "RequiresOverridable\0"
1484 "RequisiteOverridable\0"
1487 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1488 "RequiredByOverridable\0"
1492 [DEPENDENCY_AFTER] = "After\0",
1493 [DEPENDENCY_BEFORE] = "Before\0",
1496 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1497 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1498 _cleanup_strv_free_ char **ret = NULL;
1499 _cleanup_free_ char *path = NULL;
1505 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1507 path = unit_dbus_path_from_name(name);
1511 r = sd_bus_call_method(
1513 "org.freedesktop.systemd1",
1515 "org.freedesktop.DBus.Properties",
1519 "s", "org.freedesktop.systemd1.Unit");
1521 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1525 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1527 return bus_log_parse_error(r);
1529 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1532 r = sd_bus_message_read(reply, "s", &prop);
1534 return bus_log_parse_error(r);
1536 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1537 r = sd_bus_message_skip(reply, "v");
1539 return bus_log_parse_error(r);
1542 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1544 return bus_log_parse_error(r);
1546 r = bus_message_read_strv_extend(reply, &ret);
1548 return bus_log_parse_error(r);
1550 r = sd_bus_message_exit_container(reply);
1552 return bus_log_parse_error(r);
1555 r = sd_bus_message_exit_container(reply);
1557 return bus_log_parse_error(r);
1561 return bus_log_parse_error(r);
1563 r = sd_bus_message_exit_container(reply);
1565 return bus_log_parse_error(r);
1573 static int list_dependencies_compare(const void *_a, const void *_b) {
1574 const char **a = (const char**) _a, **b = (const char**) _b;
1576 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1578 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1581 return strcasecmp(*a, *b);
1584 static int list_dependencies_one(
1589 unsigned int branches) {
1591 _cleanup_strv_free_ char **deps = NULL;
1599 r = strv_extend(units, name);
1603 r = list_dependencies_get_dependencies(bus, name, &deps);
1607 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1609 STRV_FOREACH(c, deps) {
1612 if (strv_contains(*units, *c)) {
1614 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1621 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1623 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1625 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1627 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1631 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1632 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1639 strv_remove(*units, name);
1644 static int list_dependencies(sd_bus *bus, char **args) {
1645 _cleanup_strv_free_ char **units = NULL;
1646 _cleanup_free_ char *unit = NULL;
1652 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1657 u = SPECIAL_DEFAULT_TARGET;
1659 pager_open_if_enabled();
1663 return list_dependencies_one(bus, u, 0, &units, 0);
1666 struct machine_info {
1670 char *control_group;
1671 uint32_t n_failed_units;
1676 static const struct bus_properties_map machine_info_property_map[] = {
1677 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1678 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1679 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1680 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1681 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1685 static void free_machines_list(struct machine_info *machine_infos, int n) {
1691 for (i = 0; i < n; i++) {
1692 free(machine_infos[i].name);
1693 free(machine_infos[i].state);
1694 free(machine_infos[i].control_group);
1697 free(machine_infos);
1700 static int compare_machine_info(const void *a, const void *b) {
1701 const struct machine_info *u = a, *v = b;
1703 if (u->is_host != v->is_host)
1704 return u->is_host > v->is_host ? -1 : 1;
1706 return strcasecmp(u->name, v->name);
1709 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1710 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1716 r = sd_bus_open_system_machine(&container, mi->name);
1723 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1730 static bool output_show_machine(const char *name, char **patterns) {
1735 if (strv_isempty(patterns))
1738 STRV_FOREACH(i, patterns)
1739 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1745 static int get_machine_list(
1747 struct machine_info **_machine_infos,
1750 struct machine_info *machine_infos = NULL;
1751 _cleanup_strv_free_ char **m = NULL;
1752 _cleanup_free_ char *hn = NULL;
1757 hn = gethostname_malloc();
1761 if (output_show_machine(hn, patterns)) {
1762 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1765 machine_infos[c].is_host = true;
1766 machine_infos[c].name = hn;
1769 get_machine_properties(bus, &machine_infos[c]);
1773 sd_get_machine_names(&m);
1774 STRV_FOREACH(i, m) {
1775 _cleanup_free_ char *class = NULL;
1777 if (!output_show_machine(*i, patterns))
1780 sd_machine_get_class(*i, &class);
1781 if (!streq_ptr(class, "container"))
1784 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1785 free_machines_list(machine_infos, c);
1789 machine_infos[c].is_host = false;
1790 machine_infos[c].name = strdup(*i);
1791 if (!machine_infos[c].name) {
1792 free_machines_list(machine_infos, c);
1796 get_machine_properties(NULL, &machine_infos[c]);
1800 *_machine_infos = machine_infos;
1804 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1805 struct machine_info *m;
1808 namelen = sizeof("NAME") - 1,
1809 statelen = sizeof("STATE") - 1,
1810 failedlen = sizeof("FAILED") - 1,
1811 jobslen = sizeof("JOBS") - 1;
1813 assert(machine_infos || n == 0);
1815 for (m = machine_infos; m < machine_infos + n; m++) {
1816 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1817 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1818 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1819 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1821 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1825 if (!arg_no_legend) {
1829 printf("%-*s %-*s %-*s %-*s\n",
1832 failedlen, "FAILED",
1836 for (m = machine_infos; m < machine_infos + n; m++) {
1837 const char *on_state = "", *off_state = "";
1838 const char *on_failed = "", *off_failed = "";
1839 bool circle = false;
1841 if (streq_ptr(m->state, "degraded")) {
1842 on_state = ansi_highlight_red();
1843 off_state = ansi_highlight_off();
1845 } else if (!streq_ptr(m->state, "running")) {
1846 on_state = ansi_highlight_yellow();
1847 off_state = ansi_highlight_off();
1851 if (m->n_failed_units > 0) {
1852 on_failed = ansi_highlight_red();
1853 off_failed = ansi_highlight_off();
1855 on_failed = off_failed = "";
1858 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1861 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1862 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1863 on_state, statelen, strna(m->state), off_state,
1864 on_failed, failedlen, m->n_failed_units, off_failed,
1865 jobslen, m->n_jobs);
1867 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1868 namelen, strna(m->name),
1869 on_state, statelen, strna(m->state), off_state,
1870 on_failed, failedlen, m->n_failed_units, off_failed,
1871 jobslen, m->n_jobs);
1875 printf("\n%u machines listed.\n", n);
1878 static int list_machines(sd_bus *bus, char **args) {
1879 struct machine_info *machine_infos = NULL;
1884 if (geteuid() != 0) {
1885 log_error("Must be root.");
1889 pager_open_if_enabled();
1891 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1895 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1896 output_machines_list(machine_infos, r);
1897 free_machines_list(machine_infos, r);
1902 static int get_default(sd_bus *bus, char **args) {
1903 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1904 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1905 _cleanup_free_ char *_path = NULL;
1909 if (!bus || avoid_bus()) {
1910 r = unit_file_get_default(arg_scope, arg_root, &_path);
1912 return log_error_errno(r, "Failed to get default target: %m");
1916 r = sd_bus_call_method(
1918 "org.freedesktop.systemd1",
1919 "/org/freedesktop/systemd1",
1920 "org.freedesktop.systemd1.Manager",
1926 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1930 r = sd_bus_message_read(reply, "s", &path);
1932 return bus_log_parse_error(r);
1936 printf("%s\n", path);
1941 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1944 assert(changes || n_changes == 0);
1946 for (i = 0; i < n_changes; i++) {
1947 if (changes[i].type == UNIT_FILE_SYMLINK)
1948 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1950 log_info("Removed symlink %s.", changes[i].path);
1954 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1955 const char *type, *path, *source;
1958 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1960 return bus_log_parse_error(r);
1962 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1964 if (streq(type, "symlink"))
1965 log_info("Created symlink from %s to %s.", path, source);
1967 log_info("Removed symlink %s.", path);
1971 return bus_log_parse_error(r);
1973 r = sd_bus_message_exit_container(m);
1975 return bus_log_parse_error(r);
1980 static int set_default(sd_bus *bus, char **args) {
1981 _cleanup_free_ char *unit = NULL;
1982 UnitFileChange *changes = NULL;
1983 unsigned n_changes = 0;
1986 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1990 if (!bus || avoid_bus()) {
1991 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1993 return log_error_errno(r, "Failed to set default target: %m");
1996 dump_unit_file_changes(changes, n_changes);
2000 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
2001 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2003 r = sd_bus_message_new_method_call(
2006 "org.freedesktop.systemd1",
2007 "/org/freedesktop/systemd1",
2008 "org.freedesktop.systemd1.Manager",
2009 "SetDefaultTarget");
2011 return bus_log_create_error(r);
2013 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2015 return bus_log_create_error(r);
2017 r = sd_bus_message_append(m, "sb", unit, 1);
2019 return bus_log_create_error(r);
2021 r = sd_bus_call(bus, m, 0, &error, &reply);
2023 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2027 r = deserialize_and_dump_unit_file_changes(reply);
2031 /* Try to reload if enabled */
2033 r = daemon_reload(bus, args);
2038 unit_file_changes_free(changes, n_changes);
2045 const char *name, *type, *state;
2048 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2049 unsigned id_len, unit_len, type_len, state_len;
2050 const struct job_info *j;
2051 const char *on, *off;
2052 bool shorten = false;
2054 assert(n == 0 || jobs);
2057 on = ansi_highlight_green();
2058 off = ansi_highlight_off();
2060 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2064 pager_open_if_enabled();
2066 id_len = strlen("JOB");
2067 unit_len = strlen("UNIT");
2068 type_len = strlen("TYPE");
2069 state_len = strlen("STATE");
2071 for (j = jobs; j < jobs + n; j++) {
2072 uint32_t id = j->id;
2073 assert(j->name && j->type && j->state);
2075 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2076 unit_len = MAX(unit_len, strlen(j->name));
2077 type_len = MAX(type_len, strlen(j->type));
2078 state_len = MAX(state_len, strlen(j->state));
2081 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2082 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2087 printf("%*s %-*s %-*s %-*s\n",
2091 state_len, "STATE");
2093 for (j = jobs; j < jobs + n; j++) {
2094 _cleanup_free_ char *e = NULL;
2096 if (streq(j->state, "running")) {
2097 on = ansi_highlight();
2098 off = ansi_highlight_off();
2102 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2103 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2105 on, unit_len, e ? e : j->name, off,
2107 on, state_len, j->state, off);
2110 if (!arg_no_legend) {
2111 on = ansi_highlight();
2112 off = ansi_highlight_off();
2114 printf("\n%s%u jobs listed%s.\n", on, n, off);
2118 static bool output_show_job(struct job_info *job, char **patterns) {
2123 if (strv_isempty(patterns))
2126 STRV_FOREACH(pattern, patterns)
2127 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2132 static int list_jobs(sd_bus *bus, char **args) {
2133 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2134 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2135 const char *name, *type, *state, *job_path, *unit_path;
2136 _cleanup_free_ struct job_info *jobs = NULL;
2141 bool skipped = false;
2143 r = sd_bus_call_method(
2145 "org.freedesktop.systemd1",
2146 "/org/freedesktop/systemd1",
2147 "org.freedesktop.systemd1.Manager",
2153 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2157 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2159 return bus_log_parse_error(r);
2161 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2162 struct job_info job = { id, name, type, state };
2164 if (!output_show_job(&job, strv_skip_first(args))) {
2169 if (!GREEDY_REALLOC(jobs, size, c + 1))
2175 return bus_log_parse_error(r);
2177 r = sd_bus_message_exit_container(reply);
2179 return bus_log_parse_error(r);
2181 output_jobs_list(jobs, c, skipped);
2185 static int cancel_job(sd_bus *bus, char **args) {
2186 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2192 if (strv_length(args) <= 1)
2193 return daemon_reload(bus, args);
2195 STRV_FOREACH(name, args+1) {
2196 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2200 q = safe_atou32(*name, &id);
2202 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2204 q = sd_bus_message_new_method_call(
2207 "org.freedesktop.systemd1",
2208 "/org/freedesktop/systemd1",
2209 "org.freedesktop.systemd1.Manager",
2212 return bus_log_create_error(q);
2214 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2216 return bus_log_create_error(1);
2218 q = sd_bus_message_append(m, "u", id);
2220 return bus_log_create_error(q);
2222 q = sd_bus_call(bus, m, 0, &error, NULL);
2224 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2233 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2234 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2238 /* We ignore all errors here, since this is used to show a
2241 /* We don't use unit_dbus_path_from_name() directly since we
2242 * don't want to load the unit if it isn't loaded. */
2244 r = sd_bus_call_method(
2246 "org.freedesktop.systemd1",
2247 "/org/freedesktop/systemd1",
2248 "org.freedesktop.systemd1.Manager",
2256 r = sd_bus_message_read(reply, "o", &path);
2260 r = sd_bus_get_property_trivial(
2262 "org.freedesktop.systemd1",
2264 "org.freedesktop.systemd1.Unit",
2274 static void warn_unit_file_changed(const char *name) {
2275 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2276 ansi_highlight_red(),
2277 ansi_highlight_off(),
2279 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2282 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2289 STRV_FOREACH(p, lp->unit_path) {
2290 _cleanup_free_ char *path;
2292 path = path_join(arg_root, *p, unit_name);
2296 if (access(path, F_OK) == 0) {
2306 static int unit_find_paths(sd_bus *bus,
2307 const char *unit_name,
2308 bool avoid_bus_cache,
2310 char **fragment_path,
2311 char ***dropin_paths) {
2315 * Finds where the unit is defined on disk. Returns 0 if the unit
2316 * is not found. Returns 1 if it is found, and sets
2317 * - the path to the unit in *path, if it exists on disk,
2318 * - and a strv of existing drop-ins in *dropins,
2319 * if the arg is not NULL and any dropins were found.
2323 assert(fragment_path);
2326 if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2327 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2328 _cleanup_free_ char *unit = NULL;
2329 _cleanup_free_ char *path = NULL;
2330 _cleanup_strv_free_ char **dropins = NULL;
2332 unit = unit_dbus_path_from_name(unit_name);
2336 if (need_daemon_reload(bus, unit_name) > 0)
2337 warn_unit_file_changed(unit_name);
2339 r = sd_bus_get_property_string(
2341 "org.freedesktop.systemd1",
2343 "org.freedesktop.systemd1.Unit",
2348 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2350 r = sd_bus_get_property_strv(
2352 "org.freedesktop.systemd1",
2354 "org.freedesktop.systemd1.Unit",
2359 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2362 if (!isempty(path)) {
2363 *fragment_path = path;
2368 if (dropin_paths && !strv_isempty(dropins)) {
2369 *dropin_paths = dropins;
2374 _cleanup_set_free_ Set *names;
2376 names = set_new(NULL);
2380 r = set_put(names, unit_name);
2384 r = unit_file_find_path(lp, unit_name, fragment_path);
2389 _cleanup_free_ char *template;
2391 template = unit_name_template(unit_name);
2395 if (!streq(template, unit_name)) {
2396 r = unit_file_find_path(lp, template, fragment_path);
2403 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
2409 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2410 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2411 _cleanup_free_ char *n = NULL, *state = NULL;
2417 n = unit_name_mangle(name, MANGLE_NOGLOB);
2421 /* We don't use unit_dbus_path_from_name() directly since we
2422 * don't want to load the unit if it isn't loaded. */
2424 r = sd_bus_call_method(
2426 "org.freedesktop.systemd1",
2427 "/org/freedesktop/systemd1",
2428 "org.freedesktop.systemd1.Manager",
2439 r = sd_bus_message_read(reply, "o", &path);
2441 return bus_log_parse_error(r);
2443 r = sd_bus_get_property_string(
2445 "org.freedesktop.systemd1",
2447 "org.freedesktop.systemd1.Unit",
2460 return nulstr_contains(good_states, state);
2463 static int check_triggering_units(
2467 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2468 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2469 _cleanup_strv_free_ char **triggered_by = NULL;
2470 bool print_warning_label = true;
2474 n = unit_name_mangle(name, MANGLE_NOGLOB);
2478 path = unit_dbus_path_from_name(n);
2482 r = sd_bus_get_property_string(
2484 "org.freedesktop.systemd1",
2486 "org.freedesktop.systemd1.Unit",
2491 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2495 if (streq(state, "masked"))
2498 r = sd_bus_get_property_strv(
2500 "org.freedesktop.systemd1",
2502 "org.freedesktop.systemd1.Unit",
2507 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2511 STRV_FOREACH(i, triggered_by) {
2512 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2514 return log_error_errno(r, "Failed to check unit: %m");
2519 if (print_warning_label) {
2520 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2521 print_warning_label = false;
2524 log_warning(" %s", *i);
2530 static const struct {
2533 } unit_actions[] = {
2534 { "start", "StartUnit" },
2535 { "stop", "StopUnit" },
2536 { "condstop", "StopUnit" },
2537 { "reload", "ReloadUnit" },
2538 { "restart", "RestartUnit" },
2539 { "try-restart", "TryRestartUnit" },
2540 { "condrestart", "TryRestartUnit" },
2541 { "reload-or-restart", "ReloadOrRestartUnit" },
2542 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2543 { "condreload", "ReloadOrTryRestartUnit" },
2544 { "force-reload", "ReloadOrTryRestartUnit" }
2547 static const char *verb_to_method(const char *verb) {
2550 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2551 if (streq_ptr(unit_actions[i].verb, verb))
2552 return unit_actions[i].method;
2557 static const char *method_to_verb(const char *method) {
2560 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2561 if (streq_ptr(unit_actions[i].method, method))
2562 return unit_actions[i].verb;
2567 static int start_unit_one(
2572 sd_bus_error *error,
2573 BusWaitForJobs *w) {
2575 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2584 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2586 r = sd_bus_message_new_method_call(
2589 "org.freedesktop.systemd1",
2590 "/org/freedesktop/systemd1",
2591 "org.freedesktop.systemd1.Manager",
2594 return bus_log_create_error(r);
2596 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2598 return bus_log_create_error(r);
2600 r = sd_bus_message_append(m, "ss", name, mode);
2602 return bus_log_create_error(r);
2604 r = sd_bus_call(bus, m, 0, error, &reply);
2608 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2609 /* There's always a fallback possible for
2610 * legacy actions. */
2611 return -EADDRNOTAVAIL;
2613 verb = method_to_verb(method);
2615 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2619 r = sd_bus_message_read(reply, "o", &path);
2621 return bus_log_parse_error(r);
2623 if (need_daemon_reload(bus, name) > 0)
2624 warn_unit_file_changed(name);
2627 log_debug("Adding %s to the set", path);
2628 r = bus_wait_for_jobs_add(w, path);
2636 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2638 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2642 STRV_FOREACH(name, names) {
2646 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2648 t = unit_name_mangle(*name, MANGLE_GLOB);
2652 if (string_is_glob(t))
2653 r = strv_consume(&globs, t);
2655 r = strv_consume(&mangled, t);
2660 /* Query the manager only if any of the names are a glob, since
2661 * this is fairly expensive */
2662 if (!strv_isempty(globs)) {
2663 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2664 _cleanup_free_ UnitInfo *unit_infos = NULL;
2667 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2669 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2673 for (i = 0; i < r; i++)
2674 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2679 mangled = NULL; /* do not free */
2684 static const struct {
2688 } action_table[_ACTION_MAX] = {
2689 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2690 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2691 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2692 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2693 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2694 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2695 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2696 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2697 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2698 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2699 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2700 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2701 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2702 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2703 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2706 static enum action verb_to_action(const char *verb) {
2709 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2710 if (streq_ptr(action_table[i].verb, verb))
2713 return _ACTION_INVALID;
2716 static int start_unit(sd_bus *bus, char **args) {
2717 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2718 const char *method, *mode, *one_name, *suffix = NULL;
2719 _cleanup_strv_free_ char **names = NULL;
2725 ask_password_agent_open_if_enabled();
2727 if (arg_action == ACTION_SYSTEMCTL) {
2729 method = verb_to_method(args[0]);
2730 action = verb_to_action(args[0]);
2732 if (streq(args[0], "isolate")) {
2736 mode = action_table[action].mode ?: arg_job_mode;
2738 one_name = action_table[action].target;
2740 assert(arg_action < ELEMENTSOF(action_table));
2741 assert(action_table[arg_action].target);
2743 method = "StartUnit";
2745 mode = action_table[arg_action].mode;
2746 one_name = action_table[arg_action].target;
2750 names = strv_new(one_name, NULL);
2752 r = expand_names(bus, args + 1, suffix, &names);
2754 log_error_errno(r, "Failed to expand names: %m");
2757 if (!arg_no_block) {
2758 r = bus_wait_for_jobs_new(bus, &w);
2760 return log_error_errno(r, "Could not watch jobs: %m");
2763 STRV_FOREACH(name, names) {
2764 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2767 q = start_unit_one(bus, method, *name, mode, &error, w);
2768 if (r >= 0 && q < 0)
2769 r = translate_bus_error_to_exit_status(q, &error);
2772 if (!arg_no_block) {
2775 q = bus_wait_for_jobs(w, arg_quiet);
2779 /* When stopping units, warn if they can still be triggered by
2780 * another active unit (socket, path, timer) */
2781 if (!arg_quiet && streq(method, "StopUnit"))
2782 STRV_FOREACH(name, names)
2783 check_triggering_units(bus, *name);
2789 /* Ask systemd-logind, which might grant access to unprivileged users
2790 * through PolicyKit */
2791 static int reboot_with_logind(sd_bus *bus, enum action a) {
2793 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2800 polkit_agent_open_if_enabled();
2808 case ACTION_POWEROFF:
2809 method = "PowerOff";
2812 case ACTION_SUSPEND:
2816 case ACTION_HIBERNATE:
2817 method = "Hibernate";
2820 case ACTION_HYBRID_SLEEP:
2821 method = "HybridSleep";
2828 r = sd_bus_call_method(
2830 "org.freedesktop.login1",
2831 "/org/freedesktop/login1",
2832 "org.freedesktop.login1.Manager",
2836 "b", arg_ask_password);
2838 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2846 static int check_inhibitors(sd_bus *bus, enum action a) {
2848 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2849 _cleanup_strv_free_ char **sessions = NULL;
2850 const char *what, *who, *why, *mode;
2859 if (arg_ignore_inhibitors || arg_force > 0)
2871 r = sd_bus_call_method(
2873 "org.freedesktop.login1",
2874 "/org/freedesktop/login1",
2875 "org.freedesktop.login1.Manager",
2881 /* If logind is not around, then there are no inhibitors... */
2884 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2886 return bus_log_parse_error(r);
2888 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2889 _cleanup_free_ char *comm = NULL, *user = NULL;
2890 _cleanup_strv_free_ char **sv = NULL;
2892 if (!streq(mode, "block"))
2895 sv = strv_split(what, ":");
2899 if (!strv_contains(sv,
2901 a == ACTION_POWEROFF ||
2902 a == ACTION_REBOOT ||
2903 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2906 get_process_comm(pid, &comm);
2907 user = uid_to_name(uid);
2909 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2910 who, pid, strna(comm), strna(user), why);
2915 return bus_log_parse_error(r);
2917 r = sd_bus_message_exit_container(reply);
2919 return bus_log_parse_error(r);
2921 /* Check for current sessions */
2922 sd_get_sessions(&sessions);
2923 STRV_FOREACH(s, sessions) {
2924 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2926 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2929 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2932 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2935 sd_session_get_tty(*s, &tty);
2936 sd_session_get_seat(*s, &seat);
2937 sd_session_get_service(*s, &service);
2938 user = uid_to_name(uid);
2940 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2947 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2948 action_table[a].verb);
2956 static int start_special(sd_bus *bus, char **args) {
2962 a = verb_to_action(args[0]);
2964 r = check_inhibitors(bus, a);
2968 if (arg_force >= 2 && geteuid() != 0) {
2969 log_error("Must be root.");
2973 if (arg_force >= 2 &&
2974 (a == ACTION_HALT ||
2975 a == ACTION_POWEROFF ||
2976 a == ACTION_REBOOT))
2979 if (arg_force >= 1 &&
2980 (a == ACTION_HALT ||
2981 a == ACTION_POWEROFF ||
2982 a == ACTION_REBOOT ||
2983 a == ACTION_KEXEC ||
2985 return daemon_reload(bus, args);
2987 /* first try logind, to allow authentication with polkit */
2988 if (geteuid() != 0 &&
2989 (a == ACTION_POWEROFF ||
2990 a == ACTION_REBOOT ||
2991 a == ACTION_SUSPEND ||
2992 a == ACTION_HIBERNATE ||
2993 a == ACTION_HYBRID_SLEEP)) {
2994 r = reboot_with_logind(bus, a);
2999 r = start_unit(bus, args);
3000 if (r == EXIT_SUCCESS)
3006 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3007 _cleanup_strv_free_ char **names = NULL;
3014 r = expand_names(bus, args, NULL, &names);
3016 return log_error_errno(r, "Failed to expand names: %m");
3018 STRV_FOREACH(name, names) {
3021 state = check_one_unit(bus, *name, good_states, arg_quiet);
3031 static int check_unit_active(sd_bus *bus, char **args) {
3032 /* According to LSB: 3, "program is not running" */
3033 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3036 static int check_unit_failed(sd_bus *bus, char **args) {
3037 return check_unit_generic(bus, 1, "failed\0", args + 1);
3040 static int kill_unit(sd_bus *bus, char **args) {
3041 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3042 _cleanup_strv_free_ char **names = NULL;
3050 arg_kill_who = "all";
3052 r = expand_names(bus, args + 1, NULL, &names);
3054 log_error_errno(r, "Failed to expand names: %m");
3056 STRV_FOREACH(name, names) {
3057 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3059 q = sd_bus_message_new_method_call(
3062 "org.freedesktop.systemd1",
3063 "/org/freedesktop/systemd1",
3064 "org.freedesktop.systemd1.Manager",
3067 return bus_log_create_error(q);
3069 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3071 return bus_log_create_error(q);
3073 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3075 return bus_log_create_error(q);
3077 q = sd_bus_call(bus, m, 0, &error, NULL);
3079 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3088 typedef struct ExecStatusInfo {
3096 usec_t start_timestamp;
3097 usec_t exit_timestamp;
3102 LIST_FIELDS(struct ExecStatusInfo, exec);
3105 static void exec_status_info_free(ExecStatusInfo *i) {
3114 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3115 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3118 int32_t code, status;
3124 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3126 return bus_log_parse_error(r);
3130 r = sd_bus_message_read(m, "s", &path);
3132 return bus_log_parse_error(r);
3134 i->path = strdup(path);
3138 r = sd_bus_message_read_strv(m, &i->argv);
3140 return bus_log_parse_error(r);
3142 r = sd_bus_message_read(m,
3145 &start_timestamp, &start_timestamp_monotonic,
3146 &exit_timestamp, &exit_timestamp_monotonic,
3150 return bus_log_parse_error(r);
3153 i->start_timestamp = (usec_t) start_timestamp;
3154 i->exit_timestamp = (usec_t) exit_timestamp;
3155 i->pid = (pid_t) pid;
3159 r = sd_bus_message_exit_container(m);
3161 return bus_log_parse_error(r);
3166 typedef struct UnitStatusInfo {
3168 const char *load_state;
3169 const char *active_state;
3170 const char *sub_state;
3171 const char *unit_file_state;
3172 const char *unit_file_preset;
3174 const char *description;
3175 const char *following;
3177 char **documentation;
3179 const char *fragment_path;
3180 const char *source_path;
3181 const char *control_group;
3183 char **dropin_paths;
3185 const char *load_error;
3188 usec_t inactive_exit_timestamp;
3189 usec_t inactive_exit_timestamp_monotonic;
3190 usec_t active_enter_timestamp;
3191 usec_t active_exit_timestamp;
3192 usec_t inactive_enter_timestamp;
3194 bool need_daemon_reload;
3199 const char *status_text;
3200 const char *pid_file;
3204 usec_t start_timestamp;
3205 usec_t exit_timestamp;
3207 int exit_code, exit_status;
3209 usec_t condition_timestamp;
3210 bool condition_result;
3211 bool failed_condition_trigger;
3212 bool failed_condition_negate;
3213 const char *failed_condition;
3214 const char *failed_condition_parameter;
3216 usec_t assert_timestamp;
3218 bool failed_assert_trigger;
3219 bool failed_assert_negate;
3220 const char *failed_assert;
3221 const char *failed_assert_parameter;
3224 unsigned n_accepted;
3225 unsigned n_connections;
3228 /* Pairs of type, path */
3232 const char *sysfs_path;
3234 /* Mount, Automount */
3240 LIST_HEAD(ExecStatusInfo, exec);
3243 static void print_status_info(
3248 const char *active_on, *active_off, *on, *off, *ss;
3250 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3251 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3254 arg_all * OUTPUT_SHOW_ALL |
3255 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3256 on_tty() * OUTPUT_COLOR |
3257 !arg_quiet * OUTPUT_WARN_CUTOFF |
3258 arg_full * OUTPUT_FULL_WIDTH;
3263 /* This shows pretty information about a unit. See
3264 * print_property() for a low-level property printer */
3266 if (streq_ptr(i->active_state, "failed")) {
3267 active_on = ansi_highlight_red();
3268 active_off = ansi_highlight_off();
3269 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3270 active_on = ansi_highlight_green();
3271 active_off = ansi_highlight_off();
3273 active_on = active_off = "";
3275 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3277 if (i->description && !streq_ptr(i->id, i->description))
3278 printf(" - %s", i->description);
3283 printf(" Follow: unit currently follows state of %s\n", i->following);
3285 if (streq_ptr(i->load_state, "error")) {
3286 on = ansi_highlight_red();
3287 off = ansi_highlight_off();
3291 path = i->source_path ? i->source_path : i->fragment_path;
3294 printf(" Loaded: %s%s%s (Reason: %s)\n",
3295 on, strna(i->load_state), off, i->load_error);
3296 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3297 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3298 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3299 else if (path && !isempty(i->unit_file_state))
3300 printf(" Loaded: %s%s%s (%s; %s)\n",
3301 on, strna(i->load_state), off, path, i->unit_file_state);
3303 printf(" Loaded: %s%s%s (%s)\n",
3304 on, strna(i->load_state), off, path);
3306 printf(" Loaded: %s%s%s\n",
3307 on, strna(i->load_state), off);
3309 if (!strv_isempty(i->dropin_paths)) {
3310 _cleanup_free_ char *dir = NULL;
3314 STRV_FOREACH(dropin, i->dropin_paths) {
3315 if (! dir || last) {
3316 printf(dir ? " " : " Drop-In: ");
3321 if (path_get_parent(*dropin, &dir) < 0) {
3326 printf("%s\n %s", dir,
3327 draw_special_char(DRAW_TREE_RIGHT));
3330 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3332 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3336 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3338 printf(" Active: %s%s (%s)%s",
3339 active_on, strna(i->active_state), ss, active_off);
3341 printf(" Active: %s%s%s",
3342 active_on, strna(i->active_state), active_off);
3344 if (!isempty(i->result) && !streq(i->result, "success"))
3345 printf(" (Result: %s)", i->result);
3347 timestamp = (streq_ptr(i->active_state, "active") ||
3348 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3349 (streq_ptr(i->active_state, "inactive") ||
3350 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3351 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3352 i->active_exit_timestamp;
3354 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3355 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3358 printf(" since %s; %s\n", s2, s1);
3360 printf(" since %s\n", s2);
3364 if (!i->condition_result && i->condition_timestamp > 0) {
3365 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3366 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3368 printf("Condition: start %scondition failed%s at %s%s%s\n",
3369 ansi_highlight_yellow(), ansi_highlight_off(),
3370 s2, s1 ? "; " : "", s1 ? s1 : "");
3371 if (i->failed_condition_trigger)
3372 printf(" none of the trigger conditions were met\n");
3373 else if (i->failed_condition)
3374 printf(" %s=%s%s was not met\n",
3375 i->failed_condition,
3376 i->failed_condition_negate ? "!" : "",
3377 i->failed_condition_parameter);
3380 if (!i->assert_result && i->assert_timestamp > 0) {
3381 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3382 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3384 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3385 ansi_highlight_red(), ansi_highlight_off(),
3386 s2, s1 ? "; " : "", s1 ? s1 : "");
3387 if (i->failed_assert_trigger)
3388 printf(" none of the trigger assertions were met\n");
3389 else if (i->failed_assert)
3390 printf(" %s=%s%s was not met\n",
3392 i->failed_assert_negate ? "!" : "",
3393 i->failed_assert_parameter);
3397 printf(" Device: %s\n", i->sysfs_path);
3399 printf(" Where: %s\n", i->where);
3401 printf(" What: %s\n", i->what);
3403 STRV_FOREACH(t, i->documentation)
3404 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3406 STRV_FOREACH_PAIR(t, t2, i->listen)
3407 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3410 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3412 LIST_FOREACH(exec, p, i->exec) {
3413 _cleanup_free_ char *argv = NULL;
3416 /* Only show exited processes here */
3420 argv = strv_join(p->argv, " ");
3421 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3423 good = is_clean_exit_lsb(p->code, p->status, NULL);
3425 on = ansi_highlight_red();
3426 off = ansi_highlight_off();
3430 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3432 if (p->code == CLD_EXITED) {
3435 printf("status=%i", p->status);
3437 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3442 printf("signal=%s", signal_to_string(p->status));
3444 printf(")%s\n", off);
3446 if (i->main_pid == p->pid &&
3447 i->start_timestamp == p->start_timestamp &&
3448 i->exit_timestamp == p->start_timestamp)
3449 /* Let's not show this twice */
3452 if (p->pid == i->control_pid)
3456 if (i->main_pid > 0 || i->control_pid > 0) {
3457 if (i->main_pid > 0) {
3458 printf(" Main PID: "PID_FMT, i->main_pid);
3461 _cleanup_free_ char *comm = NULL;
3462 get_process_comm(i->main_pid, &comm);
3464 printf(" (%s)", comm);
3465 } else if (i->exit_code > 0) {
3466 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3468 if (i->exit_code == CLD_EXITED) {
3471 printf("status=%i", i->exit_status);
3473 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3478 printf("signal=%s", signal_to_string(i->exit_status));
3482 if (i->control_pid > 0)
3486 if (i->control_pid > 0) {
3487 _cleanup_free_ char *c = NULL;
3489 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3491 get_process_comm(i->control_pid, &c);
3500 printf(" Status: \"%s\"\n", i->status_text);
3501 if (i->status_errno > 0)
3502 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3504 if (i->control_group &&
3505 (i->main_pid > 0 || i->control_pid > 0 ||
3506 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3509 printf(" CGroup: %s\n", i->control_group);
3511 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3514 static const char prefix[] = " ";
3517 if (c > sizeof(prefix) - 1)
3518 c -= sizeof(prefix) - 1;
3522 if (i->main_pid > 0)
3523 extra[k++] = i->main_pid;
3525 if (i->control_pid > 0)
3526 extra[k++] = i->control_pid;
3528 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3532 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3533 show_journal_by_unit(stdout,
3537 i->inactive_exit_timestamp_monotonic,
3540 flags | OUTPUT_BEGIN_NEWLINE,
3541 arg_scope == UNIT_FILE_SYSTEM,
3545 if (i->need_daemon_reload)
3546 warn_unit_file_changed(i->id);
3549 static void show_unit_help(UnitStatusInfo *i) {
3554 if (!i->documentation) {
3555 log_info("Documentation for %s not known.", i->id);
3559 STRV_FOREACH(p, i->documentation)
3560 if (startswith(*p, "man:"))
3561 show_man_page(*p + 4, false);
3563 log_info("Can't show: %s", *p);
3566 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3573 switch (contents[0]) {
3575 case SD_BUS_TYPE_STRING: {
3578 r = sd_bus_message_read(m, "s", &s);
3580 return bus_log_parse_error(r);
3583 if (streq(name, "Id"))
3585 else if (streq(name, "LoadState"))
3587 else if (streq(name, "ActiveState"))
3588 i->active_state = s;
3589 else if (streq(name, "SubState"))
3591 else if (streq(name, "Description"))
3593 else if (streq(name, "FragmentPath"))
3594 i->fragment_path = s;
3595 else if (streq(name, "SourcePath"))
3598 else if (streq(name, "DefaultControlGroup")) {
3600 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3602 i->control_group = e;
3605 else if (streq(name, "ControlGroup"))
3606 i->control_group = s;
3607 else if (streq(name, "StatusText"))
3609 else if (streq(name, "PIDFile"))
3611 else if (streq(name, "SysFSPath"))
3613 else if (streq(name, "Where"))
3615 else if (streq(name, "What"))
3617 else if (streq(name, "Following"))
3619 else if (streq(name, "UnitFileState"))
3620 i->unit_file_state = s;
3621 else if (streq(name, "UnitFilePreset"))
3622 i->unit_file_preset = s;
3623 else if (streq(name, "Result"))
3630 case SD_BUS_TYPE_BOOLEAN: {
3633 r = sd_bus_message_read(m, "b", &b);
3635 return bus_log_parse_error(r);
3637 if (streq(name, "Accept"))
3639 else if (streq(name, "NeedDaemonReload"))
3640 i->need_daemon_reload = b;
3641 else if (streq(name, "ConditionResult"))
3642 i->condition_result = b;
3643 else if (streq(name, "AssertResult"))
3644 i->assert_result = b;
3649 case SD_BUS_TYPE_UINT32: {
3652 r = sd_bus_message_read(m, "u", &u);
3654 return bus_log_parse_error(r);
3656 if (streq(name, "MainPID")) {
3658 i->main_pid = (pid_t) u;
3661 } else if (streq(name, "ControlPID"))
3662 i->control_pid = (pid_t) u;
3663 else if (streq(name, "ExecMainPID")) {
3665 i->main_pid = (pid_t) u;
3666 } else if (streq(name, "NAccepted"))
3668 else if (streq(name, "NConnections"))
3669 i->n_connections = u;
3674 case SD_BUS_TYPE_INT32: {
3677 r = sd_bus_message_read(m, "i", &j);
3679 return bus_log_parse_error(r);
3681 if (streq(name, "ExecMainCode"))
3682 i->exit_code = (int) j;
3683 else if (streq(name, "ExecMainStatus"))
3684 i->exit_status = (int) j;
3685 else if (streq(name, "StatusErrno"))
3686 i->status_errno = (int) j;
3691 case SD_BUS_TYPE_UINT64: {
3694 r = sd_bus_message_read(m, "t", &u);
3696 return bus_log_parse_error(r);
3698 if (streq(name, "ExecMainStartTimestamp"))
3699 i->start_timestamp = (usec_t) u;
3700 else if (streq(name, "ExecMainExitTimestamp"))
3701 i->exit_timestamp = (usec_t) u;
3702 else if (streq(name, "ActiveEnterTimestamp"))
3703 i->active_enter_timestamp = (usec_t) u;
3704 else if (streq(name, "InactiveEnterTimestamp"))
3705 i->inactive_enter_timestamp = (usec_t) u;
3706 else if (streq(name, "InactiveExitTimestamp"))
3707 i->inactive_exit_timestamp = (usec_t) u;
3708 else if (streq(name, "InactiveExitTimestampMonotonic"))
3709 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3710 else if (streq(name, "ActiveExitTimestamp"))
3711 i->active_exit_timestamp = (usec_t) u;
3712 else if (streq(name, "ConditionTimestamp"))
3713 i->condition_timestamp = (usec_t) u;
3714 else if (streq(name, "AssertTimestamp"))
3715 i->assert_timestamp = (usec_t) u;
3720 case SD_BUS_TYPE_ARRAY:
3722 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3723 _cleanup_free_ ExecStatusInfo *info = NULL;
3725 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3727 return bus_log_parse_error(r);
3729 info = new0(ExecStatusInfo, 1);
3733 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3735 info->name = strdup(name);
3739 LIST_PREPEND(exec, i->exec, info);
3741 info = new0(ExecStatusInfo, 1);
3747 return bus_log_parse_error(r);
3749 r = sd_bus_message_exit_container(m);
3751 return bus_log_parse_error(r);
3755 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3756 const char *type, *path;
3758 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3760 return bus_log_parse_error(r);
3762 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3764 r = strv_extend(&i->listen, type);
3768 r = strv_extend(&i->listen, path);
3773 return bus_log_parse_error(r);
3775 r = sd_bus_message_exit_container(m);
3777 return bus_log_parse_error(r);
3781 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3783 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3785 return bus_log_parse_error(r);
3787 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3789 r = sd_bus_message_read_strv(m, &i->documentation);
3791 return bus_log_parse_error(r);
3793 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3794 const char *cond, *param;
3795 int trigger, negate;
3798 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3800 return bus_log_parse_error(r);
3802 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3803 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3804 if (state < 0 && (!trigger || !i->failed_condition)) {
3805 i->failed_condition = cond;
3806 i->failed_condition_trigger = trigger;
3807 i->failed_condition_negate = negate;
3808 i->failed_condition_parameter = param;
3812 return bus_log_parse_error(r);
3814 r = sd_bus_message_exit_container(m);
3816 return bus_log_parse_error(r);
3818 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3819 const char *cond, *param;
3820 int trigger, negate;
3823 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3825 return bus_log_parse_error(r);
3827 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3828 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3829 if (state < 0 && (!trigger || !i->failed_assert)) {
3830 i->failed_assert = cond;
3831 i->failed_assert_trigger = trigger;
3832 i->failed_assert_negate = negate;
3833 i->failed_assert_parameter = param;
3837 return bus_log_parse_error(r);
3839 r = sd_bus_message_exit_container(m);
3841 return bus_log_parse_error(r);
3848 case SD_BUS_TYPE_STRUCT_BEGIN:
3850 if (streq(name, "LoadError")) {
3851 const char *n, *message;
3853 r = sd_bus_message_read(m, "(ss)", &n, &message);
3855 return bus_log_parse_error(r);
3857 if (!isempty(message))
3858 i->load_error = message;
3871 r = sd_bus_message_skip(m, contents);
3873 return bus_log_parse_error(r);
3878 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3884 /* This is a low-level property printer, see
3885 * print_status_info() for the nicer output */
3887 if (arg_properties && !strv_find(arg_properties, name)) {
3888 /* skip what we didn't read */
3889 r = sd_bus_message_skip(m, contents);
3893 switch (contents[0]) {
3895 case SD_BUS_TYPE_STRUCT_BEGIN:
3897 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3900 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3902 return bus_log_parse_error(r);
3905 printf("%s=%"PRIu32"\n", name, u);
3907 printf("%s=\n", name);
3911 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3914 r = sd_bus_message_read(m, "(so)", &s, NULL);
3916 return bus_log_parse_error(r);
3918 if (arg_all || !isempty(s))
3919 printf("%s=%s\n", name, s);
3923 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3924 const char *a = NULL, *b = NULL;
3926 r = sd_bus_message_read(m, "(ss)", &a, &b);
3928 return bus_log_parse_error(r);
3930 if (arg_all || !isempty(a) || !isempty(b))
3931 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3934 } else if (streq_ptr(name, "SystemCallFilter")) {
3935 _cleanup_strv_free_ char **l = NULL;
3938 r = sd_bus_message_enter_container(m, 'r', "bas");
3940 return bus_log_parse_error(r);
3942 r = sd_bus_message_read(m, "b", &whitelist);
3944 return bus_log_parse_error(r);
3946 r = sd_bus_message_read_strv(m, &l);
3948 return bus_log_parse_error(r);
3950 r = sd_bus_message_exit_container(m);
3952 return bus_log_parse_error(r);
3954 if (arg_all || whitelist || !strv_isempty(l)) {
3958 fputs(name, stdout);
3964 STRV_FOREACH(i, l) {
3972 fputc('\n', stdout);
3980 case SD_BUS_TYPE_ARRAY:
3982 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3986 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3988 return bus_log_parse_error(r);
3990 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3991 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3994 return bus_log_parse_error(r);
3996 r = sd_bus_message_exit_container(m);
3998 return bus_log_parse_error(r);
4002 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4003 const char *type, *path;
4005 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4007 return bus_log_parse_error(r);
4009 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4010 printf("%s=%s\n", type, path);
4012 return bus_log_parse_error(r);
4014 r = sd_bus_message_exit_container(m);
4016 return bus_log_parse_error(r);
4020 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4021 const char *type, *path;
4023 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4025 return bus_log_parse_error(r);
4027 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4028 printf("Listen%s=%s\n", type, path);
4030 return bus_log_parse_error(r);
4032 r = sd_bus_message_exit_container(m);
4034 return bus_log_parse_error(r);
4038 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4040 uint64_t value, next_elapse;
4042 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4044 return bus_log_parse_error(r);
4046 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4047 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4049 printf("%s={ value=%s ; next_elapse=%s }\n",
4051 format_timespan(timespan1, sizeof(timespan1), value, 0),
4052 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4055 return bus_log_parse_error(r);
4057 r = sd_bus_message_exit_container(m);
4059 return bus_log_parse_error(r);
4063 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4064 ExecStatusInfo info = {};
4066 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4068 return bus_log_parse_error(r);
4070 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4071 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4072 _cleanup_free_ char *tt;
4074 tt = strv_join(info.argv, " ");
4076 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",
4080 yes_no(info.ignore),
4081 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4082 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4084 sigchld_code_to_string(info.code),
4086 info.code == CLD_EXITED ? "" : "/",
4087 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4090 strv_free(info.argv);
4094 r = sd_bus_message_exit_container(m);
4096 return bus_log_parse_error(r);
4100 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4101 const char *path, *rwm;
4103 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4105 return bus_log_parse_error(r);
4107 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4108 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4110 return bus_log_parse_error(r);
4112 r = sd_bus_message_exit_container(m);
4114 return bus_log_parse_error(r);
4118 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4122 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4124 return bus_log_parse_error(r);
4126 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4127 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4129 return bus_log_parse_error(r);
4131 r = sd_bus_message_exit_container(m);
4133 return bus_log_parse_error(r);
4137 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4141 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4143 return bus_log_parse_error(r);
4145 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4146 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4148 return bus_log_parse_error(r);
4150 r = sd_bus_message_exit_container(m);
4152 return bus_log_parse_error(r);
4160 r = bus_print_property(name, m, arg_all);
4162 return bus_log_parse_error(r);
4165 r = sd_bus_message_skip(m, contents);
4167 return bus_log_parse_error(r);
4170 printf("%s=[unprintable]\n", name);
4176 static int show_one(
4180 bool show_properties,
4184 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4185 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4186 UnitStatusInfo info = {};
4193 log_debug("Showing one %s", path);
4195 r = sd_bus_call_method(
4197 "org.freedesktop.systemd1",
4199 "org.freedesktop.DBus.Properties",
4205 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4209 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4211 return bus_log_parse_error(r);
4218 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4219 const char *name, *contents;
4221 r = sd_bus_message_read(reply, "s", &name);
4223 return bus_log_parse_error(r);
4225 r = sd_bus_message_peek_type(reply, NULL, &contents);
4227 return bus_log_parse_error(r);
4229 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4231 return bus_log_parse_error(r);
4233 if (show_properties)
4234 r = print_property(name, reply, contents);
4236 r = status_property(name, reply, &info, contents);
4240 r = sd_bus_message_exit_container(reply);
4242 return bus_log_parse_error(r);
4244 r = sd_bus_message_exit_container(reply);
4246 return bus_log_parse_error(r);
4249 return bus_log_parse_error(r);
4251 r = sd_bus_message_exit_container(reply);
4253 return bus_log_parse_error(r);
4257 if (!show_properties) {
4258 if (streq(verb, "help"))
4259 show_unit_help(&info);
4261 print_status_info(&info, ellipsized);
4264 strv_free(info.documentation);
4265 strv_free(info.dropin_paths);
4266 strv_free(info.listen);
4268 if (!streq_ptr(info.active_state, "active") &&
4269 !streq_ptr(info.active_state, "reloading") &&
4270 streq(verb, "status")) {
4271 /* According to LSB: "program not running" */
4272 /* 0: program is running or service is OK
4273 * 1: program is dead and /run PID file exists
4274 * 2: program is dead and /run/lock lock file exists
4275 * 3: program is not running
4276 * 4: program or service status is unknown
4278 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4284 while ((p = info.exec)) {
4285 LIST_REMOVE(exec, info.exec, p);
4286 exec_status_info_free(p);
4292 static int get_unit_dbus_path_by_pid(
4297 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4298 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4302 r = sd_bus_call_method(
4304 "org.freedesktop.systemd1",
4305 "/org/freedesktop/systemd1",
4306 "org.freedesktop.systemd1.Manager",
4312 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4316 r = sd_bus_message_read(reply, "o", &u);
4318 return bus_log_parse_error(r);
4328 static int show_all(
4331 bool show_properties,
4335 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4336 _cleanup_free_ UnitInfo *unit_infos = NULL;
4341 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4345 pager_open_if_enabled();
4349 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4351 for (u = unit_infos; u < unit_infos + c; u++) {
4352 _cleanup_free_ char *p = NULL;
4354 p = unit_dbus_path_from_name(u->id);
4358 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4361 else if (r > 0 && ret == 0)
4368 static int show_system_status(sd_bus *bus) {
4369 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4370 _cleanup_free_ char *hn = NULL;
4371 struct machine_info mi = {};
4372 const char *on, *off;
4375 hn = gethostname_malloc();
4379 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4381 return log_error_errno(r, "Failed to read server status: %m");
4383 if (streq_ptr(mi.state, "degraded")) {
4384 on = ansi_highlight_red();
4385 off = ansi_highlight_off();
4386 } else if (!streq_ptr(mi.state, "running")) {
4387 on = ansi_highlight_yellow();
4388 off = ansi_highlight_off();
4392 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4394 printf(" State: %s%s%s\n",
4395 on, strna(mi.state), off);
4397 printf(" Jobs: %u queued\n", mi.n_jobs);
4398 printf(" Failed: %u units\n", mi.n_failed_units);
4400 printf(" Since: %s; %s\n",
4401 format_timestamp(since2, sizeof(since2), mi.timestamp),
4402 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4404 printf(" CGroup: %s\n", mi.control_group ?: "/");
4405 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4407 arg_all * OUTPUT_SHOW_ALL |
4408 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4409 on_tty() * OUTPUT_COLOR |
4410 !arg_quiet * OUTPUT_WARN_CUTOFF |
4411 arg_full * OUTPUT_FULL_WIDTH;
4413 static const char prefix[] = " ";
4417 if (c > sizeof(prefix) - 1)
4418 c -= sizeof(prefix) - 1;
4422 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4426 free(mi.control_group);
4431 static int show(sd_bus *bus, char **args) {
4432 bool show_properties, show_status, new_line = false;
4433 bool ellipsized = false;
4439 show_properties = streq(args[0], "show");
4440 show_status = streq(args[0], "status");
4442 if (show_properties)
4443 pager_open_if_enabled();
4445 /* If no argument is specified inspect the manager itself */
4447 if (show_properties && strv_length(args) <= 1)
4448 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4450 if (show_status && strv_length(args) <= 1) {
4452 pager_open_if_enabled();
4453 show_system_status(bus);
4457 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4459 _cleanup_free_ char **patterns = NULL;
4462 STRV_FOREACH(name, args + 1) {
4463 _cleanup_free_ char *unit = NULL;
4466 if (safe_atou32(*name, &id) < 0) {
4467 if (strv_push(&patterns, *name) < 0)
4471 } else if (show_properties) {
4472 /* Interpret as job id */
4473 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4477 /* Interpret as PID */
4478 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4485 r = show_one(args[0], bus, unit, show_properties,
4486 &new_line, &ellipsized);
4489 else if (r > 0 && ret == 0)
4493 if (!strv_isempty(patterns)) {
4494 _cleanup_strv_free_ char **names = NULL;
4496 r = expand_names(bus, patterns, NULL, &names);
4498 log_error_errno(r, "Failed to expand names: %m");
4500 STRV_FOREACH(name, names) {
4501 _cleanup_free_ char *unit;
4503 unit = unit_dbus_path_from_name(*name);
4507 r = show_one(args[0], bus, unit, show_properties,
4508 &new_line, &ellipsized);
4511 else if (r > 0 && ret == 0)
4517 if (ellipsized && !arg_quiet)
4518 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4523 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4527 assert(user_runtime);
4530 if (arg_scope == UNIT_FILE_USER) {
4531 r = user_config_home(user_home);
4533 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4535 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4537 r = user_runtime_dir(user_runtime);
4539 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4541 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4544 r = lookup_paths_init(lp,
4545 arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
4546 arg_scope == UNIT_FILE_USER,
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;
4566 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4570 r = expand_names(bus, args + 1, NULL, &names);
4572 log_error_errno(r, "Failed to expand names: %m");
4574 avoid_bus_cache = !bus || avoid_bus();
4576 pager_open_if_enabled();
4578 STRV_FOREACH(name, names) {
4579 _cleanup_free_ char *fragment_path = NULL;
4580 _cleanup_strv_free_ char **dropin_paths = NULL;
4583 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4587 log_warning("Unit %s does not have any files on disk", *name);
4596 if (fragment_path) {
4597 printf("%s# %s%s\n",
4598 ansi_highlight_blue(),
4600 ansi_highlight_off());
4603 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4605 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4610 STRV_FOREACH(path, dropin_paths) {
4611 printf("%s%s# %s%s\n",
4612 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4613 ansi_highlight_blue(),
4615 ansi_highlight_off());
4618 r = copy_file_fd(*path, STDOUT_FILENO, false);
4620 log_warning_errno(r, "Failed to cat %s: %m", *path);
4626 return r < 0 ? r : 0;
4629 static int set_property(sd_bus *bus, char **args) {
4630 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4631 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4632 _cleanup_free_ char *n = NULL;
4636 r = sd_bus_message_new_method_call(
4639 "org.freedesktop.systemd1",
4640 "/org/freedesktop/systemd1",
4641 "org.freedesktop.systemd1.Manager",
4642 "SetUnitProperties");
4644 return bus_log_create_error(r);
4646 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4648 return bus_log_create_error(r);
4650 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4654 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4656 return bus_log_create_error(r);
4658 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4660 return bus_log_create_error(r);
4662 STRV_FOREACH(i, args + 2) {
4663 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4665 return bus_log_create_error(r);
4667 r = bus_append_unit_property_assignment(m, *i);
4671 r = sd_bus_message_close_container(m);
4673 return bus_log_create_error(r);
4676 r = sd_bus_message_close_container(m);
4678 return bus_log_create_error(r);
4680 r = sd_bus_call(bus, m, 0, &error, NULL);
4682 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4689 static int snapshot(sd_bus *bus, char **args) {
4690 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4691 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4692 _cleanup_free_ char *n = NULL, *id = NULL;
4696 if (strv_length(args) > 1)
4697 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4703 r = sd_bus_message_new_method_call(
4706 "org.freedesktop.systemd1",
4707 "/org/freedesktop/systemd1",
4708 "org.freedesktop.systemd1.Manager",
4711 return bus_log_create_error(r);
4713 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4715 return bus_log_create_error(r);
4717 r = sd_bus_message_append(m, "sb", n, false);
4719 return bus_log_create_error(r);
4721 r = sd_bus_call(bus, m, 0, &error, &reply);
4723 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4727 r = sd_bus_message_read(reply, "o", &path);
4729 return bus_log_parse_error(r);
4731 r = sd_bus_get_property_string(
4733 "org.freedesktop.systemd1",
4735 "org.freedesktop.systemd1.Unit",
4740 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4750 static int delete_snapshot(sd_bus *bus, char **args) {
4751 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4752 _cleanup_strv_free_ char **names = NULL;
4758 r = expand_names(bus, args + 1, ".snapshot", &names);
4760 log_error_errno(r, "Failed to expand names: %m");
4762 STRV_FOREACH(name, names) {
4763 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4766 q = sd_bus_message_new_method_call(
4769 "org.freedesktop.systemd1",
4770 "/org/freedesktop/systemd1",
4771 "org.freedesktop.systemd1.Manager",
4774 return bus_log_create_error(q);
4776 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4778 return bus_log_create_error(q);
4780 q = sd_bus_message_append(m, "s", *name);
4782 return bus_log_create_error(q);
4784 q = sd_bus_call(bus, m, 0, &error, NULL);
4786 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4795 static int daemon_reload(sd_bus *bus, char **args) {
4796 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4797 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4801 if (arg_action == ACTION_RELOAD)
4803 else if (arg_action == ACTION_REEXEC)
4804 method = "Reexecute";
4806 assert(arg_action == ACTION_SYSTEMCTL);
4809 streq(args[0], "clear-jobs") ||
4810 streq(args[0], "cancel") ? "ClearJobs" :
4811 streq(args[0], "daemon-reexec") ? "Reexecute" :
4812 streq(args[0], "reset-failed") ? "ResetFailed" :
4813 streq(args[0], "halt") ? "Halt" :
4814 streq(args[0], "poweroff") ? "PowerOff" :
4815 streq(args[0], "reboot") ? "Reboot" :
4816 streq(args[0], "kexec") ? "KExec" :
4817 streq(args[0], "exit") ? "Exit" :
4818 /* "daemon-reload" */ "Reload";
4821 r = sd_bus_message_new_method_call(
4824 "org.freedesktop.systemd1",
4825 "/org/freedesktop/systemd1",
4826 "org.freedesktop.systemd1.Manager",
4829 return bus_log_create_error(r);
4831 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4833 return bus_log_create_error(r);
4835 r = sd_bus_call(bus, m, 0, &error, NULL);
4836 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4837 /* There's always a fallback possible for
4838 * legacy actions. */
4840 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4841 /* On reexecution, we expect a disconnect, not a
4845 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4847 return r < 0 ? r : 0;
4850 static int reset_failed(sd_bus *bus, char **args) {
4851 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4852 _cleanup_strv_free_ char **names = NULL;
4856 if (strv_length(args) <= 1)
4857 return daemon_reload(bus, args);
4859 r = expand_names(bus, args + 1, NULL, &names);
4861 log_error_errno(r, "Failed to expand names: %m");
4863 STRV_FOREACH(name, names) {
4864 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4866 q = sd_bus_message_new_method_call(
4869 "org.freedesktop.systemd1",
4870 "/org/freedesktop/systemd1",
4871 "org.freedesktop.systemd1.Manager",
4874 return bus_log_create_error(q);
4876 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4878 return bus_log_create_error(q);
4880 q = sd_bus_message_append(m, "s", *name);
4882 return bus_log_create_error(q);
4884 q = sd_bus_call(bus, m, 0, &error, NULL);
4886 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4895 static int show_environment(sd_bus *bus, char **args) {
4896 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4897 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4901 pager_open_if_enabled();
4903 r = sd_bus_get_property(
4905 "org.freedesktop.systemd1",
4906 "/org/freedesktop/systemd1",
4907 "org.freedesktop.systemd1.Manager",
4913 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4917 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4919 return bus_log_parse_error(r);
4921 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4924 return bus_log_parse_error(r);
4926 r = sd_bus_message_exit_container(reply);
4928 return bus_log_parse_error(r);
4933 static int switch_root(sd_bus *bus, char **args) {
4934 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4935 _cleanup_free_ char *cmdline_init = NULL;
4936 const char *root, *init;
4940 l = strv_length(args);
4941 if (l < 2 || l > 3) {
4942 log_error("Wrong number of arguments.");
4951 r = parse_env_file("/proc/cmdline", WHITESPACE,
4952 "init", &cmdline_init,
4955 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4957 init = cmdline_init;
4964 const char *root_systemd_path = NULL, *root_init_path = NULL;
4966 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4967 root_init_path = strappenda(root, "/", init);
4969 /* If the passed init is actually the same as the
4970 * systemd binary, then let's suppress it. */
4971 if (files_same(root_init_path, root_systemd_path) > 0)
4975 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4977 r = sd_bus_call_method(
4979 "org.freedesktop.systemd1",
4980 "/org/freedesktop/systemd1",
4981 "org.freedesktop.systemd1.Manager",
4987 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4994 static int set_environment(sd_bus *bus, char **args) {
4995 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4996 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5003 method = streq(args[0], "set-environment")
5005 : "UnsetEnvironment";
5007 r = sd_bus_message_new_method_call(
5010 "org.freedesktop.systemd1",
5011 "/org/freedesktop/systemd1",
5012 "org.freedesktop.systemd1.Manager",
5015 return bus_log_create_error(r);
5017 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5019 return bus_log_create_error(r);
5021 r = sd_bus_message_append_strv(m, args + 1);
5023 return bus_log_create_error(r);
5025 r = sd_bus_call(bus, m, 0, &error, NULL);
5027 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5034 static int import_environment(sd_bus *bus, char **args) {
5035 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5036 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5042 r = sd_bus_message_new_method_call(
5045 "org.freedesktop.systemd1",
5046 "/org/freedesktop/systemd1",
5047 "org.freedesktop.systemd1.Manager",
5050 return bus_log_create_error(r);
5052 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5054 return bus_log_create_error(r);
5056 if (strv_isempty(args + 1))
5057 r = sd_bus_message_append_strv(m, environ);
5061 r = sd_bus_message_open_container(m, 'a', "s");
5063 return bus_log_create_error(r);
5065 STRV_FOREACH(a, args + 1) {
5067 if (!env_name_is_valid(*a)) {
5068 log_error("Not a valid environment variable name: %s", *a);
5072 STRV_FOREACH(b, environ) {
5075 eq = startswith(*b, *a);
5076 if (eq && *eq == '=') {
5078 r = sd_bus_message_append(m, "s", *b);
5080 return bus_log_create_error(r);
5087 r = sd_bus_message_close_container(m);
5090 return bus_log_create_error(r);
5092 r = sd_bus_call(bus, m, 0, &error, NULL);
5094 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5101 static int enable_sysv_units(const char *verb, char **args) {
5104 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5106 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5108 if (arg_scope != UNIT_FILE_SYSTEM)
5111 if (!streq(verb, "enable") &&
5112 !streq(verb, "disable") &&
5113 !streq(verb, "is-enabled"))
5116 /* Processes all SysV units, and reshuffles the array so that
5117 * afterwards only the native units remain */
5119 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5126 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5127 bool found_native = false, found_sysv;
5129 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5137 if (!endswith(name, ".service"))
5140 if (path_is_absolute(name))
5143 STRV_FOREACH(k, paths.unit_path) {
5144 _cleanup_free_ char *path = NULL;
5146 path = path_join(arg_root, *k, name);
5150 found_native = access(path, F_OK) >= 0;
5158 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5162 p[strlen(p) - strlen(".service")] = 0;
5163 found_sysv = access(p, F_OK) >= 0;
5167 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5169 if (!isempty(arg_root))
5170 argv[c++] = q = strappend("--root=", arg_root);
5172 argv[c++] = basename(p);
5174 streq(verb, "enable") ? "on" :
5175 streq(verb, "disable") ? "off" : "--level=5";
5178 l = strv_join((char**)argv, " ");
5182 log_info("Executing %s", l);
5186 return log_error_errno(errno, "Failed to fork: %m");
5187 else if (pid == 0) {
5190 execv(argv[0], (char**) argv);
5191 _exit(EXIT_FAILURE);
5194 j = wait_for_terminate(pid, &status);
5196 log_error_errno(r, "Failed to wait for child: %m");
5200 if (status.si_code == CLD_EXITED) {
5201 if (streq(verb, "is-enabled")) {
5202 if (status.si_status == 0) {
5211 } else if (status.si_status != 0)
5216 /* Remove this entry, so that we don't try enabling it as native unit */
5217 assert(f > 0 && streq(args[f-1], name));
5218 assert_se(strv_remove(args + f - 1, name));
5225 static int mangle_names(char **original_names, char ***mangled_names) {
5226 char **i, **l, **name;
5228 l = new(char*, strv_length(original_names) + 1);
5233 STRV_FOREACH(name, original_names) {
5235 /* When enabling units qualified path names are OK,
5236 * too, hence allow them explicitly. */
5241 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5257 static int enable_unit(sd_bus *bus, char **args) {
5258 _cleanup_strv_free_ char **names = NULL;
5259 const char *verb = args[0];
5260 UnitFileChange *changes = NULL;
5261 unsigned n_changes = 0;
5262 int carries_install_info = -1;
5268 r = mangle_names(args+1, &names);
5272 r = enable_sysv_units(verb, names);
5276 /* If the operation was fully executed by the SysV compat,
5277 * let's finish early */
5278 if (strv_isempty(names))
5281 if (!bus || avoid_bus()) {
5282 if (streq(verb, "enable")) {
5283 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5284 carries_install_info = r;
5285 } else if (streq(verb, "disable"))
5286 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5287 else if (streq(verb, "reenable")) {
5288 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5289 carries_install_info = r;
5290 } else if (streq(verb, "link"))
5291 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5292 else if (streq(verb, "preset")) {
5293 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5294 carries_install_info = r;
5295 } else if (streq(verb, "mask"))
5296 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5297 else if (streq(verb, "unmask"))
5298 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5300 assert_not_reached("Unknown verb");
5303 log_error_errno(r, "Operation failed: %m");
5308 dump_unit_file_changes(changes, n_changes);
5312 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5313 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5314 int expect_carries_install_info = false;
5315 bool send_force = true, send_preset_mode = false;
5318 if (streq(verb, "enable")) {
5319 method = "EnableUnitFiles";
5320 expect_carries_install_info = true;
5321 } else if (streq(verb, "disable")) {
5322 method = "DisableUnitFiles";
5324 } else if (streq(verb, "reenable")) {
5325 method = "ReenableUnitFiles";
5326 expect_carries_install_info = true;
5327 } else if (streq(verb, "link"))
5328 method = "LinkUnitFiles";
5329 else if (streq(verb, "preset")) {
5331 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5332 method = "PresetUnitFilesWithMode";
5333 send_preset_mode = true;
5335 method = "PresetUnitFiles";
5337 expect_carries_install_info = true;
5338 } else if (streq(verb, "mask"))
5339 method = "MaskUnitFiles";
5340 else if (streq(verb, "unmask")) {
5341 method = "UnmaskUnitFiles";
5344 assert_not_reached("Unknown verb");
5346 r = sd_bus_message_new_method_call(
5349 "org.freedesktop.systemd1",
5350 "/org/freedesktop/systemd1",
5351 "org.freedesktop.systemd1.Manager",
5354 return bus_log_create_error(r);
5356 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5358 return bus_log_create_error(r);
5360 r = sd_bus_message_append_strv(m, names);
5362 return bus_log_create_error(r);
5364 if (send_preset_mode) {
5365 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5367 return bus_log_create_error(r);
5370 r = sd_bus_message_append(m, "b", arg_runtime);
5372 return bus_log_create_error(r);
5375 r = sd_bus_message_append(m, "b", arg_force);
5377 return bus_log_create_error(r);
5380 r = sd_bus_call(bus, m, 0, &error, &reply);
5382 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5386 if (expect_carries_install_info) {
5387 r = sd_bus_message_read(reply, "b", &carries_install_info);
5389 return bus_log_parse_error(r);
5392 r = deserialize_and_dump_unit_file_changes(reply);
5396 /* Try to reload if enabled */
5398 r = daemon_reload(bus, args);
5403 if (carries_install_info == 0)
5404 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5405 "using systemctl.\n"
5406 "Possible reasons for having this kind of units are:\n"
5407 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5408 " .wants/ or .requires/ directory.\n"
5409 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5410 " a requirement dependency on it.\n"
5411 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5412 " D-Bus, udev, scripted systemctl call, ...).\n");
5415 unit_file_changes_free(changes, n_changes);
5420 static int add_dependency(sd_bus *bus, char **args) {
5421 _cleanup_strv_free_ char **names = NULL;
5422 _cleanup_free_ char *target = NULL;
5423 const char *verb = args[0];
5430 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5434 r = mangle_names(args+2, &names);
5438 if (streq(verb, "add-wants"))
5440 else if (streq(verb, "add-requires"))
5441 dep = UNIT_REQUIRES;
5443 assert_not_reached("Unknown verb");
5445 if (!bus || avoid_bus()) {
5446 UnitFileChange *changes = NULL;
5447 unsigned n_changes = 0;
5449 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5452 return log_error_errno(r, "Can't add dependency: %m");
5455 dump_unit_file_changes(changes, n_changes);
5457 unit_file_changes_free(changes, n_changes);
5460 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5461 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5463 r = sd_bus_message_new_method_call(
5466 "org.freedesktop.systemd1",
5467 "/org/freedesktop/systemd1",
5468 "org.freedesktop.systemd1.Manager",
5469 "AddDependencyUnitFiles");
5471 return bus_log_create_error(r);
5473 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5475 return bus_log_create_error(r);
5477 r = sd_bus_message_append_strv(m, names);
5479 return bus_log_create_error(r);
5481 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5483 return bus_log_create_error(r);
5485 r = sd_bus_call(bus, m, 0, &error, &reply);
5487 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5491 r = deserialize_and_dump_unit_file_changes(reply);
5496 r = daemon_reload(bus, args);
5504 static int preset_all(sd_bus *bus, char **args) {
5505 UnitFileChange *changes = NULL;
5506 unsigned n_changes = 0;
5509 if (!bus || avoid_bus()) {
5511 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5513 log_error_errno(r, "Operation failed: %m");
5518 dump_unit_file_changes(changes, n_changes);
5523 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5524 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5526 r = sd_bus_message_new_method_call(
5529 "org.freedesktop.systemd1",
5530 "/org/freedesktop/systemd1",
5531 "org.freedesktop.systemd1.Manager",
5532 "PresetAllUnitFiles");
5534 return bus_log_create_error(r);
5536 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5538 return bus_log_create_error(r);
5540 r = sd_bus_message_append(
5543 unit_file_preset_mode_to_string(arg_preset_mode),
5547 return bus_log_create_error(r);
5549 r = sd_bus_call(bus, m, 0, &error, &reply);
5551 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5555 r = deserialize_and_dump_unit_file_changes(reply);
5560 r = daemon_reload(bus, args);
5566 unit_file_changes_free(changes, n_changes);
5571 static int unit_is_enabled(sd_bus *bus, char **args) {
5573 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5574 _cleanup_strv_free_ char **names = NULL;
5579 r = mangle_names(args+1, &names);
5583 r = enable_sysv_units(args[0], names);
5589 if (!bus || avoid_bus()) {
5591 STRV_FOREACH(name, names) {
5592 UnitFileState state;
5594 state = unit_file_get_state(arg_scope, arg_root, *name);
5596 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5598 if (state == UNIT_FILE_ENABLED ||
5599 state == UNIT_FILE_ENABLED_RUNTIME ||
5600 state == UNIT_FILE_STATIC ||
5601 state == UNIT_FILE_INDIRECT)
5605 puts(unit_file_state_to_string(state));
5609 STRV_FOREACH(name, names) {
5610 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5613 r = sd_bus_call_method(
5615 "org.freedesktop.systemd1",
5616 "/org/freedesktop/systemd1",
5617 "org.freedesktop.systemd1.Manager",
5623 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5627 r = sd_bus_message_read(reply, "s", &s);
5629 return bus_log_parse_error(r);
5631 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5642 static int is_system_running(sd_bus *bus, char **args) {
5643 _cleanup_free_ char *state = NULL;
5646 r = sd_bus_get_property_string(
5648 "org.freedesktop.systemd1",
5649 "/org/freedesktop/systemd1",
5650 "org.freedesktop.systemd1.Manager",
5663 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5666 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5671 assert(original_path);
5674 r = tempfn_random(new_path, &t);
5676 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5678 r = mkdir_parents(new_path, 0755);
5680 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5685 r = copy_file(original_path, t, 0, 0644);
5689 log_error_errno(r, "Failed to create temporary file %s: %m", t);
5694 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5704 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5705 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5707 switch (arg_scope) {
5708 case UNIT_FILE_SYSTEM:
5709 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5711 run = path_join(arg_root, "/run/systemd/system/", name);
5713 case UNIT_FILE_GLOBAL:
5714 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5716 run = path_join(arg_root, "/run/systemd/user/", name);
5718 case UNIT_FILE_USER:
5720 assert(user_runtime);
5722 path = path_join(arg_root, user_home, name);
5724 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5727 run = path_join(arg_root, user_runtime, name);
5731 assert_not_reached("Invalid scope");
5733 if (!path || (arg_runtime && !run))
5737 if (access(path, F_OK) >= 0)
5738 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5740 if (path2 && access(path2, F_OK) >= 0)
5741 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5754 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) {
5755 char *tmp_new_path, *ending;
5760 assert(ret_new_path);
5761 assert(ret_tmp_path);
5763 ending = strappenda(unit_name, ".d/override.conf");
5764 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5768 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5774 *ret_new_path = tmp_new_path;
5775 *ret_tmp_path = tmp_tmp_path;
5780 static int unit_file_create_copy(const char *unit_name,
5781 const char *fragment_path,
5782 const char *user_home,
5783 const char *user_runtime,
5784 char **ret_new_path,
5785 char **ret_tmp_path) {
5790 assert(fragment_path);
5792 assert(ret_new_path);
5793 assert(ret_tmp_path);
5795 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5799 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5802 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);
5807 if (response != 'y') {
5808 log_warning("%s ignored", unit_name);
5814 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5816 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5821 *ret_new_path = tmp_new_path;
5822 *ret_tmp_path = tmp_tmp_path;
5827 static int run_editor(char **paths) {
5835 log_error_errno(errno, "Failed to fork: %m");
5841 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5843 char **tmp_path, **original_path, **p;
5847 argc = strv_length(paths)/2 + 1;
5848 args = newa(const char*, argc + 1);
5851 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5852 args[i] = *tmp_path;
5857 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5858 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5859 * we try to execute well known editors
5861 editor = getenv("SYSTEMD_EDITOR");
5863 editor = getenv("EDITOR");
5865 editor = getenv("VISUAL");
5867 if (!isempty(editor)) {
5869 execvp(editor, (char* const*) args);
5872 STRV_FOREACH(p, backup_editors) {
5874 execvp(*p, (char* const*) args);
5875 /* We do not fail if the editor doesn't exist
5876 * because we want to try each one of them before
5879 if (errno != ENOENT) {
5880 log_error("Failed to execute %s: %m", editor);
5881 _exit(EXIT_FAILURE);
5885 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5886 _exit(EXIT_FAILURE);
5889 r = wait_for_terminate_and_warn("editor", pid, true);
5891 return log_error_errno(r, "Failed to wait for child: %m");
5896 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5897 _cleanup_free_ char *user_home = NULL;
5898 _cleanup_free_ char *user_runtime = NULL;
5899 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5900 bool avoid_bus_cache;
5907 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5911 avoid_bus_cache = !bus || avoid_bus();
5913 STRV_FOREACH(name, names) {
5914 _cleanup_free_ char *path = NULL;
5915 char *new_path, *tmp_path;
5917 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5920 else if (r == 0 || !path)
5921 // FIXME: support units with path==NULL (no FragmentPath)
5922 return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
5925 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5927 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5931 r = strv_push_pair(paths, new_path, tmp_path);
5939 static int edit(sd_bus *bus, char **args) {
5940 _cleanup_strv_free_ char **names = NULL;
5941 _cleanup_strv_free_ char **paths = NULL;
5942 char **original, **tmp;
5948 log_error("Cannot edit units if we are not on a tty");
5952 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5953 log_error("Cannot remotely edit units");
5957 r = expand_names(bus, args + 1, NULL, &names);
5959 return log_error_errno(r, "Failed to expand names: %m");
5962 log_error("No unit name found by expanding names");
5966 r = find_paths_to_edit(bus, names, &paths);
5970 if (strv_isempty(paths)) {
5971 log_error("Cannot find any units to edit");
5975 r = run_editor(paths);
5979 STRV_FOREACH_PAIR(original, tmp, paths) {
5980 /* If the temporary file is empty we ignore it.
5981 * It's useful if the user wants to cancel its modification
5983 if (null_or_empty_path(*tmp)) {
5984 log_warning("Edition of %s canceled: temporary file empty", *original);
5987 r = rename(*tmp, *original);
5989 r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
5994 if (!arg_no_reload && bus && !avoid_bus())
5995 r = daemon_reload(bus, args);
5998 STRV_FOREACH_PAIR(original, tmp, paths)
5999 unlink_noerrno(*tmp);
6004 static void systemctl_help(void) {
6006 pager_open_if_enabled();
6008 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6009 "Query or send control commands to the systemd manager.\n\n"
6010 " -h --help Show this help\n"
6011 " --version Show package version\n"
6012 " --system Connect to system manager\n"
6013 " --user Connect to user service manager\n"
6014 " -H --host=[USER@]HOST\n"
6015 " Operate on remote host\n"
6016 " -M --machine=CONTAINER\n"
6017 " Operate on local container\n"
6018 " -t --type=TYPE List only units of a particular type\n"
6019 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
6020 " -p --property=NAME Show only properties by this name\n"
6021 " -a --all Show all loaded units/properties, including dead/empty\n"
6022 " ones. To list all units installed on the system, use\n"
6023 " the 'list-unit-files' command instead.\n"
6024 " -l --full Don't ellipsize unit names on output\n"
6025 " -r --recursive Show unit list of host and local containers\n"
6026 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6027 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6028 " queueing a new job\n"
6029 " --show-types When showing sockets, explicitly show their type\n"
6030 " -i --ignore-inhibitors\n"
6031 " When shutting down or sleeping, ignore inhibitors\n"
6032 " --kill-who=WHO Who to send signal to\n"
6033 " -s --signal=SIGNAL Which signal to send\n"
6034 " -q --quiet Suppress output\n"
6035 " --no-block Do not wait until operation finished\n"
6036 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6037 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
6039 " --no-legend Do not print a legend (column headers and hints)\n"
6040 " --no-pager Do not pipe output into a pager\n"
6041 " --no-ask-password\n"
6042 " Do not ask for system passwords\n"
6043 " --global Enable/disable unit files globally\n"
6044 " --runtime Enable unit files only temporarily until next reboot\n"
6045 " -f --force When enabling unit files, override existing symlinks\n"
6046 " When shutting down, execute action immediately\n"
6047 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
6048 " or only disable\n"
6049 " --root=PATH Enable unit files in the specified root directory\n"
6050 " -n --lines=INTEGER Number of journal entries to show\n"
6051 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
6052 " verbose, export, json, json-pretty, json-sse, cat)\n"
6053 " --plain Print unit dependencies as a list instead of a tree\n\n"
6055 " list-units [PATTERN...] List loaded units\n"
6056 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6057 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6058 " start NAME... Start (activate) one or more units\n"
6059 " stop NAME... Stop (deactivate) one or more units\n"
6060 " reload NAME... Reload one or more units\n"
6061 " restart NAME... Start or restart one or more units\n"
6062 " try-restart NAME... Restart one or more units if active\n"
6063 " reload-or-restart NAME... Reload one or more units if possible,\n"
6064 " otherwise start or restart\n"
6065 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6066 " otherwise restart if active\n"
6067 " isolate NAME Start one unit and stop all others\n"
6068 " kill NAME... Send signal to processes of a unit\n"
6069 " is-active PATTERN... Check whether units are active\n"
6070 " is-failed PATTERN... Check whether units are failed\n"
6071 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6072 " show [PATTERN...|JOB...] Show properties of one or more\n"
6073 " units/jobs or the manager\n"
6074 " cat PATTERN... Show files and drop-ins of one or more units\n"
6075 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6076 " help PATTERN...|PID... Show manual for one or more units\n"
6077 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6079 " list-dependencies [NAME] Recursively show units which are required\n"
6080 " or wanted by this unit or by which this\n"
6081 " unit is required or wanted\n\n"
6082 "Unit File Commands:\n"
6083 " list-unit-files [PATTERN...] List installed unit files\n"
6084 " enable NAME... Enable one or more unit files\n"
6085 " disable NAME... Disable one or more unit files\n"
6086 " reenable NAME... Reenable one or more unit files\n"
6087 " preset NAME... Enable/disable one or more unit files\n"
6088 " based on preset configuration\n"
6089 " preset-all Enable/disable all unit files based on\n"
6090 " preset configuration\n"
6091 " is-enabled NAME... Check whether unit files are enabled\n\n"
6092 " mask NAME... Mask one or more units\n"
6093 " unmask NAME... Unmask one or more units\n"
6094 " link PATH... Link one or more units files into\n"
6095 " the search path\n"
6096 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6097 " on specified one or more units\n"
6098 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6099 " on specified one or more units\n"
6100 " get-default Get the name of the default target\n"
6101 " set-default NAME Set the default target\n"
6102 " edit NAME... Edit one or more unit files\n"
6104 "Machine Commands:\n"
6105 " list-machines [PATTERN...] List local containers and host\n\n"
6107 " list-jobs [PATTERN...] List jobs\n"
6108 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6109 "Snapshot Commands:\n"
6110 " snapshot [NAME] Create a snapshot\n"
6111 " delete NAME... Remove one or more snapshots\n\n"
6112 "Environment Commands:\n"
6113 " show-environment Dump environment\n"
6114 " set-environment NAME=VALUE... Set one or more environment variables\n"
6115 " unset-environment NAME... Unset one or more environment variables\n"
6116 " import-environment NAME... Import all, one or more environment variables\n\n"
6117 "Manager Lifecycle Commands:\n"
6118 " daemon-reload Reload systemd manager configuration\n"
6119 " daemon-reexec Reexecute systemd manager\n\n"
6120 "System Commands:\n"
6121 " is-system-running Check whether system is fully running\n"
6122 " default Enter system default mode\n"
6123 " rescue Enter system rescue mode\n"
6124 " emergency Enter system emergency mode\n"
6125 " halt Shut down and halt the system\n"
6126 " poweroff Shut down and power-off the system\n"
6127 " reboot [ARG] Shut down and reboot the system\n"
6128 " kexec Shut down and reboot the system with kexec\n"
6129 " exit Request user instance exit\n"
6130 " switch-root ROOT [INIT] Change to a different root file system\n"
6131 " suspend Suspend the system\n"
6132 " hibernate Hibernate the system\n"
6133 " hybrid-sleep Hibernate and suspend the system\n",
6134 program_invocation_short_name);
6137 static void halt_help(void) {
6138 printf("%s [OPTIONS...]%s\n\n"
6139 "%s the system.\n\n"
6140 " --help Show this help\n"
6141 " --halt Halt the machine\n"
6142 " -p --poweroff Switch off the machine\n"
6143 " --reboot Reboot the machine\n"
6144 " -f --force Force immediate halt/power-off/reboot\n"
6145 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6146 " -d --no-wtmp Don't write wtmp record\n"
6147 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6148 program_invocation_short_name,
6149 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6150 arg_action == ACTION_REBOOT ? "Reboot" :
6151 arg_action == ACTION_POWEROFF ? "Power off" :
6155 static void shutdown_help(void) {
6156 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6157 "Shut down the system.\n\n"
6158 " --help Show this help\n"
6159 " -H --halt Halt the machine\n"
6160 " -P --poweroff Power-off the machine\n"
6161 " -r --reboot Reboot the machine\n"
6162 " -h Equivalent to --poweroff, overridden by --halt\n"
6163 " -k Don't halt/power-off/reboot, just send warnings\n"
6164 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6165 " -c Cancel a pending shutdown\n",
6166 program_invocation_short_name);
6169 static void telinit_help(void) {
6170 printf("%s [OPTIONS...] {COMMAND}\n\n"
6171 "Send control commands to the init daemon.\n\n"
6172 " --help Show this help\n"
6173 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6175 " 0 Power-off the machine\n"
6176 " 6 Reboot the machine\n"
6177 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6178 " 1, s, S Enter rescue mode\n"
6179 " q, Q Reload init daemon configuration\n"
6180 " u, U Reexecute init daemon\n",
6181 program_invocation_short_name);
6184 static void runlevel_help(void) {
6185 printf("%s [OPTIONS...]\n\n"
6186 "Prints the previous and current runlevel of the init system.\n\n"
6187 " --help Show this help\n",
6188 program_invocation_short_name);
6191 static void help_types(void) {
6196 puts("Available unit types:");
6197 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6198 t = unit_type_to_string(i);
6204 static int systemctl_parse_argv(int argc, char *argv[]) {
6213 ARG_IGNORE_DEPENDENCIES,
6225 ARG_NO_ASK_PASSWORD,
6235 static const struct option options[] = {
6236 { "help", no_argument, NULL, 'h' },
6237 { "version", no_argument, NULL, ARG_VERSION },
6238 { "type", required_argument, NULL, 't' },
6239 { "property", required_argument, NULL, 'p' },
6240 { "all", no_argument, NULL, 'a' },
6241 { "reverse", no_argument, NULL, ARG_REVERSE },
6242 { "after", no_argument, NULL, ARG_AFTER },
6243 { "before", no_argument, NULL, ARG_BEFORE },
6244 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6245 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6246 { "full", no_argument, NULL, 'l' },
6247 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6248 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6249 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6250 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6251 { "ignore-inhibitors", no_argument, NULL, 'i' },
6252 { "user", no_argument, NULL, ARG_USER },
6253 { "system", no_argument, NULL, ARG_SYSTEM },
6254 { "global", no_argument, NULL, ARG_GLOBAL },
6255 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6256 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6257 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6258 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6259 { "quiet", no_argument, NULL, 'q' },
6260 { "root", required_argument, NULL, ARG_ROOT },
6261 { "force", no_argument, NULL, ARG_FORCE },
6262 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6263 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6264 { "signal", required_argument, NULL, 's' },
6265 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6266 { "host", required_argument, NULL, 'H' },
6267 { "machine", required_argument, NULL, 'M' },
6268 { "runtime", no_argument, NULL, ARG_RUNTIME },
6269 { "lines", required_argument, NULL, 'n' },
6270 { "output", required_argument, NULL, 'o' },
6271 { "plain", no_argument, NULL, ARG_PLAIN },
6272 { "state", required_argument, NULL, ARG_STATE },
6273 { "recursive", no_argument, NULL, 'r' },
6274 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6283 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6292 puts(PACKAGE_STRING);
6293 puts(SYSTEMD_FEATURES);
6297 const char *word, *state;
6300 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6301 _cleanup_free_ char *type;
6303 type = strndup(word, size);
6307 if (streq(type, "help")) {
6312 if (unit_type_from_string(type) >= 0) {
6313 if (strv_push(&arg_types, type))
6319 /* It's much nicer to use --state= for
6320 * load states, but let's support this
6321 * in --types= too for compatibility
6322 * with old versions */
6323 if (unit_load_state_from_string(optarg) >= 0) {
6324 if (strv_push(&arg_states, type) < 0)
6330 log_error("Unknown unit type or load state '%s'.", type);
6331 log_info("Use -t help to see a list of allowed values.");
6339 /* Make sure that if the empty property list
6340 was specified, we won't show any properties. */
6341 if (isempty(optarg) && !arg_properties) {
6342 arg_properties = new0(char*, 1);
6343 if (!arg_properties)
6346 const char *word, *state;
6349 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6352 prop = strndup(word, size);
6356 if (strv_consume(&arg_properties, prop) < 0)
6361 /* If the user asked for a particular
6362 * property, show it to him, even if it is
6374 arg_dependency = DEPENDENCY_REVERSE;
6378 arg_dependency = DEPENDENCY_AFTER;
6382 arg_dependency = DEPENDENCY_BEFORE;
6385 case ARG_SHOW_TYPES:
6386 arg_show_types = true;
6390 arg_job_mode = optarg;
6394 arg_job_mode = "fail";
6397 case ARG_IRREVERSIBLE:
6398 arg_job_mode = "replace-irreversibly";
6401 case ARG_IGNORE_DEPENDENCIES:
6402 arg_job_mode = "ignore-dependencies";
6406 arg_scope = UNIT_FILE_USER;
6410 arg_scope = UNIT_FILE_SYSTEM;
6414 arg_scope = UNIT_FILE_GLOBAL;
6418 arg_no_block = true;
6422 arg_no_legend = true;
6426 arg_no_pager = true;
6442 if (strv_extend(&arg_states, "failed") < 0)
6460 arg_no_reload = true;
6464 arg_kill_who = optarg;
6468 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6469 log_error("Failed to parse signal string %s.", optarg);
6474 case ARG_NO_ASK_PASSWORD:
6475 arg_ask_password = false;
6479 arg_transport = BUS_TRANSPORT_REMOTE;
6484 arg_transport = BUS_TRANSPORT_MACHINE;
6493 if (safe_atou(optarg, &arg_lines) < 0) {
6494 log_error("Failed to parse lines '%s'", optarg);
6500 arg_output = output_mode_from_string(optarg);
6501 if (arg_output < 0) {
6502 log_error("Unknown output '%s'.", optarg);
6508 arg_ignore_inhibitors = true;
6516 const char *word, *state;
6519 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6522 s = strndup(word, size);
6526 if (strv_consume(&arg_states, s) < 0)
6533 if (geteuid() != 0) {
6534 log_error("--recursive requires root privileges.");
6538 arg_recursive = true;
6541 case ARG_PRESET_MODE:
6543 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6544 if (arg_preset_mode < 0) {
6545 log_error("Failed to parse preset mode: %s.", optarg);
6555 assert_not_reached("Unhandled option");
6558 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6559 log_error("Cannot access user instance remotely.");
6566 static int halt_parse_argv(int argc, char *argv[]) {
6575 static const struct option options[] = {
6576 { "help", no_argument, NULL, ARG_HELP },
6577 { "halt", no_argument, NULL, ARG_HALT },
6578 { "poweroff", no_argument, NULL, 'p' },
6579 { "reboot", no_argument, NULL, ARG_REBOOT },
6580 { "force", no_argument, NULL, 'f' },
6581 { "wtmp-only", no_argument, NULL, 'w' },
6582 { "no-wtmp", no_argument, NULL, 'd' },
6583 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6592 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6593 if (runlevel == '0' || runlevel == '6')
6596 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6604 arg_action = ACTION_HALT;
6608 if (arg_action != ACTION_REBOOT)
6609 arg_action = ACTION_POWEROFF;
6613 arg_action = ACTION_REBOOT;
6635 /* Compatibility nops */
6642 assert_not_reached("Unhandled option");
6645 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6646 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6649 } else if (optind < argc) {
6650 log_error("Too many arguments.");
6657 static int parse_time_spec(const char *t, usec_t *_u) {
6661 if (streq(t, "now"))
6663 else if (!strchr(t, ':')) {
6666 if (safe_atou64(t, &u) < 0)
6669 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6678 hour = strtol(t, &e, 10);
6679 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6682 minute = strtol(e+1, &e, 10);
6683 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6686 n = now(CLOCK_REALTIME);
6687 s = (time_t) (n / USEC_PER_SEC);
6689 assert_se(localtime_r(&s, &tm));
6691 tm.tm_hour = (int) hour;
6692 tm.tm_min = (int) minute;
6695 assert_se(s = mktime(&tm));
6697 *_u = (usec_t) s * USEC_PER_SEC;
6700 *_u += USEC_PER_DAY;
6706 static int shutdown_parse_argv(int argc, char *argv[]) {
6713 static const struct option options[] = {
6714 { "help", no_argument, NULL, ARG_HELP },
6715 { "halt", no_argument, NULL, 'H' },
6716 { "poweroff", no_argument, NULL, 'P' },
6717 { "reboot", no_argument, NULL, 'r' },
6718 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6719 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6728 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6736 arg_action = ACTION_HALT;
6740 arg_action = ACTION_POWEROFF;
6745 arg_action = ACTION_KEXEC;
6747 arg_action = ACTION_REBOOT;
6751 arg_action = ACTION_KEXEC;
6755 if (arg_action != ACTION_HALT)
6756 arg_action = ACTION_POWEROFF;
6771 /* Compatibility nops */
6775 arg_action = ACTION_CANCEL_SHUTDOWN;
6782 assert_not_reached("Unhandled option");
6785 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6786 r = parse_time_spec(argv[optind], &arg_when);
6788 log_error("Failed to parse time specification: %s", argv[optind]);
6792 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6794 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6795 /* No time argument for shutdown cancel */
6796 arg_wall = argv + optind;
6797 else if (argc > optind + 1)
6798 /* We skip the time argument */
6799 arg_wall = argv + optind + 1;
6806 static int telinit_parse_argv(int argc, char *argv[]) {
6813 static const struct option options[] = {
6814 { "help", no_argument, NULL, ARG_HELP },
6815 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6819 static const struct {
6823 { '0', ACTION_POWEROFF },
6824 { '6', ACTION_REBOOT },
6825 { '1', ACTION_RESCUE },
6826 { '2', ACTION_RUNLEVEL2 },
6827 { '3', ACTION_RUNLEVEL3 },
6828 { '4', ACTION_RUNLEVEL4 },
6829 { '5', ACTION_RUNLEVEL5 },
6830 { 's', ACTION_RESCUE },
6831 { 'S', ACTION_RESCUE },
6832 { 'q', ACTION_RELOAD },
6833 { 'Q', ACTION_RELOAD },
6834 { 'u', ACTION_REEXEC },
6835 { 'U', ACTION_REEXEC }
6844 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6859 assert_not_reached("Unhandled option");
6862 if (optind >= argc) {
6863 log_error("%s: required argument missing.",
6864 program_invocation_short_name);
6868 if (optind + 1 < argc) {
6869 log_error("Too many arguments.");
6873 if (strlen(argv[optind]) != 1) {
6874 log_error("Expected single character argument.");
6878 for (i = 0; i < ELEMENTSOF(table); i++)
6879 if (table[i].from == argv[optind][0])
6882 if (i >= ELEMENTSOF(table)) {
6883 log_error("Unknown command '%s'.", argv[optind]);
6887 arg_action = table[i].to;
6894 static int runlevel_parse_argv(int argc, char *argv[]) {
6900 static const struct option options[] = {
6901 { "help", no_argument, NULL, ARG_HELP },
6910 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6921 assert_not_reached("Unhandled option");
6924 if (optind < argc) {
6925 log_error("Too many arguments.");
6932 static int parse_argv(int argc, char *argv[]) {
6936 if (program_invocation_short_name) {
6938 if (strstr(program_invocation_short_name, "halt")) {
6939 arg_action = ACTION_HALT;
6940 return halt_parse_argv(argc, argv);
6941 } else if (strstr(program_invocation_short_name, "poweroff")) {
6942 arg_action = ACTION_POWEROFF;
6943 return halt_parse_argv(argc, argv);
6944 } else if (strstr(program_invocation_short_name, "reboot")) {
6946 arg_action = ACTION_KEXEC;
6948 arg_action = ACTION_REBOOT;
6949 return halt_parse_argv(argc, argv);
6950 } else if (strstr(program_invocation_short_name, "shutdown")) {
6951 arg_action = ACTION_POWEROFF;
6952 return shutdown_parse_argv(argc, argv);
6953 } else if (strstr(program_invocation_short_name, "init")) {
6955 if (sd_booted() > 0) {
6956 arg_action = _ACTION_INVALID;
6957 return telinit_parse_argv(argc, argv);
6959 /* Hmm, so some other init system is
6960 * running, we need to forward this
6961 * request to it. For now we simply
6962 * guess that it is Upstart. */
6964 execv(TELINIT, argv);
6966 log_error("Couldn't find an alternative telinit implementation to spawn.");
6970 } else if (strstr(program_invocation_short_name, "runlevel")) {
6971 arg_action = ACTION_RUNLEVEL;
6972 return runlevel_parse_argv(argc, argv);
6976 arg_action = ACTION_SYSTEMCTL;
6977 return systemctl_parse_argv(argc, argv);
6980 _pure_ static int action_to_runlevel(void) {
6982 static const char table[_ACTION_MAX] = {
6983 [ACTION_HALT] = '0',
6984 [ACTION_POWEROFF] = '0',
6985 [ACTION_REBOOT] = '6',
6986 [ACTION_RUNLEVEL2] = '2',
6987 [ACTION_RUNLEVEL3] = '3',
6988 [ACTION_RUNLEVEL4] = '4',
6989 [ACTION_RUNLEVEL5] = '5',
6990 [ACTION_RESCUE] = '1'
6993 assert(arg_action < _ACTION_MAX);
6995 return table[arg_action];
6998 static int talk_initctl(void) {
7000 struct init_request request = {
7001 .magic = INIT_MAGIC,
7003 .cmd = INIT_CMD_RUNLVL
7006 _cleanup_close_ int fd = -1;
7010 rl = action_to_runlevel();
7014 request.runlevel = rl;
7016 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7018 if (errno == ENOENT)
7021 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7025 r = loop_write(fd, &request, sizeof(request), false);
7027 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7032 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7034 static const struct {
7042 int (* const dispatch)(sd_bus *bus, char **args);
7048 { "list-units", MORE, 0, list_units },
7049 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7050 { "list-sockets", MORE, 1, list_sockets },
7051 { "list-timers", MORE, 1, list_timers },
7052 { "list-jobs", MORE, 1, list_jobs },
7053 { "list-machines", MORE, 1, list_machines },
7054 { "clear-jobs", EQUAL, 1, daemon_reload },
7055 { "cancel", MORE, 2, cancel_job },
7056 { "start", MORE, 2, start_unit },
7057 { "stop", MORE, 2, start_unit },
7058 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7059 { "reload", MORE, 2, start_unit },
7060 { "restart", MORE, 2, start_unit },
7061 { "try-restart", MORE, 2, start_unit },
7062 { "reload-or-restart", MORE, 2, start_unit },
7063 { "reload-or-try-restart", MORE, 2, start_unit },
7064 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7065 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7066 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7067 { "isolate", EQUAL, 2, start_unit },
7068 { "kill", MORE, 2, kill_unit },
7069 { "is-active", MORE, 2, check_unit_active },
7070 { "check", MORE, 2, check_unit_active },
7071 { "is-failed", MORE, 2, check_unit_failed },
7072 { "show", MORE, 1, show },
7073 { "cat", MORE, 2, cat, NOBUS },
7074 { "status", MORE, 1, show },
7075 { "help", MORE, 2, show },
7076 { "snapshot", LESS, 2, snapshot },
7077 { "delete", MORE, 2, delete_snapshot },
7078 { "daemon-reload", EQUAL, 1, daemon_reload },
7079 { "daemon-reexec", EQUAL, 1, daemon_reload },
7080 { "show-environment", EQUAL, 1, show_environment },
7081 { "set-environment", MORE, 2, set_environment },
7082 { "unset-environment", MORE, 2, set_environment },
7083 { "import-environment", MORE, 1, import_environment},
7084 { "halt", EQUAL, 1, start_special, FORCE },
7085 { "poweroff", EQUAL, 1, start_special, FORCE },
7086 { "reboot", EQUAL, 1, start_special, FORCE },
7087 { "kexec", EQUAL, 1, start_special },
7088 { "suspend", EQUAL, 1, start_special },
7089 { "hibernate", EQUAL, 1, start_special },
7090 { "hybrid-sleep", EQUAL, 1, start_special },
7091 { "default", EQUAL, 1, start_special },
7092 { "rescue", EQUAL, 1, start_special },
7093 { "emergency", EQUAL, 1, start_special },
7094 { "exit", EQUAL, 1, start_special },
7095 { "reset-failed", MORE, 1, reset_failed },
7096 { "enable", MORE, 2, enable_unit, NOBUS },
7097 { "disable", MORE, 2, enable_unit, NOBUS },
7098 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7099 { "reenable", MORE, 2, enable_unit, NOBUS },
7100 { "preset", MORE, 2, enable_unit, NOBUS },
7101 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7102 { "mask", MORE, 2, enable_unit, NOBUS },
7103 { "unmask", MORE, 2, enable_unit, NOBUS },
7104 { "link", MORE, 2, enable_unit, NOBUS },
7105 { "switch-root", MORE, 2, switch_root },
7106 { "list-dependencies", LESS, 2, list_dependencies },
7107 { "set-default", EQUAL, 2, set_default, NOBUS },
7108 { "get-default", EQUAL, 1, get_default, NOBUS },
7109 { "set-property", MORE, 3, set_property },
7110 { "is-system-running", EQUAL, 1, is_system_running },
7111 { "add-wants", MORE, 3, add_dependency, NOBUS },
7112 { "add-requires", MORE, 3, add_dependency, NOBUS },
7113 { "edit", MORE, 2, edit, NOBUS },
7122 left = argc - optind;
7124 /* Special rule: no arguments (left == 0) means "list-units" */
7126 if (streq(argv[optind], "help") && !argv[optind+1]) {
7127 log_error("This command expects one or more "
7128 "unit names. Did you mean --help?");
7132 for (; verb->verb; verb++)
7133 if (streq(argv[optind], verb->verb))
7136 log_error("Unknown operation '%s'.", argv[optind]);
7141 switch (verb->argc_cmp) {
7144 if (left != verb->argc) {
7145 log_error("Invalid number of arguments.");
7152 if (left < verb->argc) {
7153 log_error("Too few arguments.");
7160 if (left > verb->argc) {
7161 log_error("Too many arguments.");
7168 assert_not_reached("Unknown comparison operator.");
7171 /* Require a bus connection for all operations but
7173 if (verb->bus == NOBUS) {
7174 if (!bus && !avoid_bus()) {
7175 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7180 if (running_in_chroot() > 0) {
7181 log_info("Running in chroot, ignoring request.");
7185 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7186 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7191 return verb->dispatch(bus, argv + optind);
7194 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7196 struct sd_shutdown_command c = {
7203 union sockaddr_union sockaddr = {
7204 .un.sun_family = AF_UNIX,
7205 .un.sun_path = "/run/systemd/shutdownd",
7208 struct iovec iovec[2] = {{
7209 .iov_base = (char*) &c,
7210 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7213 struct msghdr msghdr = {
7214 .msg_name = &sockaddr,
7215 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7216 + strlen("/run/systemd/shutdownd"),
7221 _cleanup_close_ int fd;
7223 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7227 if (!isempty(message)) {
7228 iovec[1].iov_base = (char*) message;
7229 iovec[1].iov_len = strlen(message);
7230 msghdr.msg_iovlen++;
7233 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7239 static int reload_with_fallback(sd_bus *bus) {
7242 /* First, try systemd via D-Bus. */
7243 if (daemon_reload(bus, NULL) >= 0)
7247 /* Nothing else worked, so let's try signals */
7248 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7250 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7251 return log_error_errno(errno, "kill() failed: %m");
7256 static int start_with_fallback(sd_bus *bus) {
7259 /* First, try systemd via D-Bus. */
7260 if (start_unit(bus, NULL) >= 0)
7264 /* Nothing else worked, so let's try
7266 if (talk_initctl() > 0)
7269 log_error("Failed to talk to init daemon.");
7273 warn_wall(arg_action);
7277 static int halt_now(enum action a) {
7279 /* The kernel will automaticall flush ATA disks and suchlike
7280 * on reboot(), but the file systems need to be synce'd
7281 * explicitly in advance. */
7284 /* Make sure C-A-D is handled by the kernel from this point
7286 reboot(RB_ENABLE_CAD);
7291 log_info("Halting.");
7292 reboot(RB_HALT_SYSTEM);
7295 case ACTION_POWEROFF:
7296 log_info("Powering off.");
7297 reboot(RB_POWER_OFF);
7300 case ACTION_REBOOT: {
7301 _cleanup_free_ char *param = NULL;
7303 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7304 log_info("Rebooting with argument '%s'.", param);
7305 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7306 LINUX_REBOOT_CMD_RESTART2, param);
7309 log_info("Rebooting.");
7310 reboot(RB_AUTOBOOT);
7315 assert_not_reached("Unknown action.");
7319 static int halt_main(sd_bus *bus) {
7322 r = check_inhibitors(bus, arg_action);
7326 if (geteuid() != 0) {
7327 /* Try logind if we are a normal user and no special
7328 * mode applies. Maybe PolicyKit allows us to shutdown
7331 if (arg_when <= 0 &&
7334 (arg_action == ACTION_POWEROFF ||
7335 arg_action == ACTION_REBOOT)) {
7336 r = reboot_with_logind(bus, arg_action);
7341 log_error("Must be root.");
7346 _cleanup_free_ char *m;
7348 m = strv_join(arg_wall, " ");
7352 r = send_shutdownd(arg_when,
7353 arg_action == ACTION_HALT ? 'H' :
7354 arg_action == ACTION_POWEROFF ? 'P' :
7355 arg_action == ACTION_KEXEC ? 'K' :
7362 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7364 char date[FORMAT_TIMESTAMP_MAX];
7366 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7367 format_timestamp(date, sizeof(date), arg_when));
7372 if (!arg_dry && !arg_force)
7373 return start_with_fallback(bus);
7376 if (sd_booted() > 0)
7377 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7379 r = utmp_put_shutdown();
7381 log_warning_errno(r, "Failed to write utmp record: %m");
7388 r = halt_now(arg_action);
7389 log_error_errno(r, "Failed to reboot: %m");
7394 static int runlevel_main(void) {
7395 int r, runlevel, previous;
7397 r = utmp_get_runlevel(&runlevel, &previous);
7404 previous <= 0 ? 'N' : previous,
7405 runlevel <= 0 ? 'N' : runlevel);
7410 int main(int argc, char*argv[]) {
7411 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7414 setlocale(LC_ALL, "");
7415 log_parse_environment();
7418 /* Explicitly not on_tty() to avoid setting cached value.
7419 * This becomes relevant for piping output which might be
7421 original_stdout_is_tty = isatty(STDOUT_FILENO);
7423 r = parse_argv(argc, argv);
7427 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7428 * let's shortcut this */
7429 if (arg_action == ACTION_RUNLEVEL) {
7430 r = runlevel_main();
7434 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7435 log_info("Running in chroot, ignoring request.");
7441 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7443 /* systemctl_main() will print an error message for the bus
7444 * connection, but only if it needs to */
7446 switch (arg_action) {
7448 case ACTION_SYSTEMCTL:
7449 r = systemctl_main(bus, argc, argv, r);
7453 case ACTION_POWEROFF:
7459 case ACTION_RUNLEVEL2:
7460 case ACTION_RUNLEVEL3:
7461 case ACTION_RUNLEVEL4:
7462 case ACTION_RUNLEVEL5:
7464 case ACTION_EMERGENCY:
7465 case ACTION_DEFAULT:
7466 r = start_with_fallback(bus);
7471 r = reload_with_fallback(bus);
7474 case ACTION_CANCEL_SHUTDOWN: {
7475 _cleanup_free_ char *m = NULL;
7478 m = strv_join(arg_wall, " ");
7485 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7487 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7491 case ACTION_RUNLEVEL:
7492 case _ACTION_INVALID:
7494 assert_not_reached("Unknown action");
7499 ask_password_agent_close();
7500 polkit_agent_close();
7502 strv_free(arg_types);
7503 strv_free(arg_states);
7504 strv_free(arg_properties);
7506 return r < 0 ? EXIT_FAILURE : r;