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 ((pid_t) pid < 0)
2855 return log_error_errno(ERANGE, "Bad PID %"PRIu32": %m", pid);
2857 if (!strv_contains(sv,
2859 a == ACTION_POWEROFF ||
2860 a == ACTION_REBOOT ||
2861 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2864 get_process_comm(pid, &comm);
2865 user = uid_to_name(uid);
2867 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2868 who, (pid_t) pid, strna(comm), strna(user), why);
2873 return bus_log_parse_error(r);
2875 r = sd_bus_message_exit_container(reply);
2877 return bus_log_parse_error(r);
2879 /* Check for current sessions */
2880 sd_get_sessions(&sessions);
2881 STRV_FOREACH(s, sessions) {
2882 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2884 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2887 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2890 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2893 sd_session_get_tty(*s, &tty);
2894 sd_session_get_seat(*s, &seat);
2895 sd_session_get_service(*s, &service);
2896 user = uid_to_name(uid);
2898 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2905 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2906 action_table[a].verb);
2914 static int start_special(sd_bus *bus, char **args) {
2920 a = verb_to_action(args[0]);
2922 r = check_inhibitors(bus, a);
2926 if (arg_force >= 2 && geteuid() != 0) {
2927 log_error("Must be root.");
2931 if (a == ACTION_REBOOT && args[1]) {
2932 r = update_reboot_param_file(args[1]);
2937 if (arg_force >= 2 &&
2938 (a == ACTION_HALT ||
2939 a == ACTION_POWEROFF ||
2940 a == ACTION_REBOOT))
2943 if (arg_force >= 1 &&
2944 (a == ACTION_HALT ||
2945 a == ACTION_POWEROFF ||
2946 a == ACTION_REBOOT ||
2947 a == ACTION_KEXEC ||
2949 return daemon_reload(bus, args);
2951 /* first try logind, to allow authentication with polkit */
2952 if (geteuid() != 0 &&
2953 (a == ACTION_POWEROFF ||
2954 a == ACTION_REBOOT ||
2955 a == ACTION_SUSPEND ||
2956 a == ACTION_HIBERNATE ||
2957 a == ACTION_HYBRID_SLEEP)) {
2958 r = reboot_with_logind(bus, a);
2959 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
2963 r = start_unit(bus, args);
2964 if (r == EXIT_SUCCESS)
2970 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2971 _cleanup_strv_free_ char **names = NULL;
2978 r = expand_names(bus, args, NULL, &names);
2980 return log_error_errno(r, "Failed to expand names: %m");
2982 STRV_FOREACH(name, names) {
2985 state = check_one_unit(bus, *name, good_states, arg_quiet);
2995 static int check_unit_active(sd_bus *bus, char **args) {
2996 /* According to LSB: 3, "program is not running" */
2997 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3000 static int check_unit_failed(sd_bus *bus, char **args) {
3001 return check_unit_generic(bus, 1, "failed\0", args + 1);
3004 static int kill_unit(sd_bus *bus, char **args) {
3005 _cleanup_strv_free_ char **names = NULL;
3012 polkit_agent_open_if_enabled();
3015 arg_kill_who = "all";
3017 r = expand_names(bus, args + 1, NULL, &names);
3019 log_error_errno(r, "Failed to expand names: %m");
3021 STRV_FOREACH(name, names) {
3022 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3024 q = sd_bus_call_method(
3026 "org.freedesktop.systemd1",
3027 "/org/freedesktop/systemd1",
3028 "org.freedesktop.systemd1.Manager",
3032 "ssi", *names, arg_kill_who, arg_signal);
3034 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3043 typedef struct ExecStatusInfo {
3051 usec_t start_timestamp;
3052 usec_t exit_timestamp;
3057 LIST_FIELDS(struct ExecStatusInfo, exec);
3060 static void exec_status_info_free(ExecStatusInfo *i) {
3069 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3070 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3073 int32_t code, status;
3079 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3081 return bus_log_parse_error(r);
3085 r = sd_bus_message_read(m, "s", &path);
3087 return bus_log_parse_error(r);
3089 i->path = strdup(path);
3093 r = sd_bus_message_read_strv(m, &i->argv);
3095 return bus_log_parse_error(r);
3097 r = sd_bus_message_read(m,
3100 &start_timestamp, &start_timestamp_monotonic,
3101 &exit_timestamp, &exit_timestamp_monotonic,
3105 return bus_log_parse_error(r);
3108 i->start_timestamp = (usec_t) start_timestamp;
3109 i->exit_timestamp = (usec_t) exit_timestamp;
3110 i->pid = (pid_t) pid;
3114 r = sd_bus_message_exit_container(m);
3116 return bus_log_parse_error(r);
3121 typedef struct UnitStatusInfo {
3123 const char *load_state;
3124 const char *active_state;
3125 const char *sub_state;
3126 const char *unit_file_state;
3127 const char *unit_file_preset;
3129 const char *description;
3130 const char *following;
3132 char **documentation;
3134 const char *fragment_path;
3135 const char *source_path;
3136 const char *control_group;
3138 char **dropin_paths;
3140 const char *load_error;
3143 usec_t inactive_exit_timestamp;
3144 usec_t inactive_exit_timestamp_monotonic;
3145 usec_t active_enter_timestamp;
3146 usec_t active_exit_timestamp;
3147 usec_t inactive_enter_timestamp;
3149 bool need_daemon_reload;
3154 const char *status_text;
3155 const char *pid_file;
3159 usec_t start_timestamp;
3160 usec_t exit_timestamp;
3162 int exit_code, exit_status;
3164 usec_t condition_timestamp;
3165 bool condition_result;
3166 bool failed_condition_trigger;
3167 bool failed_condition_negate;
3168 const char *failed_condition;
3169 const char *failed_condition_parameter;
3171 usec_t assert_timestamp;
3173 bool failed_assert_trigger;
3174 bool failed_assert_negate;
3175 const char *failed_assert;
3176 const char *failed_assert_parameter;
3179 unsigned n_accepted;
3180 unsigned n_connections;
3183 /* Pairs of type, path */
3187 const char *sysfs_path;
3189 /* Mount, Automount */
3196 uint64_t memory_current;
3197 uint64_t memory_limit;
3198 uint64_t cpu_usage_nsec;
3200 LIST_HEAD(ExecStatusInfo, exec);
3203 static void print_status_info(
3208 const char *active_on, *active_off, *on, *off, *ss;
3210 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3211 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3217 /* This shows pretty information about a unit. See
3218 * print_property() for a low-level property printer */
3220 if (streq_ptr(i->active_state, "failed")) {
3221 active_on = ansi_highlight_red();
3222 active_off = ansi_highlight_off();
3223 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3224 active_on = ansi_highlight_green();
3225 active_off = ansi_highlight_off();
3227 active_on = active_off = "";
3229 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3231 if (i->description && !streq_ptr(i->id, i->description))
3232 printf(" - %s", i->description);
3237 printf(" Follow: unit currently follows state of %s\n", i->following);
3239 if (streq_ptr(i->load_state, "error")) {
3240 on = ansi_highlight_red();
3241 off = ansi_highlight_off();
3245 path = i->source_path ? i->source_path : i->fragment_path;
3248 printf(" Loaded: %s%s%s (Reason: %s)\n",
3249 on, strna(i->load_state), off, i->load_error);
3250 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3251 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3252 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3253 else if (path && !isempty(i->unit_file_state))
3254 printf(" Loaded: %s%s%s (%s; %s)\n",
3255 on, strna(i->load_state), off, path, i->unit_file_state);
3257 printf(" Loaded: %s%s%s (%s)\n",
3258 on, strna(i->load_state), off, path);
3260 printf(" Loaded: %s%s%s\n",
3261 on, strna(i->load_state), off);
3263 if (!strv_isempty(i->dropin_paths)) {
3264 _cleanup_free_ char *dir = NULL;
3268 STRV_FOREACH(dropin, i->dropin_paths) {
3269 if (! dir || last) {
3270 printf(dir ? " " : " Drop-In: ");
3275 if (path_get_parent(*dropin, &dir) < 0) {
3280 printf("%s\n %s", dir,
3281 draw_special_char(DRAW_TREE_RIGHT));
3284 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3286 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3290 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3292 printf(" Active: %s%s (%s)%s",
3293 active_on, strna(i->active_state), ss, active_off);
3295 printf(" Active: %s%s%s",
3296 active_on, strna(i->active_state), active_off);
3298 if (!isempty(i->result) && !streq(i->result, "success"))
3299 printf(" (Result: %s)", i->result);
3301 timestamp = (streq_ptr(i->active_state, "active") ||
3302 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3303 (streq_ptr(i->active_state, "inactive") ||
3304 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3305 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3306 i->active_exit_timestamp;
3308 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3309 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3312 printf(" since %s; %s\n", s2, s1);
3314 printf(" since %s\n", s2);
3318 if (!i->condition_result && i->condition_timestamp > 0) {
3319 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3320 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3322 printf("Condition: start %scondition failed%s at %s%s%s\n",
3323 ansi_highlight_yellow(), ansi_highlight_off(),
3324 s2, s1 ? "; " : "", s1 ? s1 : "");
3325 if (i->failed_condition_trigger)
3326 printf(" none of the trigger conditions were met\n");
3327 else if (i->failed_condition)
3328 printf(" %s=%s%s was not met\n",
3329 i->failed_condition,
3330 i->failed_condition_negate ? "!" : "",
3331 i->failed_condition_parameter);
3334 if (!i->assert_result && i->assert_timestamp > 0) {
3335 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3336 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3338 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3339 ansi_highlight_red(), ansi_highlight_off(),
3340 s2, s1 ? "; " : "", s1 ? s1 : "");
3341 if (i->failed_assert_trigger)
3342 printf(" none of the trigger assertions were met\n");
3343 else if (i->failed_assert)
3344 printf(" %s=%s%s was not met\n",
3346 i->failed_assert_negate ? "!" : "",
3347 i->failed_assert_parameter);
3351 printf(" Device: %s\n", i->sysfs_path);
3353 printf(" Where: %s\n", i->where);
3355 printf(" What: %s\n", i->what);
3357 STRV_FOREACH(t, i->documentation)
3358 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3360 STRV_FOREACH_PAIR(t, t2, i->listen)
3361 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3364 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3366 LIST_FOREACH(exec, p, i->exec) {
3367 _cleanup_free_ char *argv = NULL;
3370 /* Only show exited processes here */
3374 argv = strv_join(p->argv, " ");
3375 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3377 good = is_clean_exit_lsb(p->code, p->status, NULL);
3379 on = ansi_highlight_red();
3380 off = ansi_highlight_off();
3384 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3386 if (p->code == CLD_EXITED) {
3389 printf("status=%i", p->status);
3391 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3396 printf("signal=%s", signal_to_string(p->status));
3398 printf(")%s\n", off);
3400 if (i->main_pid == p->pid &&
3401 i->start_timestamp == p->start_timestamp &&
3402 i->exit_timestamp == p->start_timestamp)
3403 /* Let's not show this twice */
3406 if (p->pid == i->control_pid)
3410 if (i->main_pid > 0 || i->control_pid > 0) {
3411 if (i->main_pid > 0) {
3412 printf(" Main PID: "PID_FMT, i->main_pid);
3415 _cleanup_free_ char *comm = NULL;
3416 get_process_comm(i->main_pid, &comm);
3418 printf(" (%s)", comm);
3419 } else if (i->exit_code > 0) {
3420 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3422 if (i->exit_code == CLD_EXITED) {
3425 printf("status=%i", i->exit_status);
3427 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3432 printf("signal=%s", signal_to_string(i->exit_status));
3436 if (i->control_pid > 0)
3440 if (i->control_pid > 0) {
3441 _cleanup_free_ char *c = NULL;
3443 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3445 get_process_comm(i->control_pid, &c);
3454 printf(" Status: \"%s\"\n", i->status_text);
3455 if (i->status_errno > 0)
3456 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3458 if (i->memory_current != (uint64_t) -1) {
3459 char buf[FORMAT_BYTES_MAX];
3461 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3463 if (i->memory_limit != (uint64_t) -1)
3464 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3469 if (i->cpu_usage_nsec != (uint64_t) -1) {
3470 char buf[FORMAT_TIMESPAN_MAX];
3471 printf(" CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
3474 if (i->control_group &&
3475 (i->main_pid > 0 || i->control_pid > 0 ||
3476 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3479 printf(" CGroup: %s\n", i->control_group);
3481 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3484 static const char prefix[] = " ";
3487 if (c > sizeof(prefix) - 1)
3488 c -= sizeof(prefix) - 1;
3492 if (i->main_pid > 0)
3493 extra[k++] = i->main_pid;
3495 if (i->control_pid > 0)
3496 extra[k++] = i->control_pid;
3498 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3502 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3503 show_journal_by_unit(
3508 i->inactive_exit_timestamp_monotonic,
3511 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3512 SD_JOURNAL_LOCAL_ONLY,
3513 arg_scope == UNIT_FILE_SYSTEM,
3517 if (i->need_daemon_reload)
3518 warn_unit_file_changed(i->id);
3521 static void show_unit_help(UnitStatusInfo *i) {
3526 if (!i->documentation) {
3527 log_info("Documentation for %s not known.", i->id);
3531 STRV_FOREACH(p, i->documentation)
3532 if (startswith(*p, "man:"))
3533 show_man_page(*p + 4, false);
3535 log_info("Can't show: %s", *p);
3538 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3545 switch (contents[0]) {
3547 case SD_BUS_TYPE_STRING: {
3550 r = sd_bus_message_read(m, "s", &s);
3552 return bus_log_parse_error(r);
3555 if (streq(name, "Id"))
3557 else if (streq(name, "LoadState"))
3559 else if (streq(name, "ActiveState"))
3560 i->active_state = s;
3561 else if (streq(name, "SubState"))
3563 else if (streq(name, "Description"))
3565 else if (streq(name, "FragmentPath"))
3566 i->fragment_path = s;
3567 else if (streq(name, "SourcePath"))
3570 else if (streq(name, "DefaultControlGroup")) {
3572 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3574 i->control_group = e;
3577 else if (streq(name, "ControlGroup"))
3578 i->control_group = s;
3579 else if (streq(name, "StatusText"))
3581 else if (streq(name, "PIDFile"))
3583 else if (streq(name, "SysFSPath"))
3585 else if (streq(name, "Where"))
3587 else if (streq(name, "What"))
3589 else if (streq(name, "Following"))
3591 else if (streq(name, "UnitFileState"))
3592 i->unit_file_state = s;
3593 else if (streq(name, "UnitFilePreset"))
3594 i->unit_file_preset = s;
3595 else if (streq(name, "Result"))
3602 case SD_BUS_TYPE_BOOLEAN: {
3605 r = sd_bus_message_read(m, "b", &b);
3607 return bus_log_parse_error(r);
3609 if (streq(name, "Accept"))
3611 else if (streq(name, "NeedDaemonReload"))
3612 i->need_daemon_reload = b;
3613 else if (streq(name, "ConditionResult"))
3614 i->condition_result = b;
3615 else if (streq(name, "AssertResult"))
3616 i->assert_result = b;
3621 case SD_BUS_TYPE_UINT32: {
3624 r = sd_bus_message_read(m, "u", &u);
3626 return bus_log_parse_error(r);
3628 if (streq(name, "MainPID")) {
3630 i->main_pid = (pid_t) u;
3633 } else if (streq(name, "ControlPID"))
3634 i->control_pid = (pid_t) u;
3635 else if (streq(name, "ExecMainPID")) {
3637 i->main_pid = (pid_t) u;
3638 } else if (streq(name, "NAccepted"))
3640 else if (streq(name, "NConnections"))
3641 i->n_connections = u;
3646 case SD_BUS_TYPE_INT32: {
3649 r = sd_bus_message_read(m, "i", &j);
3651 return bus_log_parse_error(r);
3653 if (streq(name, "ExecMainCode"))
3654 i->exit_code = (int) j;
3655 else if (streq(name, "ExecMainStatus"))
3656 i->exit_status = (int) j;
3657 else if (streq(name, "StatusErrno"))
3658 i->status_errno = (int) j;
3663 case SD_BUS_TYPE_UINT64: {
3666 r = sd_bus_message_read(m, "t", &u);
3668 return bus_log_parse_error(r);
3670 if (streq(name, "ExecMainStartTimestamp"))
3671 i->start_timestamp = (usec_t) u;
3672 else if (streq(name, "ExecMainExitTimestamp"))
3673 i->exit_timestamp = (usec_t) u;
3674 else if (streq(name, "ActiveEnterTimestamp"))
3675 i->active_enter_timestamp = (usec_t) u;
3676 else if (streq(name, "InactiveEnterTimestamp"))
3677 i->inactive_enter_timestamp = (usec_t) u;
3678 else if (streq(name, "InactiveExitTimestamp"))
3679 i->inactive_exit_timestamp = (usec_t) u;
3680 else if (streq(name, "InactiveExitTimestampMonotonic"))
3681 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3682 else if (streq(name, "ActiveExitTimestamp"))
3683 i->active_exit_timestamp = (usec_t) u;
3684 else if (streq(name, "ConditionTimestamp"))
3685 i->condition_timestamp = (usec_t) u;
3686 else if (streq(name, "AssertTimestamp"))
3687 i->assert_timestamp = (usec_t) u;
3688 else if (streq(name, "MemoryCurrent"))
3689 i->memory_current = u;
3690 else if (streq(name, "MemoryLimit"))
3691 i->memory_limit = u;
3692 else if (streq(name, "CPUUsageNSec"))
3693 i->cpu_usage_nsec = u;
3698 case SD_BUS_TYPE_ARRAY:
3700 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3701 _cleanup_free_ ExecStatusInfo *info = NULL;
3703 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3705 return bus_log_parse_error(r);
3707 info = new0(ExecStatusInfo, 1);
3711 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3713 info->name = strdup(name);
3717 LIST_PREPEND(exec, i->exec, info);
3719 info = new0(ExecStatusInfo, 1);
3725 return bus_log_parse_error(r);
3727 r = sd_bus_message_exit_container(m);
3729 return bus_log_parse_error(r);
3733 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3734 const char *type, *path;
3736 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3738 return bus_log_parse_error(r);
3740 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3742 r = strv_extend(&i->listen, type);
3746 r = strv_extend(&i->listen, path);
3751 return bus_log_parse_error(r);
3753 r = sd_bus_message_exit_container(m);
3755 return bus_log_parse_error(r);
3759 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3761 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3763 return bus_log_parse_error(r);
3765 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3767 r = sd_bus_message_read_strv(m, &i->documentation);
3769 return bus_log_parse_error(r);
3771 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3772 const char *cond, *param;
3773 int trigger, negate;
3776 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3778 return bus_log_parse_error(r);
3780 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3781 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3782 if (state < 0 && (!trigger || !i->failed_condition)) {
3783 i->failed_condition = cond;
3784 i->failed_condition_trigger = trigger;
3785 i->failed_condition_negate = negate;
3786 i->failed_condition_parameter = param;
3790 return bus_log_parse_error(r);
3792 r = sd_bus_message_exit_container(m);
3794 return bus_log_parse_error(r);
3796 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3797 const char *cond, *param;
3798 int trigger, negate;
3801 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3803 return bus_log_parse_error(r);
3805 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3806 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3807 if (state < 0 && (!trigger || !i->failed_assert)) {
3808 i->failed_assert = cond;
3809 i->failed_assert_trigger = trigger;
3810 i->failed_assert_negate = negate;
3811 i->failed_assert_parameter = param;
3815 return bus_log_parse_error(r);
3817 r = sd_bus_message_exit_container(m);
3819 return bus_log_parse_error(r);
3826 case SD_BUS_TYPE_STRUCT_BEGIN:
3828 if (streq(name, "LoadError")) {
3829 const char *n, *message;
3831 r = sd_bus_message_read(m, "(ss)", &n, &message);
3833 return bus_log_parse_error(r);
3835 if (!isempty(message))
3836 i->load_error = message;
3849 r = sd_bus_message_skip(m, contents);
3851 return bus_log_parse_error(r);
3856 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3862 /* This is a low-level property printer, see
3863 * print_status_info() for the nicer output */
3865 if (arg_properties && !strv_find(arg_properties, name)) {
3866 /* skip what we didn't read */
3867 r = sd_bus_message_skip(m, contents);
3871 switch (contents[0]) {
3873 case SD_BUS_TYPE_STRUCT_BEGIN:
3875 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3878 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3880 return bus_log_parse_error(r);
3883 printf("%s=%"PRIu32"\n", name, u);
3885 printf("%s=\n", name);
3889 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3892 r = sd_bus_message_read(m, "(so)", &s, NULL);
3894 return bus_log_parse_error(r);
3896 if (arg_all || !isempty(s))
3897 printf("%s=%s\n", name, s);
3901 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3902 const char *a = NULL, *b = NULL;
3904 r = sd_bus_message_read(m, "(ss)", &a, &b);
3906 return bus_log_parse_error(r);
3908 if (arg_all || !isempty(a) || !isempty(b))
3909 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3912 } else if (streq_ptr(name, "SystemCallFilter")) {
3913 _cleanup_strv_free_ char **l = NULL;
3916 r = sd_bus_message_enter_container(m, 'r', "bas");
3918 return bus_log_parse_error(r);
3920 r = sd_bus_message_read(m, "b", &whitelist);
3922 return bus_log_parse_error(r);
3924 r = sd_bus_message_read_strv(m, &l);
3926 return bus_log_parse_error(r);
3928 r = sd_bus_message_exit_container(m);
3930 return bus_log_parse_error(r);
3932 if (arg_all || whitelist || !strv_isempty(l)) {
3936 fputs(name, stdout);
3942 STRV_FOREACH(i, l) {
3950 fputc('\n', stdout);
3958 case SD_BUS_TYPE_ARRAY:
3960 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3964 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3966 return bus_log_parse_error(r);
3968 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3969 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3972 return bus_log_parse_error(r);
3974 r = sd_bus_message_exit_container(m);
3976 return bus_log_parse_error(r);
3980 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3981 const char *type, *path;
3983 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3985 return bus_log_parse_error(r);
3987 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3988 printf("%s=%s\n", type, path);
3990 return bus_log_parse_error(r);
3992 r = sd_bus_message_exit_container(m);
3994 return bus_log_parse_error(r);
3998 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3999 const char *type, *path;
4001 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4003 return bus_log_parse_error(r);
4005 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4006 printf("Listen%s=%s\n", type, path);
4008 return bus_log_parse_error(r);
4010 r = sd_bus_message_exit_container(m);
4012 return bus_log_parse_error(r);
4016 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4018 uint64_t value, next_elapse;
4020 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4022 return bus_log_parse_error(r);
4024 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4025 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4027 printf("%s={ value=%s ; next_elapse=%s }\n",
4029 format_timespan(timespan1, sizeof(timespan1), value, 0),
4030 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4033 return bus_log_parse_error(r);
4035 r = sd_bus_message_exit_container(m);
4037 return bus_log_parse_error(r);
4041 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4042 ExecStatusInfo info = {};
4044 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4046 return bus_log_parse_error(r);
4048 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4049 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4050 _cleanup_free_ char *tt;
4052 tt = strv_join(info.argv, " ");
4054 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",
4058 yes_no(info.ignore),
4059 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4060 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4062 sigchld_code_to_string(info.code),
4064 info.code == CLD_EXITED ? "" : "/",
4065 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4068 strv_free(info.argv);
4072 r = sd_bus_message_exit_container(m);
4074 return bus_log_parse_error(r);
4078 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4079 const char *path, *rwm;
4081 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4083 return bus_log_parse_error(r);
4085 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4086 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4088 return bus_log_parse_error(r);
4090 r = sd_bus_message_exit_container(m);
4092 return bus_log_parse_error(r);
4096 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4100 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4102 return bus_log_parse_error(r);
4104 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4105 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4107 return bus_log_parse_error(r);
4109 r = sd_bus_message_exit_container(m);
4111 return bus_log_parse_error(r);
4115 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4119 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4121 return bus_log_parse_error(r);
4123 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4124 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4126 return bus_log_parse_error(r);
4128 r = sd_bus_message_exit_container(m);
4130 return bus_log_parse_error(r);
4138 r = bus_print_property(name, m, arg_all);
4140 return bus_log_parse_error(r);
4143 r = sd_bus_message_skip(m, contents);
4145 return bus_log_parse_error(r);
4148 printf("%s=[unprintable]\n", name);
4154 static int show_one(
4158 bool show_properties,
4162 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4163 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4164 UnitStatusInfo info = {
4165 .memory_current = (uint64_t) -1,
4166 .memory_limit = (uint64_t) -1,
4167 .cpu_usage_nsec = (uint64_t) -1,
4175 log_debug("Showing one %s", path);
4177 r = sd_bus_call_method(
4179 "org.freedesktop.systemd1",
4181 "org.freedesktop.DBus.Properties",
4187 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4191 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4193 return bus_log_parse_error(r);
4200 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4201 const char *name, *contents;
4203 r = sd_bus_message_read(reply, "s", &name);
4205 return bus_log_parse_error(r);
4207 r = sd_bus_message_peek_type(reply, NULL, &contents);
4209 return bus_log_parse_error(r);
4211 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4213 return bus_log_parse_error(r);
4215 if (show_properties)
4216 r = print_property(name, reply, contents);
4218 r = status_property(name, reply, &info, contents);
4222 r = sd_bus_message_exit_container(reply);
4224 return bus_log_parse_error(r);
4226 r = sd_bus_message_exit_container(reply);
4228 return bus_log_parse_error(r);
4231 return bus_log_parse_error(r);
4233 r = sd_bus_message_exit_container(reply);
4235 return bus_log_parse_error(r);
4239 if (!show_properties) {
4240 if (streq(verb, "help"))
4241 show_unit_help(&info);
4243 print_status_info(&info, ellipsized);
4246 strv_free(info.documentation);
4247 strv_free(info.dropin_paths);
4248 strv_free(info.listen);
4250 if (!streq_ptr(info.active_state, "active") &&
4251 !streq_ptr(info.active_state, "reloading") &&
4252 streq(verb, "status")) {
4253 /* According to LSB: "program not running" */
4254 /* 0: program is running or service is OK
4255 * 1: program is dead and /run PID file exists
4256 * 2: program is dead and /run/lock lock file exists
4257 * 3: program is not running
4258 * 4: program or service status is unknown
4260 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4266 while ((p = info.exec)) {
4267 LIST_REMOVE(exec, info.exec, p);
4268 exec_status_info_free(p);
4274 static int get_unit_dbus_path_by_pid(
4279 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4280 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4284 r = sd_bus_call_method(
4286 "org.freedesktop.systemd1",
4287 "/org/freedesktop/systemd1",
4288 "org.freedesktop.systemd1.Manager",
4294 log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4298 r = sd_bus_message_read(reply, "o", &u);
4300 return bus_log_parse_error(r);
4310 static int show_all(
4313 bool show_properties,
4317 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4318 _cleanup_free_ UnitInfo *unit_infos = NULL;
4323 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4327 pager_open_if_enabled();
4331 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4333 for (u = unit_infos; u < unit_infos + c; u++) {
4334 _cleanup_free_ char *p = NULL;
4336 p = unit_dbus_path_from_name(u->id);
4340 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4343 else if (r > 0 && ret == 0)
4350 static int show_system_status(sd_bus *bus) {
4351 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4352 _cleanup_free_ char *hn = NULL;
4353 struct machine_info mi = {};
4354 const char *on, *off;
4357 hn = gethostname_malloc();
4361 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4363 return log_error_errno(r, "Failed to read server status: %m");
4365 if (streq_ptr(mi.state, "degraded")) {
4366 on = ansi_highlight_red();
4367 off = ansi_highlight_off();
4368 } else if (!streq_ptr(mi.state, "running")) {
4369 on = ansi_highlight_yellow();
4370 off = ansi_highlight_off();
4374 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4376 printf(" State: %s%s%s\n",
4377 on, strna(mi.state), off);
4379 printf(" Jobs: %u queued\n", mi.n_jobs);
4380 printf(" Failed: %u units\n", mi.n_failed_units);
4382 printf(" Since: %s; %s\n",
4383 format_timestamp(since2, sizeof(since2), mi.timestamp),
4384 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4386 printf(" CGroup: %s\n", mi.control_group ?: "/");
4387 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4388 static const char prefix[] = " ";
4392 if (c > sizeof(prefix) - 1)
4393 c -= sizeof(prefix) - 1;
4397 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4401 free(mi.control_group);
4406 static int show(sd_bus *bus, char **args) {
4407 bool show_properties, show_status, new_line = false;
4408 bool ellipsized = false;
4414 show_properties = streq(args[0], "show");
4415 show_status = streq(args[0], "status");
4417 if (show_properties)
4418 pager_open_if_enabled();
4420 /* If no argument is specified inspect the manager itself */
4422 if (show_properties && strv_length(args) <= 1)
4423 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4425 if (show_status && strv_length(args) <= 1) {
4427 pager_open_if_enabled();
4428 show_system_status(bus);
4432 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4434 _cleanup_free_ char **patterns = NULL;
4437 STRV_FOREACH(name, args + 1) {
4438 _cleanup_free_ char *unit = NULL;
4441 if (safe_atou32(*name, &id) < 0) {
4442 if (strv_push(&patterns, *name) < 0)
4446 } else if (show_properties) {
4447 /* Interpret as job id */
4448 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4452 /* Interpret as PID */
4453 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4460 r = show_one(args[0], bus, unit, show_properties,
4461 &new_line, &ellipsized);
4464 else if (r > 0 && ret == 0)
4468 if (!strv_isempty(patterns)) {
4469 _cleanup_strv_free_ char **names = NULL;
4471 r = expand_names(bus, patterns, NULL, &names);
4473 log_error_errno(r, "Failed to expand names: %m");
4475 STRV_FOREACH(name, names) {
4476 _cleanup_free_ char *unit;
4478 unit = unit_dbus_path_from_name(*name);
4482 r = show_one(args[0], bus, unit, show_properties,
4483 &new_line, &ellipsized);
4486 else if (r > 0 && ret == 0)
4492 if (ellipsized && !arg_quiet)
4493 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4498 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4502 assert(user_runtime);
4505 if (arg_scope == UNIT_FILE_USER) {
4506 r = user_config_home(user_home);
4508 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4510 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4512 r = user_runtime_dir(user_runtime);
4514 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4516 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4519 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4521 return log_error_errno(r, "Failed to query unit lookup paths: %m");
4526 static int cat_file(const char *filename, bool newline) {
4527 _cleanup_close_ int fd;
4529 fd = open(filename, O_RDONLY|O_CLOEXEC|O_NOCTTY);
4533 printf("%s%s# %s%s\n",
4534 newline ? "\n" : "",
4535 ansi_highlight_blue(),
4537 ansi_highlight_off());
4540 return copy_bytes(fd, STDOUT_FILENO, (off_t) -1, false);
4543 static int cat(sd_bus *bus, char **args) {
4544 _cleanup_free_ char *user_home = NULL;
4545 _cleanup_free_ char *user_runtime = NULL;
4546 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4547 _cleanup_strv_free_ char **names = NULL;
4549 bool first = true, avoid_bus_cache;
4554 if (arg_transport != BUS_TRANSPORT_LOCAL) {
4555 log_error("Cannot remotely cat units");
4559 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4563 r = expand_names(bus, args + 1, NULL, &names);
4565 return log_error_errno(r, "Failed to expand names: %m");
4567 avoid_bus_cache = !bus || avoid_bus();
4569 pager_open_if_enabled();
4571 STRV_FOREACH(name, names) {
4572 _cleanup_free_ char *fragment_path = NULL;
4573 _cleanup_strv_free_ char **dropin_paths = NULL;
4576 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4587 if (fragment_path) {
4588 r = cat_file(fragment_path, false);
4590 return log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4593 STRV_FOREACH(path, dropin_paths) {
4594 r = cat_file(*path, path == dropin_paths);
4596 return log_warning_errno(r, "Failed to cat %s: %m", *path);
4603 static int set_property(sd_bus *bus, char **args) {
4604 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4605 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4606 _cleanup_free_ char *n = NULL;
4610 polkit_agent_open_if_enabled();
4612 r = sd_bus_message_new_method_call(
4615 "org.freedesktop.systemd1",
4616 "/org/freedesktop/systemd1",
4617 "org.freedesktop.systemd1.Manager",
4618 "SetUnitProperties");
4620 return bus_log_create_error(r);
4622 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4626 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4628 return bus_log_create_error(r);
4630 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4632 return bus_log_create_error(r);
4634 STRV_FOREACH(i, args + 2) {
4635 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4637 return bus_log_create_error(r);
4639 r = bus_append_unit_property_assignment(m, *i);
4643 r = sd_bus_message_close_container(m);
4645 return bus_log_create_error(r);
4648 r = sd_bus_message_close_container(m);
4650 return bus_log_create_error(r);
4652 r = sd_bus_call(bus, m, 0, &error, NULL);
4654 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4661 static int snapshot(sd_bus *bus, char **args) {
4662 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4663 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4664 _cleanup_free_ char *n = NULL, *id = NULL;
4668 polkit_agent_open_if_enabled();
4670 if (strv_length(args) > 1)
4671 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4677 r = sd_bus_call_method(
4679 "org.freedesktop.systemd1",
4680 "/org/freedesktop/systemd1",
4681 "org.freedesktop.systemd1.Manager",
4687 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4691 r = sd_bus_message_read(reply, "o", &path);
4693 return bus_log_parse_error(r);
4695 r = sd_bus_get_property_string(
4697 "org.freedesktop.systemd1",
4699 "org.freedesktop.systemd1.Unit",
4704 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4714 static int delete_snapshot(sd_bus *bus, char **args) {
4715 _cleanup_strv_free_ char **names = NULL;
4721 polkit_agent_open_if_enabled();
4723 r = expand_names(bus, args + 1, ".snapshot", &names);
4725 log_error_errno(r, "Failed to expand names: %m");
4727 STRV_FOREACH(name, names) {
4728 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4731 q = sd_bus_call_method(
4733 "org.freedesktop.systemd1",
4734 "/org/freedesktop/systemd1",
4735 "org.freedesktop.systemd1.Manager",
4741 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4750 static int daemon_reload(sd_bus *bus, char **args) {
4751 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4755 polkit_agent_open_if_enabled();
4757 if (arg_action == ACTION_RELOAD)
4759 else if (arg_action == ACTION_REEXEC)
4760 method = "Reexecute";
4762 assert(arg_action == ACTION_SYSTEMCTL);
4765 streq(args[0], "clear-jobs") ||
4766 streq(args[0], "cancel") ? "ClearJobs" :
4767 streq(args[0], "daemon-reexec") ? "Reexecute" :
4768 streq(args[0], "reset-failed") ? "ResetFailed" :
4769 streq(args[0], "halt") ? "Halt" :
4770 streq(args[0], "poweroff") ? "PowerOff" :
4771 streq(args[0], "reboot") ? "Reboot" :
4772 streq(args[0], "kexec") ? "KExec" :
4773 streq(args[0], "exit") ? "Exit" :
4774 /* "daemon-reload" */ "Reload";
4777 r = sd_bus_call_method(
4779 "org.freedesktop.systemd1",
4780 "/org/freedesktop/systemd1",
4781 "org.freedesktop.systemd1.Manager",
4786 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4787 /* There's always a fallback possible for
4788 * legacy actions. */
4790 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4791 /* On reexecution, we expect a disconnect, not a
4795 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4797 return r < 0 ? r : 0;
4800 static int reset_failed(sd_bus *bus, char **args) {
4801 _cleanup_strv_free_ char **names = NULL;
4805 if (strv_length(args) <= 1)
4806 return daemon_reload(bus, args);
4808 polkit_agent_open_if_enabled();
4810 r = expand_names(bus, args + 1, NULL, &names);
4812 log_error_errno(r, "Failed to expand names: %m");
4814 STRV_FOREACH(name, names) {
4815 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4817 q = sd_bus_call_method(
4819 "org.freedesktop.systemd1",
4820 "/org/freedesktop/systemd1",
4821 "org.freedesktop.systemd1.Manager",
4827 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4836 static int show_environment(sd_bus *bus, char **args) {
4837 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4838 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4842 pager_open_if_enabled();
4844 r = sd_bus_get_property(
4846 "org.freedesktop.systemd1",
4847 "/org/freedesktop/systemd1",
4848 "org.freedesktop.systemd1.Manager",
4854 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4858 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4860 return bus_log_parse_error(r);
4862 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4865 return bus_log_parse_error(r);
4867 r = sd_bus_message_exit_container(reply);
4869 return bus_log_parse_error(r);
4874 static int switch_root(sd_bus *bus, char **args) {
4875 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4876 _cleanup_free_ char *cmdline_init = NULL;
4877 const char *root, *init;
4881 l = strv_length(args);
4882 if (l < 2 || l > 3) {
4883 log_error("Wrong number of arguments.");
4892 r = parse_env_file("/proc/cmdline", WHITESPACE,
4893 "init", &cmdline_init,
4896 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4898 init = cmdline_init;
4905 const char *root_systemd_path = NULL, *root_init_path = NULL;
4907 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
4908 root_init_path = strjoina(root, "/", init);
4910 /* If the passed init is actually the same as the
4911 * systemd binary, then let's suppress it. */
4912 if (files_same(root_init_path, root_systemd_path) > 0)
4916 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4918 r = sd_bus_call_method(
4920 "org.freedesktop.systemd1",
4921 "/org/freedesktop/systemd1",
4922 "org.freedesktop.systemd1.Manager",
4928 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4935 static int set_environment(sd_bus *bus, char **args) {
4936 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4937 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4944 polkit_agent_open_if_enabled();
4946 method = streq(args[0], "set-environment")
4948 : "UnsetEnvironment";
4950 r = sd_bus_message_new_method_call(
4953 "org.freedesktop.systemd1",
4954 "/org/freedesktop/systemd1",
4955 "org.freedesktop.systemd1.Manager",
4958 return bus_log_create_error(r);
4960 r = sd_bus_message_append_strv(m, args + 1);
4962 return bus_log_create_error(r);
4964 r = sd_bus_call(bus, m, 0, &error, NULL);
4966 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4973 static int import_environment(sd_bus *bus, char **args) {
4974 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4975 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4981 polkit_agent_open_if_enabled();
4983 r = sd_bus_message_new_method_call(
4986 "org.freedesktop.systemd1",
4987 "/org/freedesktop/systemd1",
4988 "org.freedesktop.systemd1.Manager",
4991 return bus_log_create_error(r);
4993 if (strv_isempty(args + 1))
4994 r = sd_bus_message_append_strv(m, environ);
4998 r = sd_bus_message_open_container(m, 'a', "s");
5000 return bus_log_create_error(r);
5002 STRV_FOREACH(a, args + 1) {
5004 if (!env_name_is_valid(*a)) {
5005 log_error("Not a valid environment variable name: %s", *a);
5009 STRV_FOREACH(b, environ) {
5012 eq = startswith(*b, *a);
5013 if (eq && *eq == '=') {
5015 r = sd_bus_message_append(m, "s", *b);
5017 return bus_log_create_error(r);
5024 r = sd_bus_message_close_container(m);
5027 return bus_log_create_error(r);
5029 r = sd_bus_call(bus, m, 0, &error, NULL);
5031 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5038 static int enable_sysv_units(const char *verb, char **args) {
5041 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5043 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5045 if (arg_scope != UNIT_FILE_SYSTEM)
5048 if (!streq(verb, "enable") &&
5049 !streq(verb, "disable") &&
5050 !streq(verb, "is-enabled"))
5053 /* Processes all SysV units, and reshuffles the array so that
5054 * afterwards only the native units remain */
5056 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5063 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5064 bool found_native = false, found_sysv;
5066 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5074 if (!endswith(name, ".service"))
5077 if (path_is_absolute(name))
5080 STRV_FOREACH(k, paths.unit_path) {
5081 _cleanup_free_ char *path = NULL;
5083 path = path_join(arg_root, *k, name);
5087 found_native = access(path, F_OK) >= 0;
5095 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5099 p[strlen(p) - strlen(".service")] = 0;
5100 found_sysv = access(p, F_OK) >= 0;
5104 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5106 if (!isempty(arg_root))
5107 argv[c++] = q = strappend("--root=", arg_root);
5109 argv[c++] = basename(p);
5111 streq(verb, "enable") ? "on" :
5112 streq(verb, "disable") ? "off" : "--level=5";
5115 l = strv_join((char**)argv, " ");
5119 log_info("Executing %s", l);
5123 return log_error_errno(errno, "Failed to fork: %m");
5124 else if (pid == 0) {
5127 execv(argv[0], (char**) argv);
5128 _exit(EXIT_FAILURE);
5131 j = wait_for_terminate(pid, &status);
5133 log_error_errno(r, "Failed to wait for child: %m");
5137 if (status.si_code == CLD_EXITED) {
5138 if (streq(verb, "is-enabled")) {
5139 if (status.si_status == 0) {
5148 } else if (status.si_status != 0)
5153 /* Remove this entry, so that we don't try enabling it as native unit */
5156 assert(args[f] == name);
5157 strv_remove(args, name);
5164 static int mangle_names(char **original_names, char ***mangled_names) {
5165 char **i, **l, **name;
5167 l = new(char*, strv_length(original_names) + 1);
5172 STRV_FOREACH(name, original_names) {
5174 /* When enabling units qualified path names are OK,
5175 * too, hence allow them explicitly. */
5180 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5196 static int enable_unit(sd_bus *bus, char **args) {
5197 _cleanup_strv_free_ char **names = NULL;
5198 const char *verb = args[0];
5199 UnitFileChange *changes = NULL;
5200 unsigned n_changes = 0;
5201 int carries_install_info = -1;
5207 r = mangle_names(args+1, &names);
5211 r = enable_sysv_units(verb, names);
5215 /* If the operation was fully executed by the SysV compat,
5216 * let's finish early */
5217 if (strv_isempty(names))
5220 if (!bus || avoid_bus()) {
5221 if (streq(verb, "enable")) {
5222 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5223 carries_install_info = r;
5224 } else if (streq(verb, "disable"))
5225 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5226 else if (streq(verb, "reenable")) {
5227 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5228 carries_install_info = r;
5229 } else if (streq(verb, "link"))
5230 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5231 else if (streq(verb, "preset")) {
5232 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5233 carries_install_info = r;
5234 } else if (streq(verb, "mask"))
5235 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5236 else if (streq(verb, "unmask"))
5237 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5239 assert_not_reached("Unknown verb");
5242 log_error_errno(r, "Operation failed: %m");
5247 dump_unit_file_changes(changes, n_changes);
5251 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5252 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5253 int expect_carries_install_info = false;
5254 bool send_force = true, send_preset_mode = false;
5257 polkit_agent_open_if_enabled();
5259 if (streq(verb, "enable")) {
5260 method = "EnableUnitFiles";
5261 expect_carries_install_info = true;
5262 } else if (streq(verb, "disable")) {
5263 method = "DisableUnitFiles";
5265 } else if (streq(verb, "reenable")) {
5266 method = "ReenableUnitFiles";
5267 expect_carries_install_info = true;
5268 } else if (streq(verb, "link"))
5269 method = "LinkUnitFiles";
5270 else if (streq(verb, "preset")) {
5272 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5273 method = "PresetUnitFilesWithMode";
5274 send_preset_mode = true;
5276 method = "PresetUnitFiles";
5278 expect_carries_install_info = true;
5279 } else if (streq(verb, "mask"))
5280 method = "MaskUnitFiles";
5281 else if (streq(verb, "unmask")) {
5282 method = "UnmaskUnitFiles";
5285 assert_not_reached("Unknown verb");
5287 r = sd_bus_message_new_method_call(
5290 "org.freedesktop.systemd1",
5291 "/org/freedesktop/systemd1",
5292 "org.freedesktop.systemd1.Manager",
5295 return bus_log_create_error(r);
5297 r = sd_bus_message_append_strv(m, names);
5299 return bus_log_create_error(r);
5301 if (send_preset_mode) {
5302 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5304 return bus_log_create_error(r);
5307 r = sd_bus_message_append(m, "b", arg_runtime);
5309 return bus_log_create_error(r);
5312 r = sd_bus_message_append(m, "b", arg_force);
5314 return bus_log_create_error(r);
5317 r = sd_bus_call(bus, m, 0, &error, &reply);
5319 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5323 if (expect_carries_install_info) {
5324 r = sd_bus_message_read(reply, "b", &carries_install_info);
5326 return bus_log_parse_error(r);
5329 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5333 /* Try to reload if enabled */
5335 r = daemon_reload(bus, args);
5340 if (carries_install_info == 0)
5341 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5342 "using systemctl.\n"
5343 "Possible reasons for having this kind of units are:\n"
5344 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5345 " .wants/ or .requires/ directory.\n"
5346 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5347 " a requirement dependency on it.\n"
5348 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5349 " D-Bus, udev, scripted systemctl call, ...).\n");
5352 unit_file_changes_free(changes, n_changes);
5357 static int add_dependency(sd_bus *bus, char **args) {
5358 _cleanup_strv_free_ char **names = NULL;
5359 _cleanup_free_ char *target = NULL;
5360 const char *verb = args[0];
5367 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5371 r = mangle_names(args+2, &names);
5375 if (streq(verb, "add-wants"))
5377 else if (streq(verb, "add-requires"))
5378 dep = UNIT_REQUIRES;
5380 assert_not_reached("Unknown verb");
5382 if (!bus || avoid_bus()) {
5383 UnitFileChange *changes = NULL;
5384 unsigned n_changes = 0;
5386 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5389 return log_error_errno(r, "Can't add dependency: %m");
5392 dump_unit_file_changes(changes, n_changes);
5394 unit_file_changes_free(changes, n_changes);
5397 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5398 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5400 polkit_agent_open_if_enabled();
5402 r = sd_bus_message_new_method_call(
5405 "org.freedesktop.systemd1",
5406 "/org/freedesktop/systemd1",
5407 "org.freedesktop.systemd1.Manager",
5408 "AddDependencyUnitFiles");
5410 return bus_log_create_error(r);
5412 r = sd_bus_message_append_strv(m, names);
5414 return bus_log_create_error(r);
5416 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5418 return bus_log_create_error(r);
5420 r = sd_bus_call(bus, m, 0, &error, &reply);
5422 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5426 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5431 r = daemon_reload(bus, args);
5439 static int preset_all(sd_bus *bus, char **args) {
5440 UnitFileChange *changes = NULL;
5441 unsigned n_changes = 0;
5444 if (!bus || avoid_bus()) {
5446 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5448 log_error_errno(r, "Operation failed: %m");
5453 dump_unit_file_changes(changes, n_changes);
5458 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5459 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5461 polkit_agent_open_if_enabled();
5463 r = sd_bus_call_method(
5465 "org.freedesktop.systemd1",
5466 "/org/freedesktop/systemd1",
5467 "org.freedesktop.systemd1.Manager",
5468 "PresetAllUnitFiles",
5472 unit_file_preset_mode_to_string(arg_preset_mode),
5476 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5480 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5485 r = daemon_reload(bus, args);
5491 unit_file_changes_free(changes, n_changes);
5496 static int unit_is_enabled(sd_bus *bus, char **args) {
5498 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5499 _cleanup_strv_free_ char **names = NULL;
5504 r = mangle_names(args+1, &names);
5508 r = enable_sysv_units(args[0], names);
5514 if (!bus || avoid_bus()) {
5516 STRV_FOREACH(name, names) {
5517 UnitFileState state;
5519 state = unit_file_get_state(arg_scope, arg_root, *name);
5521 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5523 if (state == UNIT_FILE_ENABLED ||
5524 state == UNIT_FILE_ENABLED_RUNTIME ||
5525 state == UNIT_FILE_STATIC ||
5526 state == UNIT_FILE_INDIRECT)
5530 puts(unit_file_state_to_string(state));
5534 STRV_FOREACH(name, names) {
5535 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5538 r = sd_bus_call_method(
5540 "org.freedesktop.systemd1",
5541 "/org/freedesktop/systemd1",
5542 "org.freedesktop.systemd1.Manager",
5548 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5552 r = sd_bus_message_read(reply, "s", &s);
5554 return bus_log_parse_error(r);
5556 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5567 static int is_system_running(sd_bus *bus, char **args) {
5568 _cleanup_free_ char *state = NULL;
5571 r = sd_bus_get_property_string(
5573 "org.freedesktop.systemd1",
5574 "/org/freedesktop/systemd1",
5575 "org.freedesktop.systemd1.Manager",
5588 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5591 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5596 assert(original_path);
5599 r = tempfn_random(new_path, &t);
5601 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5603 r = mkdir_parents(new_path, 0755);
5605 log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5610 r = copy_file(original_path, t, 0, 0644, 0);
5614 log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5619 log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5629 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5630 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5632 switch (arg_scope) {
5633 case UNIT_FILE_SYSTEM:
5634 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5636 run = path_join(arg_root, "/run/systemd/system/", name);
5638 case UNIT_FILE_GLOBAL:
5639 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5641 run = path_join(arg_root, "/run/systemd/user/", name);
5643 case UNIT_FILE_USER:
5645 assert(user_runtime);
5647 path = path_join(arg_root, user_home, name);
5649 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5652 run = path_join(arg_root, user_runtime, name);
5656 assert_not_reached("Invalid scope");
5658 if (!path || (arg_runtime && !run))
5662 if (access(path, F_OK) >= 0)
5663 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5665 if (path2 && access(path2, F_OK) >= 0)
5666 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5678 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) {
5679 char *tmp_new_path, *ending;
5684 assert(ret_new_path);
5685 assert(ret_tmp_path);
5687 ending = strjoina(unit_name, ".d/override.conf");
5688 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5692 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5698 *ret_new_path = tmp_new_path;
5699 *ret_tmp_path = tmp_tmp_path;
5704 static int unit_file_create_copy(
5705 const char *unit_name,
5706 const char *fragment_path,
5707 const char *user_home,
5708 const char *user_runtime,
5709 char **ret_new_path,
5710 char **ret_tmp_path) {
5716 assert(fragment_path);
5718 assert(ret_new_path);
5719 assert(ret_tmp_path);
5721 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5725 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5728 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5733 if (response != 'y') {
5734 log_warning("%s ignored", unit_name);
5740 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5742 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
5747 *ret_new_path = tmp_new_path;
5748 *ret_tmp_path = tmp_tmp_path;
5753 static int run_editor(char **paths) {
5761 log_error_errno(errno, "Failed to fork: %m");
5768 char **tmp_path, **original_path, *p;
5772 argc = strv_length(paths)/2 + 1;
5773 args = newa(const char*, argc + 1);
5776 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5777 args[i] = *tmp_path;
5782 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5783 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5784 * we try to execute well known editors
5786 editor = getenv("SYSTEMD_EDITOR");
5788 editor = getenv("EDITOR");
5790 editor = getenv("VISUAL");
5792 if (!isempty(editor)) {
5794 execvp(editor, (char* const*) args);
5797 FOREACH_STRING(p, "nano", "vim", "vi") {
5799 execvp(p, (char* const*) args);
5800 /* We do not fail if the editor doesn't exist
5801 * because we want to try each one of them before
5804 if (errno != ENOENT) {
5805 log_error("Failed to execute %s: %m", editor);
5806 _exit(EXIT_FAILURE);
5810 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
5811 _exit(EXIT_FAILURE);
5814 r = wait_for_terminate_and_warn("editor", pid, true);
5816 return log_error_errno(r, "Failed to wait for child: %m");
5821 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5822 _cleanup_free_ char *user_home = NULL;
5823 _cleanup_free_ char *user_runtime = NULL;
5824 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5825 bool avoid_bus_cache;
5832 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5836 avoid_bus_cache = !bus || avoid_bus();
5838 STRV_FOREACH(name, names) {
5839 _cleanup_free_ char *path = NULL;
5840 char *new_path, *tmp_path;
5842 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5848 // FIXME: support units with path==NULL (no FragmentPath)
5849 log_error("No fragment exists for %s.", *name);
5854 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5856 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5860 r = strv_push_pair(paths, new_path, tmp_path);
5868 static int edit(sd_bus *bus, char **args) {
5869 _cleanup_strv_free_ char **names = NULL;
5870 _cleanup_strv_free_ char **paths = NULL;
5871 char **original, **tmp;
5877 log_error("Cannot edit units if not on a tty");
5881 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5882 log_error("Cannot remotely edit units");
5886 r = expand_names(bus, args + 1, NULL, &names);
5888 return log_error_errno(r, "Failed to expand names: %m");
5890 r = find_paths_to_edit(bus, names, &paths);
5894 if (strv_isempty(paths))
5897 r = run_editor(paths);
5901 STRV_FOREACH_PAIR(original, tmp, paths) {
5902 /* If the temporary file is empty we ignore it.
5903 * It's useful if the user wants to cancel its modification
5905 if (null_or_empty_path(*tmp)) {
5906 log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
5909 r = rename(*tmp, *original);
5911 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
5916 if (!arg_no_reload && bus && !avoid_bus())
5917 r = daemon_reload(bus, args);
5920 STRV_FOREACH_PAIR(original, tmp, paths)
5921 unlink_noerrno(*tmp);
5926 static void systemctl_help(void) {
5928 pager_open_if_enabled();
5930 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5931 "Query or send control commands to the systemd manager.\n\n"
5932 " -h --help Show this help\n"
5933 " --version Show package version\n"
5934 " --system Connect to system manager\n"
5935 " --user Connect to user service manager\n"
5936 " -H --host=[USER@]HOST\n"
5937 " Operate on remote host\n"
5938 " -M --machine=CONTAINER\n"
5939 " Operate on local container\n"
5940 " -t --type=TYPE List units of a particular type\n"
5941 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
5942 " -p --property=NAME Show only properties by this name\n"
5943 " -a --all Show all loaded units/properties, including dead/empty\n"
5944 " ones. To list all units installed on the system, use\n"
5945 " the 'list-unit-files' command instead.\n"
5946 " -l --full Don't ellipsize unit names on output\n"
5947 " -r --recursive Show unit list of host and local containers\n"
5948 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5949 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5950 " queueing a new job\n"
5951 " --show-types When showing sockets, explicitly show their type\n"
5952 " -i --ignore-inhibitors\n"
5953 " When shutting down or sleeping, ignore inhibitors\n"
5954 " --kill-who=WHO Who to send signal to\n"
5955 " -s --signal=SIGNAL Which signal to send\n"
5956 " -q --quiet Suppress output\n"
5957 " --no-block Do not wait until operation finished\n"
5958 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5959 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
5960 " --no-legend Do not print a legend (column headers and hints)\n"
5961 " --no-pager Do not pipe output into a pager\n"
5962 " --no-ask-password\n"
5963 " Do not ask for system passwords\n"
5964 " --global Enable/disable unit files globally\n"
5965 " --runtime Enable unit files only temporarily until next reboot\n"
5966 " -f --force When enabling unit files, override existing symlinks\n"
5967 " When shutting down, execute action immediately\n"
5968 " --preset-mode= Apply only enable, only disable, or all presets\n"
5969 " --root=PATH Enable unit files in the specified root directory\n"
5970 " -n --lines=INTEGER Number of journal entries to show\n"
5971 " -o --output=STRING Change journal output mode (short, short-iso,\n"
5972 " short-precise, short-monotonic, verbose,\n"
5973 " export, json, json-pretty, json-sse, cat)\n"
5974 " --plain Print unit dependencies as a list instead of a tree\n\n"
5976 " list-units [PATTERN...] List loaded units\n"
5977 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5978 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5979 " start NAME... Start (activate) one or more units\n"
5980 " stop NAME... Stop (deactivate) one or more units\n"
5981 " reload NAME... Reload one or more units\n"
5982 " restart NAME... Start or restart one or more units\n"
5983 " try-restart NAME... Restart one or more units if active\n"
5984 " reload-or-restart NAME... Reload one or more units if possible,\n"
5985 " otherwise start or restart\n"
5986 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5987 " otherwise restart if active\n"
5988 " isolate NAME Start one unit and stop all others\n"
5989 " kill NAME... Send signal to processes of a unit\n"
5990 " is-active PATTERN... Check whether units are active\n"
5991 " is-failed PATTERN... Check whether units are failed\n"
5992 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5993 " show [PATTERN...|JOB...] Show properties of one or more\n"
5994 " units/jobs or the manager\n"
5995 " cat PATTERN... Show files and drop-ins of one or more units\n"
5996 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5997 " help PATTERN...|PID... Show manual for one or more units\n"
5998 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6000 " list-dependencies [NAME] Recursively show units which are required\n"
6001 " or wanted by this unit or by which this\n"
6002 " unit is required or wanted\n\n"
6003 "Unit File Commands:\n"
6004 " list-unit-files [PATTERN...] List installed unit files\n"
6005 " enable NAME... Enable one or more unit files\n"
6006 " disable NAME... Disable one or more unit files\n"
6007 " reenable NAME... Reenable one or more unit files\n"
6008 " preset NAME... Enable/disable one or more unit files\n"
6009 " based on preset configuration\n"
6010 " preset-all Enable/disable all unit files based on\n"
6011 " preset configuration\n"
6012 " is-enabled NAME... Check whether unit files are enabled\n"
6013 " mask NAME... Mask one or more units\n"
6014 " unmask NAME... Unmask one or more units\n"
6015 " link PATH... Link one or more units files into\n"
6016 " the search path\n"
6017 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6018 " on specified one or more units\n"
6019 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6020 " on specified one or more units\n"
6021 " edit NAME... Edit one or more unit files\n"
6022 " get-default Get the name of the default target\n"
6023 " set-default NAME Set the default target\n\n"
6024 "Machine Commands:\n"
6025 " list-machines [PATTERN...] List local containers and host\n\n"
6027 " list-jobs [PATTERN...] List jobs\n"
6028 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6029 "Snapshot Commands:\n"
6030 " snapshot [NAME] Create a snapshot\n"
6031 " delete NAME... Remove one or more snapshots\n\n"
6032 "Environment Commands:\n"
6033 " show-environment Dump environment\n"
6034 " set-environment NAME=VALUE... Set one or more environment variables\n"
6035 " unset-environment NAME... Unset one or more environment variables\n"
6036 " import-environment [NAME...] Import all or some environment variables\n\n"
6037 "Manager Lifecycle Commands:\n"
6038 " daemon-reload Reload systemd manager configuration\n"
6039 " daemon-reexec Reexecute systemd manager\n\n"
6040 "System Commands:\n"
6041 " is-system-running Check whether system is fully running\n"
6042 " default Enter system default mode\n"
6043 " rescue Enter system rescue mode\n"
6044 " emergency Enter system emergency mode\n"
6045 " halt Shut down and halt the system\n"
6046 " poweroff Shut down and power-off the system\n"
6047 " reboot [ARG] Shut down and reboot the system\n"
6048 " kexec Shut down and reboot the system with kexec\n"
6049 " exit Request user instance exit\n"
6050 " switch-root ROOT [INIT] Change to a different root file system\n"
6051 " suspend Suspend the system\n"
6052 " hibernate Hibernate the system\n"
6053 " hybrid-sleep Hibernate and suspend the system\n",
6054 program_invocation_short_name);
6057 static void halt_help(void) {
6058 printf("%s [OPTIONS...]%s\n\n"
6059 "%s the system.\n\n"
6060 " --help Show this help\n"
6061 " --halt Halt the machine\n"
6062 " -p --poweroff Switch off the machine\n"
6063 " --reboot Reboot the machine\n"
6064 " -f --force Force immediate halt/power-off/reboot\n"
6065 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6066 " -d --no-wtmp Don't write wtmp record\n"
6067 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6068 program_invocation_short_name,
6069 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6070 arg_action == ACTION_REBOOT ? "Reboot" :
6071 arg_action == ACTION_POWEROFF ? "Power off" :
6075 static void shutdown_help(void) {
6076 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6077 "Shut down the system.\n\n"
6078 " --help Show this help\n"
6079 " -H --halt Halt the machine\n"
6080 " -P --poweroff Power-off the machine\n"
6081 " -r --reboot Reboot the machine\n"
6082 " -h Equivalent to --poweroff, overridden by --halt\n"
6083 " -k Don't halt/power-off/reboot, just send warnings\n"
6084 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6085 " -c Cancel a pending shutdown\n",
6086 program_invocation_short_name);
6089 static void telinit_help(void) {
6090 printf("%s [OPTIONS...] {COMMAND}\n\n"
6091 "Send control commands to the init daemon.\n\n"
6092 " --help Show this help\n"
6093 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6095 " 0 Power-off the machine\n"
6096 " 6 Reboot the machine\n"
6097 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6098 " 1, s, S Enter rescue mode\n"
6099 " q, Q Reload init daemon configuration\n"
6100 " u, U Reexecute init daemon\n",
6101 program_invocation_short_name);
6104 static void runlevel_help(void) {
6105 printf("%s [OPTIONS...]\n\n"
6106 "Prints the previous and current runlevel of the init system.\n\n"
6107 " --help Show this help\n",
6108 program_invocation_short_name);
6111 static void help_types(void) {
6116 puts("Available unit types:");
6117 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6118 t = unit_type_to_string(i);
6124 static int systemctl_parse_argv(int argc, char *argv[]) {
6133 ARG_IGNORE_DEPENDENCIES,
6145 ARG_NO_ASK_PASSWORD,
6155 static const struct option options[] = {
6156 { "help", no_argument, NULL, 'h' },
6157 { "version", no_argument, NULL, ARG_VERSION },
6158 { "type", required_argument, NULL, 't' },
6159 { "property", required_argument, NULL, 'p' },
6160 { "all", no_argument, NULL, 'a' },
6161 { "reverse", no_argument, NULL, ARG_REVERSE },
6162 { "after", no_argument, NULL, ARG_AFTER },
6163 { "before", no_argument, NULL, ARG_BEFORE },
6164 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6165 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6166 { "full", no_argument, NULL, 'l' },
6167 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6168 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6169 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6170 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6171 { "ignore-inhibitors", no_argument, NULL, 'i' },
6172 { "user", no_argument, NULL, ARG_USER },
6173 { "system", no_argument, NULL, ARG_SYSTEM },
6174 { "global", no_argument, NULL, ARG_GLOBAL },
6175 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6176 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6177 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6178 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6179 { "quiet", no_argument, NULL, 'q' },
6180 { "root", required_argument, NULL, ARG_ROOT },
6181 { "force", no_argument, NULL, ARG_FORCE },
6182 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6183 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6184 { "signal", required_argument, NULL, 's' },
6185 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6186 { "host", required_argument, NULL, 'H' },
6187 { "machine", required_argument, NULL, 'M' },
6188 { "runtime", no_argument, NULL, ARG_RUNTIME },
6189 { "lines", required_argument, NULL, 'n' },
6190 { "output", required_argument, NULL, 'o' },
6191 { "plain", no_argument, NULL, ARG_PLAIN },
6192 { "state", required_argument, NULL, ARG_STATE },
6193 { "recursive", no_argument, NULL, 'r' },
6194 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6203 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6212 puts(PACKAGE_STRING);
6213 puts(SYSTEMD_FEATURES);
6217 const char *word, *state;
6220 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6221 _cleanup_free_ char *type;
6223 type = strndup(word, size);
6227 if (streq(type, "help")) {
6232 if (unit_type_from_string(type) >= 0) {
6233 if (strv_push(&arg_types, type))
6239 /* It's much nicer to use --state= for
6240 * load states, but let's support this
6241 * in --types= too for compatibility
6242 * with old versions */
6243 if (unit_load_state_from_string(optarg) >= 0) {
6244 if (strv_push(&arg_states, type) < 0)
6250 log_error("Unknown unit type or load state '%s'.", type);
6251 log_info("Use -t help to see a list of allowed values.");
6259 /* Make sure that if the empty property list
6260 was specified, we won't show any properties. */
6261 if (isempty(optarg) && !arg_properties) {
6262 arg_properties = new0(char*, 1);
6263 if (!arg_properties)
6266 const char *word, *state;
6269 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6272 prop = strndup(word, size);
6276 if (strv_consume(&arg_properties, prop) < 0)
6281 /* If the user asked for a particular
6282 * property, show it to him, even if it is
6294 arg_dependency = DEPENDENCY_REVERSE;
6298 arg_dependency = DEPENDENCY_AFTER;
6302 arg_dependency = DEPENDENCY_BEFORE;
6305 case ARG_SHOW_TYPES:
6306 arg_show_types = true;
6310 arg_job_mode = optarg;
6314 arg_job_mode = "fail";
6317 case ARG_IRREVERSIBLE:
6318 arg_job_mode = "replace-irreversibly";
6321 case ARG_IGNORE_DEPENDENCIES:
6322 arg_job_mode = "ignore-dependencies";
6326 arg_scope = UNIT_FILE_USER;
6330 arg_scope = UNIT_FILE_SYSTEM;
6334 arg_scope = UNIT_FILE_GLOBAL;
6338 arg_no_block = true;
6342 arg_no_legend = true;
6346 arg_no_pager = true;
6362 if (strv_extend(&arg_states, "failed") < 0)
6380 arg_no_reload = true;
6384 arg_kill_who = optarg;
6388 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6389 log_error("Failed to parse signal string %s.", optarg);
6394 case ARG_NO_ASK_PASSWORD:
6395 arg_ask_password = false;
6399 arg_transport = BUS_TRANSPORT_REMOTE;
6404 arg_transport = BUS_TRANSPORT_MACHINE;
6413 if (safe_atou(optarg, &arg_lines) < 0) {
6414 log_error("Failed to parse lines '%s'", optarg);
6420 arg_output = output_mode_from_string(optarg);
6421 if (arg_output < 0) {
6422 log_error("Unknown output '%s'.", optarg);
6428 arg_ignore_inhibitors = true;
6436 const char *word, *state;
6439 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6442 s = strndup(word, size);
6446 if (strv_consume(&arg_states, s) < 0)
6453 if (geteuid() != 0) {
6454 log_error("--recursive requires root privileges.");
6458 arg_recursive = true;
6461 case ARG_PRESET_MODE:
6463 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6464 if (arg_preset_mode < 0) {
6465 log_error("Failed to parse preset mode: %s.", optarg);
6475 assert_not_reached("Unhandled option");
6478 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6479 log_error("Cannot access user instance remotely.");
6486 static int halt_parse_argv(int argc, char *argv[]) {
6495 static const struct option options[] = {
6496 { "help", no_argument, NULL, ARG_HELP },
6497 { "halt", no_argument, NULL, ARG_HALT },
6498 { "poweroff", no_argument, NULL, 'p' },
6499 { "reboot", no_argument, NULL, ARG_REBOOT },
6500 { "force", no_argument, NULL, 'f' },
6501 { "wtmp-only", no_argument, NULL, 'w' },
6502 { "no-wtmp", no_argument, NULL, 'd' },
6503 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6512 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6513 if (runlevel == '0' || runlevel == '6')
6516 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6524 arg_action = ACTION_HALT;
6528 if (arg_action != ACTION_REBOOT)
6529 arg_action = ACTION_POWEROFF;
6533 arg_action = ACTION_REBOOT;
6555 /* Compatibility nops */
6562 assert_not_reached("Unhandled option");
6565 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6566 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6569 } else if (optind < argc) {
6570 log_error("Too many arguments.");
6577 static int parse_time_spec(const char *t, usec_t *_u) {
6581 if (streq(t, "now"))
6583 else if (!strchr(t, ':')) {
6586 if (safe_atou64(t, &u) < 0)
6589 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6598 hour = strtol(t, &e, 10);
6599 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6602 minute = strtol(e+1, &e, 10);
6603 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6606 n = now(CLOCK_REALTIME);
6607 s = (time_t) (n / USEC_PER_SEC);
6609 assert_se(localtime_r(&s, &tm));
6611 tm.tm_hour = (int) hour;
6612 tm.tm_min = (int) minute;
6615 assert_se(s = mktime(&tm));
6617 *_u = (usec_t) s * USEC_PER_SEC;
6620 *_u += USEC_PER_DAY;
6626 static int shutdown_parse_argv(int argc, char *argv[]) {
6633 static const struct option options[] = {
6634 { "help", no_argument, NULL, ARG_HELP },
6635 { "halt", no_argument, NULL, 'H' },
6636 { "poweroff", no_argument, NULL, 'P' },
6637 { "reboot", no_argument, NULL, 'r' },
6638 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6639 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6648 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6656 arg_action = ACTION_HALT;
6660 arg_action = ACTION_POWEROFF;
6665 arg_action = ACTION_KEXEC;
6667 arg_action = ACTION_REBOOT;
6671 arg_action = ACTION_KEXEC;
6675 if (arg_action != ACTION_HALT)
6676 arg_action = ACTION_POWEROFF;
6691 /* Compatibility nops */
6695 arg_action = ACTION_CANCEL_SHUTDOWN;
6702 assert_not_reached("Unhandled option");
6705 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6706 r = parse_time_spec(argv[optind], &arg_when);
6708 log_error("Failed to parse time specification: %s", argv[optind]);
6712 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6714 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6715 /* No time argument for shutdown cancel */
6716 arg_wall = argv + optind;
6717 else if (argc > optind + 1)
6718 /* We skip the time argument */
6719 arg_wall = argv + optind + 1;
6726 static int telinit_parse_argv(int argc, char *argv[]) {
6733 static const struct option options[] = {
6734 { "help", no_argument, NULL, ARG_HELP },
6735 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6739 static const struct {
6743 { '0', ACTION_POWEROFF },
6744 { '6', ACTION_REBOOT },
6745 { '1', ACTION_RESCUE },
6746 { '2', ACTION_RUNLEVEL2 },
6747 { '3', ACTION_RUNLEVEL3 },
6748 { '4', ACTION_RUNLEVEL4 },
6749 { '5', ACTION_RUNLEVEL5 },
6750 { 's', ACTION_RESCUE },
6751 { 'S', ACTION_RESCUE },
6752 { 'q', ACTION_RELOAD },
6753 { 'Q', ACTION_RELOAD },
6754 { 'u', ACTION_REEXEC },
6755 { 'U', ACTION_REEXEC }
6764 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6779 assert_not_reached("Unhandled option");
6782 if (optind >= argc) {
6783 log_error("%s: required argument missing.",
6784 program_invocation_short_name);
6788 if (optind + 1 < argc) {
6789 log_error("Too many arguments.");
6793 if (strlen(argv[optind]) != 1) {
6794 log_error("Expected single character argument.");
6798 for (i = 0; i < ELEMENTSOF(table); i++)
6799 if (table[i].from == argv[optind][0])
6802 if (i >= ELEMENTSOF(table)) {
6803 log_error("Unknown command '%s'.", argv[optind]);
6807 arg_action = table[i].to;
6814 static int runlevel_parse_argv(int argc, char *argv[]) {
6820 static const struct option options[] = {
6821 { "help", no_argument, NULL, ARG_HELP },
6830 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6841 assert_not_reached("Unhandled option");
6844 if (optind < argc) {
6845 log_error("Too many arguments.");
6852 static int parse_argv(int argc, char *argv[]) {
6856 if (program_invocation_short_name) {
6858 if (strstr(program_invocation_short_name, "halt")) {
6859 arg_action = ACTION_HALT;
6860 return halt_parse_argv(argc, argv);
6861 } else if (strstr(program_invocation_short_name, "poweroff")) {
6862 arg_action = ACTION_POWEROFF;
6863 return halt_parse_argv(argc, argv);
6864 } else if (strstr(program_invocation_short_name, "reboot")) {
6866 arg_action = ACTION_KEXEC;
6868 arg_action = ACTION_REBOOT;
6869 return halt_parse_argv(argc, argv);
6870 } else if (strstr(program_invocation_short_name, "shutdown")) {
6871 arg_action = ACTION_POWEROFF;
6872 return shutdown_parse_argv(argc, argv);
6873 } else if (strstr(program_invocation_short_name, "init")) {
6875 if (sd_booted() > 0) {
6876 arg_action = _ACTION_INVALID;
6877 return telinit_parse_argv(argc, argv);
6879 /* Hmm, so some other init system is
6880 * running, we need to forward this
6881 * request to it. For now we simply
6882 * guess that it is Upstart. */
6884 execv(TELINIT, argv);
6886 log_error("Couldn't find an alternative telinit implementation to spawn.");
6890 } else if (strstr(program_invocation_short_name, "runlevel")) {
6891 arg_action = ACTION_RUNLEVEL;
6892 return runlevel_parse_argv(argc, argv);
6896 arg_action = ACTION_SYSTEMCTL;
6897 return systemctl_parse_argv(argc, argv);
6900 _pure_ static int action_to_runlevel(void) {
6902 static const char table[_ACTION_MAX] = {
6903 [ACTION_HALT] = '0',
6904 [ACTION_POWEROFF] = '0',
6905 [ACTION_REBOOT] = '6',
6906 [ACTION_RUNLEVEL2] = '2',
6907 [ACTION_RUNLEVEL3] = '3',
6908 [ACTION_RUNLEVEL4] = '4',
6909 [ACTION_RUNLEVEL5] = '5',
6910 [ACTION_RESCUE] = '1'
6913 assert(arg_action < _ACTION_MAX);
6915 return table[arg_action];
6918 static int talk_initctl(void) {
6920 struct init_request request = {
6921 .magic = INIT_MAGIC,
6923 .cmd = INIT_CMD_RUNLVL
6926 _cleanup_close_ int fd = -1;
6930 rl = action_to_runlevel();
6934 request.runlevel = rl;
6936 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6938 if (errno == ENOENT)
6941 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
6945 r = loop_write(fd, &request, sizeof(request), false);
6947 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
6952 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6954 static const struct {
6962 int (* const dispatch)(sd_bus *bus, char **args);
6968 { "list-units", MORE, 0, list_units },
6969 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6970 { "list-sockets", MORE, 1, list_sockets },
6971 { "list-timers", MORE, 1, list_timers },
6972 { "list-jobs", MORE, 1, list_jobs },
6973 { "list-machines", MORE, 1, list_machines },
6974 { "clear-jobs", EQUAL, 1, daemon_reload },
6975 { "cancel", MORE, 2, cancel_job },
6976 { "start", MORE, 2, start_unit },
6977 { "stop", MORE, 2, start_unit },
6978 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6979 { "reload", MORE, 2, start_unit },
6980 { "restart", MORE, 2, start_unit },
6981 { "try-restart", MORE, 2, start_unit },
6982 { "reload-or-restart", MORE, 2, start_unit },
6983 { "reload-or-try-restart", MORE, 2, start_unit },
6984 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6985 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6986 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6987 { "isolate", EQUAL, 2, start_unit },
6988 { "kill", MORE, 2, kill_unit },
6989 { "is-active", MORE, 2, check_unit_active },
6990 { "check", MORE, 2, check_unit_active },
6991 { "is-failed", MORE, 2, check_unit_failed },
6992 { "show", MORE, 1, show },
6993 { "cat", MORE, 2, cat, NOBUS },
6994 { "status", MORE, 1, show },
6995 { "help", MORE, 2, show },
6996 { "snapshot", LESS, 2, snapshot },
6997 { "delete", MORE, 2, delete_snapshot },
6998 { "daemon-reload", EQUAL, 1, daemon_reload },
6999 { "daemon-reexec", EQUAL, 1, daemon_reload },
7000 { "show-environment", EQUAL, 1, show_environment },
7001 { "set-environment", MORE, 2, set_environment },
7002 { "unset-environment", MORE, 2, set_environment },
7003 { "import-environment", MORE, 1, import_environment},
7004 { "halt", EQUAL, 1, start_special, FORCE },
7005 { "poweroff", EQUAL, 1, start_special, FORCE },
7006 { "reboot", MORE, 1, start_special, FORCE },
7007 { "kexec", EQUAL, 1, start_special },
7008 { "suspend", EQUAL, 1, start_special },
7009 { "hibernate", EQUAL, 1, start_special },
7010 { "hybrid-sleep", EQUAL, 1, start_special },
7011 { "default", EQUAL, 1, start_special },
7012 { "rescue", EQUAL, 1, start_special },
7013 { "emergency", EQUAL, 1, start_special },
7014 { "exit", EQUAL, 1, start_special },
7015 { "reset-failed", MORE, 1, reset_failed },
7016 { "enable", MORE, 2, enable_unit, NOBUS },
7017 { "disable", MORE, 2, enable_unit, NOBUS },
7018 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7019 { "reenable", MORE, 2, enable_unit, NOBUS },
7020 { "preset", MORE, 2, enable_unit, NOBUS },
7021 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7022 { "mask", MORE, 2, enable_unit, NOBUS },
7023 { "unmask", MORE, 2, enable_unit, NOBUS },
7024 { "link", MORE, 2, enable_unit, NOBUS },
7025 { "switch-root", MORE, 2, switch_root },
7026 { "list-dependencies", LESS, 2, list_dependencies },
7027 { "set-default", EQUAL, 2, set_default, NOBUS },
7028 { "get-default", EQUAL, 1, get_default, NOBUS },
7029 { "set-property", MORE, 3, set_property },
7030 { "is-system-running", EQUAL, 1, is_system_running },
7031 { "add-wants", MORE, 3, add_dependency, NOBUS },
7032 { "add-requires", MORE, 3, add_dependency, NOBUS },
7033 { "edit", MORE, 2, edit, NOBUS },
7042 left = argc - optind;
7044 /* Special rule: no arguments (left == 0) means "list-units" */
7046 if (streq(argv[optind], "help") && !argv[optind+1]) {
7047 log_error("This command expects one or more "
7048 "unit names. Did you mean --help?");
7052 for (; verb->verb; verb++)
7053 if (streq(argv[optind], verb->verb))
7056 log_error("Unknown operation '%s'.", argv[optind]);
7061 switch (verb->argc_cmp) {
7064 if (left != verb->argc) {
7065 log_error("Invalid number of arguments.");
7072 if (left < verb->argc) {
7073 log_error("Too few arguments.");
7080 if (left > verb->argc) {
7081 log_error("Too many arguments.");
7088 assert_not_reached("Unknown comparison operator.");
7091 /* Require a bus connection for all operations but
7093 if (verb->bus == NOBUS) {
7094 if (!bus && !avoid_bus()) {
7095 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7100 if (running_in_chroot() > 0) {
7101 log_info("Running in chroot, ignoring request.");
7105 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7106 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7111 /* Increase max number of open files to 16K if we can, we
7112 * might needs this when browsing journal files, which might
7113 * be split up into many files. */
7114 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7116 return verb->dispatch(bus, argv + optind);
7119 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7121 struct sd_shutdown_command c = {
7128 union sockaddr_union sockaddr = {
7129 .un.sun_family = AF_UNIX,
7130 .un.sun_path = "/run/systemd/shutdownd",
7133 struct iovec iovec[2] = {{
7134 .iov_base = (char*) &c,
7135 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7138 struct msghdr msghdr = {
7139 .msg_name = &sockaddr,
7140 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7141 + strlen("/run/systemd/shutdownd"),
7146 _cleanup_close_ int fd;
7148 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7152 if (!isempty(message)) {
7153 iovec[1].iov_base = (char*) message;
7154 iovec[1].iov_len = strlen(message);
7155 msghdr.msg_iovlen++;
7158 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7164 static int reload_with_fallback(sd_bus *bus) {
7167 /* First, try systemd via D-Bus. */
7168 if (daemon_reload(bus, NULL) >= 0)
7172 /* Nothing else worked, so let's try signals */
7173 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7175 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7176 return log_error_errno(errno, "kill() failed: %m");
7181 static int start_with_fallback(sd_bus *bus) {
7184 /* First, try systemd via D-Bus. */
7185 if (start_unit(bus, NULL) >= 0)
7189 /* Nothing else worked, so let's try
7191 if (talk_initctl() > 0)
7194 log_error("Failed to talk to init daemon.");
7198 warn_wall(arg_action);
7202 static int halt_now(enum action a) {
7204 /* The kernel will automaticall flush ATA disks and suchlike
7205 * on reboot(), but the file systems need to be synce'd
7206 * explicitly in advance. */
7209 /* Make sure C-A-D is handled by the kernel from this point
7211 reboot(RB_ENABLE_CAD);
7216 log_info("Halting.");
7217 reboot(RB_HALT_SYSTEM);
7220 case ACTION_POWEROFF:
7221 log_info("Powering off.");
7222 reboot(RB_POWER_OFF);
7225 case ACTION_REBOOT: {
7226 _cleanup_free_ char *param = NULL;
7228 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7229 log_info("Rebooting with argument '%s'.", param);
7230 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7231 LINUX_REBOOT_CMD_RESTART2, param);
7234 log_info("Rebooting.");
7235 reboot(RB_AUTOBOOT);
7240 assert_not_reached("Unknown action.");
7244 static int halt_main(sd_bus *bus) {
7247 r = check_inhibitors(bus, arg_action);
7251 if (geteuid() != 0) {
7252 /* Try logind if we are a normal user and no special
7253 * mode applies. Maybe PolicyKit allows us to shutdown
7256 if (arg_when <= 0 &&
7259 (arg_action == ACTION_POWEROFF ||
7260 arg_action == ACTION_REBOOT)) {
7261 r = reboot_with_logind(bus, arg_action);
7266 log_error("Must be root.");
7271 _cleanup_free_ char *m;
7273 m = strv_join(arg_wall, " ");
7277 r = send_shutdownd(arg_when,
7278 arg_action == ACTION_HALT ? 'H' :
7279 arg_action == ACTION_POWEROFF ? 'P' :
7280 arg_action == ACTION_KEXEC ? 'K' :
7287 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7289 char date[FORMAT_TIMESTAMP_MAX];
7291 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7292 format_timestamp(date, sizeof(date), arg_when));
7297 if (!arg_dry && !arg_force)
7298 return start_with_fallback(bus);
7301 if (sd_booted() > 0)
7302 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7304 r = utmp_put_shutdown();
7306 log_warning_errno(r, "Failed to write utmp record: %m");
7313 r = halt_now(arg_action);
7314 log_error_errno(r, "Failed to reboot: %m");
7319 static int runlevel_main(void) {
7320 int r, runlevel, previous;
7322 r = utmp_get_runlevel(&runlevel, &previous);
7329 previous <= 0 ? 'N' : previous,
7330 runlevel <= 0 ? 'N' : runlevel);
7335 int main(int argc, char*argv[]) {
7336 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7339 setlocale(LC_ALL, "");
7340 log_parse_environment();
7343 /* Explicitly not on_tty() to avoid setting cached value.
7344 * This becomes relevant for piping output which might be
7346 original_stdout_is_tty = isatty(STDOUT_FILENO);
7348 r = parse_argv(argc, argv);
7352 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7353 * let's shortcut this */
7354 if (arg_action == ACTION_RUNLEVEL) {
7355 r = runlevel_main();
7359 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7360 log_info("Running in chroot, ignoring request.");
7366 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7369 sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);
7371 /* systemctl_main() will print an error message for the bus
7372 * connection, but only if it needs to */
7374 switch (arg_action) {
7376 case ACTION_SYSTEMCTL:
7377 r = systemctl_main(bus, argc, argv, r);
7381 case ACTION_POWEROFF:
7387 case ACTION_RUNLEVEL2:
7388 case ACTION_RUNLEVEL3:
7389 case ACTION_RUNLEVEL4:
7390 case ACTION_RUNLEVEL5:
7392 case ACTION_EMERGENCY:
7393 case ACTION_DEFAULT:
7394 r = start_with_fallback(bus);
7399 r = reload_with_fallback(bus);
7402 case ACTION_CANCEL_SHUTDOWN: {
7403 _cleanup_free_ char *m = NULL;
7406 m = strv_join(arg_wall, " ");
7413 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7415 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7419 case ACTION_RUNLEVEL:
7420 case _ACTION_INVALID:
7422 assert_not_reached("Unknown action");
7427 ask_password_agent_close();
7428 polkit_agent_close();
7430 strv_free(arg_types);
7431 strv_free(arg_states);
7432 strv_free(arg_properties);
7434 return r < 0 ? EXIT_FAILURE : r;