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>
33 #include <sys/socket.h>
36 #include "sd-daemon.h"
37 #include "sd-shutdown.h"
44 #include "utmp-wtmp.h"
47 #include "path-util.h"
49 #include "cgroup-show.h"
50 #include "cgroup-util.h"
52 #include "path-lookup.h"
53 #include "exit-status.h"
55 #include "unit-name.h"
57 #include "spawn-ask-password-agent.h"
58 #include "spawn-polkit-agent.h"
60 #include "logs-show.h"
61 #include "socket-util.h"
66 #include "bus-message.h"
67 #include "bus-error.h"
68 #include "bus-common-errors.h"
72 static char **arg_types = NULL;
73 static char **arg_states = NULL;
74 static char **arg_properties = NULL;
75 static bool arg_all = false;
76 static enum dependency {
82 } arg_dependency = DEPENDENCY_FORWARD;
83 static const char *arg_job_mode = "replace";
84 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
85 static bool arg_no_block = false;
86 static bool arg_no_legend = false;
87 static bool arg_no_pager = false;
88 static bool arg_no_wtmp = false;
89 static bool arg_no_wall = false;
90 static bool arg_no_reload = false;
91 static bool arg_show_types = false;
92 static bool arg_ignore_inhibitors = false;
93 static bool arg_dry = false;
94 static bool arg_quiet = false;
95 static bool arg_full = false;
96 static bool arg_recursive = false;
97 static int arg_force = 0;
98 static bool arg_ask_password = true;
99 static bool arg_runtime = false;
100 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
101 static char **arg_wall = NULL;
102 static const char *arg_kill_who = NULL;
103 static int arg_signal = SIGTERM;
104 static const char *arg_root = NULL;
105 static usec_t arg_when = 0;
127 ACTION_CANCEL_SHUTDOWN,
129 } arg_action = ACTION_SYSTEMCTL;
130 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
131 static char *arg_host = NULL;
132 static unsigned arg_lines = 10;
133 static OutputMode arg_output = OUTPUT_SHORT;
134 static bool arg_plain = false;
136 static bool original_stdout_is_tty;
138 static int daemon_reload(sd_bus *bus, char **args);
139 static int halt_now(enum action a);
140 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
142 static char** strv_skip_first(char **strv) {
143 if (strv_length(strv) > 0)
148 static void pager_open_if_enabled(void) {
156 static void ask_password_agent_open_if_enabled(void) {
158 /* Open the password agent as a child process if necessary */
160 if (!arg_ask_password)
163 if (arg_scope != UNIT_FILE_SYSTEM)
166 if (arg_transport != BUS_TRANSPORT_LOCAL)
169 ask_password_agent_open();
172 static void polkit_agent_open_if_enabled(void) {
174 /* Open the polkit agent as a child process if necessary */
176 if (!arg_ask_password)
179 if (arg_scope != UNIT_FILE_SYSTEM)
182 if (arg_transport != BUS_TRANSPORT_LOCAL)
188 static OutputFlags get_output_flags(void) {
190 arg_all * OUTPUT_SHOW_ALL |
191 arg_full * OUTPUT_FULL_WIDTH |
192 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
193 on_tty() * OUTPUT_COLOR |
194 !arg_quiet * OUTPUT_WARN_CUTOFF;
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_fnmatch_or_empty(patterns, u->id, FNM_NOESCAPE))
313 dot = strrchr(u->id, '.');
317 if (!strv_find(arg_types, dot+1))
327 if (streq(u->active_state, "inactive") || u->following[0])
333 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
334 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
336 unsigned n_shown = 0;
339 max_id_len = strlen("UNIT");
340 load_len = strlen("LOAD");
341 active_len = strlen("ACTIVE");
342 sub_len = strlen("SUB");
343 job_len = strlen("JOB");
346 for (u = unit_infos; u < unit_infos + c; u++) {
347 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
348 load_len = MAX(load_len, strlen(u->load_state));
349 active_len = MAX(active_len, strlen(u->active_state));
350 sub_len = MAX(sub_len, strlen(u->sub_state));
352 if (u->job_id != 0) {
353 job_len = MAX(job_len, strlen(u->job_type));
357 if (!arg_no_legend &&
358 (streq(u->active_state, "failed") ||
359 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
363 if (!arg_full && original_stdout_is_tty) {
366 id_len = MIN(max_id_len, 25u);
367 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
370 basic_len += job_len + 1;
372 if (basic_len < (unsigned) columns()) {
373 unsigned extra_len, incr;
374 extra_len = columns() - basic_len;
376 /* Either UNIT already got 25, or is fully satisfied.
377 * Grant up to 25 to DESC now. */
378 incr = MIN(extra_len, 25u);
382 /* split the remaining space between UNIT and DESC,
383 * but do not give UNIT more than it needs. */
385 incr = MIN(extra_len / 2, max_id_len - id_len);
387 desc_len += extra_len - incr;
393 for (u = unit_infos; u < unit_infos + c; u++) {
394 _cleanup_free_ char *e = NULL, *j = NULL;
395 const char *on_loaded = "", *off_loaded = "";
396 const char *on_active = "", *off_active = "";
397 const char *on_circle = "", *off_circle = "";
401 if (!n_shown && !arg_no_legend) {
406 printf("%-*s %-*s %-*s %-*s ",
409 active_len, "ACTIVE",
413 printf("%-*s ", job_len, "JOB");
415 if (!arg_full && arg_no_pager)
416 printf("%.*s\n", desc_len, "DESCRIPTION");
418 printf("%s\n", "DESCRIPTION");
423 if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) {
424 on_loaded = ansi_highlight_red();
425 on_circle = ansi_highlight_yellow();
426 off_loaded = off_circle = ansi_highlight_off();
428 } else if (streq(u->active_state, "failed") && !arg_plain) {
429 on_circle = on_active = ansi_highlight_red();
430 off_circle = off_active = ansi_highlight_off();
435 j = strjoin(u->machine, ":", u->id, NULL);
444 e = ellipsize(id, id_len, 33);
452 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
454 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
455 on_active, id_len, id, off_active,
456 on_loaded, load_len, u->load_state, off_loaded,
457 on_active, active_len, u->active_state,
458 sub_len, u->sub_state, off_active,
459 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
462 printf("%.*s\n", desc_len, u->description);
464 printf("%s\n", u->description);
467 if (!arg_no_legend) {
468 const char *on, *off;
472 "LOAD = Reflects whether the unit definition was properly loaded.\n"
473 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
474 "SUB = The low-level unit activation state, values depend on unit type.");
475 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
476 on = ansi_highlight();
477 off = ansi_highlight_off();
479 on = ansi_highlight_red();
480 off = ansi_highlight_off();
484 printf("%s%u loaded units listed.%s\n"
485 "To show all installed unit files use 'systemctl list-unit-files'.\n",
488 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
489 "To show all installed unit files use 'systemctl list-unit-files'.\n",
496 static int get_unit_list(
500 UnitInfo **unit_infos,
502 sd_bus_message **_reply) {
504 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
505 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
506 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
515 r = sd_bus_message_new_method_call(
518 "org.freedesktop.systemd1",
519 "/org/freedesktop/systemd1",
520 "org.freedesktop.systemd1.Manager",
521 "ListUnitsFiltered");
524 return bus_log_create_error(r);
526 r = sd_bus_message_append_strv(m, arg_states);
528 return bus_log_create_error(r);
530 r = sd_bus_call(bus, m, 0, &error, &reply);
532 log_error("Failed to list units: %s", bus_error_message(&error, r));
536 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
538 return bus_log_parse_error(r);
540 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
543 if (!output_show_unit(&u, patterns))
546 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
549 (*unit_infos)[c++] = u;
552 return bus_log_parse_error(r);
554 r = sd_bus_message_exit_container(reply);
556 return bus_log_parse_error(r);
564 static void message_set_freep(Set **set) {
567 while ((m = set_steal_first(*set)))
568 sd_bus_message_unref(m);
573 static int get_unit_list_recursive(
576 UnitInfo **_unit_infos,
580 _cleanup_free_ UnitInfo *unit_infos = NULL;
581 _cleanup_(message_set_freep) Set *replies;
582 sd_bus_message *reply;
590 replies = set_new(NULL);
594 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
598 r = set_put(replies, reply);
600 sd_bus_message_unref(reply);
605 _cleanup_strv_free_ char **machines = NULL;
608 r = sd_get_machine_names(&machines);
612 STRV_FOREACH(i, machines) {
613 _cleanup_bus_close_unref_ sd_bus *container = NULL;
616 r = sd_bus_open_system_machine(&container, *i);
618 log_error_errno(r, "Failed to connect to container %s: %m", *i);
622 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
628 r = set_put(replies, reply);
630 sd_bus_message_unref(reply);
635 *_machines = machines;
640 *_unit_infos = unit_infos;
649 static int list_units(sd_bus *bus, char **args) {
650 _cleanup_free_ UnitInfo *unit_infos = NULL;
651 _cleanup_(message_set_freep) Set *replies = NULL;
652 _cleanup_strv_free_ char **machines = NULL;
655 pager_open_if_enabled();
657 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
661 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
662 return output_units_list(unit_infos, r);
665 static int get_triggered_units(
670 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
673 r = sd_bus_get_property_strv(
675 "org.freedesktop.systemd1",
677 "org.freedesktop.systemd1.Unit",
683 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
688 static int get_listening(
690 const char* unit_path,
693 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
694 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
695 const char *type, *path;
698 r = sd_bus_get_property(
700 "org.freedesktop.systemd1",
702 "org.freedesktop.systemd1.Socket",
708 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
712 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
714 return bus_log_parse_error(r);
716 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
718 r = strv_extend(listening, type);
722 r = strv_extend(listening, path);
729 return bus_log_parse_error(r);
731 r = sd_bus_message_exit_container(reply);
733 return bus_log_parse_error(r);
745 /* Note: triggered is a list here, although it almost certainly
746 * will always be one unit. Nevertheless, dbus API allows for multiple
747 * values, so let's follow that. */
750 /* The strv above is shared. free is set only in the first one. */
754 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
760 if (!a->machine && b->machine)
762 if (a->machine && !b->machine)
764 if (a->machine && b->machine) {
765 o = strcasecmp(a->machine, b->machine);
770 o = strcmp(a->path, b->path);
772 o = strcmp(a->type, b->type);
777 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
778 struct socket_info *s;
779 unsigned pathlen = strlen("LISTEN"),
780 typelen = strlen("TYPE") * arg_show_types,
781 socklen = strlen("UNIT"),
782 servlen = strlen("ACTIVATES");
783 const char *on, *off;
785 for (s = socket_infos; s < socket_infos + cs; s++) {
789 socklen = MAX(socklen, strlen(s->id));
791 typelen = MAX(typelen, strlen(s->type));
792 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
794 STRV_FOREACH(a, s->triggered)
795 tmp += strlen(*a) + 2*(a != s->triggered);
796 servlen = MAX(servlen, tmp);
801 printf("%-*s %-*.*s%-*s %s\n",
803 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
807 for (s = socket_infos; s < socket_infos + cs; s++) {
808 _cleanup_free_ char *j = NULL;
813 j = strjoin(s->machine, ":", s->path, NULL);
821 printf("%-*s %-*s %-*s",
822 pathlen, path, typelen, s->type, socklen, s->id);
825 pathlen, path, socklen, s->id);
826 STRV_FOREACH(a, s->triggered)
828 a == s->triggered ? "" : ",", *a);
832 on = ansi_highlight();
833 off = ansi_highlight_off();
837 on = ansi_highlight_red();
838 off = ansi_highlight_off();
841 if (!arg_no_legend) {
842 printf("%s%u sockets listed.%s\n", on, cs, off);
844 printf("Pass --all to see loaded but inactive sockets, too.\n");
850 static int list_sockets(sd_bus *bus, char **args) {
851 _cleanup_(message_set_freep) Set *replies = NULL;
852 _cleanup_strv_free_ char **machines = NULL;
853 _cleanup_free_ UnitInfo *unit_infos = NULL;
854 _cleanup_free_ struct socket_info *socket_infos = NULL;
856 struct socket_info *s;
861 pager_open_if_enabled();
863 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
867 for (u = unit_infos; u < unit_infos + n; u++) {
868 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
871 if (!endswith(u->id, ".socket"))
874 r = get_triggered_units(bus, u->unit_path, &triggered);
878 c = get_listening(bus, u->unit_path, &listening);
884 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
889 for (i = 0; i < c; i++)
890 socket_infos[cs + i] = (struct socket_info) {
891 .machine = u->machine,
893 .type = listening[i*2],
894 .path = listening[i*2 + 1],
895 .triggered = triggered,
896 .own_triggered = i==0,
899 /* from this point on we will cleanup those socket_infos */
902 listening = triggered = NULL; /* avoid cleanup */
905 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
906 (__compar_fn_t) socket_info_compare);
908 output_sockets_list(socket_infos, cs);
911 assert(cs == 0 || socket_infos);
912 for (s = socket_infos; s < socket_infos + cs; s++) {
915 if (s->own_triggered)
916 strv_free(s->triggered);
922 static int get_next_elapse(
925 dual_timestamp *next) {
927 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
935 r = sd_bus_get_property_trivial(
937 "org.freedesktop.systemd1",
939 "org.freedesktop.systemd1.Timer",
940 "NextElapseUSecMonotonic",
945 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
949 r = sd_bus_get_property_trivial(
951 "org.freedesktop.systemd1",
953 "org.freedesktop.systemd1.Timer",
954 "NextElapseUSecRealtime",
959 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
967 static int get_last_trigger(
972 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
979 r = sd_bus_get_property_trivial(
981 "org.freedesktop.systemd1",
983 "org.freedesktop.systemd1.Timer",
989 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1000 usec_t last_trigger;
1004 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1010 if (!a->machine && b->machine)
1012 if (a->machine && !b->machine)
1014 if (a->machine && b->machine) {
1015 o = strcasecmp(a->machine, b->machine);
1020 if (a->next_elapse < b->next_elapse)
1022 if (a->next_elapse > b->next_elapse)
1025 return strcmp(a->id, b->id);
1028 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1029 struct timer_info *t;
1031 nextlen = strlen("NEXT"),
1032 leftlen = strlen("LEFT"),
1033 lastlen = strlen("LAST"),
1034 passedlen = strlen("PASSED"),
1035 unitlen = strlen("UNIT"),
1036 activatelen = strlen("ACTIVATES");
1038 const char *on, *off;
1040 assert(timer_infos || n == 0);
1042 for (t = timer_infos; t < timer_infos + n; t++) {
1046 if (t->next_elapse > 0) {
1047 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1049 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1050 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1052 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1053 leftlen = MAX(leftlen, strlen(trel));
1056 if (t->last_trigger > 0) {
1057 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1059 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1060 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1062 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1063 passedlen = MAX(passedlen, strlen(trel));
1066 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1068 STRV_FOREACH(a, t->triggered)
1069 ul += strlen(*a) + 2*(a != t->triggered);
1071 activatelen = MAX(activatelen, ul);
1076 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1080 passedlen, "PASSED",
1084 for (t = timer_infos; t < timer_infos + n; t++) {
1085 _cleanup_free_ char *j = NULL;
1087 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1088 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1091 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1092 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1094 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1095 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1098 j = strjoin(t->machine, ":", t->id, NULL);
1105 printf("%-*s %-*s %-*s %-*s %-*s",
1106 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1108 STRV_FOREACH(a, t->triggered)
1110 a == t->triggered ? "" : ",", *a);
1114 on = ansi_highlight();
1115 off = ansi_highlight_off();
1119 on = ansi_highlight_red();
1120 off = ansi_highlight_off();
1123 if (!arg_no_legend) {
1124 printf("%s%u timers listed.%s\n", on, n, off);
1126 printf("Pass --all to see loaded but inactive timers, too.\n");
1132 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1138 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1141 if (next->monotonic > nw->monotonic)
1142 converted = nw->realtime + (next->monotonic - nw->monotonic);
1144 converted = nw->realtime - (nw->monotonic - next->monotonic);
1146 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1147 next_elapse = MIN(converted, next->realtime);
1149 next_elapse = converted;
1152 next_elapse = next->realtime;
1157 static int list_timers(sd_bus *bus, char **args) {
1158 _cleanup_(message_set_freep) Set *replies = NULL;
1159 _cleanup_strv_free_ char **machines = NULL;
1160 _cleanup_free_ struct timer_info *timer_infos = NULL;
1161 _cleanup_free_ UnitInfo *unit_infos = NULL;
1162 struct timer_info *t;
1169 pager_open_if_enabled();
1171 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1175 dual_timestamp_get(&nw);
1177 for (u = unit_infos; u < unit_infos + n; u++) {
1178 _cleanup_strv_free_ char **triggered = NULL;
1179 dual_timestamp next = {};
1182 if (!endswith(u->id, ".timer"))
1185 r = get_triggered_units(bus, u->unit_path, &triggered);
1189 r = get_next_elapse(bus, u->unit_path, &next);
1193 get_last_trigger(bus, u->unit_path, &last);
1195 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1200 m = calc_next_elapse(&nw, &next);
1202 timer_infos[c++] = (struct timer_info) {
1203 .machine = u->machine,
1206 .last_trigger = last,
1207 .triggered = triggered,
1210 triggered = NULL; /* avoid cleanup */
1213 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1214 (__compar_fn_t) timer_info_compare);
1216 output_timers_list(timer_infos, c);
1219 for (t = timer_infos; t < timer_infos + c; t++)
1220 strv_free(t->triggered);
1225 static int compare_unit_file_list(const void *a, const void *b) {
1226 const char *d1, *d2;
1227 const UnitFileList *u = a, *v = b;
1229 d1 = strrchr(u->path, '.');
1230 d2 = strrchr(v->path, '.');
1235 r = strcasecmp(d1, d2);
1240 return strcasecmp(basename(u->path), basename(v->path));
1243 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1244 if (!strv_fnmatch_or_empty(patterns, basename(u->path), FNM_NOESCAPE))
1247 if (!strv_isempty(arg_types)) {
1250 dot = strrchr(u->path, '.');
1254 if (!strv_find(arg_types, dot+1))
1258 if (!strv_isempty(arg_states) &&
1259 !strv_find(arg_states, unit_file_state_to_string(u->state)))
1265 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1266 unsigned max_id_len, id_cols, state_cols;
1267 const UnitFileList *u;
1269 max_id_len = strlen("UNIT FILE");
1270 state_cols = strlen("STATE");
1272 for (u = units; u < units + c; u++) {
1273 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1274 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1278 unsigned basic_cols;
1280 id_cols = MIN(max_id_len, 25u);
1281 basic_cols = 1 + id_cols + state_cols;
1282 if (basic_cols < (unsigned) columns())
1283 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1285 id_cols = max_id_len;
1288 printf("%-*s %-*s\n",
1289 id_cols, "UNIT FILE",
1290 state_cols, "STATE");
1292 for (u = units; u < units + c; u++) {
1293 _cleanup_free_ char *e = NULL;
1294 const char *on, *off;
1297 if (u->state == UNIT_FILE_MASKED ||
1298 u->state == UNIT_FILE_MASKED_RUNTIME ||
1299 u->state == UNIT_FILE_DISABLED ||
1300 u->state == UNIT_FILE_INVALID) {
1301 on = ansi_highlight_red();
1302 off = ansi_highlight_off();
1303 } else if (u->state == UNIT_FILE_ENABLED) {
1304 on = ansi_highlight_green();
1305 off = ansi_highlight_off();
1309 id = basename(u->path);
1311 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1313 printf("%-*s %s%-*s%s\n",
1314 id_cols, e ? e : id,
1315 on, state_cols, unit_file_state_to_string(u->state), off);
1319 printf("\n%u unit files listed.\n", c);
1322 static int list_unit_files(sd_bus *bus, char **args) {
1323 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1324 _cleanup_free_ UnitFileList *units = NULL;
1332 pager_open_if_enabled();
1340 h = hashmap_new(&string_hash_ops);
1344 r = unit_file_get_list(arg_scope, arg_root, h);
1346 unit_file_list_free(h);
1347 log_error_errno(r, "Failed to get unit file list: %m");
1351 n_units = hashmap_size(h);
1353 units = new(UnitFileList, n_units);
1354 if (!units && n_units > 0) {
1355 unit_file_list_free(h);
1359 HASHMAP_FOREACH(u, h, i) {
1360 if (!output_show_unit_file(u, strv_skip_first(args)))
1367 assert(c <= n_units);
1370 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1372 r = sd_bus_call_method(
1374 "org.freedesktop.systemd1",
1375 "/org/freedesktop/systemd1",
1376 "org.freedesktop.systemd1.Manager",
1382 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1386 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1388 return bus_log_parse_error(r);
1390 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1392 if (!GREEDY_REALLOC(units, size, c + 1))
1395 units[c] = (struct UnitFileList) {
1397 unit_file_state_from_string(state)
1400 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1405 return bus_log_parse_error(r);
1407 r = sd_bus_message_exit_container(reply);
1409 return bus_log_parse_error(r);
1412 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1413 output_unit_file_list(units, c);
1416 for (unit = units; unit < units + c; unit++)
1423 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1424 _cleanup_free_ char *n = NULL;
1425 size_t max_len = MAX(columns(),20u);
1431 for (i = level - 1; i >= 0; i--) {
1433 if (len > max_len - 3 && !arg_full) {
1434 printf("%s...\n",max_len % 2 ? "" : " ");
1437 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1441 if (len > max_len - 3 && !arg_full) {
1442 printf("%s...\n",max_len % 2 ? "" : " ");
1446 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1450 printf("%s\n", name);
1454 n = ellipsize(name, max_len-len, 100);
1462 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1464 static const char *dependencies[_DEPENDENCY_MAX] = {
1465 [DEPENDENCY_FORWARD] = "Requires\0"
1466 "RequiresOverridable\0"
1468 "RequisiteOverridable\0"
1471 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1472 "RequiredByOverridable\0"
1476 [DEPENDENCY_AFTER] = "After\0",
1477 [DEPENDENCY_BEFORE] = "Before\0",
1480 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1481 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1482 _cleanup_strv_free_ char **ret = NULL;
1483 _cleanup_free_ char *path = NULL;
1489 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1491 path = unit_dbus_path_from_name(name);
1495 r = sd_bus_call_method(
1497 "org.freedesktop.systemd1",
1499 "org.freedesktop.DBus.Properties",
1503 "s", "org.freedesktop.systemd1.Unit");
1505 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1509 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1511 return bus_log_parse_error(r);
1513 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1516 r = sd_bus_message_read(reply, "s", &prop);
1518 return bus_log_parse_error(r);
1520 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1521 r = sd_bus_message_skip(reply, "v");
1523 return bus_log_parse_error(r);
1526 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1528 return bus_log_parse_error(r);
1530 r = bus_message_read_strv_extend(reply, &ret);
1532 return bus_log_parse_error(r);
1534 r = sd_bus_message_exit_container(reply);
1536 return bus_log_parse_error(r);
1539 r = sd_bus_message_exit_container(reply);
1541 return bus_log_parse_error(r);
1545 return bus_log_parse_error(r);
1547 r = sd_bus_message_exit_container(reply);
1549 return bus_log_parse_error(r);
1557 static int list_dependencies_compare(const void *_a, const void *_b) {
1558 const char **a = (const char**) _a, **b = (const char**) _b;
1560 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1562 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1565 return strcasecmp(*a, *b);
1568 static int list_dependencies_one(
1573 unsigned int branches) {
1575 _cleanup_strv_free_ char **deps = NULL;
1583 r = strv_extend(units, name);
1587 r = list_dependencies_get_dependencies(bus, name, &deps);
1591 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1593 STRV_FOREACH(c, deps) {
1594 if (strv_contains(*units, *c)) {
1596 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1609 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1610 on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
1611 printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1614 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1618 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1619 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1626 strv_remove(*units, name);
1631 static int list_dependencies(sd_bus *bus, char **args) {
1632 _cleanup_strv_free_ char **units = NULL;
1633 _cleanup_free_ char *unit = NULL;
1639 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1644 u = SPECIAL_DEFAULT_TARGET;
1646 pager_open_if_enabled();
1650 return list_dependencies_one(bus, u, 0, &units, 0);
1653 struct machine_info {
1657 char *control_group;
1658 uint32_t n_failed_units;
1663 static const struct bus_properties_map machine_info_property_map[] = {
1664 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1665 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1666 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1667 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1668 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1672 static void free_machines_list(struct machine_info *machine_infos, int n) {
1678 for (i = 0; i < n; i++) {
1679 free(machine_infos[i].name);
1680 free(machine_infos[i].state);
1681 free(machine_infos[i].control_group);
1684 free(machine_infos);
1687 static int compare_machine_info(const void *a, const void *b) {
1688 const struct machine_info *u = a, *v = b;
1690 if (u->is_host != v->is_host)
1691 return u->is_host > v->is_host ? -1 : 1;
1693 return strcasecmp(u->name, v->name);
1696 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1697 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1703 r = sd_bus_open_system_machine(&container, mi->name);
1710 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1717 static bool output_show_machine(const char *name, char **patterns) {
1718 return strv_fnmatch_or_empty(patterns, name, FNM_NOESCAPE);
1721 static int get_machine_list(
1723 struct machine_info **_machine_infos,
1726 struct machine_info *machine_infos = NULL;
1727 _cleanup_strv_free_ char **m = NULL;
1728 _cleanup_free_ char *hn = NULL;
1733 hn = gethostname_malloc();
1737 if (output_show_machine(hn, patterns)) {
1738 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1741 machine_infos[c].is_host = true;
1742 machine_infos[c].name = hn;
1745 get_machine_properties(bus, &machine_infos[c]);
1749 sd_get_machine_names(&m);
1750 STRV_FOREACH(i, m) {
1751 _cleanup_free_ char *class = NULL;
1753 if (!output_show_machine(*i, patterns))
1756 sd_machine_get_class(*i, &class);
1757 if (!streq_ptr(class, "container"))
1760 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1761 free_machines_list(machine_infos, c);
1765 machine_infos[c].is_host = false;
1766 machine_infos[c].name = strdup(*i);
1767 if (!machine_infos[c].name) {
1768 free_machines_list(machine_infos, c);
1772 get_machine_properties(NULL, &machine_infos[c]);
1776 *_machine_infos = machine_infos;
1780 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1781 struct machine_info *m;
1784 namelen = sizeof("NAME") - 1,
1785 statelen = sizeof("STATE") - 1,
1786 failedlen = sizeof("FAILED") - 1,
1787 jobslen = sizeof("JOBS") - 1;
1789 assert(machine_infos || n == 0);
1791 for (m = machine_infos; m < machine_infos + n; m++) {
1792 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1793 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1794 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1795 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1797 if (!arg_plain && !streq_ptr(m->state, "running"))
1801 if (!arg_no_legend) {
1805 printf("%-*s %-*s %-*s %-*s\n",
1808 failedlen, "FAILED",
1812 for (m = machine_infos; m < machine_infos + n; m++) {
1813 const char *on_state = "", *off_state = "";
1814 const char *on_failed = "", *off_failed = "";
1815 bool circle = false;
1817 if (streq_ptr(m->state, "degraded")) {
1818 on_state = ansi_highlight_red();
1819 off_state = ansi_highlight_off();
1821 } else if (!streq_ptr(m->state, "running")) {
1822 on_state = ansi_highlight_yellow();
1823 off_state = ansi_highlight_off();
1827 if (m->n_failed_units > 0) {
1828 on_failed = ansi_highlight_red();
1829 off_failed = ansi_highlight_off();
1831 on_failed = off_failed = "";
1834 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1837 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1838 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1839 on_state, statelen, strna(m->state), off_state,
1840 on_failed, failedlen, m->n_failed_units, off_failed,
1841 jobslen, m->n_jobs);
1843 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1844 namelen, strna(m->name),
1845 on_state, statelen, strna(m->state), off_state,
1846 on_failed, failedlen, m->n_failed_units, off_failed,
1847 jobslen, m->n_jobs);
1851 printf("\n%u machines listed.\n", n);
1854 static int list_machines(sd_bus *bus, char **args) {
1855 struct machine_info *machine_infos = NULL;
1860 if (geteuid() != 0) {
1861 log_error("Must be root.");
1865 pager_open_if_enabled();
1867 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1871 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1872 output_machines_list(machine_infos, r);
1873 free_machines_list(machine_infos, r);
1878 static int get_default(sd_bus *bus, char **args) {
1879 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1880 _cleanup_free_ char *_path = NULL;
1884 if (!bus || avoid_bus()) {
1885 r = unit_file_get_default(arg_scope, arg_root, &_path);
1887 return log_error_errno(r, "Failed to get default target: %m");
1891 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1893 r = sd_bus_call_method(
1895 "org.freedesktop.systemd1",
1896 "/org/freedesktop/systemd1",
1897 "org.freedesktop.systemd1.Manager",
1903 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1907 r = sd_bus_message_read(reply, "s", &path);
1909 return bus_log_parse_error(r);
1913 printf("%s\n", path);
1918 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1921 assert(changes || n_changes == 0);
1923 for (i = 0; i < n_changes; i++) {
1924 if (changes[i].type == UNIT_FILE_SYMLINK)
1925 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1927 log_info("Removed symlink %s.", changes[i].path);
1931 static int set_default(sd_bus *bus, char **args) {
1932 _cleanup_free_ char *unit = NULL;
1933 UnitFileChange *changes = NULL;
1934 unsigned n_changes = 0;
1937 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1941 if (!bus || avoid_bus()) {
1942 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1944 return log_error_errno(r, "Failed to set default target: %m");
1947 dump_unit_file_changes(changes, n_changes);
1951 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1952 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1954 polkit_agent_open_if_enabled();
1956 r = sd_bus_call_method(
1958 "org.freedesktop.systemd1",
1959 "/org/freedesktop/systemd1",
1960 "org.freedesktop.systemd1.Manager",
1966 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1970 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
1974 /* Try to reload if enabled */
1976 r = daemon_reload(bus, args);
1981 unit_file_changes_free(changes, n_changes);
1988 const char *name, *type, *state;
1991 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1992 unsigned id_len, unit_len, type_len, state_len;
1993 const struct job_info *j;
1994 const char *on, *off;
1995 bool shorten = false;
1997 assert(n == 0 || jobs);
2000 if (!arg_no_legend) {
2001 on = ansi_highlight_green();
2002 off = ansi_highlight_off();
2004 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2009 pager_open_if_enabled();
2011 id_len = strlen("JOB");
2012 unit_len = strlen("UNIT");
2013 type_len = strlen("TYPE");
2014 state_len = strlen("STATE");
2016 for (j = jobs; j < jobs + n; j++) {
2017 uint32_t id = j->id;
2018 assert(j->name && j->type && j->state);
2020 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2021 unit_len = MAX(unit_len, strlen(j->name));
2022 type_len = MAX(type_len, strlen(j->type));
2023 state_len = MAX(state_len, strlen(j->state));
2026 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2027 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2032 printf("%*s %-*s %-*s %-*s\n",
2036 state_len, "STATE");
2038 for (j = jobs; j < jobs + n; j++) {
2039 _cleanup_free_ char *e = NULL;
2041 if (streq(j->state, "running")) {
2042 on = ansi_highlight();
2043 off = ansi_highlight_off();
2047 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2048 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2050 on, unit_len, e ? e : j->name, off,
2052 on, state_len, j->state, off);
2055 if (!arg_no_legend) {
2056 on = ansi_highlight();
2057 off = ansi_highlight_off();
2059 printf("\n%s%u jobs listed%s.\n", on, n, off);
2063 static bool output_show_job(struct job_info *job, char **patterns) {
2064 return strv_fnmatch_or_empty(patterns, job->name, FNM_NOESCAPE);
2067 static int list_jobs(sd_bus *bus, char **args) {
2068 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2069 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2070 const char *name, *type, *state, *job_path, *unit_path;
2071 _cleanup_free_ struct job_info *jobs = NULL;
2076 bool skipped = false;
2078 r = sd_bus_call_method(
2080 "org.freedesktop.systemd1",
2081 "/org/freedesktop/systemd1",
2082 "org.freedesktop.systemd1.Manager",
2088 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2092 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2094 return bus_log_parse_error(r);
2096 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2097 struct job_info job = { id, name, type, state };
2099 if (!output_show_job(&job, strv_skip_first(args))) {
2104 if (!GREEDY_REALLOC(jobs, size, c + 1))
2110 return bus_log_parse_error(r);
2112 r = sd_bus_message_exit_container(reply);
2114 return bus_log_parse_error(r);
2116 output_jobs_list(jobs, c, skipped);
2120 static int cancel_job(sd_bus *bus, char **args) {
2126 if (strv_length(args) <= 1)
2127 return daemon_reload(bus, args);
2129 polkit_agent_open_if_enabled();
2131 STRV_FOREACH(name, args+1) {
2132 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2136 q = safe_atou32(*name, &id);
2138 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2140 q = sd_bus_call_method(
2142 "org.freedesktop.systemd1",
2143 "/org/freedesktop/systemd1",
2144 "org.freedesktop.systemd1.Manager",
2150 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2159 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2160 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2164 /* We ignore all errors here, since this is used to show a
2167 /* We don't use unit_dbus_path_from_name() directly since we
2168 * don't want to load the unit if it isn't loaded. */
2170 r = sd_bus_call_method(
2172 "org.freedesktop.systemd1",
2173 "/org/freedesktop/systemd1",
2174 "org.freedesktop.systemd1.Manager",
2182 r = sd_bus_message_read(reply, "o", &path);
2186 r = sd_bus_get_property_trivial(
2188 "org.freedesktop.systemd1",
2190 "org.freedesktop.systemd1.Unit",
2200 static void warn_unit_file_changed(const char *name) {
2201 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2202 ansi_highlight_red(),
2203 ansi_highlight_off(),
2205 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2208 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2215 STRV_FOREACH(p, lp->unit_path) {
2216 _cleanup_free_ char *path;
2218 path = path_join(arg_root, *p, unit_name);
2222 if (access(path, F_OK) == 0) {
2232 static int unit_find_paths(
2234 const char *unit_name,
2235 bool avoid_bus_cache,
2237 char **fragment_path,
2238 char ***dropin_paths) {
2240 _cleanup_free_ char *path = NULL;
2241 _cleanup_strv_free_ char **dropins = NULL;
2245 * Finds where the unit is defined on disk. Returns 0 if the unit
2246 * is not found. Returns 1 if it is found, and sets
2247 * - the path to the unit in *path, if it exists on disk,
2248 * - and a strv of existing drop-ins in *dropins,
2249 * if the arg is not NULL and any dropins were found.
2253 assert(fragment_path);
2256 if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2257 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2258 _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
2259 _cleanup_free_ char *unit = NULL;
2260 char *unit_load_error_name, *unit_load_error_message;
2262 unit = unit_dbus_path_from_name(unit_name);
2266 if (need_daemon_reload(bus, unit_name) > 0)
2267 warn_unit_file_changed(unit_name);
2269 r = sd_bus_get_property(
2271 "org.freedesktop.systemd1",
2273 "org.freedesktop.systemd1.Unit",
2279 return log_error_errno(r, "Failed to get LoadError: %s", bus_error_message(&error, r));
2281 r = sd_bus_message_read(
2284 &unit_load_error_name,
2285 &unit_load_error_message);
2287 return bus_log_parse_error(r);
2289 if (!isempty(unit_load_error_name)) {
2290 log_error("Unit %s is not loaded: %s", unit_name, unit_load_error_message);
2294 r = sd_bus_get_property_string(
2296 "org.freedesktop.systemd1",
2298 "org.freedesktop.systemd1.Unit",
2303 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2306 r = sd_bus_get_property_strv(
2308 "org.freedesktop.systemd1",
2310 "org.freedesktop.systemd1.Unit",
2315 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2318 _cleanup_set_free_ Set *names;
2320 names = set_new(NULL);
2324 r = set_put(names, unit_name);
2328 r = unit_file_find_path(lp, unit_name, &path);
2333 _cleanup_free_ char *template;
2335 template = unit_name_template(unit_name);
2339 if (!streq(template, unit_name)) {
2340 r = unit_file_find_path(lp, template, &path);
2347 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
2355 if (!isempty(path)) {
2356 *fragment_path = path;
2361 if (dropin_paths && !strv_isempty(dropins)) {
2362 *dropin_paths = dropins;
2368 log_error("No files found for %s.", unit_name);
2373 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2374 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2375 _cleanup_free_ char *n = NULL, *state = NULL;
2381 n = unit_name_mangle(name, MANGLE_NOGLOB);
2385 /* We don't use unit_dbus_path_from_name() directly since we
2386 * don't want to load the unit if it isn't loaded. */
2388 r = sd_bus_call_method(
2390 "org.freedesktop.systemd1",
2391 "/org/freedesktop/systemd1",
2392 "org.freedesktop.systemd1.Manager",
2403 r = sd_bus_message_read(reply, "o", &path);
2405 return bus_log_parse_error(r);
2407 r = sd_bus_get_property_string(
2409 "org.freedesktop.systemd1",
2411 "org.freedesktop.systemd1.Unit",
2424 return nulstr_contains(good_states, state);
2427 static int check_triggering_units(
2431 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2432 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2433 _cleanup_strv_free_ char **triggered_by = NULL;
2434 bool print_warning_label = true;
2438 n = unit_name_mangle(name, MANGLE_NOGLOB);
2442 path = unit_dbus_path_from_name(n);
2446 r = sd_bus_get_property_string(
2448 "org.freedesktop.systemd1",
2450 "org.freedesktop.systemd1.Unit",
2455 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2459 if (streq(state, "masked"))
2462 r = sd_bus_get_property_strv(
2464 "org.freedesktop.systemd1",
2466 "org.freedesktop.systemd1.Unit",
2471 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2475 STRV_FOREACH(i, triggered_by) {
2476 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2478 return log_error_errno(r, "Failed to check unit: %m");
2483 if (print_warning_label) {
2484 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2485 print_warning_label = false;
2488 log_warning(" %s", *i);
2494 static const struct {
2497 } unit_actions[] = {
2498 { "start", "StartUnit" },
2499 { "stop", "StopUnit" },
2500 { "condstop", "StopUnit" },
2501 { "reload", "ReloadUnit" },
2502 { "restart", "RestartUnit" },
2503 { "try-restart", "TryRestartUnit" },
2504 { "condrestart", "TryRestartUnit" },
2505 { "reload-or-restart", "ReloadOrRestartUnit" },
2506 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2507 { "condreload", "ReloadOrTryRestartUnit" },
2508 { "force-reload", "ReloadOrTryRestartUnit" }
2511 static const char *verb_to_method(const char *verb) {
2514 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2515 if (streq_ptr(unit_actions[i].verb, verb))
2516 return unit_actions[i].method;
2521 static const char *method_to_verb(const char *method) {
2524 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2525 if (streq_ptr(unit_actions[i].method, method))
2526 return unit_actions[i].verb;
2531 static int start_unit_one(
2536 sd_bus_error *error,
2537 BusWaitForJobs *w) {
2539 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2548 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2550 r = sd_bus_call_method(
2552 "org.freedesktop.systemd1",
2553 "/org/freedesktop/systemd1",
2554 "org.freedesktop.systemd1.Manager",
2562 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2563 /* There's always a fallback possible for
2564 * legacy actions. */
2565 return -EADDRNOTAVAIL;
2567 verb = method_to_verb(method);
2569 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2573 r = sd_bus_message_read(reply, "o", &path);
2575 return bus_log_parse_error(r);
2577 if (need_daemon_reload(bus, name) > 0)
2578 warn_unit_file_changed(name);
2581 log_debug("Adding %s to the set", path);
2582 r = bus_wait_for_jobs_add(w, path);
2590 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2592 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2596 STRV_FOREACH(name, names) {
2600 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2602 t = unit_name_mangle(*name, MANGLE_GLOB);
2606 if (string_is_glob(t))
2607 r = strv_consume(&globs, t);
2609 r = strv_consume(&mangled, t);
2614 /* Query the manager only if any of the names are a glob, since
2615 * this is fairly expensive */
2616 if (!strv_isempty(globs)) {
2617 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2618 _cleanup_free_ UnitInfo *unit_infos = NULL;
2621 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2623 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2627 for (i = 0; i < r; i++)
2628 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2633 mangled = NULL; /* do not free */
2638 static const struct {
2642 } action_table[_ACTION_MAX] = {
2643 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2644 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2645 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2646 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2647 [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2648 [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2649 [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" },
2650 [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" },
2651 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2652 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2653 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2654 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2655 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2656 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2657 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2660 static enum action verb_to_action(const char *verb) {
2663 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2664 if (streq_ptr(action_table[i].verb, verb))
2667 return _ACTION_INVALID;
2670 static int start_unit(sd_bus *bus, char **args) {
2671 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2672 const char *method, *mode, *one_name, *suffix = NULL;
2673 _cleanup_strv_free_ char **names = NULL;
2679 ask_password_agent_open_if_enabled();
2680 polkit_agent_open_if_enabled();
2682 if (arg_action == ACTION_SYSTEMCTL) {
2684 method = verb_to_method(args[0]);
2685 action = verb_to_action(args[0]);
2687 if (streq(args[0], "isolate")) {
2691 mode = action_table[action].mode ?: arg_job_mode;
2693 one_name = action_table[action].target;
2695 assert(arg_action < ELEMENTSOF(action_table));
2696 assert(action_table[arg_action].target);
2698 method = "StartUnit";
2700 mode = action_table[arg_action].mode;
2701 one_name = action_table[arg_action].target;
2705 names = strv_new(one_name, NULL);
2707 r = expand_names(bus, args + 1, suffix, &names);
2709 log_error_errno(r, "Failed to expand names: %m");
2712 if (!arg_no_block) {
2713 r = bus_wait_for_jobs_new(bus, &w);
2715 return log_error_errno(r, "Could not watch jobs: %m");
2718 STRV_FOREACH(name, names) {
2719 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2722 q = start_unit_one(bus, method, *name, mode, &error, w);
2723 if (r >= 0 && q < 0)
2724 r = translate_bus_error_to_exit_status(q, &error);
2727 if (!arg_no_block) {
2730 q = bus_wait_for_jobs(w, arg_quiet);
2734 /* When stopping units, warn if they can still be triggered by
2735 * another active unit (socket, path, timer) */
2736 if (!arg_quiet && streq(method, "StopUnit"))
2737 STRV_FOREACH(name, names)
2738 check_triggering_units(bus, *name);
2744 /* Ask systemd-logind, which might grant access to unprivileged users
2745 * through PolicyKit */
2746 static int reboot_with_logind(sd_bus *bus, enum action a) {
2748 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2755 polkit_agent_open_if_enabled();
2763 case ACTION_POWEROFF:
2764 method = "PowerOff";
2767 case ACTION_SUSPEND:
2771 case ACTION_HIBERNATE:
2772 method = "Hibernate";
2775 case ACTION_HYBRID_SLEEP:
2776 method = "HybridSleep";
2783 r = sd_bus_call_method(
2785 "org.freedesktop.login1",
2786 "/org/freedesktop/login1",
2787 "org.freedesktop.login1.Manager",
2791 "b", arg_ask_password);
2793 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2801 static int check_inhibitors(sd_bus *bus, enum action a) {
2803 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2804 _cleanup_strv_free_ char **sessions = NULL;
2805 const char *what, *who, *why, *mode;
2814 if (arg_ignore_inhibitors || arg_force > 0)
2826 r = sd_bus_call_method(
2828 "org.freedesktop.login1",
2829 "/org/freedesktop/login1",
2830 "org.freedesktop.login1.Manager",
2836 /* If logind is not around, then there are no inhibitors... */
2839 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2841 return bus_log_parse_error(r);
2843 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2844 _cleanup_free_ char *comm = NULL, *user = NULL;
2845 _cleanup_strv_free_ char **sv = NULL;
2847 if (!streq(mode, "block"))
2850 sv = strv_split(what, ":");
2854 if (!strv_contains(sv,
2856 a == ACTION_POWEROFF ||
2857 a == ACTION_REBOOT ||
2858 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2861 get_process_comm(pid, &comm);
2862 user = uid_to_name(uid);
2864 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2865 who, pid, strna(comm), strna(user), why);
2870 return bus_log_parse_error(r);
2872 r = sd_bus_message_exit_container(reply);
2874 return bus_log_parse_error(r);
2876 /* Check for current sessions */
2877 sd_get_sessions(&sessions);
2878 STRV_FOREACH(s, sessions) {
2879 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2881 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2884 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2887 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2890 sd_session_get_tty(*s, &tty);
2891 sd_session_get_seat(*s, &seat);
2892 sd_session_get_service(*s, &service);
2893 user = uid_to_name(uid);
2895 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2902 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2903 action_table[a].verb);
2911 static int start_special(sd_bus *bus, char **args) {
2917 a = verb_to_action(args[0]);
2919 r = check_inhibitors(bus, a);
2923 if (arg_force >= 2 && geteuid() != 0) {
2924 log_error("Must be root.");
2928 if (a == ACTION_REBOOT && args[1]) {
2929 r = update_reboot_param_file(args[1]);
2934 if (arg_force >= 2 &&
2935 (a == ACTION_HALT ||
2936 a == ACTION_POWEROFF ||
2937 a == ACTION_REBOOT))
2940 if (arg_force >= 1 &&
2941 (a == ACTION_HALT ||
2942 a == ACTION_POWEROFF ||
2943 a == ACTION_REBOOT ||
2944 a == ACTION_KEXEC ||
2946 return daemon_reload(bus, args);
2948 /* first try logind, to allow authentication with polkit */
2949 if (geteuid() != 0 &&
2950 (a == ACTION_POWEROFF ||
2951 a == ACTION_REBOOT ||
2952 a == ACTION_SUSPEND ||
2953 a == ACTION_HIBERNATE ||
2954 a == ACTION_HYBRID_SLEEP)) {
2955 r = reboot_with_logind(bus, a);
2956 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
2960 r = start_unit(bus, args);
2961 if (r == EXIT_SUCCESS)
2967 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2968 _cleanup_strv_free_ char **names = NULL;
2975 r = expand_names(bus, args, NULL, &names);
2977 return log_error_errno(r, "Failed to expand names: %m");
2979 STRV_FOREACH(name, names) {
2982 state = check_one_unit(bus, *name, good_states, arg_quiet);
2992 static int check_unit_active(sd_bus *bus, char **args) {
2993 /* According to LSB: 3, "program is not running" */
2994 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2997 static int check_unit_failed(sd_bus *bus, char **args) {
2998 return check_unit_generic(bus, 1, "failed\0", args + 1);
3001 static int kill_unit(sd_bus *bus, char **args) {
3002 _cleanup_strv_free_ char **names = NULL;
3009 polkit_agent_open_if_enabled();
3012 arg_kill_who = "all";
3014 r = expand_names(bus, args + 1, NULL, &names);
3016 log_error_errno(r, "Failed to expand names: %m");
3018 STRV_FOREACH(name, names) {
3019 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3021 q = sd_bus_call_method(
3023 "org.freedesktop.systemd1",
3024 "/org/freedesktop/systemd1",
3025 "org.freedesktop.systemd1.Manager",
3029 "ssi", *names, arg_kill_who, arg_signal);
3031 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3040 typedef struct ExecStatusInfo {
3048 usec_t start_timestamp;
3049 usec_t exit_timestamp;
3054 LIST_FIELDS(struct ExecStatusInfo, exec);
3057 static void exec_status_info_free(ExecStatusInfo *i) {
3066 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3067 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3070 int32_t code, status;
3076 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3078 return bus_log_parse_error(r);
3082 r = sd_bus_message_read(m, "s", &path);
3084 return bus_log_parse_error(r);
3086 i->path = strdup(path);
3090 r = sd_bus_message_read_strv(m, &i->argv);
3092 return bus_log_parse_error(r);
3094 r = sd_bus_message_read(m,
3097 &start_timestamp, &start_timestamp_monotonic,
3098 &exit_timestamp, &exit_timestamp_monotonic,
3102 return bus_log_parse_error(r);
3105 i->start_timestamp = (usec_t) start_timestamp;
3106 i->exit_timestamp = (usec_t) exit_timestamp;
3107 i->pid = (pid_t) pid;
3111 r = sd_bus_message_exit_container(m);
3113 return bus_log_parse_error(r);
3118 typedef struct UnitStatusInfo {
3120 const char *load_state;
3121 const char *active_state;
3122 const char *sub_state;
3123 const char *unit_file_state;
3124 const char *unit_file_preset;
3126 const char *description;
3127 const char *following;
3129 char **documentation;
3131 const char *fragment_path;
3132 const char *source_path;
3133 const char *control_group;
3135 char **dropin_paths;
3137 const char *load_error;
3140 usec_t inactive_exit_timestamp;
3141 usec_t inactive_exit_timestamp_monotonic;
3142 usec_t active_enter_timestamp;
3143 usec_t active_exit_timestamp;
3144 usec_t inactive_enter_timestamp;
3146 bool need_daemon_reload;
3151 const char *status_text;
3152 const char *pid_file;
3156 usec_t start_timestamp;
3157 usec_t exit_timestamp;
3159 int exit_code, exit_status;
3161 usec_t condition_timestamp;
3162 bool condition_result;
3163 bool failed_condition_trigger;
3164 bool failed_condition_negate;
3165 const char *failed_condition;
3166 const char *failed_condition_parameter;
3168 usec_t assert_timestamp;
3170 bool failed_assert_trigger;
3171 bool failed_assert_negate;
3172 const char *failed_assert;
3173 const char *failed_assert_parameter;
3176 unsigned n_accepted;
3177 unsigned n_connections;
3180 /* Pairs of type, path */
3184 const char *sysfs_path;
3186 /* Mount, Automount */
3193 uint64_t memory_current;
3194 uint64_t memory_limit;
3196 LIST_HEAD(ExecStatusInfo, exec);
3199 static void print_status_info(
3204 const char *active_on, *active_off, *on, *off, *ss;
3206 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3207 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3213 /* This shows pretty information about a unit. See
3214 * print_property() for a low-level property printer */
3216 if (streq_ptr(i->active_state, "failed")) {
3217 active_on = ansi_highlight_red();
3218 active_off = ansi_highlight_off();
3219 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3220 active_on = ansi_highlight_green();
3221 active_off = ansi_highlight_off();
3223 active_on = active_off = "";
3225 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3227 if (i->description && !streq_ptr(i->id, i->description))
3228 printf(" - %s", i->description);
3233 printf(" Follow: unit currently follows state of %s\n", i->following);
3235 if (streq_ptr(i->load_state, "error")) {
3236 on = ansi_highlight_red();
3237 off = ansi_highlight_off();
3241 path = i->source_path ? i->source_path : i->fragment_path;
3244 printf(" Loaded: %s%s%s (Reason: %s)\n",
3245 on, strna(i->load_state), off, i->load_error);
3246 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3247 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3248 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3249 else if (path && !isempty(i->unit_file_state))
3250 printf(" Loaded: %s%s%s (%s; %s)\n",
3251 on, strna(i->load_state), off, path, i->unit_file_state);
3253 printf(" Loaded: %s%s%s (%s)\n",
3254 on, strna(i->load_state), off, path);
3256 printf(" Loaded: %s%s%s\n",
3257 on, strna(i->load_state), off);
3259 if (!strv_isempty(i->dropin_paths)) {
3260 _cleanup_free_ char *dir = NULL;
3264 STRV_FOREACH(dropin, i->dropin_paths) {
3265 if (! dir || last) {
3266 printf(dir ? " " : " Drop-In: ");
3271 if (path_get_parent(*dropin, &dir) < 0) {
3276 printf("%s\n %s", dir,
3277 draw_special_char(DRAW_TREE_RIGHT));
3280 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3282 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3286 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3288 printf(" Active: %s%s (%s)%s",
3289 active_on, strna(i->active_state), ss, active_off);
3291 printf(" Active: %s%s%s",
3292 active_on, strna(i->active_state), active_off);
3294 if (!isempty(i->result) && !streq(i->result, "success"))
3295 printf(" (Result: %s)", i->result);
3297 timestamp = (streq_ptr(i->active_state, "active") ||
3298 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3299 (streq_ptr(i->active_state, "inactive") ||
3300 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3301 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3302 i->active_exit_timestamp;
3304 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3305 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3308 printf(" since %s; %s\n", s2, s1);
3310 printf(" since %s\n", s2);
3314 if (!i->condition_result && i->condition_timestamp > 0) {
3315 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3316 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3318 printf("Condition: start %scondition failed%s at %s%s%s\n",
3319 ansi_highlight_yellow(), ansi_highlight_off(),
3320 s2, s1 ? "; " : "", s1 ? s1 : "");
3321 if (i->failed_condition_trigger)
3322 printf(" none of the trigger conditions were met\n");
3323 else if (i->failed_condition)
3324 printf(" %s=%s%s was not met\n",
3325 i->failed_condition,
3326 i->failed_condition_negate ? "!" : "",
3327 i->failed_condition_parameter);
3330 if (!i->assert_result && i->assert_timestamp > 0) {
3331 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3332 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3334 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3335 ansi_highlight_red(), ansi_highlight_off(),
3336 s2, s1 ? "; " : "", s1 ? s1 : "");
3337 if (i->failed_assert_trigger)
3338 printf(" none of the trigger assertions were met\n");
3339 else if (i->failed_assert)
3340 printf(" %s=%s%s was not met\n",
3342 i->failed_assert_negate ? "!" : "",
3343 i->failed_assert_parameter);
3347 printf(" Device: %s\n", i->sysfs_path);
3349 printf(" Where: %s\n", i->where);
3351 printf(" What: %s\n", i->what);
3353 STRV_FOREACH(t, i->documentation)
3354 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3356 STRV_FOREACH_PAIR(t, t2, i->listen)
3357 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3360 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3362 LIST_FOREACH(exec, p, i->exec) {
3363 _cleanup_free_ char *argv = NULL;
3366 /* Only show exited processes here */
3370 argv = strv_join(p->argv, " ");
3371 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3373 good = is_clean_exit_lsb(p->code, p->status, NULL);
3375 on = ansi_highlight_red();
3376 off = ansi_highlight_off();
3380 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3382 if (p->code == CLD_EXITED) {
3385 printf("status=%i", p->status);
3387 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3392 printf("signal=%s", signal_to_string(p->status));
3394 printf(")%s\n", off);
3396 if (i->main_pid == p->pid &&
3397 i->start_timestamp == p->start_timestamp &&
3398 i->exit_timestamp == p->start_timestamp)
3399 /* Let's not show this twice */
3402 if (p->pid == i->control_pid)
3406 if (i->main_pid > 0 || i->control_pid > 0) {
3407 if (i->main_pid > 0) {
3408 printf(" Main PID: "PID_FMT, i->main_pid);
3411 _cleanup_free_ char *comm = NULL;
3412 get_process_comm(i->main_pid, &comm);
3414 printf(" (%s)", comm);
3415 } else if (i->exit_code > 0) {
3416 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3418 if (i->exit_code == CLD_EXITED) {
3421 printf("status=%i", i->exit_status);
3423 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3428 printf("signal=%s", signal_to_string(i->exit_status));
3432 if (i->control_pid > 0)
3436 if (i->control_pid > 0) {
3437 _cleanup_free_ char *c = NULL;
3439 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3441 get_process_comm(i->control_pid, &c);
3450 printf(" Status: \"%s\"\n", i->status_text);
3451 if (i->status_errno > 0)
3452 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3454 if (i->memory_current != (uint64_t) -1) {
3455 char buf[FORMAT_BYTES_MAX];
3457 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3459 if (i->memory_limit != (uint64_t) -1)
3460 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3465 if (i->control_group &&
3466 (i->main_pid > 0 || i->control_pid > 0 ||
3467 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3470 printf(" CGroup: %s\n", i->control_group);
3472 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3475 static const char prefix[] = " ";
3478 if (c > sizeof(prefix) - 1)
3479 c -= sizeof(prefix) - 1;
3483 if (i->main_pid > 0)
3484 extra[k++] = i->main_pid;
3486 if (i->control_pid > 0)
3487 extra[k++] = i->control_pid;
3489 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3493 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3494 show_journal_by_unit(
3499 i->inactive_exit_timestamp_monotonic,
3502 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3503 SD_JOURNAL_LOCAL_ONLY,
3504 arg_scope == UNIT_FILE_SYSTEM,
3508 if (i->need_daemon_reload)
3509 warn_unit_file_changed(i->id);
3512 static void show_unit_help(UnitStatusInfo *i) {
3517 if (!i->documentation) {
3518 log_info("Documentation for %s not known.", i->id);
3522 STRV_FOREACH(p, i->documentation)
3523 if (startswith(*p, "man:"))
3524 show_man_page(*p + 4, false);
3526 log_info("Can't show: %s", *p);
3529 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3536 switch (contents[0]) {
3538 case SD_BUS_TYPE_STRING: {
3541 r = sd_bus_message_read(m, "s", &s);
3543 return bus_log_parse_error(r);
3546 if (streq(name, "Id"))
3548 else if (streq(name, "LoadState"))
3550 else if (streq(name, "ActiveState"))
3551 i->active_state = s;
3552 else if (streq(name, "SubState"))
3554 else if (streq(name, "Description"))
3556 else if (streq(name, "FragmentPath"))
3557 i->fragment_path = s;
3558 else if (streq(name, "SourcePath"))
3561 else if (streq(name, "DefaultControlGroup")) {
3563 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3565 i->control_group = e;
3568 else if (streq(name, "ControlGroup"))
3569 i->control_group = s;
3570 else if (streq(name, "StatusText"))
3572 else if (streq(name, "PIDFile"))
3574 else if (streq(name, "SysFSPath"))
3576 else if (streq(name, "Where"))
3578 else if (streq(name, "What"))
3580 else if (streq(name, "Following"))
3582 else if (streq(name, "UnitFileState"))
3583 i->unit_file_state = s;
3584 else if (streq(name, "UnitFilePreset"))
3585 i->unit_file_preset = s;
3586 else if (streq(name, "Result"))
3593 case SD_BUS_TYPE_BOOLEAN: {
3596 r = sd_bus_message_read(m, "b", &b);
3598 return bus_log_parse_error(r);
3600 if (streq(name, "Accept"))
3602 else if (streq(name, "NeedDaemonReload"))
3603 i->need_daemon_reload = b;
3604 else if (streq(name, "ConditionResult"))
3605 i->condition_result = b;
3606 else if (streq(name, "AssertResult"))
3607 i->assert_result = b;
3612 case SD_BUS_TYPE_UINT32: {
3615 r = sd_bus_message_read(m, "u", &u);
3617 return bus_log_parse_error(r);
3619 if (streq(name, "MainPID")) {
3621 i->main_pid = (pid_t) u;
3624 } else if (streq(name, "ControlPID"))
3625 i->control_pid = (pid_t) u;
3626 else if (streq(name, "ExecMainPID")) {
3628 i->main_pid = (pid_t) u;
3629 } else if (streq(name, "NAccepted"))
3631 else if (streq(name, "NConnections"))
3632 i->n_connections = u;
3637 case SD_BUS_TYPE_INT32: {
3640 r = sd_bus_message_read(m, "i", &j);
3642 return bus_log_parse_error(r);
3644 if (streq(name, "ExecMainCode"))
3645 i->exit_code = (int) j;
3646 else if (streq(name, "ExecMainStatus"))
3647 i->exit_status = (int) j;
3648 else if (streq(name, "StatusErrno"))
3649 i->status_errno = (int) j;
3654 case SD_BUS_TYPE_UINT64: {
3657 r = sd_bus_message_read(m, "t", &u);
3659 return bus_log_parse_error(r);
3661 if (streq(name, "ExecMainStartTimestamp"))
3662 i->start_timestamp = (usec_t) u;
3663 else if (streq(name, "ExecMainExitTimestamp"))
3664 i->exit_timestamp = (usec_t) u;
3665 else if (streq(name, "ActiveEnterTimestamp"))
3666 i->active_enter_timestamp = (usec_t) u;
3667 else if (streq(name, "InactiveEnterTimestamp"))
3668 i->inactive_enter_timestamp = (usec_t) u;
3669 else if (streq(name, "InactiveExitTimestamp"))
3670 i->inactive_exit_timestamp = (usec_t) u;
3671 else if (streq(name, "InactiveExitTimestampMonotonic"))
3672 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3673 else if (streq(name, "ActiveExitTimestamp"))
3674 i->active_exit_timestamp = (usec_t) u;
3675 else if (streq(name, "ConditionTimestamp"))
3676 i->condition_timestamp = (usec_t) u;
3677 else if (streq(name, "AssertTimestamp"))
3678 i->assert_timestamp = (usec_t) u;
3679 else if (streq(name, "MemoryCurrent"))
3680 i->memory_current = u;
3681 else if (streq(name, "MemoryLimit"))
3682 i->memory_limit = u;
3687 case SD_BUS_TYPE_ARRAY:
3689 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3690 _cleanup_free_ ExecStatusInfo *info = NULL;
3692 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3694 return bus_log_parse_error(r);
3696 info = new0(ExecStatusInfo, 1);
3700 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3702 info->name = strdup(name);
3706 LIST_PREPEND(exec, i->exec, info);
3708 info = new0(ExecStatusInfo, 1);
3714 return bus_log_parse_error(r);
3716 r = sd_bus_message_exit_container(m);
3718 return bus_log_parse_error(r);
3722 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3723 const char *type, *path;
3725 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3727 return bus_log_parse_error(r);
3729 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3731 r = strv_extend(&i->listen, type);
3735 r = strv_extend(&i->listen, path);
3740 return bus_log_parse_error(r);
3742 r = sd_bus_message_exit_container(m);
3744 return bus_log_parse_error(r);
3748 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3750 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3752 return bus_log_parse_error(r);
3754 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3756 r = sd_bus_message_read_strv(m, &i->documentation);
3758 return bus_log_parse_error(r);
3760 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3761 const char *cond, *param;
3762 int trigger, negate;
3765 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3767 return bus_log_parse_error(r);
3769 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3770 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3771 if (state < 0 && (!trigger || !i->failed_condition)) {
3772 i->failed_condition = cond;
3773 i->failed_condition_trigger = trigger;
3774 i->failed_condition_negate = negate;
3775 i->failed_condition_parameter = param;
3779 return bus_log_parse_error(r);
3781 r = sd_bus_message_exit_container(m);
3783 return bus_log_parse_error(r);
3785 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3786 const char *cond, *param;
3787 int trigger, negate;
3790 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3792 return bus_log_parse_error(r);
3794 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3795 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3796 if (state < 0 && (!trigger || !i->failed_assert)) {
3797 i->failed_assert = cond;
3798 i->failed_assert_trigger = trigger;
3799 i->failed_assert_negate = negate;
3800 i->failed_assert_parameter = param;
3804 return bus_log_parse_error(r);
3806 r = sd_bus_message_exit_container(m);
3808 return bus_log_parse_error(r);
3815 case SD_BUS_TYPE_STRUCT_BEGIN:
3817 if (streq(name, "LoadError")) {
3818 const char *n, *message;
3820 r = sd_bus_message_read(m, "(ss)", &n, &message);
3822 return bus_log_parse_error(r);
3824 if (!isempty(message))
3825 i->load_error = message;
3838 r = sd_bus_message_skip(m, contents);
3840 return bus_log_parse_error(r);
3845 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3851 /* This is a low-level property printer, see
3852 * print_status_info() for the nicer output */
3854 if (arg_properties && !strv_find(arg_properties, name)) {
3855 /* skip what we didn't read */
3856 r = sd_bus_message_skip(m, contents);
3860 switch (contents[0]) {
3862 case SD_BUS_TYPE_STRUCT_BEGIN:
3864 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3867 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3869 return bus_log_parse_error(r);
3872 printf("%s=%"PRIu32"\n", name, u);
3874 printf("%s=\n", name);
3878 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3881 r = sd_bus_message_read(m, "(so)", &s, NULL);
3883 return bus_log_parse_error(r);
3885 if (arg_all || !isempty(s))
3886 printf("%s=%s\n", name, s);
3890 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3891 const char *a = NULL, *b = NULL;
3893 r = sd_bus_message_read(m, "(ss)", &a, &b);
3895 return bus_log_parse_error(r);
3897 if (arg_all || !isempty(a) || !isempty(b))
3898 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3901 } else if (streq_ptr(name, "SystemCallFilter")) {
3902 _cleanup_strv_free_ char **l = NULL;
3905 r = sd_bus_message_enter_container(m, 'r', "bas");
3907 return bus_log_parse_error(r);
3909 r = sd_bus_message_read(m, "b", &whitelist);
3911 return bus_log_parse_error(r);
3913 r = sd_bus_message_read_strv(m, &l);
3915 return bus_log_parse_error(r);
3917 r = sd_bus_message_exit_container(m);
3919 return bus_log_parse_error(r);
3921 if (arg_all || whitelist || !strv_isempty(l)) {
3925 fputs(name, stdout);
3931 STRV_FOREACH(i, l) {
3939 fputc('\n', stdout);
3947 case SD_BUS_TYPE_ARRAY:
3949 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3953 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3955 return bus_log_parse_error(r);
3957 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3958 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3961 return bus_log_parse_error(r);
3963 r = sd_bus_message_exit_container(m);
3965 return bus_log_parse_error(r);
3969 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3970 const char *type, *path;
3972 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3974 return bus_log_parse_error(r);
3976 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3977 printf("%s=%s\n", type, path);
3979 return bus_log_parse_error(r);
3981 r = sd_bus_message_exit_container(m);
3983 return bus_log_parse_error(r);
3987 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3988 const char *type, *path;
3990 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3992 return bus_log_parse_error(r);
3994 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3995 printf("Listen%s=%s\n", type, path);
3997 return bus_log_parse_error(r);
3999 r = sd_bus_message_exit_container(m);
4001 return bus_log_parse_error(r);
4005 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4007 uint64_t value, next_elapse;
4009 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4011 return bus_log_parse_error(r);
4013 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4014 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4016 printf("%s={ value=%s ; next_elapse=%s }\n",
4018 format_timespan(timespan1, sizeof(timespan1), value, 0),
4019 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4022 return bus_log_parse_error(r);
4024 r = sd_bus_message_exit_container(m);
4026 return bus_log_parse_error(r);
4030 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4031 ExecStatusInfo info = {};
4033 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4035 return bus_log_parse_error(r);
4037 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4038 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4039 _cleanup_free_ char *tt;
4041 tt = strv_join(info.argv, " ");
4043 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",
4047 yes_no(info.ignore),
4048 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4049 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4051 sigchld_code_to_string(info.code),
4053 info.code == CLD_EXITED ? "" : "/",
4054 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4057 strv_free(info.argv);
4061 r = sd_bus_message_exit_container(m);
4063 return bus_log_parse_error(r);
4067 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4068 const char *path, *rwm;
4070 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4072 return bus_log_parse_error(r);
4074 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4075 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4077 return bus_log_parse_error(r);
4079 r = sd_bus_message_exit_container(m);
4081 return bus_log_parse_error(r);
4085 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4089 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4091 return bus_log_parse_error(r);
4093 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4094 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4096 return bus_log_parse_error(r);
4098 r = sd_bus_message_exit_container(m);
4100 return bus_log_parse_error(r);
4104 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4108 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4110 return bus_log_parse_error(r);
4112 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4113 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4115 return bus_log_parse_error(r);
4117 r = sd_bus_message_exit_container(m);
4119 return bus_log_parse_error(r);
4127 r = bus_print_property(name, m, arg_all);
4129 return bus_log_parse_error(r);
4132 r = sd_bus_message_skip(m, contents);
4134 return bus_log_parse_error(r);
4137 printf("%s=[unprintable]\n", name);
4143 static int show_one(
4147 bool show_properties,
4151 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4152 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4153 UnitStatusInfo info = {
4154 .memory_current = (uint64_t) -1,
4155 .memory_limit = (uint64_t) -1,
4163 log_debug("Showing one %s", path);
4165 r = sd_bus_call_method(
4167 "org.freedesktop.systemd1",
4169 "org.freedesktop.DBus.Properties",
4175 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4179 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4181 return bus_log_parse_error(r);
4188 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4189 const char *name, *contents;
4191 r = sd_bus_message_read(reply, "s", &name);
4193 return bus_log_parse_error(r);
4195 r = sd_bus_message_peek_type(reply, NULL, &contents);
4197 return bus_log_parse_error(r);
4199 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4201 return bus_log_parse_error(r);
4203 if (show_properties)
4204 r = print_property(name, reply, contents);
4206 r = status_property(name, reply, &info, contents);
4210 r = sd_bus_message_exit_container(reply);
4212 return bus_log_parse_error(r);
4214 r = sd_bus_message_exit_container(reply);
4216 return bus_log_parse_error(r);
4219 return bus_log_parse_error(r);
4221 r = sd_bus_message_exit_container(reply);
4223 return bus_log_parse_error(r);
4227 if (!show_properties) {
4228 if (streq(verb, "help"))
4229 show_unit_help(&info);
4231 print_status_info(&info, ellipsized);
4234 strv_free(info.documentation);
4235 strv_free(info.dropin_paths);
4236 strv_free(info.listen);
4238 if (!streq_ptr(info.active_state, "active") &&
4239 !streq_ptr(info.active_state, "reloading") &&
4240 streq(verb, "status")) {
4241 /* According to LSB: "program not running" */
4242 /* 0: program is running or service is OK
4243 * 1: program is dead and /run PID file exists
4244 * 2: program is dead and /run/lock lock file exists
4245 * 3: program is not running
4246 * 4: program or service status is unknown
4248 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4254 while ((p = info.exec)) {
4255 LIST_REMOVE(exec, info.exec, p);
4256 exec_status_info_free(p);
4262 static int get_unit_dbus_path_by_pid(
4267 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4268 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4272 r = sd_bus_call_method(
4274 "org.freedesktop.systemd1",
4275 "/org/freedesktop/systemd1",
4276 "org.freedesktop.systemd1.Manager",
4282 log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4286 r = sd_bus_message_read(reply, "o", &u);
4288 return bus_log_parse_error(r);
4298 static int show_all(
4301 bool show_properties,
4305 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4306 _cleanup_free_ UnitInfo *unit_infos = NULL;
4311 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4315 pager_open_if_enabled();
4319 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4321 for (u = unit_infos; u < unit_infos + c; u++) {
4322 _cleanup_free_ char *p = NULL;
4324 p = unit_dbus_path_from_name(u->id);
4328 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4331 else if (r > 0 && ret == 0)
4338 static int show_system_status(sd_bus *bus) {
4339 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4340 _cleanup_free_ char *hn = NULL;
4341 struct machine_info mi = {};
4342 const char *on, *off;
4345 hn = gethostname_malloc();
4349 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4351 return log_error_errno(r, "Failed to read server status: %m");
4353 if (streq_ptr(mi.state, "degraded")) {
4354 on = ansi_highlight_red();
4355 off = ansi_highlight_off();
4356 } else if (!streq_ptr(mi.state, "running")) {
4357 on = ansi_highlight_yellow();
4358 off = ansi_highlight_off();
4362 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4364 printf(" State: %s%s%s\n",
4365 on, strna(mi.state), off);
4367 printf(" Jobs: %u queued\n", mi.n_jobs);
4368 printf(" Failed: %u units\n", mi.n_failed_units);
4370 printf(" Since: %s; %s\n",
4371 format_timestamp(since2, sizeof(since2), mi.timestamp),
4372 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4374 printf(" CGroup: %s\n", mi.control_group ?: "/");
4375 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4376 static const char prefix[] = " ";
4380 if (c > sizeof(prefix) - 1)
4381 c -= sizeof(prefix) - 1;
4385 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4389 free(mi.control_group);
4394 static int show(sd_bus *bus, char **args) {
4395 bool show_properties, show_status, new_line = false;
4396 bool ellipsized = false;
4402 show_properties = streq(args[0], "show");
4403 show_status = streq(args[0], "status");
4405 if (show_properties)
4406 pager_open_if_enabled();
4408 /* If no argument is specified inspect the manager itself */
4410 if (show_properties && strv_length(args) <= 1)
4411 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4413 if (show_status && strv_length(args) <= 1) {
4415 pager_open_if_enabled();
4416 show_system_status(bus);
4420 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4422 _cleanup_free_ char **patterns = NULL;
4425 STRV_FOREACH(name, args + 1) {
4426 _cleanup_free_ char *unit = NULL;
4429 if (safe_atou32(*name, &id) < 0) {
4430 if (strv_push(&patterns, *name) < 0)
4434 } else if (show_properties) {
4435 /* Interpret as job id */
4436 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4440 /* Interpret as PID */
4441 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4448 r = show_one(args[0], bus, unit, show_properties,
4449 &new_line, &ellipsized);
4452 else if (r > 0 && ret == 0)
4456 if (!strv_isempty(patterns)) {
4457 _cleanup_strv_free_ char **names = NULL;
4459 r = expand_names(bus, patterns, NULL, &names);
4461 log_error_errno(r, "Failed to expand names: %m");
4463 STRV_FOREACH(name, names) {
4464 _cleanup_free_ char *unit;
4466 unit = unit_dbus_path_from_name(*name);
4470 r = show_one(args[0], bus, unit, show_properties,
4471 &new_line, &ellipsized);
4474 else if (r > 0 && ret == 0)
4480 if (ellipsized && !arg_quiet)
4481 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4486 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4490 assert(user_runtime);
4493 if (arg_scope == UNIT_FILE_USER) {
4494 r = user_config_home(user_home);
4496 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4498 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4500 r = user_runtime_dir(user_runtime);
4502 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4504 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4507 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4509 return log_error_errno(r, "Failed to query unit lookup paths: %m");
4514 static int cat(sd_bus *bus, char **args) {
4515 _cleanup_free_ char *user_home = NULL;
4516 _cleanup_free_ char *user_runtime = NULL;
4517 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4518 _cleanup_strv_free_ char **names = NULL;
4520 bool first = true, avoid_bus_cache;
4525 if (arg_transport != BUS_TRANSPORT_LOCAL) {
4526 log_error("Cannot remotely cat units");
4530 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4534 r = expand_names(bus, args + 1, NULL, &names);
4536 return log_error_errno(r, "Failed to expand names: %m");
4538 avoid_bus_cache = !bus || avoid_bus();
4540 pager_open_if_enabled();
4542 STRV_FOREACH(name, names) {
4543 _cleanup_free_ char *fragment_path = NULL;
4544 _cleanup_strv_free_ char **dropin_paths = NULL;
4547 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4558 if (fragment_path) {
4559 printf("%s# %s%s\n",
4560 ansi_highlight_blue(),
4562 ansi_highlight_off());
4565 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4567 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4572 STRV_FOREACH(path, dropin_paths) {
4573 printf("%s%s# %s%s\n",
4574 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4575 ansi_highlight_blue(),
4577 ansi_highlight_off());
4580 r = copy_file_fd(*path, STDOUT_FILENO, false);
4582 log_warning_errno(r, "Failed to cat %s: %m", *path);
4588 return r < 0 ? r : 0;
4591 static int set_property(sd_bus *bus, char **args) {
4592 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4593 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4594 _cleanup_free_ char *n = NULL;
4598 polkit_agent_open_if_enabled();
4600 r = sd_bus_message_new_method_call(
4603 "org.freedesktop.systemd1",
4604 "/org/freedesktop/systemd1",
4605 "org.freedesktop.systemd1.Manager",
4606 "SetUnitProperties");
4608 return bus_log_create_error(r);
4610 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4614 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4616 return bus_log_create_error(r);
4618 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4620 return bus_log_create_error(r);
4622 STRV_FOREACH(i, args + 2) {
4623 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4625 return bus_log_create_error(r);
4627 r = bus_append_unit_property_assignment(m, *i);
4631 r = sd_bus_message_close_container(m);
4633 return bus_log_create_error(r);
4636 r = sd_bus_message_close_container(m);
4638 return bus_log_create_error(r);
4640 r = sd_bus_call(bus, m, 0, &error, NULL);
4642 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4649 static int snapshot(sd_bus *bus, char **args) {
4650 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4651 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4652 _cleanup_free_ char *n = NULL, *id = NULL;
4656 polkit_agent_open_if_enabled();
4658 if (strv_length(args) > 1)
4659 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4665 r = sd_bus_call_method(
4667 "org.freedesktop.systemd1",
4668 "/org/freedesktop/systemd1",
4669 "org.freedesktop.systemd1.Manager",
4675 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4679 r = sd_bus_message_read(reply, "o", &path);
4681 return bus_log_parse_error(r);
4683 r = sd_bus_get_property_string(
4685 "org.freedesktop.systemd1",
4687 "org.freedesktop.systemd1.Unit",
4692 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4702 static int delete_snapshot(sd_bus *bus, char **args) {
4703 _cleanup_strv_free_ char **names = NULL;
4709 polkit_agent_open_if_enabled();
4711 r = expand_names(bus, args + 1, ".snapshot", &names);
4713 log_error_errno(r, "Failed to expand names: %m");
4715 STRV_FOREACH(name, names) {
4716 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4719 q = sd_bus_call_method(
4721 "org.freedesktop.systemd1",
4722 "/org/freedesktop/systemd1",
4723 "org.freedesktop.systemd1.Manager",
4729 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4738 static int daemon_reload(sd_bus *bus, char **args) {
4739 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4743 polkit_agent_open_if_enabled();
4745 if (arg_action == ACTION_RELOAD)
4747 else if (arg_action == ACTION_REEXEC)
4748 method = "Reexecute";
4750 assert(arg_action == ACTION_SYSTEMCTL);
4753 streq(args[0], "clear-jobs") ||
4754 streq(args[0], "cancel") ? "ClearJobs" :
4755 streq(args[0], "daemon-reexec") ? "Reexecute" :
4756 streq(args[0], "reset-failed") ? "ResetFailed" :
4757 streq(args[0], "halt") ? "Halt" :
4758 streq(args[0], "poweroff") ? "PowerOff" :
4759 streq(args[0], "reboot") ? "Reboot" :
4760 streq(args[0], "kexec") ? "KExec" :
4761 streq(args[0], "exit") ? "Exit" :
4762 /* "daemon-reload" */ "Reload";
4765 r = sd_bus_call_method(
4767 "org.freedesktop.systemd1",
4768 "/org/freedesktop/systemd1",
4769 "org.freedesktop.systemd1.Manager",
4774 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4775 /* There's always a fallback possible for
4776 * legacy actions. */
4778 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4779 /* On reexecution, we expect a disconnect, not a
4783 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4785 return r < 0 ? r : 0;
4788 static int reset_failed(sd_bus *bus, char **args) {
4789 _cleanup_strv_free_ char **names = NULL;
4793 if (strv_length(args) <= 1)
4794 return daemon_reload(bus, args);
4796 polkit_agent_open_if_enabled();
4798 r = expand_names(bus, args + 1, NULL, &names);
4800 log_error_errno(r, "Failed to expand names: %m");
4802 STRV_FOREACH(name, names) {
4803 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4805 q = sd_bus_call_method(
4807 "org.freedesktop.systemd1",
4808 "/org/freedesktop/systemd1",
4809 "org.freedesktop.systemd1.Manager",
4815 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4824 static int show_environment(sd_bus *bus, char **args) {
4825 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4826 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4830 pager_open_if_enabled();
4832 r = sd_bus_get_property(
4834 "org.freedesktop.systemd1",
4835 "/org/freedesktop/systemd1",
4836 "org.freedesktop.systemd1.Manager",
4842 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4846 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4848 return bus_log_parse_error(r);
4850 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4853 return bus_log_parse_error(r);
4855 r = sd_bus_message_exit_container(reply);
4857 return bus_log_parse_error(r);
4862 static int switch_root(sd_bus *bus, char **args) {
4863 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4864 _cleanup_free_ char *cmdline_init = NULL;
4865 const char *root, *init;
4869 l = strv_length(args);
4870 if (l < 2 || l > 3) {
4871 log_error("Wrong number of arguments.");
4880 r = parse_env_file("/proc/cmdline", WHITESPACE,
4881 "init", &cmdline_init,
4884 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4886 init = cmdline_init;
4893 const char *root_systemd_path = NULL, *root_init_path = NULL;
4895 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
4896 root_init_path = strjoina(root, "/", init);
4898 /* If the passed init is actually the same as the
4899 * systemd binary, then let's suppress it. */
4900 if (files_same(root_init_path, root_systemd_path) > 0)
4904 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4906 r = sd_bus_call_method(
4908 "org.freedesktop.systemd1",
4909 "/org/freedesktop/systemd1",
4910 "org.freedesktop.systemd1.Manager",
4916 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4923 static int set_environment(sd_bus *bus, char **args) {
4924 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4925 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4932 polkit_agent_open_if_enabled();
4934 method = streq(args[0], "set-environment")
4936 : "UnsetEnvironment";
4938 r = sd_bus_message_new_method_call(
4941 "org.freedesktop.systemd1",
4942 "/org/freedesktop/systemd1",
4943 "org.freedesktop.systemd1.Manager",
4946 return bus_log_create_error(r);
4948 r = sd_bus_message_append_strv(m, args + 1);
4950 return bus_log_create_error(r);
4952 r = sd_bus_call(bus, m, 0, &error, NULL);
4954 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4961 static int import_environment(sd_bus *bus, char **args) {
4962 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4963 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4969 polkit_agent_open_if_enabled();
4971 r = sd_bus_message_new_method_call(
4974 "org.freedesktop.systemd1",
4975 "/org/freedesktop/systemd1",
4976 "org.freedesktop.systemd1.Manager",
4979 return bus_log_create_error(r);
4981 if (strv_isempty(args + 1))
4982 r = sd_bus_message_append_strv(m, environ);
4986 r = sd_bus_message_open_container(m, 'a', "s");
4988 return bus_log_create_error(r);
4990 STRV_FOREACH(a, args + 1) {
4992 if (!env_name_is_valid(*a)) {
4993 log_error("Not a valid environment variable name: %s", *a);
4997 STRV_FOREACH(b, environ) {
5000 eq = startswith(*b, *a);
5001 if (eq && *eq == '=') {
5003 r = sd_bus_message_append(m, "s", *b);
5005 return bus_log_create_error(r);
5012 r = sd_bus_message_close_container(m);
5015 return bus_log_create_error(r);
5017 r = sd_bus_call(bus, m, 0, &error, NULL);
5019 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5026 static int enable_sysv_units(const char *verb, char **args) {
5029 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5031 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5033 if (arg_scope != UNIT_FILE_SYSTEM)
5036 if (!streq(verb, "enable") &&
5037 !streq(verb, "disable") &&
5038 !streq(verb, "is-enabled"))
5041 /* Processes all SysV units, and reshuffles the array so that
5042 * afterwards only the native units remain */
5044 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5051 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5052 bool found_native = false, found_sysv;
5054 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5062 if (!endswith(name, ".service"))
5065 if (path_is_absolute(name))
5068 STRV_FOREACH(k, paths.unit_path) {
5069 _cleanup_free_ char *path = NULL;
5071 path = path_join(arg_root, *k, name);
5075 found_native = access(path, F_OK) >= 0;
5083 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5087 p[strlen(p) - strlen(".service")] = 0;
5088 found_sysv = access(p, F_OK) >= 0;
5092 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5094 if (!isempty(arg_root))
5095 argv[c++] = q = strappend("--root=", arg_root);
5097 argv[c++] = basename(p);
5099 streq(verb, "enable") ? "on" :
5100 streq(verb, "disable") ? "off" : "--level=5";
5103 l = strv_join((char**)argv, " ");
5107 log_info("Executing %s", l);
5111 return log_error_errno(errno, "Failed to fork: %m");
5112 else if (pid == 0) {
5115 execv(argv[0], (char**) argv);
5116 _exit(EXIT_FAILURE);
5119 j = wait_for_terminate(pid, &status);
5121 log_error_errno(r, "Failed to wait for child: %m");
5125 if (status.si_code == CLD_EXITED) {
5126 if (streq(verb, "is-enabled")) {
5127 if (status.si_status == 0) {
5136 } else if (status.si_status != 0)
5141 /* Remove this entry, so that we don't try enabling it as native unit */
5144 assert(args[f] == name);
5145 strv_remove(args, name);
5152 static int mangle_names(char **original_names, char ***mangled_names) {
5153 char **i, **l, **name;
5155 l = new(char*, strv_length(original_names) + 1);
5160 STRV_FOREACH(name, original_names) {
5162 /* When enabling units qualified path names are OK,
5163 * too, hence allow them explicitly. */
5168 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5184 static int enable_unit(sd_bus *bus, char **args) {
5185 _cleanup_strv_free_ char **names = NULL;
5186 const char *verb = args[0];
5187 UnitFileChange *changes = NULL;
5188 unsigned n_changes = 0;
5189 int carries_install_info = -1;
5195 r = mangle_names(args+1, &names);
5199 r = enable_sysv_units(verb, names);
5203 /* If the operation was fully executed by the SysV compat,
5204 * let's finish early */
5205 if (strv_isempty(names))
5208 if (!bus || avoid_bus()) {
5209 if (streq(verb, "enable")) {
5210 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5211 carries_install_info = r;
5212 } else if (streq(verb, "disable"))
5213 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5214 else if (streq(verb, "reenable")) {
5215 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5216 carries_install_info = r;
5217 } else if (streq(verb, "link"))
5218 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5219 else if (streq(verb, "preset")) {
5220 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5221 carries_install_info = r;
5222 } else if (streq(verb, "mask"))
5223 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5224 else if (streq(verb, "unmask"))
5225 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5227 assert_not_reached("Unknown verb");
5230 log_error_errno(r, "Operation failed: %m");
5235 dump_unit_file_changes(changes, n_changes);
5239 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5240 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5241 int expect_carries_install_info = false;
5242 bool send_force = true, send_preset_mode = false;
5245 polkit_agent_open_if_enabled();
5247 if (streq(verb, "enable")) {
5248 method = "EnableUnitFiles";
5249 expect_carries_install_info = true;
5250 } else if (streq(verb, "disable")) {
5251 method = "DisableUnitFiles";
5253 } else if (streq(verb, "reenable")) {
5254 method = "ReenableUnitFiles";
5255 expect_carries_install_info = true;
5256 } else if (streq(verb, "link"))
5257 method = "LinkUnitFiles";
5258 else if (streq(verb, "preset")) {
5260 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5261 method = "PresetUnitFilesWithMode";
5262 send_preset_mode = true;
5264 method = "PresetUnitFiles";
5266 expect_carries_install_info = true;
5267 } else if (streq(verb, "mask"))
5268 method = "MaskUnitFiles";
5269 else if (streq(verb, "unmask")) {
5270 method = "UnmaskUnitFiles";
5273 assert_not_reached("Unknown verb");
5275 r = sd_bus_message_new_method_call(
5278 "org.freedesktop.systemd1",
5279 "/org/freedesktop/systemd1",
5280 "org.freedesktop.systemd1.Manager",
5283 return bus_log_create_error(r);
5285 r = sd_bus_message_append_strv(m, names);
5287 return bus_log_create_error(r);
5289 if (send_preset_mode) {
5290 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5292 return bus_log_create_error(r);
5295 r = sd_bus_message_append(m, "b", arg_runtime);
5297 return bus_log_create_error(r);
5300 r = sd_bus_message_append(m, "b", arg_force);
5302 return bus_log_create_error(r);
5305 r = sd_bus_call(bus, m, 0, &error, &reply);
5307 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5311 if (expect_carries_install_info) {
5312 r = sd_bus_message_read(reply, "b", &carries_install_info);
5314 return bus_log_parse_error(r);
5317 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5321 /* Try to reload if enabled */
5323 r = daemon_reload(bus, args);
5328 if (carries_install_info == 0)
5329 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5330 "using systemctl.\n"
5331 "Possible reasons for having this kind of units are:\n"
5332 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5333 " .wants/ or .requires/ directory.\n"
5334 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5335 " a requirement dependency on it.\n"
5336 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5337 " D-Bus, udev, scripted systemctl call, ...).\n");
5340 unit_file_changes_free(changes, n_changes);
5345 static int add_dependency(sd_bus *bus, char **args) {
5346 _cleanup_strv_free_ char **names = NULL;
5347 _cleanup_free_ char *target = NULL;
5348 const char *verb = args[0];
5355 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5359 r = mangle_names(args+2, &names);
5363 if (streq(verb, "add-wants"))
5365 else if (streq(verb, "add-requires"))
5366 dep = UNIT_REQUIRES;
5368 assert_not_reached("Unknown verb");
5370 if (!bus || avoid_bus()) {
5371 UnitFileChange *changes = NULL;
5372 unsigned n_changes = 0;
5374 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5377 return log_error_errno(r, "Can't add dependency: %m");
5380 dump_unit_file_changes(changes, n_changes);
5382 unit_file_changes_free(changes, n_changes);
5385 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5386 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5388 polkit_agent_open_if_enabled();
5390 r = sd_bus_message_new_method_call(
5393 "org.freedesktop.systemd1",
5394 "/org/freedesktop/systemd1",
5395 "org.freedesktop.systemd1.Manager",
5396 "AddDependencyUnitFiles");
5398 return bus_log_create_error(r);
5400 r = sd_bus_message_append_strv(m, names);
5402 return bus_log_create_error(r);
5404 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5406 return bus_log_create_error(r);
5408 r = sd_bus_call(bus, m, 0, &error, &reply);
5410 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5414 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5419 r = daemon_reload(bus, args);
5427 static int preset_all(sd_bus *bus, char **args) {
5428 UnitFileChange *changes = NULL;
5429 unsigned n_changes = 0;
5432 if (!bus || avoid_bus()) {
5434 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5436 log_error_errno(r, "Operation failed: %m");
5441 dump_unit_file_changes(changes, n_changes);
5446 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5447 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5449 polkit_agent_open_if_enabled();
5451 r = sd_bus_call_method(
5453 "org.freedesktop.systemd1",
5454 "/org/freedesktop/systemd1",
5455 "org.freedesktop.systemd1.Manager",
5456 "PresetAllUnitFiles",
5460 unit_file_preset_mode_to_string(arg_preset_mode),
5464 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5468 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5473 r = daemon_reload(bus, args);
5479 unit_file_changes_free(changes, n_changes);
5484 static int unit_is_enabled(sd_bus *bus, char **args) {
5486 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5487 _cleanup_strv_free_ char **names = NULL;
5492 r = mangle_names(args+1, &names);
5496 r = enable_sysv_units(args[0], names);
5502 if (!bus || avoid_bus()) {
5504 STRV_FOREACH(name, names) {
5505 UnitFileState state;
5507 state = unit_file_get_state(arg_scope, arg_root, *name);
5509 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5511 if (state == UNIT_FILE_ENABLED ||
5512 state == UNIT_FILE_ENABLED_RUNTIME ||
5513 state == UNIT_FILE_STATIC ||
5514 state == UNIT_FILE_INDIRECT)
5518 puts(unit_file_state_to_string(state));
5522 STRV_FOREACH(name, names) {
5523 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5526 r = sd_bus_call_method(
5528 "org.freedesktop.systemd1",
5529 "/org/freedesktop/systemd1",
5530 "org.freedesktop.systemd1.Manager",
5536 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5540 r = sd_bus_message_read(reply, "s", &s);
5542 return bus_log_parse_error(r);
5544 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5555 static int is_system_running(sd_bus *bus, char **args) {
5556 _cleanup_free_ char *state = NULL;
5559 r = sd_bus_get_property_string(
5561 "org.freedesktop.systemd1",
5562 "/org/freedesktop/systemd1",
5563 "org.freedesktop.systemd1.Manager",
5576 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5579 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5584 assert(original_path);
5587 r = tempfn_random(new_path, &t);
5589 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5591 r = mkdir_parents(new_path, 0755);
5593 log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5598 r = copy_file(original_path, t, 0, 0644, 0);
5602 log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5607 log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5617 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5618 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5620 switch (arg_scope) {
5621 case UNIT_FILE_SYSTEM:
5622 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5624 run = path_join(arg_root, "/run/systemd/system/", name);
5626 case UNIT_FILE_GLOBAL:
5627 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5629 run = path_join(arg_root, "/run/systemd/user/", name);
5631 case UNIT_FILE_USER:
5633 assert(user_runtime);
5635 path = path_join(arg_root, user_home, name);
5637 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5640 run = path_join(arg_root, user_runtime, name);
5644 assert_not_reached("Invalid scope");
5646 if (!path || (arg_runtime && !run))
5650 if (access(path, F_OK) >= 0)
5651 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5653 if (path2 && access(path2, F_OK) >= 0)
5654 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5666 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) {
5667 char *tmp_new_path, *ending;
5672 assert(ret_new_path);
5673 assert(ret_tmp_path);
5675 ending = strjoina(unit_name, ".d/override.conf");
5676 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5680 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5686 *ret_new_path = tmp_new_path;
5687 *ret_tmp_path = tmp_tmp_path;
5692 static int unit_file_create_copy(
5693 const char *unit_name,
5694 const char *fragment_path,
5695 const char *user_home,
5696 const char *user_runtime,
5697 char **ret_new_path,
5698 char **ret_tmp_path) {
5704 assert(fragment_path);
5706 assert(ret_new_path);
5707 assert(ret_tmp_path);
5709 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5713 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5716 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5721 if (response != 'y') {
5722 log_warning("%s ignored", unit_name);
5728 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5730 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
5735 *ret_new_path = tmp_new_path;
5736 *ret_tmp_path = tmp_tmp_path;
5741 static int run_editor(char **paths) {
5749 log_error_errno(errno, "Failed to fork: %m");
5756 char **tmp_path, **original_path, *p;
5760 argc = strv_length(paths)/2 + 1;
5761 args = newa(const char*, argc + 1);
5764 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5765 args[i] = *tmp_path;
5770 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5771 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5772 * we try to execute well known editors
5774 editor = getenv("SYSTEMD_EDITOR");
5776 editor = getenv("EDITOR");
5778 editor = getenv("VISUAL");
5780 if (!isempty(editor)) {
5782 execvp(editor, (char* const*) args);
5785 FOREACH_STRING(p, "nano", "vim", "vi") {
5787 execvp(p, (char* const*) args);
5788 /* We do not fail if the editor doesn't exist
5789 * because we want to try each one of them before
5792 if (errno != ENOENT) {
5793 log_error("Failed to execute %s: %m", editor);
5794 _exit(EXIT_FAILURE);
5798 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
5799 _exit(EXIT_FAILURE);
5802 r = wait_for_terminate_and_warn("editor", pid, true);
5804 return log_error_errno(r, "Failed to wait for child: %m");
5809 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5810 _cleanup_free_ char *user_home = NULL;
5811 _cleanup_free_ char *user_runtime = NULL;
5812 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5813 bool avoid_bus_cache;
5820 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5824 avoid_bus_cache = !bus || avoid_bus();
5826 STRV_FOREACH(name, names) {
5827 _cleanup_free_ char *path = NULL;
5828 char *new_path, *tmp_path;
5830 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5836 // FIXME: support units with path==NULL (no FragmentPath)
5837 log_error("No fragment exists for %s.", *name);
5842 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5844 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5848 r = strv_push_pair(paths, new_path, tmp_path);
5856 static int edit(sd_bus *bus, char **args) {
5857 _cleanup_strv_free_ char **names = NULL;
5858 _cleanup_strv_free_ char **paths = NULL;
5859 char **original, **tmp;
5865 log_error("Cannot edit units if not on a tty");
5869 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5870 log_error("Cannot remotely edit units");
5874 r = expand_names(bus, args + 1, NULL, &names);
5876 return log_error_errno(r, "Failed to expand names: %m");
5878 r = find_paths_to_edit(bus, names, &paths);
5882 if (strv_isempty(paths))
5885 r = run_editor(paths);
5889 STRV_FOREACH_PAIR(original, tmp, paths) {
5890 /* If the temporary file is empty we ignore it.
5891 * It's useful if the user wants to cancel its modification
5893 if (null_or_empty_path(*tmp)) {
5894 log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
5897 r = rename(*tmp, *original);
5899 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
5904 if (!arg_no_reload && bus && !avoid_bus())
5905 r = daemon_reload(bus, args);
5908 STRV_FOREACH_PAIR(original, tmp, paths)
5909 unlink_noerrno(*tmp);
5914 static void systemctl_help(void) {
5916 pager_open_if_enabled();
5918 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5919 "Query or send control commands to the systemd manager.\n\n"
5920 " -h --help Show this help\n"
5921 " --version Show package version\n"
5922 " --system Connect to system manager\n"
5923 " --user Connect to user service manager\n"
5924 " -H --host=[USER@]HOST\n"
5925 " Operate on remote host\n"
5926 " -M --machine=CONTAINER\n"
5927 " Operate on local container\n"
5928 " -t --type=TYPE List units of a particular type\n"
5929 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
5930 " -p --property=NAME Show only properties by this name\n"
5931 " -a --all Show all loaded units/properties, including dead/empty\n"
5932 " ones. To list all units installed on the system, use\n"
5933 " the 'list-unit-files' command instead.\n"
5934 " -l --full Don't ellipsize unit names on output\n"
5935 " -r --recursive Show unit list of host and local containers\n"
5936 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5937 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5938 " queueing a new job\n"
5939 " --show-types When showing sockets, explicitly show their type\n"
5940 " -i --ignore-inhibitors\n"
5941 " When shutting down or sleeping, ignore inhibitors\n"
5942 " --kill-who=WHO Who to send signal to\n"
5943 " -s --signal=SIGNAL Which signal to send\n"
5944 " -q --quiet Suppress output\n"
5945 " --no-block Do not wait until operation finished\n"
5946 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5947 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
5948 " --no-legend Do not print a legend (column headers and hints)\n"
5949 " --no-pager Do not pipe output into a pager\n"
5950 " --no-ask-password\n"
5951 " Do not ask for system passwords\n"
5952 " --global Enable/disable unit files globally\n"
5953 " --runtime Enable unit files only temporarily until next reboot\n"
5954 " -f --force When enabling unit files, override existing symlinks\n"
5955 " When shutting down, execute action immediately\n"
5956 " --preset-mode= Apply only enable, only disable, or all presets\n"
5957 " --root=PATH Enable unit files in the specified root directory\n"
5958 " -n --lines=INTEGER Number of journal entries to show\n"
5959 " -o --output=STRING Change journal output mode (short, short-iso,\n"
5960 " short-precise, short-monotonic, verbose,\n"
5961 " export, json, json-pretty, json-sse, cat)\n"
5962 " --plain Print unit dependencies as a list instead of a tree\n\n"
5964 " list-units [PATTERN...] List loaded units\n"
5965 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5966 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5967 " start NAME... Start (activate) one or more units\n"
5968 " stop NAME... Stop (deactivate) one or more units\n"
5969 " reload NAME... Reload one or more units\n"
5970 " restart NAME... Start or restart one or more units\n"
5971 " try-restart NAME... Restart one or more units if active\n"
5972 " reload-or-restart NAME... Reload one or more units if possible,\n"
5973 " otherwise start or restart\n"
5974 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5975 " otherwise restart if active\n"
5976 " isolate NAME Start one unit and stop all others\n"
5977 " kill NAME... Send signal to processes of a unit\n"
5978 " is-active PATTERN... Check whether units are active\n"
5979 " is-failed PATTERN... Check whether units are failed\n"
5980 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5981 " show [PATTERN...|JOB...] Show properties of one or more\n"
5982 " units/jobs or the manager\n"
5983 " cat PATTERN... Show files and drop-ins of one or more units\n"
5984 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5985 " help PATTERN...|PID... Show manual for one or more units\n"
5986 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5988 " list-dependencies [NAME] Recursively show units which are required\n"
5989 " or wanted by this unit or by which this\n"
5990 " unit is required or wanted\n\n"
5991 "Unit File Commands:\n"
5992 " list-unit-files [PATTERN...] List installed unit files\n"
5993 " enable NAME... Enable one or more unit files\n"
5994 " disable NAME... Disable one or more unit files\n"
5995 " reenable NAME... Reenable one or more unit files\n"
5996 " preset NAME... Enable/disable one or more unit files\n"
5997 " based on preset configuration\n"
5998 " preset-all Enable/disable all unit files based on\n"
5999 " preset configuration\n"
6000 " is-enabled NAME... Check whether unit files are enabled\n"
6001 " mask NAME... Mask one or more units\n"
6002 " unmask NAME... Unmask one or more units\n"
6003 " link PATH... Link one or more units files into\n"
6004 " the search path\n"
6005 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6006 " on specified one or more units\n"
6007 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6008 " on specified one or more units\n"
6009 " edit NAME... Edit one or more unit files\n"
6010 " get-default Get the name of the default target\n"
6011 " set-default NAME Set the default target\n\n"
6012 "Machine Commands:\n"
6013 " list-machines [PATTERN...] List local containers and host\n\n"
6015 " list-jobs [PATTERN...] List jobs\n"
6016 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6017 "Snapshot Commands:\n"
6018 " snapshot [NAME] Create a snapshot\n"
6019 " delete NAME... Remove one or more snapshots\n\n"
6020 "Environment Commands:\n"
6021 " show-environment Dump environment\n"
6022 " set-environment NAME=VALUE... Set one or more environment variables\n"
6023 " unset-environment NAME... Unset one or more environment variables\n"
6024 " import-environment [NAME...] Import all or some environment variables\n\n"
6025 "Manager Lifecycle Commands:\n"
6026 " daemon-reload Reload systemd manager configuration\n"
6027 " daemon-reexec Reexecute systemd manager\n\n"
6028 "System Commands:\n"
6029 " is-system-running Check whether system is fully running\n"
6030 " default Enter system default mode\n"
6031 " rescue Enter system rescue mode\n"
6032 " emergency Enter system emergency mode\n"
6033 " halt Shut down and halt the system\n"
6034 " poweroff Shut down and power-off the system\n"
6035 " reboot [ARG] Shut down and reboot the system\n"
6036 " kexec Shut down and reboot the system with kexec\n"
6037 " exit Request user instance exit\n"
6038 " switch-root ROOT [INIT] Change to a different root file system\n"
6039 " suspend Suspend the system\n"
6040 " hibernate Hibernate the system\n"
6041 " hybrid-sleep Hibernate and suspend the system\n",
6042 program_invocation_short_name);
6045 static void halt_help(void) {
6046 printf("%s [OPTIONS...]%s\n\n"
6047 "%s the system.\n\n"
6048 " --help Show this help\n"
6049 " --halt Halt the machine\n"
6050 " -p --poweroff Switch off the machine\n"
6051 " --reboot Reboot the machine\n"
6052 " -f --force Force immediate halt/power-off/reboot\n"
6053 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6054 " -d --no-wtmp Don't write wtmp record\n"
6055 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6056 program_invocation_short_name,
6057 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6058 arg_action == ACTION_REBOOT ? "Reboot" :
6059 arg_action == ACTION_POWEROFF ? "Power off" :
6063 static void shutdown_help(void) {
6064 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6065 "Shut down the system.\n\n"
6066 " --help Show this help\n"
6067 " -H --halt Halt the machine\n"
6068 " -P --poweroff Power-off the machine\n"
6069 " -r --reboot Reboot the machine\n"
6070 " -h Equivalent to --poweroff, overridden by --halt\n"
6071 " -k Don't halt/power-off/reboot, just send warnings\n"
6072 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6073 " -c Cancel a pending shutdown\n",
6074 program_invocation_short_name);
6077 static void telinit_help(void) {
6078 printf("%s [OPTIONS...] {COMMAND}\n\n"
6079 "Send control commands to the init daemon.\n\n"
6080 " --help Show this help\n"
6081 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6083 " 0 Power-off the machine\n"
6084 " 6 Reboot the machine\n"
6085 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6086 " 1, s, S Enter rescue mode\n"
6087 " q, Q Reload init daemon configuration\n"
6088 " u, U Reexecute init daemon\n",
6089 program_invocation_short_name);
6092 static void runlevel_help(void) {
6093 printf("%s [OPTIONS...]\n\n"
6094 "Prints the previous and current runlevel of the init system.\n\n"
6095 " --help Show this help\n",
6096 program_invocation_short_name);
6099 static void help_types(void) {
6104 puts("Available unit types:");
6105 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6106 t = unit_type_to_string(i);
6112 static int systemctl_parse_argv(int argc, char *argv[]) {
6121 ARG_IGNORE_DEPENDENCIES,
6133 ARG_NO_ASK_PASSWORD,
6143 static const struct option options[] = {
6144 { "help", no_argument, NULL, 'h' },
6145 { "version", no_argument, NULL, ARG_VERSION },
6146 { "type", required_argument, NULL, 't' },
6147 { "property", required_argument, NULL, 'p' },
6148 { "all", no_argument, NULL, 'a' },
6149 { "reverse", no_argument, NULL, ARG_REVERSE },
6150 { "after", no_argument, NULL, ARG_AFTER },
6151 { "before", no_argument, NULL, ARG_BEFORE },
6152 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6153 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6154 { "full", no_argument, NULL, 'l' },
6155 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6156 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6157 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6158 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6159 { "ignore-inhibitors", no_argument, NULL, 'i' },
6160 { "user", no_argument, NULL, ARG_USER },
6161 { "system", no_argument, NULL, ARG_SYSTEM },
6162 { "global", no_argument, NULL, ARG_GLOBAL },
6163 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6164 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6165 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6166 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6167 { "quiet", no_argument, NULL, 'q' },
6168 { "root", required_argument, NULL, ARG_ROOT },
6169 { "force", no_argument, NULL, ARG_FORCE },
6170 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6171 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6172 { "signal", required_argument, NULL, 's' },
6173 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6174 { "host", required_argument, NULL, 'H' },
6175 { "machine", required_argument, NULL, 'M' },
6176 { "runtime", no_argument, NULL, ARG_RUNTIME },
6177 { "lines", required_argument, NULL, 'n' },
6178 { "output", required_argument, NULL, 'o' },
6179 { "plain", no_argument, NULL, ARG_PLAIN },
6180 { "state", required_argument, NULL, ARG_STATE },
6181 { "recursive", no_argument, NULL, 'r' },
6182 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6191 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6200 puts(PACKAGE_STRING);
6201 puts(SYSTEMD_FEATURES);
6205 const char *word, *state;
6208 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6209 _cleanup_free_ char *type;
6211 type = strndup(word, size);
6215 if (streq(type, "help")) {
6220 if (unit_type_from_string(type) >= 0) {
6221 if (strv_push(&arg_types, type))
6227 /* It's much nicer to use --state= for
6228 * load states, but let's support this
6229 * in --types= too for compatibility
6230 * with old versions */
6231 if (unit_load_state_from_string(optarg) >= 0) {
6232 if (strv_push(&arg_states, type) < 0)
6238 log_error("Unknown unit type or load state '%s'.", type);
6239 log_info("Use -t help to see a list of allowed values.");
6247 /* Make sure that if the empty property list
6248 was specified, we won't show any properties. */
6249 if (isempty(optarg) && !arg_properties) {
6250 arg_properties = new0(char*, 1);
6251 if (!arg_properties)
6254 const char *word, *state;
6257 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6260 prop = strndup(word, size);
6264 if (strv_consume(&arg_properties, prop) < 0)
6269 /* If the user asked for a particular
6270 * property, show it to him, even if it is
6282 arg_dependency = DEPENDENCY_REVERSE;
6286 arg_dependency = DEPENDENCY_AFTER;
6290 arg_dependency = DEPENDENCY_BEFORE;
6293 case ARG_SHOW_TYPES:
6294 arg_show_types = true;
6298 arg_job_mode = optarg;
6302 arg_job_mode = "fail";
6305 case ARG_IRREVERSIBLE:
6306 arg_job_mode = "replace-irreversibly";
6309 case ARG_IGNORE_DEPENDENCIES:
6310 arg_job_mode = "ignore-dependencies";
6314 arg_scope = UNIT_FILE_USER;
6318 arg_scope = UNIT_FILE_SYSTEM;
6322 arg_scope = UNIT_FILE_GLOBAL;
6326 arg_no_block = true;
6330 arg_no_legend = true;
6334 arg_no_pager = true;
6350 if (strv_extend(&arg_states, "failed") < 0)
6368 arg_no_reload = true;
6372 arg_kill_who = optarg;
6376 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6377 log_error("Failed to parse signal string %s.", optarg);
6382 case ARG_NO_ASK_PASSWORD:
6383 arg_ask_password = false;
6387 arg_transport = BUS_TRANSPORT_REMOTE;
6392 arg_transport = BUS_TRANSPORT_MACHINE;
6401 if (safe_atou(optarg, &arg_lines) < 0) {
6402 log_error("Failed to parse lines '%s'", optarg);
6408 arg_output = output_mode_from_string(optarg);
6409 if (arg_output < 0) {
6410 log_error("Unknown output '%s'.", optarg);
6416 arg_ignore_inhibitors = true;
6424 const char *word, *state;
6427 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6430 s = strndup(word, size);
6434 if (strv_consume(&arg_states, s) < 0)
6441 if (geteuid() != 0) {
6442 log_error("--recursive requires root privileges.");
6446 arg_recursive = true;
6449 case ARG_PRESET_MODE:
6451 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6452 if (arg_preset_mode < 0) {
6453 log_error("Failed to parse preset mode: %s.", optarg);
6463 assert_not_reached("Unhandled option");
6466 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6467 log_error("Cannot access user instance remotely.");
6474 static int halt_parse_argv(int argc, char *argv[]) {
6483 static const struct option options[] = {
6484 { "help", no_argument, NULL, ARG_HELP },
6485 { "halt", no_argument, NULL, ARG_HALT },
6486 { "poweroff", no_argument, NULL, 'p' },
6487 { "reboot", no_argument, NULL, ARG_REBOOT },
6488 { "force", no_argument, NULL, 'f' },
6489 { "wtmp-only", no_argument, NULL, 'w' },
6490 { "no-wtmp", no_argument, NULL, 'd' },
6491 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6500 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6501 if (runlevel == '0' || runlevel == '6')
6504 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6512 arg_action = ACTION_HALT;
6516 if (arg_action != ACTION_REBOOT)
6517 arg_action = ACTION_POWEROFF;
6521 arg_action = ACTION_REBOOT;
6543 /* Compatibility nops */
6550 assert_not_reached("Unhandled option");
6553 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6554 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6557 } else if (optind < argc) {
6558 log_error("Too many arguments.");
6565 static int parse_time_spec(const char *t, usec_t *_u) {
6569 if (streq(t, "now"))
6571 else if (!strchr(t, ':')) {
6574 if (safe_atou64(t, &u) < 0)
6577 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6586 hour = strtol(t, &e, 10);
6587 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6590 minute = strtol(e+1, &e, 10);
6591 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6594 n = now(CLOCK_REALTIME);
6595 s = (time_t) (n / USEC_PER_SEC);
6597 assert_se(localtime_r(&s, &tm));
6599 tm.tm_hour = (int) hour;
6600 tm.tm_min = (int) minute;
6603 assert_se(s = mktime(&tm));
6605 *_u = (usec_t) s * USEC_PER_SEC;
6608 *_u += USEC_PER_DAY;
6614 static int shutdown_parse_argv(int argc, char *argv[]) {
6621 static const struct option options[] = {
6622 { "help", no_argument, NULL, ARG_HELP },
6623 { "halt", no_argument, NULL, 'H' },
6624 { "poweroff", no_argument, NULL, 'P' },
6625 { "reboot", no_argument, NULL, 'r' },
6626 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6627 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6636 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6644 arg_action = ACTION_HALT;
6648 arg_action = ACTION_POWEROFF;
6653 arg_action = ACTION_KEXEC;
6655 arg_action = ACTION_REBOOT;
6659 arg_action = ACTION_KEXEC;
6663 if (arg_action != ACTION_HALT)
6664 arg_action = ACTION_POWEROFF;
6679 /* Compatibility nops */
6683 arg_action = ACTION_CANCEL_SHUTDOWN;
6690 assert_not_reached("Unhandled option");
6693 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6694 r = parse_time_spec(argv[optind], &arg_when);
6696 log_error("Failed to parse time specification: %s", argv[optind]);
6700 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6702 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6703 /* No time argument for shutdown cancel */
6704 arg_wall = argv + optind;
6705 else if (argc > optind + 1)
6706 /* We skip the time argument */
6707 arg_wall = argv + optind + 1;
6714 static int telinit_parse_argv(int argc, char *argv[]) {
6721 static const struct option options[] = {
6722 { "help", no_argument, NULL, ARG_HELP },
6723 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6727 static const struct {
6731 { '0', ACTION_POWEROFF },
6732 { '6', ACTION_REBOOT },
6733 { '1', ACTION_RESCUE },
6734 { '2', ACTION_RUNLEVEL2 },
6735 { '3', ACTION_RUNLEVEL3 },
6736 { '4', ACTION_RUNLEVEL4 },
6737 { '5', ACTION_RUNLEVEL5 },
6738 { 's', ACTION_RESCUE },
6739 { 'S', ACTION_RESCUE },
6740 { 'q', ACTION_RELOAD },
6741 { 'Q', ACTION_RELOAD },
6742 { 'u', ACTION_REEXEC },
6743 { 'U', ACTION_REEXEC }
6752 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6767 assert_not_reached("Unhandled option");
6770 if (optind >= argc) {
6771 log_error("%s: required argument missing.",
6772 program_invocation_short_name);
6776 if (optind + 1 < argc) {
6777 log_error("Too many arguments.");
6781 if (strlen(argv[optind]) != 1) {
6782 log_error("Expected single character argument.");
6786 for (i = 0; i < ELEMENTSOF(table); i++)
6787 if (table[i].from == argv[optind][0])
6790 if (i >= ELEMENTSOF(table)) {
6791 log_error("Unknown command '%s'.", argv[optind]);
6795 arg_action = table[i].to;
6802 static int runlevel_parse_argv(int argc, char *argv[]) {
6808 static const struct option options[] = {
6809 { "help", no_argument, NULL, ARG_HELP },
6818 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6829 assert_not_reached("Unhandled option");
6832 if (optind < argc) {
6833 log_error("Too many arguments.");
6840 static int parse_argv(int argc, char *argv[]) {
6844 if (program_invocation_short_name) {
6846 if (strstr(program_invocation_short_name, "halt")) {
6847 arg_action = ACTION_HALT;
6848 return halt_parse_argv(argc, argv);
6849 } else if (strstr(program_invocation_short_name, "poweroff")) {
6850 arg_action = ACTION_POWEROFF;
6851 return halt_parse_argv(argc, argv);
6852 } else if (strstr(program_invocation_short_name, "reboot")) {
6854 arg_action = ACTION_KEXEC;
6856 arg_action = ACTION_REBOOT;
6857 return halt_parse_argv(argc, argv);
6858 } else if (strstr(program_invocation_short_name, "shutdown")) {
6859 arg_action = ACTION_POWEROFF;
6860 return shutdown_parse_argv(argc, argv);
6861 } else if (strstr(program_invocation_short_name, "init")) {
6863 if (sd_booted() > 0) {
6864 arg_action = _ACTION_INVALID;
6865 return telinit_parse_argv(argc, argv);
6867 /* Hmm, so some other init system is
6868 * running, we need to forward this
6869 * request to it. For now we simply
6870 * guess that it is Upstart. */
6872 execv(TELINIT, argv);
6874 log_error("Couldn't find an alternative telinit implementation to spawn.");
6878 } else if (strstr(program_invocation_short_name, "runlevel")) {
6879 arg_action = ACTION_RUNLEVEL;
6880 return runlevel_parse_argv(argc, argv);
6884 arg_action = ACTION_SYSTEMCTL;
6885 return systemctl_parse_argv(argc, argv);
6888 _pure_ static int action_to_runlevel(void) {
6890 static const char table[_ACTION_MAX] = {
6891 [ACTION_HALT] = '0',
6892 [ACTION_POWEROFF] = '0',
6893 [ACTION_REBOOT] = '6',
6894 [ACTION_RUNLEVEL2] = '2',
6895 [ACTION_RUNLEVEL3] = '3',
6896 [ACTION_RUNLEVEL4] = '4',
6897 [ACTION_RUNLEVEL5] = '5',
6898 [ACTION_RESCUE] = '1'
6901 assert(arg_action < _ACTION_MAX);
6903 return table[arg_action];
6906 static int talk_initctl(void) {
6908 struct init_request request = {
6909 .magic = INIT_MAGIC,
6911 .cmd = INIT_CMD_RUNLVL
6914 _cleanup_close_ int fd = -1;
6918 rl = action_to_runlevel();
6922 request.runlevel = rl;
6924 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6926 if (errno == ENOENT)
6929 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
6933 r = loop_write(fd, &request, sizeof(request), false);
6935 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
6940 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6942 static const struct {
6950 int (* const dispatch)(sd_bus *bus, char **args);
6956 { "list-units", MORE, 0, list_units },
6957 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6958 { "list-sockets", MORE, 1, list_sockets },
6959 { "list-timers", MORE, 1, list_timers },
6960 { "list-jobs", MORE, 1, list_jobs },
6961 { "list-machines", MORE, 1, list_machines },
6962 { "clear-jobs", EQUAL, 1, daemon_reload },
6963 { "cancel", MORE, 2, cancel_job },
6964 { "start", MORE, 2, start_unit },
6965 { "stop", MORE, 2, start_unit },
6966 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6967 { "reload", MORE, 2, start_unit },
6968 { "restart", MORE, 2, start_unit },
6969 { "try-restart", MORE, 2, start_unit },
6970 { "reload-or-restart", MORE, 2, start_unit },
6971 { "reload-or-try-restart", MORE, 2, start_unit },
6972 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6973 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6974 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6975 { "isolate", EQUAL, 2, start_unit },
6976 { "kill", MORE, 2, kill_unit },
6977 { "is-active", MORE, 2, check_unit_active },
6978 { "check", MORE, 2, check_unit_active },
6979 { "is-failed", MORE, 2, check_unit_failed },
6980 { "show", MORE, 1, show },
6981 { "cat", MORE, 2, cat, NOBUS },
6982 { "status", MORE, 1, show },
6983 { "help", MORE, 2, show },
6984 { "snapshot", LESS, 2, snapshot },
6985 { "delete", MORE, 2, delete_snapshot },
6986 { "daemon-reload", EQUAL, 1, daemon_reload },
6987 { "daemon-reexec", EQUAL, 1, daemon_reload },
6988 { "show-environment", EQUAL, 1, show_environment },
6989 { "set-environment", MORE, 2, set_environment },
6990 { "unset-environment", MORE, 2, set_environment },
6991 { "import-environment", MORE, 1, import_environment},
6992 { "halt", EQUAL, 1, start_special, FORCE },
6993 { "poweroff", EQUAL, 1, start_special, FORCE },
6994 { "reboot", MORE, 1, start_special, FORCE },
6995 { "kexec", EQUAL, 1, start_special },
6996 { "suspend", EQUAL, 1, start_special },
6997 { "hibernate", EQUAL, 1, start_special },
6998 { "hybrid-sleep", EQUAL, 1, start_special },
6999 { "default", EQUAL, 1, start_special },
7000 { "rescue", EQUAL, 1, start_special },
7001 { "emergency", EQUAL, 1, start_special },
7002 { "exit", EQUAL, 1, start_special },
7003 { "reset-failed", MORE, 1, reset_failed },
7004 { "enable", MORE, 2, enable_unit, NOBUS },
7005 { "disable", MORE, 2, enable_unit, NOBUS },
7006 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7007 { "reenable", MORE, 2, enable_unit, NOBUS },
7008 { "preset", MORE, 2, enable_unit, NOBUS },
7009 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7010 { "mask", MORE, 2, enable_unit, NOBUS },
7011 { "unmask", MORE, 2, enable_unit, NOBUS },
7012 { "link", MORE, 2, enable_unit, NOBUS },
7013 { "switch-root", MORE, 2, switch_root },
7014 { "list-dependencies", LESS, 2, list_dependencies },
7015 { "set-default", EQUAL, 2, set_default, NOBUS },
7016 { "get-default", EQUAL, 1, get_default, NOBUS },
7017 { "set-property", MORE, 3, set_property },
7018 { "is-system-running", EQUAL, 1, is_system_running },
7019 { "add-wants", MORE, 3, add_dependency, NOBUS },
7020 { "add-requires", MORE, 3, add_dependency, NOBUS },
7021 { "edit", MORE, 2, edit, NOBUS },
7030 left = argc - optind;
7032 /* Special rule: no arguments (left == 0) means "list-units" */
7034 if (streq(argv[optind], "help") && !argv[optind+1]) {
7035 log_error("This command expects one or more "
7036 "unit names. Did you mean --help?");
7040 for (; verb->verb; verb++)
7041 if (streq(argv[optind], verb->verb))
7044 log_error("Unknown operation '%s'.", argv[optind]);
7049 switch (verb->argc_cmp) {
7052 if (left != verb->argc) {
7053 log_error("Invalid number of arguments.");
7060 if (left < verb->argc) {
7061 log_error("Too few arguments.");
7068 if (left > verb->argc) {
7069 log_error("Too many arguments.");
7076 assert_not_reached("Unknown comparison operator.");
7079 /* Require a bus connection for all operations but
7081 if (verb->bus == NOBUS) {
7082 if (!bus && !avoid_bus()) {
7083 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7088 if (running_in_chroot() > 0) {
7089 log_info("Running in chroot, ignoring request.");
7093 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7094 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7099 return verb->dispatch(bus, argv + optind);
7102 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7104 struct sd_shutdown_command c = {
7111 union sockaddr_union sockaddr = {
7112 .un.sun_family = AF_UNIX,
7113 .un.sun_path = "/run/systemd/shutdownd",
7116 struct iovec iovec[2] = {{
7117 .iov_base = (char*) &c,
7118 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7121 struct msghdr msghdr = {
7122 .msg_name = &sockaddr,
7123 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7124 + strlen("/run/systemd/shutdownd"),
7129 _cleanup_close_ int fd;
7131 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7135 if (!isempty(message)) {
7136 iovec[1].iov_base = (char*) message;
7137 iovec[1].iov_len = strlen(message);
7138 msghdr.msg_iovlen++;
7141 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7147 static int reload_with_fallback(sd_bus *bus) {
7150 /* First, try systemd via D-Bus. */
7151 if (daemon_reload(bus, NULL) >= 0)
7155 /* Nothing else worked, so let's try signals */
7156 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7158 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7159 return log_error_errno(errno, "kill() failed: %m");
7164 static int start_with_fallback(sd_bus *bus) {
7167 /* First, try systemd via D-Bus. */
7168 if (start_unit(bus, NULL) >= 0)
7172 /* Nothing else worked, so let's try
7174 if (talk_initctl() > 0)
7177 log_error("Failed to talk to init daemon.");
7181 warn_wall(arg_action);
7185 static int halt_now(enum action a) {
7187 /* The kernel will automaticall flush ATA disks and suchlike
7188 * on reboot(), but the file systems need to be synce'd
7189 * explicitly in advance. */
7192 /* Make sure C-A-D is handled by the kernel from this point
7194 reboot(RB_ENABLE_CAD);
7199 log_info("Halting.");
7200 reboot(RB_HALT_SYSTEM);
7203 case ACTION_POWEROFF:
7204 log_info("Powering off.");
7205 reboot(RB_POWER_OFF);
7208 case ACTION_REBOOT: {
7209 _cleanup_free_ char *param = NULL;
7211 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7212 log_info("Rebooting with argument '%s'.", param);
7213 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7214 LINUX_REBOOT_CMD_RESTART2, param);
7217 log_info("Rebooting.");
7218 reboot(RB_AUTOBOOT);
7223 assert_not_reached("Unknown action.");
7227 static int halt_main(sd_bus *bus) {
7230 r = check_inhibitors(bus, arg_action);
7234 if (geteuid() != 0) {
7235 /* Try logind if we are a normal user and no special
7236 * mode applies. Maybe PolicyKit allows us to shutdown
7239 if (arg_when <= 0 &&
7242 (arg_action == ACTION_POWEROFF ||
7243 arg_action == ACTION_REBOOT)) {
7244 r = reboot_with_logind(bus, arg_action);
7249 log_error("Must be root.");
7254 _cleanup_free_ char *m;
7256 m = strv_join(arg_wall, " ");
7260 r = send_shutdownd(arg_when,
7261 arg_action == ACTION_HALT ? 'H' :
7262 arg_action == ACTION_POWEROFF ? 'P' :
7263 arg_action == ACTION_KEXEC ? 'K' :
7270 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7272 char date[FORMAT_TIMESTAMP_MAX];
7274 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7275 format_timestamp(date, sizeof(date), arg_when));
7280 if (!arg_dry && !arg_force)
7281 return start_with_fallback(bus);
7284 if (sd_booted() > 0)
7285 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7287 r = utmp_put_shutdown();
7289 log_warning_errno(r, "Failed to write utmp record: %m");
7296 r = halt_now(arg_action);
7297 log_error_errno(r, "Failed to reboot: %m");
7302 static int runlevel_main(void) {
7303 int r, runlevel, previous;
7305 r = utmp_get_runlevel(&runlevel, &previous);
7312 previous <= 0 ? 'N' : previous,
7313 runlevel <= 0 ? 'N' : runlevel);
7318 int main(int argc, char*argv[]) {
7319 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7322 setlocale(LC_ALL, "");
7323 log_parse_environment();
7326 /* Explicitly not on_tty() to avoid setting cached value.
7327 * This becomes relevant for piping output which might be
7329 original_stdout_is_tty = isatty(STDOUT_FILENO);
7331 r = parse_argv(argc, argv);
7335 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7336 * let's shortcut this */
7337 if (arg_action == ACTION_RUNLEVEL) {
7338 r = runlevel_main();
7342 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7343 log_info("Running in chroot, ignoring request.");
7348 /* Increase max number of open files to 16K if we can, we
7349 * might needs this when browsing journal files, which might
7350 * be split up into many files. */
7351 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7354 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7357 sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
7359 /* systemctl_main() will print an error message for the bus
7360 * connection, but only if it needs to */
7362 switch (arg_action) {
7364 case ACTION_SYSTEMCTL:
7365 r = systemctl_main(bus, argc, argv, r);
7369 case ACTION_POWEROFF:
7375 case ACTION_RUNLEVEL2:
7376 case ACTION_RUNLEVEL3:
7377 case ACTION_RUNLEVEL4:
7378 case ACTION_RUNLEVEL5:
7380 case ACTION_EMERGENCY:
7381 case ACTION_DEFAULT:
7382 r = start_with_fallback(bus);
7387 r = reload_with_fallback(bus);
7390 case ACTION_CANCEL_SHUTDOWN: {
7391 _cleanup_free_ char *m = NULL;
7394 m = strv_join(arg_wall, " ");
7401 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7403 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7407 case ACTION_RUNLEVEL:
7408 case _ACTION_INVALID:
7410 assert_not_reached("Unknown action");
7415 ask_password_agent_close();
7416 polkit_agent_close();
7418 strv_free(arg_types);
7419 strv_free(arg_states);
7420 strv_free(arg_properties);
7422 return r < 0 ? EXIT_FAILURE : r;