1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
50 #include "utmp-wtmp.h"
53 #include "path-util.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "socket-util.h"
73 #include "bus-message.h"
74 #include "bus-error.h"
75 #include "bus-common-errors.h"
79 static char **arg_types = NULL;
80 static char **arg_states = NULL;
81 static char **arg_properties = NULL;
82 static bool arg_all = false;
83 static enum dependency {
89 } arg_dependency = DEPENDENCY_FORWARD;
90 static const char *arg_job_mode = "replace";
91 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
92 static bool arg_no_block = false;
93 static bool arg_no_legend = false;
94 static bool arg_no_pager = false;
95 static bool arg_no_wtmp = false;
96 static bool arg_no_wall = false;
97 static bool arg_no_reload = false;
98 static bool arg_show_types = false;
99 static bool arg_ignore_inhibitors = false;
100 static bool arg_dry = false;
101 static bool arg_quiet = false;
102 static bool arg_full = false;
103 static bool arg_recursive = false;
104 static int arg_force = 0;
105 static bool arg_ask_password = true;
106 static bool arg_runtime = false;
107 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
108 static char **arg_wall = NULL;
109 static const char *arg_kill_who = NULL;
110 static int arg_signal = SIGTERM;
111 static const char *arg_root = NULL;
112 static usec_t arg_when = 0;
134 ACTION_CANCEL_SHUTDOWN,
136 } arg_action = ACTION_SYSTEMCTL;
137 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
138 static char *arg_host = NULL;
139 static unsigned arg_lines = 10;
140 static OutputMode arg_output = OUTPUT_SHORT;
141 static bool arg_plain = false;
143 static bool original_stdout_is_tty;
145 static int daemon_reload(sd_bus *bus, char **args);
146 static int halt_now(enum action a);
147 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
149 static char** strv_skip_first(char **strv) {
150 if (strv_length(strv) > 0)
155 static void pager_open_if_enabled(void) {
163 static void ask_password_agent_open_if_enabled(void) {
165 /* Open the password agent as a child process if necessary */
167 if (!arg_ask_password)
170 if (arg_scope != UNIT_FILE_SYSTEM)
173 if (arg_transport != BUS_TRANSPORT_LOCAL)
176 ask_password_agent_open();
180 static void polkit_agent_open_if_enabled(void) {
182 /* Open the polkit agent as a child process if necessary */
184 if (!arg_ask_password)
187 if (arg_scope != UNIT_FILE_SYSTEM)
190 if (arg_transport != BUS_TRANSPORT_LOCAL)
197 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
200 if (!sd_bus_error_is_set(error))
203 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
204 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
205 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
206 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
207 return EXIT_NOPERMISSION;
209 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
210 return EXIT_NOTINSTALLED;
212 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
213 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
214 return EXIT_NOTIMPLEMENTED;
216 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
217 return EXIT_NOTCONFIGURED;
225 static void warn_wall(enum action a) {
226 static const char *table[_ACTION_MAX] = {
227 [ACTION_HALT] = "The system is going down for system halt NOW!",
228 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
229 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
230 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
231 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
232 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
233 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
240 _cleanup_free_ char *p;
242 p = strv_join(arg_wall, " ");
249 utmp_wall(p, NULL, NULL);
257 utmp_wall(table[a], NULL, NULL);
260 static bool avoid_bus(void) {
262 if (running_in_chroot() > 0)
265 if (sd_booted() <= 0)
268 if (!isempty(arg_root))
271 if (arg_scope == UNIT_FILE_GLOBAL)
277 static int compare_unit_info(const void *a, const void *b) {
278 const UnitInfo *u = a, *v = b;
282 /* First, order by machine */
283 if (!u->machine && v->machine)
285 if (u->machine && !v->machine)
287 if (u->machine && v->machine) {
288 r = strcasecmp(u->machine, v->machine);
293 /* Second, order by unit type */
294 d1 = strrchr(u->id, '.');
295 d2 = strrchr(v->id, '.');
297 r = strcasecmp(d1, d2);
302 /* Third, order by name */
303 return strcasecmp(u->id, v->id);
306 static bool output_show_unit(const UnitInfo *u, char **patterns) {
307 if (!strv_isempty(patterns)) {
310 STRV_FOREACH(pattern, patterns)
311 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
320 dot = strrchr(u->id, '.');
324 if (!strv_find(arg_types, dot+1))
334 if (streq(u->active_state, "inactive") || u->following[0])
340 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
341 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
343 unsigned n_shown = 0;
346 max_id_len = strlen("UNIT");
347 load_len = strlen("LOAD");
348 active_len = strlen("ACTIVE");
349 sub_len = strlen("SUB");
350 job_len = strlen("JOB");
353 for (u = unit_infos; u < unit_infos + c; u++) {
354 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
355 load_len = MAX(load_len, strlen(u->load_state));
356 active_len = MAX(active_len, strlen(u->active_state));
357 sub_len = MAX(sub_len, strlen(u->sub_state));
359 if (u->job_id != 0) {
360 job_len = MAX(job_len, strlen(u->job_type));
364 if (!arg_no_legend &&
365 (streq(u->active_state, "failed") ||
366 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
370 if (!arg_full && original_stdout_is_tty) {
373 id_len = MIN(max_id_len, 25u);
374 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
377 basic_len += job_len + 1;
379 if (basic_len < (unsigned) columns()) {
380 unsigned extra_len, incr;
381 extra_len = columns() - basic_len;
383 /* Either UNIT already got 25, or is fully satisfied.
384 * Grant up to 25 to DESC now. */
385 incr = MIN(extra_len, 25u);
389 /* split the remaining space between UNIT and DESC,
390 * but do not give UNIT more than it needs. */
392 incr = MIN(extra_len / 2, max_id_len - id_len);
394 desc_len += extra_len - incr;
400 for (u = unit_infos; u < unit_infos + c; u++) {
401 _cleanup_free_ char *e = NULL, *j = NULL;
402 const char *on_loaded = "", *off_loaded = "";
403 const char *on_active = "", *off_active = "";
404 const char *on_circle = "", *off_circle = "";
408 if (!n_shown && !arg_no_legend) {
413 printf("%-*s %-*s %-*s %-*s ",
416 active_len, "ACTIVE",
420 printf("%-*s ", job_len, "JOB");
422 if (!arg_full && arg_no_pager)
423 printf("%.*s\n", desc_len, "DESCRIPTION");
425 printf("%s\n", "DESCRIPTION");
430 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
431 on_loaded = ansi_highlight_red();
432 on_circle = ansi_highlight_yellow();
433 off_loaded = off_circle = ansi_highlight_off();
437 if (streq(u->active_state, "failed")) {
438 on_circle = on_active = ansi_highlight_red();
439 off_circle = off_active = ansi_highlight_off();
444 j = strjoin(u->machine, ":", u->id, NULL);
453 e = ellipsize(id, id_len, 33);
461 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
463 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
464 on_active, id_len, id, off_active,
465 on_loaded, load_len, u->load_state, off_loaded,
466 on_active, active_len, u->active_state,
467 sub_len, u->sub_state, off_active,
468 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
471 printf("%.*s\n", desc_len, u->description);
473 printf("%s\n", u->description);
476 if (!arg_no_legend) {
477 const char *on, *off;
481 "LOAD = Reflects whether the unit definition was properly loaded.\n"
482 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
483 "SUB = The low-level unit activation state, values depend on unit type.");
484 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
485 on = ansi_highlight();
486 off = ansi_highlight_off();
488 on = ansi_highlight_red();
489 off = ansi_highlight_off();
493 printf("%s%u loaded units listed.%s\n"
494 "To show all installed unit files use 'systemctl list-unit-files'.\n",
497 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
498 "To show all installed unit files use 'systemctl list-unit-files'.\n",
505 static int get_unit_list(
509 UnitInfo **unit_infos,
511 sd_bus_message **_reply) {
513 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
514 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
515 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
524 r = sd_bus_message_new_method_call(
527 "org.freedesktop.systemd1",
528 "/org/freedesktop/systemd1",
529 "org.freedesktop.systemd1.Manager",
530 "ListUnitsFiltered");
533 return bus_log_create_error(r);
535 r = sd_bus_message_append_strv(m, arg_states);
537 return bus_log_create_error(r);
539 r = sd_bus_call(bus, m, 0, &error, &reply);
541 log_error("Failed to list units: %s", bus_error_message(&error, r));
545 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
547 return bus_log_parse_error(r);
549 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
552 if (!output_show_unit(&u, patterns))
555 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
558 (*unit_infos)[c++] = u;
561 return bus_log_parse_error(r);
563 r = sd_bus_message_exit_container(reply);
565 return bus_log_parse_error(r);
573 static void message_set_freep(Set **set) {
576 while ((m = set_steal_first(*set)))
577 sd_bus_message_unref(m);
582 static int get_unit_list_recursive(
585 UnitInfo **_unit_infos,
589 _cleanup_free_ UnitInfo *unit_infos = NULL;
590 _cleanup_(message_set_freep) Set *replies;
591 sd_bus_message *reply;
599 replies = set_new(NULL);
603 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
607 r = set_put(replies, reply);
609 sd_bus_message_unref(reply);
614 _cleanup_strv_free_ char **machines = NULL;
617 r = sd_get_machine_names(&machines);
621 STRV_FOREACH(i, machines) {
622 _cleanup_bus_close_unref_ sd_bus *container = NULL;
625 r = sd_bus_open_system_container(&container, *i);
627 log_error_errno(r, "Failed to connect to container %s: %m", *i);
631 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
637 r = set_put(replies, reply);
639 sd_bus_message_unref(reply);
644 *_machines = machines;
649 *_unit_infos = unit_infos;
658 static int list_units(sd_bus *bus, char **args) {
659 _cleanup_free_ UnitInfo *unit_infos = NULL;
660 _cleanup_(message_set_freep) Set *replies = NULL;
661 _cleanup_strv_free_ char **machines = NULL;
664 pager_open_if_enabled();
666 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
670 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
671 return output_units_list(unit_infos, r);
674 static int get_triggered_units(
679 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
682 r = sd_bus_get_property_strv(
684 "org.freedesktop.systemd1",
686 "org.freedesktop.systemd1.Unit",
692 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
697 static int get_listening(
699 const char* unit_path,
702 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
703 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
704 const char *type, *path;
707 r = sd_bus_get_property(
709 "org.freedesktop.systemd1",
711 "org.freedesktop.systemd1.Socket",
717 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
721 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
723 return bus_log_parse_error(r);
725 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
727 r = strv_extend(listening, type);
731 r = strv_extend(listening, path);
738 return bus_log_parse_error(r);
740 r = sd_bus_message_exit_container(reply);
742 return bus_log_parse_error(r);
754 /* Note: triggered is a list here, although it almost certainly
755 * will always be one unit. Nevertheless, dbus API allows for multiple
756 * values, so let's follow that. */
759 /* The strv above is shared. free is set only in the first one. */
763 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
769 if (!a->machine && b->machine)
771 if (a->machine && !b->machine)
773 if (a->machine && b->machine) {
774 o = strcasecmp(a->machine, b->machine);
779 o = strcmp(a->path, b->path);
781 o = strcmp(a->type, b->type);
786 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
787 struct socket_info *s;
788 unsigned pathlen = strlen("LISTEN"),
789 typelen = strlen("TYPE") * arg_show_types,
790 socklen = strlen("UNIT"),
791 servlen = strlen("ACTIVATES");
792 const char *on, *off;
794 for (s = socket_infos; s < socket_infos + cs; s++) {
798 socklen = MAX(socklen, strlen(s->id));
800 typelen = MAX(typelen, strlen(s->type));
801 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
803 STRV_FOREACH(a, s->triggered)
804 tmp += strlen(*a) + 2*(a != s->triggered);
805 servlen = MAX(servlen, tmp);
810 printf("%-*s %-*.*s%-*s %s\n",
812 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
816 for (s = socket_infos; s < socket_infos + cs; s++) {
817 _cleanup_free_ char *j = NULL;
822 j = strjoin(s->machine, ":", s->path, NULL);
830 printf("%-*s %-*s %-*s",
831 pathlen, path, typelen, s->type, socklen, s->id);
834 pathlen, path, socklen, s->id);
835 STRV_FOREACH(a, s->triggered)
837 a == s->triggered ? "" : ",", *a);
841 on = ansi_highlight();
842 off = ansi_highlight_off();
846 on = ansi_highlight_red();
847 off = ansi_highlight_off();
850 if (!arg_no_legend) {
851 printf("%s%u sockets listed.%s\n", on, cs, off);
853 printf("Pass --all to see loaded but inactive sockets, too.\n");
859 static int list_sockets(sd_bus *bus, char **args) {
860 _cleanup_(message_set_freep) Set *replies = NULL;
861 _cleanup_strv_free_ char **machines = NULL;
862 _cleanup_free_ UnitInfo *unit_infos = NULL;
863 _cleanup_free_ struct socket_info *socket_infos = NULL;
865 struct socket_info *s;
870 pager_open_if_enabled();
872 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
876 for (u = unit_infos; u < unit_infos + n; u++) {
877 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
880 if (!endswith(u->id, ".socket"))
883 r = get_triggered_units(bus, u->unit_path, &triggered);
887 c = get_listening(bus, u->unit_path, &listening);
893 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
898 for (i = 0; i < c; i++)
899 socket_infos[cs + i] = (struct socket_info) {
900 .machine = u->machine,
902 .type = listening[i*2],
903 .path = listening[i*2 + 1],
904 .triggered = triggered,
905 .own_triggered = i==0,
908 /* from this point on we will cleanup those socket_infos */
911 listening = triggered = NULL; /* avoid cleanup */
914 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
915 (__compar_fn_t) socket_info_compare);
917 output_sockets_list(socket_infos, cs);
920 assert(cs == 0 || socket_infos);
921 for (s = socket_infos; s < socket_infos + cs; s++) {
924 if (s->own_triggered)
925 strv_free(s->triggered);
931 static int get_next_elapse(
934 dual_timestamp *next) {
936 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
944 r = sd_bus_get_property_trivial(
946 "org.freedesktop.systemd1",
948 "org.freedesktop.systemd1.Timer",
949 "NextElapseUSecMonotonic",
954 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
958 r = sd_bus_get_property_trivial(
960 "org.freedesktop.systemd1",
962 "org.freedesktop.systemd1.Timer",
963 "NextElapseUSecRealtime",
968 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
976 static int get_last_trigger(
981 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
988 r = sd_bus_get_property_trivial(
990 "org.freedesktop.systemd1",
992 "org.freedesktop.systemd1.Timer",
998 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1006 const char* machine;
1009 usec_t last_trigger;
1013 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1019 if (!a->machine && b->machine)
1021 if (a->machine && !b->machine)
1023 if (a->machine && b->machine) {
1024 o = strcasecmp(a->machine, b->machine);
1029 if (a->next_elapse < b->next_elapse)
1031 if (a->next_elapse > b->next_elapse)
1034 return strcmp(a->id, b->id);
1037 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1038 struct timer_info *t;
1040 nextlen = strlen("NEXT"),
1041 leftlen = strlen("LEFT"),
1042 lastlen = strlen("LAST"),
1043 passedlen = strlen("PASSED"),
1044 unitlen = strlen("UNIT"),
1045 activatelen = strlen("ACTIVATES");
1047 const char *on, *off;
1049 assert(timer_infos || n == 0);
1051 for (t = timer_infos; t < timer_infos + n; t++) {
1055 if (t->next_elapse > 0) {
1056 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1058 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1059 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1061 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1062 leftlen = MAX(leftlen, strlen(trel));
1065 if (t->last_trigger > 0) {
1066 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1068 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1069 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1071 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1072 passedlen = MAX(passedlen, strlen(trel));
1075 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1077 STRV_FOREACH(a, t->triggered)
1078 ul += strlen(*a) + 2*(a != t->triggered);
1080 activatelen = MAX(activatelen, ul);
1085 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1089 passedlen, "PASSED",
1093 for (t = timer_infos; t < timer_infos + n; t++) {
1094 _cleanup_free_ char *j = NULL;
1096 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1097 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1100 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1101 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1103 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1104 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1107 j = strjoin(t->machine, ":", t->id, NULL);
1114 printf("%-*s %-*s %-*s %-*s %-*s",
1115 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1117 STRV_FOREACH(a, t->triggered)
1119 a == t->triggered ? "" : ",", *a);
1123 on = ansi_highlight();
1124 off = ansi_highlight_off();
1128 on = ansi_highlight_red();
1129 off = ansi_highlight_off();
1132 if (!arg_no_legend) {
1133 printf("%s%u timers listed.%s\n", on, n, off);
1135 printf("Pass --all to see loaded but inactive timers, too.\n");
1141 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1147 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1150 if (next->monotonic > nw->monotonic)
1151 converted = nw->realtime + (next->monotonic - nw->monotonic);
1153 converted = nw->realtime - (nw->monotonic - next->monotonic);
1155 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1156 next_elapse = MIN(converted, next->realtime);
1158 next_elapse = converted;
1161 next_elapse = next->realtime;
1166 static int list_timers(sd_bus *bus, char **args) {
1167 _cleanup_(message_set_freep) Set *replies = NULL;
1168 _cleanup_strv_free_ char **machines = NULL;
1169 _cleanup_free_ struct timer_info *timer_infos = NULL;
1170 _cleanup_free_ UnitInfo *unit_infos = NULL;
1171 struct timer_info *t;
1178 pager_open_if_enabled();
1180 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1184 dual_timestamp_get(&nw);
1186 for (u = unit_infos; u < unit_infos + n; u++) {
1187 _cleanup_strv_free_ char **triggered = NULL;
1188 dual_timestamp next = {};
1191 if (!endswith(u->id, ".timer"))
1194 r = get_triggered_units(bus, u->unit_path, &triggered);
1198 r = get_next_elapse(bus, u->unit_path, &next);
1202 get_last_trigger(bus, u->unit_path, &last);
1204 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1209 m = calc_next_elapse(&nw, &next);
1211 timer_infos[c++] = (struct timer_info) {
1212 .machine = u->machine,
1215 .last_trigger = last,
1216 .triggered = triggered,
1219 triggered = NULL; /* avoid cleanup */
1222 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1223 (__compar_fn_t) timer_info_compare);
1225 output_timers_list(timer_infos, c);
1228 for (t = timer_infos; t < timer_infos + c; t++)
1229 strv_free(t->triggered);
1234 static int compare_unit_file_list(const void *a, const void *b) {
1235 const char *d1, *d2;
1236 const UnitFileList *u = a, *v = b;
1238 d1 = strrchr(u->path, '.');
1239 d2 = strrchr(v->path, '.');
1244 r = strcasecmp(d1, d2);
1249 return strcasecmp(basename(u->path), basename(v->path));
1252 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1253 if (!strv_isempty(patterns)) {
1256 STRV_FOREACH(pattern, patterns)
1257 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1263 if (!strv_isempty(arg_types)) {
1266 dot = strrchr(u->path, '.');
1270 if (!strv_find(arg_types, dot+1))
1274 if (!strv_isempty(arg_states)) {
1275 if (!strv_find(arg_states, unit_file_state_to_string(u->state)))
1282 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1283 unsigned max_id_len, id_cols, state_cols;
1284 const UnitFileList *u;
1286 max_id_len = strlen("UNIT FILE");
1287 state_cols = strlen("STATE");
1289 for (u = units; u < units + c; u++) {
1290 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1291 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1295 unsigned basic_cols;
1297 id_cols = MIN(max_id_len, 25u);
1298 basic_cols = 1 + id_cols + state_cols;
1299 if (basic_cols < (unsigned) columns())
1300 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1302 id_cols = max_id_len;
1305 printf("%-*s %-*s\n",
1306 id_cols, "UNIT FILE",
1307 state_cols, "STATE");
1309 for (u = units; u < units + c; u++) {
1310 _cleanup_free_ char *e = NULL;
1311 const char *on, *off;
1314 if (u->state == UNIT_FILE_MASKED ||
1315 u->state == UNIT_FILE_MASKED_RUNTIME ||
1316 u->state == UNIT_FILE_DISABLED ||
1317 u->state == UNIT_FILE_INVALID) {
1318 on = ansi_highlight_red();
1319 off = ansi_highlight_off();
1320 } else if (u->state == UNIT_FILE_ENABLED) {
1321 on = ansi_highlight_green();
1322 off = ansi_highlight_off();
1326 id = basename(u->path);
1328 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1330 printf("%-*s %s%-*s%s\n",
1331 id_cols, e ? e : id,
1332 on, state_cols, unit_file_state_to_string(u->state), off);
1336 printf("\n%u unit files listed.\n", c);
1339 static int list_unit_files(sd_bus *bus, char **args) {
1340 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1341 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1342 _cleanup_free_ UnitFileList *units = NULL;
1350 pager_open_if_enabled();
1358 h = hashmap_new(&string_hash_ops);
1362 r = unit_file_get_list(arg_scope, arg_root, h);
1364 unit_file_list_free(h);
1365 log_error_errno(r, "Failed to get unit file list: %m");
1369 n_units = hashmap_size(h);
1371 units = new(UnitFileList, n_units);
1372 if (!units && n_units > 0) {
1373 unit_file_list_free(h);
1377 HASHMAP_FOREACH(u, h, i) {
1378 if (!output_show_unit_file(u, strv_skip_first(args)))
1385 assert(c <= n_units);
1388 r = sd_bus_call_method(
1390 "org.freedesktop.systemd1",
1391 "/org/freedesktop/systemd1",
1392 "org.freedesktop.systemd1.Manager",
1398 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1402 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1404 return bus_log_parse_error(r);
1406 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1408 if (!GREEDY_REALLOC(units, size, c + 1))
1411 units[c] = (struct UnitFileList) {
1413 unit_file_state_from_string(state)
1416 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1421 return bus_log_parse_error(r);
1423 r = sd_bus_message_exit_container(reply);
1425 return bus_log_parse_error(r);
1428 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1429 output_unit_file_list(units, c);
1432 for (unit = units; unit < units + c; unit++)
1439 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1440 _cleanup_free_ char *n = NULL;
1441 size_t max_len = MAX(columns(),20u);
1447 for (i = level - 1; i >= 0; i--) {
1449 if (len > max_len - 3 && !arg_full) {
1450 printf("%s...\n",max_len % 2 ? "" : " ");
1453 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1457 if (len > max_len - 3 && !arg_full) {
1458 printf("%s...\n",max_len % 2 ? "" : " ");
1462 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1466 printf("%s\n", name);
1470 n = ellipsize(name, max_len-len, 100);
1478 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1480 static const char *dependencies[_DEPENDENCY_MAX] = {
1481 [DEPENDENCY_FORWARD] = "Requires\0"
1482 "RequiresOverridable\0"
1484 "RequisiteOverridable\0"
1487 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1488 "RequiredByOverridable\0"
1492 [DEPENDENCY_AFTER] = "After\0",
1493 [DEPENDENCY_BEFORE] = "Before\0",
1496 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1497 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1498 _cleanup_strv_free_ char **ret = NULL;
1499 _cleanup_free_ char *path = NULL;
1505 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1507 path = unit_dbus_path_from_name(name);
1511 r = sd_bus_call_method(
1513 "org.freedesktop.systemd1",
1515 "org.freedesktop.DBus.Properties",
1519 "s", "org.freedesktop.systemd1.Unit");
1521 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1525 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1527 return bus_log_parse_error(r);
1529 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1532 r = sd_bus_message_read(reply, "s", &prop);
1534 return bus_log_parse_error(r);
1536 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1537 r = sd_bus_message_skip(reply, "v");
1539 return bus_log_parse_error(r);
1542 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1544 return bus_log_parse_error(r);
1546 r = bus_message_read_strv_extend(reply, &ret);
1548 return bus_log_parse_error(r);
1550 r = sd_bus_message_exit_container(reply);
1552 return bus_log_parse_error(r);
1555 r = sd_bus_message_exit_container(reply);
1557 return bus_log_parse_error(r);
1561 return bus_log_parse_error(r);
1563 r = sd_bus_message_exit_container(reply);
1565 return bus_log_parse_error(r);
1573 static int list_dependencies_compare(const void *_a, const void *_b) {
1574 const char **a = (const char**) _a, **b = (const char**) _b;
1576 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1578 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1581 return strcasecmp(*a, *b);
1584 static int list_dependencies_one(
1589 unsigned int branches) {
1591 _cleanup_strv_free_ char **deps = NULL;
1599 r = strv_extend(units, name);
1603 r = list_dependencies_get_dependencies(bus, name, &deps);
1607 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1609 STRV_FOREACH(c, deps) {
1612 if (strv_contains(*units, *c)) {
1614 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1621 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1623 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1625 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1627 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1631 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1632 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1639 strv_remove(*units, name);
1644 static int list_dependencies(sd_bus *bus, char **args) {
1645 _cleanup_strv_free_ char **units = NULL;
1646 _cleanup_free_ char *unit = NULL;
1652 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1657 u = SPECIAL_DEFAULT_TARGET;
1659 pager_open_if_enabled();
1663 return list_dependencies_one(bus, u, 0, &units, 0);
1666 struct machine_info {
1670 char *control_group;
1671 uint32_t n_failed_units;
1676 static const struct bus_properties_map machine_info_property_map[] = {
1677 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1678 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1679 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1680 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1681 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1685 static void free_machines_list(struct machine_info *machine_infos, int n) {
1691 for (i = 0; i < n; i++) {
1692 free(machine_infos[i].name);
1693 free(machine_infos[i].state);
1694 free(machine_infos[i].control_group);
1697 free(machine_infos);
1700 static int compare_machine_info(const void *a, const void *b) {
1701 const struct machine_info *u = a, *v = b;
1703 if (u->is_host != v->is_host)
1704 return u->is_host > v->is_host ? -1 : 1;
1706 return strcasecmp(u->name, v->name);
1709 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1710 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1716 r = sd_bus_open_system_container(&container, mi->name);
1723 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1730 static bool output_show_machine(const char *name, char **patterns) {
1735 if (strv_isempty(patterns))
1738 STRV_FOREACH(i, patterns)
1739 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1745 static int get_machine_list(
1747 struct machine_info **_machine_infos,
1750 struct machine_info *machine_infos = NULL;
1751 _cleanup_strv_free_ char **m = NULL;
1752 _cleanup_free_ char *hn = NULL;
1757 hn = gethostname_malloc();
1761 if (output_show_machine(hn, patterns)) {
1762 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1765 machine_infos[c].is_host = true;
1766 machine_infos[c].name = hn;
1769 get_machine_properties(bus, &machine_infos[c]);
1773 sd_get_machine_names(&m);
1774 STRV_FOREACH(i, m) {
1775 _cleanup_free_ char *class = NULL;
1777 if (!output_show_machine(*i, patterns))
1780 sd_machine_get_class(*i, &class);
1781 if (!streq_ptr(class, "container"))
1784 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1785 free_machines_list(machine_infos, c);
1789 machine_infos[c].is_host = false;
1790 machine_infos[c].name = strdup(*i);
1791 if (!machine_infos[c].name) {
1792 free_machines_list(machine_infos, c);
1796 get_machine_properties(NULL, &machine_infos[c]);
1800 *_machine_infos = machine_infos;
1804 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1805 struct machine_info *m;
1808 namelen = sizeof("NAME") - 1,
1809 statelen = sizeof("STATE") - 1,
1810 failedlen = sizeof("FAILED") - 1,
1811 jobslen = sizeof("JOBS") - 1;
1813 assert(machine_infos || n == 0);
1815 for (m = machine_infos; m < machine_infos + n; m++) {
1816 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1817 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1818 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1819 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1821 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1825 if (!arg_no_legend) {
1829 printf("%-*s %-*s %-*s %-*s\n",
1832 failedlen, "FAILED",
1836 for (m = machine_infos; m < machine_infos + n; m++) {
1837 const char *on_state = "", *off_state = "";
1838 const char *on_failed = "", *off_failed = "";
1839 bool circle = false;
1841 if (streq_ptr(m->state, "degraded")) {
1842 on_state = ansi_highlight_red();
1843 off_state = ansi_highlight_off();
1845 } else if (!streq_ptr(m->state, "running")) {
1846 on_state = ansi_highlight_yellow();
1847 off_state = ansi_highlight_off();
1851 if (m->n_failed_units > 0) {
1852 on_failed = ansi_highlight_red();
1853 off_failed = ansi_highlight_off();
1855 on_failed = off_failed = "";
1858 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1861 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1862 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1863 on_state, statelen, strna(m->state), off_state,
1864 on_failed, failedlen, m->n_failed_units, off_failed,
1865 jobslen, m->n_jobs);
1867 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1868 namelen, strna(m->name),
1869 on_state, statelen, strna(m->state), off_state,
1870 on_failed, failedlen, m->n_failed_units, off_failed,
1871 jobslen, m->n_jobs);
1875 printf("\n%u machines listed.\n", n);
1878 static int list_machines(sd_bus *bus, char **args) {
1879 struct machine_info *machine_infos = NULL;
1884 if (geteuid() != 0) {
1885 log_error("Must be root.");
1889 pager_open_if_enabled();
1891 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1895 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1896 output_machines_list(machine_infos, r);
1897 free_machines_list(machine_infos, r);
1902 static int get_default(sd_bus *bus, char **args) {
1903 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1904 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1905 _cleanup_free_ char *_path = NULL;
1909 if (!bus || avoid_bus()) {
1910 r = unit_file_get_default(arg_scope, arg_root, &_path);
1912 return log_error_errno(r, "Failed to get default target: %m");
1916 r = sd_bus_call_method(
1918 "org.freedesktop.systemd1",
1919 "/org/freedesktop/systemd1",
1920 "org.freedesktop.systemd1.Manager",
1926 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1930 r = sd_bus_message_read(reply, "s", &path);
1932 return bus_log_parse_error(r);
1936 printf("%s\n", path);
1941 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1944 assert(changes || n_changes == 0);
1946 for (i = 0; i < n_changes; i++) {
1947 if (changes[i].type == UNIT_FILE_SYMLINK)
1948 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1950 log_info("Removed symlink %s.", changes[i].path);
1954 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1955 const char *type, *path, *source;
1958 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1960 return bus_log_parse_error(r);
1962 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1964 if (streq(type, "symlink"))
1965 log_info("Created symlink from %s to %s.", path, source);
1967 log_info("Removed symlink %s.", path);
1971 return bus_log_parse_error(r);
1973 r = sd_bus_message_exit_container(m);
1975 return bus_log_parse_error(r);
1980 static int set_default(sd_bus *bus, char **args) {
1981 _cleanup_free_ char *unit = NULL;
1982 UnitFileChange *changes = NULL;
1983 unsigned n_changes = 0;
1986 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1990 if (!bus || avoid_bus()) {
1991 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1993 return log_error_errno(r, "Failed to set default target: %m");
1996 dump_unit_file_changes(changes, n_changes);
2000 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
2001 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2003 r = sd_bus_message_new_method_call(
2006 "org.freedesktop.systemd1",
2007 "/org/freedesktop/systemd1",
2008 "org.freedesktop.systemd1.Manager",
2009 "SetDefaultTarget");
2011 return bus_log_create_error(r);
2013 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2015 return bus_log_create_error(r);
2017 r = sd_bus_message_append(m, "sb", unit, 1);
2019 return bus_log_create_error(r);
2021 r = sd_bus_call(bus, m, 0, &error, &reply);
2023 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2027 r = deserialize_and_dump_unit_file_changes(reply);
2031 /* Try to reload if enabled */
2033 r = daemon_reload(bus, args);
2038 unit_file_changes_free(changes, n_changes);
2045 const char *name, *type, *state;
2048 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2049 unsigned id_len, unit_len, type_len, state_len;
2050 const struct job_info *j;
2051 const char *on, *off;
2052 bool shorten = false;
2054 assert(n == 0 || jobs);
2057 on = ansi_highlight_green();
2058 off = ansi_highlight_off();
2060 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2064 pager_open_if_enabled();
2066 id_len = strlen("JOB");
2067 unit_len = strlen("UNIT");
2068 type_len = strlen("TYPE");
2069 state_len = strlen("STATE");
2071 for (j = jobs; j < jobs + n; j++) {
2072 uint32_t id = j->id;
2073 assert(j->name && j->type && j->state);
2075 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2076 unit_len = MAX(unit_len, strlen(j->name));
2077 type_len = MAX(type_len, strlen(j->type));
2078 state_len = MAX(state_len, strlen(j->state));
2081 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2082 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2087 printf("%*s %-*s %-*s %-*s\n",
2091 state_len, "STATE");
2093 for (j = jobs; j < jobs + n; j++) {
2094 _cleanup_free_ char *e = NULL;
2096 if (streq(j->state, "running")) {
2097 on = ansi_highlight();
2098 off = ansi_highlight_off();
2102 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2103 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2105 on, unit_len, e ? e : j->name, off,
2107 on, state_len, j->state, off);
2110 if (!arg_no_legend) {
2111 on = ansi_highlight();
2112 off = ansi_highlight_off();
2114 printf("\n%s%u jobs listed%s.\n", on, n, off);
2118 static bool output_show_job(struct job_info *job, char **patterns) {
2123 if (strv_isempty(patterns))
2126 STRV_FOREACH(pattern, patterns)
2127 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2132 static int list_jobs(sd_bus *bus, char **args) {
2133 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2134 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2135 const char *name, *type, *state, *job_path, *unit_path;
2136 _cleanup_free_ struct job_info *jobs = NULL;
2141 bool skipped = false;
2143 r = sd_bus_call_method(
2145 "org.freedesktop.systemd1",
2146 "/org/freedesktop/systemd1",
2147 "org.freedesktop.systemd1.Manager",
2153 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2157 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2159 return bus_log_parse_error(r);
2161 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2162 struct job_info job = { id, name, type, state };
2164 if (!output_show_job(&job, strv_skip_first(args))) {
2169 if (!GREEDY_REALLOC(jobs, size, c + 1))
2175 return bus_log_parse_error(r);
2177 r = sd_bus_message_exit_container(reply);
2179 return bus_log_parse_error(r);
2181 output_jobs_list(jobs, c, skipped);
2185 static int cancel_job(sd_bus *bus, char **args) {
2186 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2192 if (strv_length(args) <= 1)
2193 return daemon_reload(bus, args);
2195 STRV_FOREACH(name, args+1) {
2196 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2200 q = safe_atou32(*name, &id);
2202 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2204 q = sd_bus_message_new_method_call(
2207 "org.freedesktop.systemd1",
2208 "/org/freedesktop/systemd1",
2209 "org.freedesktop.systemd1.Manager",
2212 return bus_log_create_error(q);
2214 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2216 return bus_log_create_error(1);
2218 q = sd_bus_message_append(m, "u", id);
2220 return bus_log_create_error(q);
2222 q = sd_bus_call(bus, m, 0, &error, NULL);
2224 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2233 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2234 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2238 /* We ignore all errors here, since this is used to show a
2241 /* We don't use unit_dbus_path_from_name() directly since we
2242 * don't want to load the unit if it isn't loaded. */
2244 r = sd_bus_call_method(
2246 "org.freedesktop.systemd1",
2247 "/org/freedesktop/systemd1",
2248 "org.freedesktop.systemd1.Manager",
2256 r = sd_bus_message_read(reply, "o", &path);
2260 r = sd_bus_get_property_trivial(
2262 "org.freedesktop.systemd1",
2264 "org.freedesktop.systemd1.Unit",
2274 static void warn_unit_file_changed(const char *name) {
2275 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2276 ansi_highlight_red(),
2277 ansi_highlight_off(),
2279 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2282 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2289 STRV_FOREACH(p, lp->unit_path) {
2290 _cleanup_free_ char *path;
2292 path = path_join(arg_root, *p, unit_name);
2296 if (access(path, F_OK) == 0) {
2306 static int unit_find_paths(sd_bus *bus,
2307 const char *unit_name,
2308 bool avoid_bus_cache,
2310 char **fragment_path,
2311 char ***dropin_paths) {
2315 * Finds where the unit is defined on disk. Returns 0 if the unit
2316 * is not found. Returns 1 if it is found, and sets
2317 * - the path to the unit in *path, if it exists on disk,
2318 * - and a strv of existing drop-ins in *dropins,
2319 * if the arg is not NULL and any dropins were found.
2323 assert(fragment_path);
2326 if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2327 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2328 _cleanup_free_ char *unit = NULL;
2329 _cleanup_free_ char *path = NULL;
2330 _cleanup_strv_free_ char **dropins = NULL;
2332 unit = unit_dbus_path_from_name(unit_name);
2336 if (need_daemon_reload(bus, unit_name) > 0)
2337 warn_unit_file_changed(unit_name);
2339 r = sd_bus_get_property_string(
2341 "org.freedesktop.systemd1",
2343 "org.freedesktop.systemd1.Unit",
2348 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2350 r = sd_bus_get_property_strv(
2352 "org.freedesktop.systemd1",
2354 "org.freedesktop.systemd1.Unit",
2359 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2362 if (!isempty(path)) {
2363 *fragment_path = path;
2368 if (dropin_paths && !strv_isempty(dropins)) {
2369 *dropin_paths = dropins;
2374 _cleanup_set_free_ Set *names;
2376 names = set_new(NULL);
2380 r = set_put(names, unit_name);
2384 r = unit_file_find_path(lp, unit_name, fragment_path);
2389 _cleanup_free_ char *template;
2391 template = unit_name_template(unit_name);
2395 if (!streq(template, unit_name)) {
2396 r = unit_file_find_path(lp, template, fragment_path);
2403 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, dropin_paths);
2409 typedef struct WaitData {
2416 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2423 log_debug("Got D-Bus request: %s.%s() on %s",
2424 sd_bus_message_get_interface(m),
2425 sd_bus_message_get_member(m),
2426 sd_bus_message_get_path(m));
2428 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2429 log_error("Warning! D-Bus connection terminated.");
2431 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2433 const char *path, *result, *unit;
2437 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2439 ret = set_remove(d->set, (char*) path);
2445 if (!isempty(result))
2446 d->result = strdup(result);
2449 d->name = strdup(unit);
2454 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2456 ret = set_remove(d->set, (char*) path);
2463 d->result = strdup(result);
2469 bus_log_parse_error(r);
2475 static int enable_wait_for_jobs(sd_bus *bus) {
2480 r = sd_bus_add_match(
2484 "sender='org.freedesktop.systemd1',"
2485 "interface='org.freedesktop.systemd1.Manager',"
2486 "member='JobRemoved',"
2487 "path='/org/freedesktop/systemd1'",
2490 log_error("Failed to add match");
2494 /* This is slightly dirty, since we don't undo the match registrations. */
2498 static int bus_process_wait(sd_bus *bus) {
2502 r = sd_bus_process(bus, NULL);
2507 r = sd_bus_wait(bus, (uint64_t) -1);
2513 static int check_wait_response(WaitData *d) {
2519 if (streq(d->result, "canceled"))
2520 log_error("Job for %s canceled.", strna(d->name));
2521 else if (streq(d->result, "timeout"))
2522 log_error("Job for %s timed out.", strna(d->name));
2523 else if (streq(d->result, "dependency"))
2524 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
2525 else if (streq(d->result, "invalid"))
2526 log_error("Job for %s invalid.", strna(d->name));
2527 else if (streq(d->result, "assert"))
2528 log_error("Assertion failed on job for %s.", strna(d->name));
2529 else if (streq(d->result, "unsupported"))
2530 log_error("Operation on or unit type of %s not supported on this system.", strna(d->name));
2531 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
2535 quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
2537 log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
2539 quotes ? "'" : "", d->name, quotes ? "'" : "");
2541 log_error("Job failed. See \"journalctl -xe\" for details.");
2545 if (streq(d->result, "canceled"))
2547 else if (streq(d->result, "timeout"))
2549 else if (streq(d->result, "dependency"))
2551 else if (streq(d->result, "invalid"))
2553 else if (streq(d->result, "assert"))
2555 else if (streq(d->result, "unsupported"))
2557 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2563 static int wait_for_jobs(sd_bus *bus, Set *s) {
2564 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2565 WaitData d = { .set = s };
2571 q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2575 while (!set_isempty(s)) {
2576 q = bus_process_wait(bus);
2578 return log_error_errno(q, "Failed to wait for response: %m");
2581 q = check_wait_response(&d);
2582 /* Return the first error as it is most likely to be
2584 if (q < 0 && r == 0)
2586 log_debug("Got result %s/%s for job %s",
2587 strna(d.result), strerror(-q), strna(d.name));
2600 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2601 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2602 _cleanup_free_ char *n = NULL, *state = NULL;
2608 n = unit_name_mangle(name, MANGLE_NOGLOB);
2612 /* We don't use unit_dbus_path_from_name() directly since we
2613 * don't want to load the unit if it isn't loaded. */
2615 r = sd_bus_call_method(
2617 "org.freedesktop.systemd1",
2618 "/org/freedesktop/systemd1",
2619 "org.freedesktop.systemd1.Manager",
2630 r = sd_bus_message_read(reply, "o", &path);
2632 return bus_log_parse_error(r);
2634 r = sd_bus_get_property_string(
2636 "org.freedesktop.systemd1",
2638 "org.freedesktop.systemd1.Unit",
2651 return nulstr_contains(good_states, state);
2654 static int check_triggering_units(
2658 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2659 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2660 _cleanup_strv_free_ char **triggered_by = NULL;
2661 bool print_warning_label = true;
2665 n = unit_name_mangle(name, MANGLE_NOGLOB);
2669 path = unit_dbus_path_from_name(n);
2673 r = sd_bus_get_property_string(
2675 "org.freedesktop.systemd1",
2677 "org.freedesktop.systemd1.Unit",
2682 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2686 if (streq(state, "masked"))
2689 r = sd_bus_get_property_strv(
2691 "org.freedesktop.systemd1",
2693 "org.freedesktop.systemd1.Unit",
2698 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2702 STRV_FOREACH(i, triggered_by) {
2703 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2705 return log_error_errno(r, "Failed to check unit: %m");
2710 if (print_warning_label) {
2711 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2712 print_warning_label = false;
2715 log_warning(" %s", *i);
2721 static const struct {
2724 } unit_actions[] = {
2725 { "start", "StartUnit" },
2726 { "stop", "StopUnit" },
2727 { "condstop", "StopUnit" },
2728 { "reload", "ReloadUnit" },
2729 { "restart", "RestartUnit" },
2730 { "try-restart", "TryRestartUnit" },
2731 { "condrestart", "TryRestartUnit" },
2732 { "reload-or-restart", "ReloadOrRestartUnit" },
2733 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2734 { "condreload", "ReloadOrTryRestartUnit" },
2735 { "force-reload", "ReloadOrTryRestartUnit" }
2738 static const char *verb_to_method(const char *verb) {
2741 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2742 if (streq_ptr(unit_actions[i].verb, verb))
2743 return unit_actions[i].method;
2748 static const char *method_to_verb(const char *method) {
2751 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2752 if (streq_ptr(unit_actions[i].method, method))
2753 return unit_actions[i].verb;
2758 static int start_unit_one(
2763 sd_bus_error *error,
2766 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2775 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2777 r = sd_bus_message_new_method_call(
2780 "org.freedesktop.systemd1",
2781 "/org/freedesktop/systemd1",
2782 "org.freedesktop.systemd1.Manager",
2785 return bus_log_create_error(r);
2787 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2789 return bus_log_create_error(r);
2791 r = sd_bus_message_append(m, "ss", name, mode);
2793 return bus_log_create_error(r);
2795 r = sd_bus_call(bus, m, 0, error, &reply);
2799 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2800 /* There's always a fallback possible for
2801 * legacy actions. */
2802 return -EADDRNOTAVAIL;
2804 verb = method_to_verb(method);
2806 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2810 r = sd_bus_message_read(reply, "o", &path);
2812 return bus_log_parse_error(r);
2814 if (need_daemon_reload(bus, name) > 0)
2815 warn_unit_file_changed(name);
2824 log_debug("Adding %s to the set", p);
2825 r = set_consume(s, p);
2833 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2835 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2839 STRV_FOREACH(name, names) {
2843 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2845 t = unit_name_mangle(*name, MANGLE_GLOB);
2849 if (string_is_glob(t))
2850 r = strv_consume(&globs, t);
2852 r = strv_consume(&mangled, t);
2857 /* Query the manager only if any of the names are a glob, since
2858 * this is fairly expensive */
2859 if (!strv_isempty(globs)) {
2860 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2861 _cleanup_free_ UnitInfo *unit_infos = NULL;
2864 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2866 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2870 for (i = 0; i < r; i++)
2871 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2876 mangled = NULL; /* do not free */
2881 static const struct {
2885 } action_table[_ACTION_MAX] = {
2886 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2887 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2888 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2889 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2890 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2891 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2892 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2893 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2894 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2895 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2896 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2897 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2898 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2899 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2900 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2903 static enum action verb_to_action(const char *verb) {
2906 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2907 if (streq_ptr(action_table[i].verb, verb))
2910 return _ACTION_INVALID;
2913 static int start_unit(sd_bus *bus, char **args) {
2914 _cleanup_set_free_free_ Set *s = NULL;
2915 _cleanup_strv_free_ char **names = NULL;
2916 const char *method, *mode, *one_name, *suffix = NULL;
2922 ask_password_agent_open_if_enabled();
2924 if (arg_action == ACTION_SYSTEMCTL) {
2926 method = verb_to_method(args[0]);
2927 action = verb_to_action(args[0]);
2929 if (streq(args[0], "isolate")) {
2933 mode = action_table[action].mode ?: arg_job_mode;
2935 one_name = action_table[action].target;
2937 assert(arg_action < ELEMENTSOF(action_table));
2938 assert(action_table[arg_action].target);
2940 method = "StartUnit";
2942 mode = action_table[arg_action].mode;
2943 one_name = action_table[arg_action].target;
2947 names = strv_new(one_name, NULL);
2949 r = expand_names(bus, args + 1, suffix, &names);
2951 log_error_errno(r, "Failed to expand names: %m");
2954 if (!arg_no_block) {
2955 r = enable_wait_for_jobs(bus);
2957 return log_error_errno(r, "Could not watch jobs: %m");
2959 s = set_new(&string_hash_ops);
2964 STRV_FOREACH(name, names) {
2965 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2968 q = start_unit_one(bus, method, *name, mode, &error, s);
2969 if (r >= 0 && q < 0)
2970 r = translate_bus_error_to_exit_status(q, &error);
2973 if (!arg_no_block) {
2976 q = wait_for_jobs(bus, s);
2980 /* When stopping units, warn if they can still be triggered by
2981 * another active unit (socket, path, timer) */
2982 if (!arg_quiet && streq(method, "StopUnit"))
2983 STRV_FOREACH(name, names)
2984 check_triggering_units(bus, *name);
2990 /* Ask systemd-logind, which might grant access to unprivileged users
2991 * through PolicyKit */
2992 static int reboot_with_logind(sd_bus *bus, enum action a) {
2994 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3001 polkit_agent_open_if_enabled();
3009 case ACTION_POWEROFF:
3010 method = "PowerOff";
3013 case ACTION_SUSPEND:
3017 case ACTION_HIBERNATE:
3018 method = "Hibernate";
3021 case ACTION_HYBRID_SLEEP:
3022 method = "HybridSleep";
3029 r = sd_bus_call_method(
3031 "org.freedesktop.login1",
3032 "/org/freedesktop/login1",
3033 "org.freedesktop.login1.Manager",
3037 "b", arg_ask_password);
3039 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3047 static int check_inhibitors(sd_bus *bus, enum action a) {
3049 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3050 _cleanup_strv_free_ char **sessions = NULL;
3051 const char *what, *who, *why, *mode;
3060 if (arg_ignore_inhibitors || arg_force > 0)
3072 r = sd_bus_call_method(
3074 "org.freedesktop.login1",
3075 "/org/freedesktop/login1",
3076 "org.freedesktop.login1.Manager",
3082 /* If logind is not around, then there are no inhibitors... */
3085 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
3087 return bus_log_parse_error(r);
3089 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
3090 _cleanup_free_ char *comm = NULL, *user = NULL;
3091 _cleanup_strv_free_ char **sv = NULL;
3093 if (!streq(mode, "block"))
3096 sv = strv_split(what, ":");
3100 if (!strv_contains(sv,
3102 a == ACTION_POWEROFF ||
3103 a == ACTION_REBOOT ||
3104 a == ACTION_KEXEC ? "shutdown" : "sleep"))
3107 get_process_comm(pid, &comm);
3108 user = uid_to_name(uid);
3110 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
3111 who, pid, strna(comm), strna(user), why);
3116 return bus_log_parse_error(r);
3118 r = sd_bus_message_exit_container(reply);
3120 return bus_log_parse_error(r);
3122 /* Check for current sessions */
3123 sd_get_sessions(&sessions);
3124 STRV_FOREACH(s, sessions) {
3125 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
3127 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
3130 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
3133 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
3136 sd_session_get_tty(*s, &tty);
3137 sd_session_get_seat(*s, &seat);
3138 sd_session_get_service(*s, &service);
3139 user = uid_to_name(uid);
3141 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
3148 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3149 action_table[a].verb);
3157 static int start_special(sd_bus *bus, char **args) {
3163 a = verb_to_action(args[0]);
3165 r = check_inhibitors(bus, a);
3169 if (arg_force >= 2 && geteuid() != 0) {
3170 log_error("Must be root.");
3174 if (arg_force >= 2 &&
3175 (a == ACTION_HALT ||
3176 a == ACTION_POWEROFF ||
3177 a == ACTION_REBOOT))
3180 if (arg_force >= 1 &&
3181 (a == ACTION_HALT ||
3182 a == ACTION_POWEROFF ||
3183 a == ACTION_REBOOT ||
3184 a == ACTION_KEXEC ||
3186 return daemon_reload(bus, args);
3188 /* first try logind, to allow authentication with polkit */
3189 if (geteuid() != 0 &&
3190 (a == ACTION_POWEROFF ||
3191 a == ACTION_REBOOT ||
3192 a == ACTION_SUSPEND ||
3193 a == ACTION_HIBERNATE ||
3194 a == ACTION_HYBRID_SLEEP)) {
3195 r = reboot_with_logind(bus, a);
3200 r = start_unit(bus, args);
3201 if (r == EXIT_SUCCESS)
3207 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3208 _cleanup_strv_free_ char **names = NULL;
3215 r = expand_names(bus, args, NULL, &names);
3217 return log_error_errno(r, "Failed to expand names: %m");
3219 STRV_FOREACH(name, names) {
3222 state = check_one_unit(bus, *name, good_states, arg_quiet);
3232 static int check_unit_active(sd_bus *bus, char **args) {
3233 /* According to LSB: 3, "program is not running" */
3234 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3237 static int check_unit_failed(sd_bus *bus, char **args) {
3238 return check_unit_generic(bus, 1, "failed\0", args + 1);
3241 static int kill_unit(sd_bus *bus, char **args) {
3242 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3243 _cleanup_strv_free_ char **names = NULL;
3251 arg_kill_who = "all";
3253 r = expand_names(bus, args + 1, NULL, &names);
3255 log_error_errno(r, "Failed to expand names: %m");
3257 STRV_FOREACH(name, names) {
3258 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3260 q = sd_bus_message_new_method_call(
3263 "org.freedesktop.systemd1",
3264 "/org/freedesktop/systemd1",
3265 "org.freedesktop.systemd1.Manager",
3268 return bus_log_create_error(q);
3270 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3272 return bus_log_create_error(q);
3274 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3276 return bus_log_create_error(q);
3278 q = sd_bus_call(bus, m, 0, &error, NULL);
3280 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3289 typedef struct ExecStatusInfo {
3297 usec_t start_timestamp;
3298 usec_t exit_timestamp;
3303 LIST_FIELDS(struct ExecStatusInfo, exec);
3306 static void exec_status_info_free(ExecStatusInfo *i) {
3315 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3316 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3319 int32_t code, status;
3325 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3327 return bus_log_parse_error(r);
3331 r = sd_bus_message_read(m, "s", &path);
3333 return bus_log_parse_error(r);
3335 i->path = strdup(path);
3339 r = sd_bus_message_read_strv(m, &i->argv);
3341 return bus_log_parse_error(r);
3343 r = sd_bus_message_read(m,
3346 &start_timestamp, &start_timestamp_monotonic,
3347 &exit_timestamp, &exit_timestamp_monotonic,
3351 return bus_log_parse_error(r);
3354 i->start_timestamp = (usec_t) start_timestamp;
3355 i->exit_timestamp = (usec_t) exit_timestamp;
3356 i->pid = (pid_t) pid;
3360 r = sd_bus_message_exit_container(m);
3362 return bus_log_parse_error(r);
3367 typedef struct UnitStatusInfo {
3369 const char *load_state;
3370 const char *active_state;
3371 const char *sub_state;
3372 const char *unit_file_state;
3373 const char *unit_file_preset;
3375 const char *description;
3376 const char *following;
3378 char **documentation;
3380 const char *fragment_path;
3381 const char *source_path;
3382 const char *control_group;
3384 char **dropin_paths;
3386 const char *load_error;
3389 usec_t inactive_exit_timestamp;
3390 usec_t inactive_exit_timestamp_monotonic;
3391 usec_t active_enter_timestamp;
3392 usec_t active_exit_timestamp;
3393 usec_t inactive_enter_timestamp;
3395 bool need_daemon_reload;
3400 const char *status_text;
3401 const char *pid_file;
3405 usec_t start_timestamp;
3406 usec_t exit_timestamp;
3408 int exit_code, exit_status;
3410 usec_t condition_timestamp;
3411 bool condition_result;
3412 bool failed_condition_trigger;
3413 bool failed_condition_negate;
3414 const char *failed_condition;
3415 const char *failed_condition_parameter;
3417 usec_t assert_timestamp;
3419 bool failed_assert_trigger;
3420 bool failed_assert_negate;
3421 const char *failed_assert;
3422 const char *failed_assert_parameter;
3425 unsigned n_accepted;
3426 unsigned n_connections;
3429 /* Pairs of type, path */
3433 const char *sysfs_path;
3435 /* Mount, Automount */
3441 LIST_HEAD(ExecStatusInfo, exec);
3444 static void print_status_info(
3449 const char *active_on, *active_off, *on, *off, *ss;
3451 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3452 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3455 arg_all * OUTPUT_SHOW_ALL |
3456 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3457 on_tty() * OUTPUT_COLOR |
3458 !arg_quiet * OUTPUT_WARN_CUTOFF |
3459 arg_full * OUTPUT_FULL_WIDTH;
3464 /* This shows pretty information about a unit. See
3465 * print_property() for a low-level property printer */
3467 if (streq_ptr(i->active_state, "failed")) {
3468 active_on = ansi_highlight_red();
3469 active_off = ansi_highlight_off();
3470 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3471 active_on = ansi_highlight_green();
3472 active_off = ansi_highlight_off();
3474 active_on = active_off = "";
3476 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3478 if (i->description && !streq_ptr(i->id, i->description))
3479 printf(" - %s", i->description);
3484 printf(" Follow: unit currently follows state of %s\n", i->following);
3486 if (streq_ptr(i->load_state, "error")) {
3487 on = ansi_highlight_red();
3488 off = ansi_highlight_off();
3492 path = i->source_path ? i->source_path : i->fragment_path;
3495 printf(" Loaded: %s%s%s (Reason: %s)\n",
3496 on, strna(i->load_state), off, i->load_error);
3497 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3498 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3499 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3500 else if (path && !isempty(i->unit_file_state))
3501 printf(" Loaded: %s%s%s (%s; %s)\n",
3502 on, strna(i->load_state), off, path, i->unit_file_state);
3504 printf(" Loaded: %s%s%s (%s)\n",
3505 on, strna(i->load_state), off, path);
3507 printf(" Loaded: %s%s%s\n",
3508 on, strna(i->load_state), off);
3510 if (!strv_isempty(i->dropin_paths)) {
3511 _cleanup_free_ char *dir = NULL;
3515 STRV_FOREACH(dropin, i->dropin_paths) {
3516 if (! dir || last) {
3517 printf(dir ? " " : " Drop-In: ");
3522 if (path_get_parent(*dropin, &dir) < 0) {
3527 printf("%s\n %s", dir,
3528 draw_special_char(DRAW_TREE_RIGHT));
3531 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3533 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3537 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3539 printf(" Active: %s%s (%s)%s",
3540 active_on, strna(i->active_state), ss, active_off);
3542 printf(" Active: %s%s%s",
3543 active_on, strna(i->active_state), active_off);
3545 if (!isempty(i->result) && !streq(i->result, "success"))
3546 printf(" (Result: %s)", i->result);
3548 timestamp = (streq_ptr(i->active_state, "active") ||
3549 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3550 (streq_ptr(i->active_state, "inactive") ||
3551 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3552 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3553 i->active_exit_timestamp;
3555 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3556 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3559 printf(" since %s; %s\n", s2, s1);
3561 printf(" since %s\n", s2);
3565 if (!i->condition_result && i->condition_timestamp > 0) {
3566 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3567 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3569 printf("Condition: start %scondition failed%s at %s%s%s\n",
3570 ansi_highlight_yellow(), ansi_highlight_off(),
3571 s2, s1 ? "; " : "", s1 ? s1 : "");
3572 if (i->failed_condition_trigger)
3573 printf(" none of the trigger conditions were met\n");
3574 else if (i->failed_condition)
3575 printf(" %s=%s%s was not met\n",
3576 i->failed_condition,
3577 i->failed_condition_negate ? "!" : "",
3578 i->failed_condition_parameter);
3581 if (!i->assert_result && i->assert_timestamp > 0) {
3582 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3583 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3585 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3586 ansi_highlight_red(), ansi_highlight_off(),
3587 s2, s1 ? "; " : "", s1 ? s1 : "");
3588 if (i->failed_assert_trigger)
3589 printf(" none of the trigger assertions were met\n");
3590 else if (i->failed_assert)
3591 printf(" %s=%s%s was not met\n",
3593 i->failed_assert_negate ? "!" : "",
3594 i->failed_assert_parameter);
3598 printf(" Device: %s\n", i->sysfs_path);
3600 printf(" Where: %s\n", i->where);
3602 printf(" What: %s\n", i->what);
3604 STRV_FOREACH(t, i->documentation)
3605 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3607 STRV_FOREACH_PAIR(t, t2, i->listen)
3608 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3611 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3613 LIST_FOREACH(exec, p, i->exec) {
3614 _cleanup_free_ char *argv = NULL;
3617 /* Only show exited processes here */
3621 argv = strv_join(p->argv, " ");
3622 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3624 good = is_clean_exit_lsb(p->code, p->status, NULL);
3626 on = ansi_highlight_red();
3627 off = ansi_highlight_off();
3631 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3633 if (p->code == CLD_EXITED) {
3636 printf("status=%i", p->status);
3638 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3643 printf("signal=%s", signal_to_string(p->status));
3645 printf(")%s\n", off);
3647 if (i->main_pid == p->pid &&
3648 i->start_timestamp == p->start_timestamp &&
3649 i->exit_timestamp == p->start_timestamp)
3650 /* Let's not show this twice */
3653 if (p->pid == i->control_pid)
3657 if (i->main_pid > 0 || i->control_pid > 0) {
3658 if (i->main_pid > 0) {
3659 printf(" Main PID: "PID_FMT, i->main_pid);
3662 _cleanup_free_ char *comm = NULL;
3663 get_process_comm(i->main_pid, &comm);
3665 printf(" (%s)", comm);
3666 } else if (i->exit_code > 0) {
3667 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3669 if (i->exit_code == CLD_EXITED) {
3672 printf("status=%i", i->exit_status);
3674 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3679 printf("signal=%s", signal_to_string(i->exit_status));
3683 if (i->control_pid > 0)
3687 if (i->control_pid > 0) {
3688 _cleanup_free_ char *c = NULL;
3690 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3692 get_process_comm(i->control_pid, &c);
3701 printf(" Status: \"%s\"\n", i->status_text);
3702 if (i->status_errno > 0)
3703 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3705 if (i->control_group &&
3706 (i->main_pid > 0 || i->control_pid > 0 ||
3707 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3710 printf(" CGroup: %s\n", i->control_group);
3712 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3715 static const char prefix[] = " ";
3718 if (c > sizeof(prefix) - 1)
3719 c -= sizeof(prefix) - 1;
3723 if (i->main_pid > 0)
3724 extra[k++] = i->main_pid;
3726 if (i->control_pid > 0)
3727 extra[k++] = i->control_pid;
3729 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3733 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3734 show_journal_by_unit(stdout,
3738 i->inactive_exit_timestamp_monotonic,
3741 flags | OUTPUT_BEGIN_NEWLINE,
3742 arg_scope == UNIT_FILE_SYSTEM,
3746 if (i->need_daemon_reload)
3747 warn_unit_file_changed(i->id);
3750 static void show_unit_help(UnitStatusInfo *i) {
3755 if (!i->documentation) {
3756 log_info("Documentation for %s not known.", i->id);
3760 STRV_FOREACH(p, i->documentation)
3761 if (startswith(*p, "man:"))
3762 show_man_page(*p + 4, false);
3764 log_info("Can't show: %s", *p);
3767 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3774 switch (contents[0]) {
3776 case SD_BUS_TYPE_STRING: {
3779 r = sd_bus_message_read(m, "s", &s);
3781 return bus_log_parse_error(r);
3784 if (streq(name, "Id"))
3786 else if (streq(name, "LoadState"))
3788 else if (streq(name, "ActiveState"))
3789 i->active_state = s;
3790 else if (streq(name, "SubState"))
3792 else if (streq(name, "Description"))
3794 else if (streq(name, "FragmentPath"))
3795 i->fragment_path = s;
3796 else if (streq(name, "SourcePath"))
3799 else if (streq(name, "DefaultControlGroup")) {
3801 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3803 i->control_group = e;
3806 else if (streq(name, "ControlGroup"))
3807 i->control_group = s;
3808 else if (streq(name, "StatusText"))
3810 else if (streq(name, "PIDFile"))
3812 else if (streq(name, "SysFSPath"))
3814 else if (streq(name, "Where"))
3816 else if (streq(name, "What"))
3818 else if (streq(name, "Following"))
3820 else if (streq(name, "UnitFileState"))
3821 i->unit_file_state = s;
3822 else if (streq(name, "UnitFilePreset"))
3823 i->unit_file_preset = s;
3824 else if (streq(name, "Result"))
3831 case SD_BUS_TYPE_BOOLEAN: {
3834 r = sd_bus_message_read(m, "b", &b);
3836 return bus_log_parse_error(r);
3838 if (streq(name, "Accept"))
3840 else if (streq(name, "NeedDaemonReload"))
3841 i->need_daemon_reload = b;
3842 else if (streq(name, "ConditionResult"))
3843 i->condition_result = b;
3844 else if (streq(name, "AssertResult"))
3845 i->assert_result = b;
3850 case SD_BUS_TYPE_UINT32: {
3853 r = sd_bus_message_read(m, "u", &u);
3855 return bus_log_parse_error(r);
3857 if (streq(name, "MainPID")) {
3859 i->main_pid = (pid_t) u;
3862 } else if (streq(name, "ControlPID"))
3863 i->control_pid = (pid_t) u;
3864 else if (streq(name, "ExecMainPID")) {
3866 i->main_pid = (pid_t) u;
3867 } else if (streq(name, "NAccepted"))
3869 else if (streq(name, "NConnections"))
3870 i->n_connections = u;
3875 case SD_BUS_TYPE_INT32: {
3878 r = sd_bus_message_read(m, "i", &j);
3880 return bus_log_parse_error(r);
3882 if (streq(name, "ExecMainCode"))
3883 i->exit_code = (int) j;
3884 else if (streq(name, "ExecMainStatus"))
3885 i->exit_status = (int) j;
3886 else if (streq(name, "StatusErrno"))
3887 i->status_errno = (int) j;
3892 case SD_BUS_TYPE_UINT64: {
3895 r = sd_bus_message_read(m, "t", &u);
3897 return bus_log_parse_error(r);
3899 if (streq(name, "ExecMainStartTimestamp"))
3900 i->start_timestamp = (usec_t) u;
3901 else if (streq(name, "ExecMainExitTimestamp"))
3902 i->exit_timestamp = (usec_t) u;
3903 else if (streq(name, "ActiveEnterTimestamp"))
3904 i->active_enter_timestamp = (usec_t) u;
3905 else if (streq(name, "InactiveEnterTimestamp"))
3906 i->inactive_enter_timestamp = (usec_t) u;
3907 else if (streq(name, "InactiveExitTimestamp"))
3908 i->inactive_exit_timestamp = (usec_t) u;
3909 else if (streq(name, "InactiveExitTimestampMonotonic"))
3910 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3911 else if (streq(name, "ActiveExitTimestamp"))
3912 i->active_exit_timestamp = (usec_t) u;
3913 else if (streq(name, "ConditionTimestamp"))
3914 i->condition_timestamp = (usec_t) u;
3915 else if (streq(name, "AssertTimestamp"))
3916 i->assert_timestamp = (usec_t) u;
3921 case SD_BUS_TYPE_ARRAY:
3923 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3924 _cleanup_free_ ExecStatusInfo *info = NULL;
3926 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3928 return bus_log_parse_error(r);
3930 info = new0(ExecStatusInfo, 1);
3934 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3936 info->name = strdup(name);
3940 LIST_PREPEND(exec, i->exec, info);
3942 info = new0(ExecStatusInfo, 1);
3948 return bus_log_parse_error(r);
3950 r = sd_bus_message_exit_container(m);
3952 return bus_log_parse_error(r);
3956 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3957 const char *type, *path;
3959 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3961 return bus_log_parse_error(r);
3963 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3965 r = strv_extend(&i->listen, type);
3969 r = strv_extend(&i->listen, path);
3974 return bus_log_parse_error(r);
3976 r = sd_bus_message_exit_container(m);
3978 return bus_log_parse_error(r);
3982 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3984 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3986 return bus_log_parse_error(r);
3988 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3990 r = sd_bus_message_read_strv(m, &i->documentation);
3992 return bus_log_parse_error(r);
3994 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3995 const char *cond, *param;
3996 int trigger, negate;
3999 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4001 return bus_log_parse_error(r);
4003 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
4004 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
4005 if (state < 0 && (!trigger || !i->failed_condition)) {
4006 i->failed_condition = cond;
4007 i->failed_condition_trigger = trigger;
4008 i->failed_condition_negate = negate;
4009 i->failed_condition_parameter = param;
4013 return bus_log_parse_error(r);
4015 r = sd_bus_message_exit_container(m);
4017 return bus_log_parse_error(r);
4019 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
4020 const char *cond, *param;
4021 int trigger, negate;
4024 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
4026 return bus_log_parse_error(r);
4028 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
4029 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
4030 if (state < 0 && (!trigger || !i->failed_assert)) {
4031 i->failed_assert = cond;
4032 i->failed_assert_trigger = trigger;
4033 i->failed_assert_negate = negate;
4034 i->failed_assert_parameter = param;
4038 return bus_log_parse_error(r);
4040 r = sd_bus_message_exit_container(m);
4042 return bus_log_parse_error(r);
4049 case SD_BUS_TYPE_STRUCT_BEGIN:
4051 if (streq(name, "LoadError")) {
4052 const char *n, *message;
4054 r = sd_bus_message_read(m, "(ss)", &n, &message);
4056 return bus_log_parse_error(r);
4058 if (!isempty(message))
4059 i->load_error = message;
4072 r = sd_bus_message_skip(m, contents);
4074 return bus_log_parse_error(r);
4079 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
4085 /* This is a low-level property printer, see
4086 * print_status_info() for the nicer output */
4088 if (arg_properties && !strv_find(arg_properties, name)) {
4089 /* skip what we didn't read */
4090 r = sd_bus_message_skip(m, contents);
4094 switch (contents[0]) {
4096 case SD_BUS_TYPE_STRUCT_BEGIN:
4098 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
4101 r = sd_bus_message_read(m, "(uo)", &u, NULL);
4103 return bus_log_parse_error(r);
4106 printf("%s=%"PRIu32"\n", name, u);
4108 printf("%s=\n", name);
4112 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
4115 r = sd_bus_message_read(m, "(so)", &s, NULL);
4117 return bus_log_parse_error(r);
4119 if (arg_all || !isempty(s))
4120 printf("%s=%s\n", name, s);
4124 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
4125 const char *a = NULL, *b = NULL;
4127 r = sd_bus_message_read(m, "(ss)", &a, &b);
4129 return bus_log_parse_error(r);
4131 if (arg_all || !isempty(a) || !isempty(b))
4132 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
4135 } else if (streq_ptr(name, "SystemCallFilter")) {
4136 _cleanup_strv_free_ char **l = NULL;
4139 r = sd_bus_message_enter_container(m, 'r', "bas");
4141 return bus_log_parse_error(r);
4143 r = sd_bus_message_read(m, "b", &whitelist);
4145 return bus_log_parse_error(r);
4147 r = sd_bus_message_read_strv(m, &l);
4149 return bus_log_parse_error(r);
4151 r = sd_bus_message_exit_container(m);
4153 return bus_log_parse_error(r);
4155 if (arg_all || whitelist || !strv_isempty(l)) {
4159 fputs(name, stdout);
4165 STRV_FOREACH(i, l) {
4173 fputc('\n', stdout);
4181 case SD_BUS_TYPE_ARRAY:
4183 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4187 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4189 return bus_log_parse_error(r);
4191 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4192 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4195 return bus_log_parse_error(r);
4197 r = sd_bus_message_exit_container(m);
4199 return bus_log_parse_error(r);
4203 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4204 const char *type, *path;
4206 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4208 return bus_log_parse_error(r);
4210 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4211 printf("%s=%s\n", type, path);
4213 return bus_log_parse_error(r);
4215 r = sd_bus_message_exit_container(m);
4217 return bus_log_parse_error(r);
4221 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4222 const char *type, *path;
4224 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4226 return bus_log_parse_error(r);
4228 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4229 printf("Listen%s=%s\n", type, path);
4231 return bus_log_parse_error(r);
4233 r = sd_bus_message_exit_container(m);
4235 return bus_log_parse_error(r);
4239 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4241 uint64_t value, next_elapse;
4243 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4245 return bus_log_parse_error(r);
4247 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4248 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4250 printf("%s={ value=%s ; next_elapse=%s }\n",
4252 format_timespan(timespan1, sizeof(timespan1), value, 0),
4253 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4256 return bus_log_parse_error(r);
4258 r = sd_bus_message_exit_container(m);
4260 return bus_log_parse_error(r);
4264 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4265 ExecStatusInfo info = {};
4267 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4269 return bus_log_parse_error(r);
4271 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4272 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4273 _cleanup_free_ char *tt;
4275 tt = strv_join(info.argv, " ");
4277 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",
4281 yes_no(info.ignore),
4282 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4283 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4285 sigchld_code_to_string(info.code),
4287 info.code == CLD_EXITED ? "" : "/",
4288 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4291 strv_free(info.argv);
4295 r = sd_bus_message_exit_container(m);
4297 return bus_log_parse_error(r);
4301 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4302 const char *path, *rwm;
4304 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4306 return bus_log_parse_error(r);
4308 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4309 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4311 return bus_log_parse_error(r);
4313 r = sd_bus_message_exit_container(m);
4315 return bus_log_parse_error(r);
4319 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4323 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4325 return bus_log_parse_error(r);
4327 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4328 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4330 return bus_log_parse_error(r);
4332 r = sd_bus_message_exit_container(m);
4334 return bus_log_parse_error(r);
4338 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4342 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4344 return bus_log_parse_error(r);
4346 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4347 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4349 return bus_log_parse_error(r);
4351 r = sd_bus_message_exit_container(m);
4353 return bus_log_parse_error(r);
4361 r = bus_print_property(name, m, arg_all);
4363 return bus_log_parse_error(r);
4366 r = sd_bus_message_skip(m, contents);
4368 return bus_log_parse_error(r);
4371 printf("%s=[unprintable]\n", name);
4377 static int show_one(
4381 bool show_properties,
4385 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4386 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4387 UnitStatusInfo info = {};
4394 log_debug("Showing one %s", path);
4396 r = sd_bus_call_method(
4398 "org.freedesktop.systemd1",
4400 "org.freedesktop.DBus.Properties",
4406 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4410 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4412 return bus_log_parse_error(r);
4419 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4420 const char *name, *contents;
4422 r = sd_bus_message_read(reply, "s", &name);
4424 return bus_log_parse_error(r);
4426 r = sd_bus_message_peek_type(reply, NULL, &contents);
4428 return bus_log_parse_error(r);
4430 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4432 return bus_log_parse_error(r);
4434 if (show_properties)
4435 r = print_property(name, reply, contents);
4437 r = status_property(name, reply, &info, contents);
4441 r = sd_bus_message_exit_container(reply);
4443 return bus_log_parse_error(r);
4445 r = sd_bus_message_exit_container(reply);
4447 return bus_log_parse_error(r);
4450 return bus_log_parse_error(r);
4452 r = sd_bus_message_exit_container(reply);
4454 return bus_log_parse_error(r);
4458 if (!show_properties) {
4459 if (streq(verb, "help"))
4460 show_unit_help(&info);
4462 print_status_info(&info, ellipsized);
4465 strv_free(info.documentation);
4466 strv_free(info.dropin_paths);
4467 strv_free(info.listen);
4469 if (!streq_ptr(info.active_state, "active") &&
4470 !streq_ptr(info.active_state, "reloading") &&
4471 streq(verb, "status")) {
4472 /* According to LSB: "program not running" */
4473 /* 0: program is running or service is OK
4474 * 1: program is dead and /run PID file exists
4475 * 2: program is dead and /run/lock lock file exists
4476 * 3: program is not running
4477 * 4: program or service status is unknown
4479 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4485 while ((p = info.exec)) {
4486 LIST_REMOVE(exec, info.exec, p);
4487 exec_status_info_free(p);
4493 static int get_unit_dbus_path_by_pid(
4498 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4499 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4503 r = sd_bus_call_method(
4505 "org.freedesktop.systemd1",
4506 "/org/freedesktop/systemd1",
4507 "org.freedesktop.systemd1.Manager",
4513 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4517 r = sd_bus_message_read(reply, "o", &u);
4519 return bus_log_parse_error(r);
4529 static int show_all(
4532 bool show_properties,
4536 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4537 _cleanup_free_ UnitInfo *unit_infos = NULL;
4542 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4546 pager_open_if_enabled();
4550 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4552 for (u = unit_infos; u < unit_infos + c; u++) {
4553 _cleanup_free_ char *p = NULL;
4555 p = unit_dbus_path_from_name(u->id);
4559 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4562 else if (r > 0 && ret == 0)
4569 static int show_system_status(sd_bus *bus) {
4570 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4571 _cleanup_free_ char *hn = NULL;
4572 struct machine_info mi = {};
4573 const char *on, *off;
4576 hn = gethostname_malloc();
4580 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4582 return log_error_errno(r, "Failed to read server status: %m");
4584 if (streq_ptr(mi.state, "degraded")) {
4585 on = ansi_highlight_red();
4586 off = ansi_highlight_off();
4587 } else if (!streq_ptr(mi.state, "running")) {
4588 on = ansi_highlight_yellow();
4589 off = ansi_highlight_off();
4593 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4595 printf(" State: %s%s%s\n",
4596 on, strna(mi.state), off);
4598 printf(" Jobs: %u queued\n", mi.n_jobs);
4599 printf(" Failed: %u units\n", mi.n_failed_units);
4601 printf(" Since: %s; %s\n",
4602 format_timestamp(since2, sizeof(since2), mi.timestamp),
4603 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4605 printf(" CGroup: %s\n", mi.control_group ?: "/");
4606 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4608 arg_all * OUTPUT_SHOW_ALL |
4609 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4610 on_tty() * OUTPUT_COLOR |
4611 !arg_quiet * OUTPUT_WARN_CUTOFF |
4612 arg_full * OUTPUT_FULL_WIDTH;
4614 static const char prefix[] = " ";
4618 if (c > sizeof(prefix) - 1)
4619 c -= sizeof(prefix) - 1;
4623 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4627 free(mi.control_group);
4632 static int show(sd_bus *bus, char **args) {
4633 bool show_properties, show_status, new_line = false;
4634 bool ellipsized = false;
4640 show_properties = streq(args[0], "show");
4641 show_status = streq(args[0], "status");
4643 if (show_properties)
4644 pager_open_if_enabled();
4646 /* If no argument is specified inspect the manager itself */
4648 if (show_properties && strv_length(args) <= 1)
4649 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4651 if (show_status && strv_length(args) <= 1) {
4653 pager_open_if_enabled();
4654 show_system_status(bus);
4658 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4660 _cleanup_free_ char **patterns = NULL;
4663 STRV_FOREACH(name, args + 1) {
4664 _cleanup_free_ char *unit = NULL;
4667 if (safe_atou32(*name, &id) < 0) {
4668 if (strv_push(&patterns, *name) < 0)
4672 } else if (show_properties) {
4673 /* Interpret as job id */
4674 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4678 /* Interpret as PID */
4679 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4686 r = show_one(args[0], bus, unit, show_properties,
4687 &new_line, &ellipsized);
4690 else if (r > 0 && ret == 0)
4694 if (!strv_isempty(patterns)) {
4695 _cleanup_strv_free_ char **names = NULL;
4697 r = expand_names(bus, patterns, NULL, &names);
4699 log_error_errno(r, "Failed to expand names: %m");
4701 STRV_FOREACH(name, names) {
4702 _cleanup_free_ char *unit;
4704 unit = unit_dbus_path_from_name(*name);
4708 r = show_one(args[0], bus, unit, show_properties,
4709 &new_line, &ellipsized);
4712 else if (r > 0 && ret == 0)
4718 if (ellipsized && !arg_quiet)
4719 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4724 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4728 assert(user_runtime);
4731 if (arg_scope == UNIT_FILE_USER) {
4732 r = user_config_home(user_home);
4734 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4736 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4738 r = user_runtime_dir(user_runtime);
4740 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4742 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4745 r = lookup_paths_init(lp,
4746 arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
4747 arg_scope == UNIT_FILE_USER,
4751 return log_error_errno(r, "Failed to lookup unit lookup paths: %m");
4756 static int cat(sd_bus *bus, char **args) {
4757 _cleanup_free_ char *user_home = NULL;
4758 _cleanup_free_ char *user_runtime = NULL;
4759 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4760 _cleanup_strv_free_ char **names = NULL;
4762 bool first = true, avoid_bus_cache;
4767 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4771 r = expand_names(bus, args + 1, NULL, &names);
4773 log_error_errno(r, "Failed to expand names: %m");
4775 avoid_bus_cache = !bus || avoid_bus();
4777 pager_open_if_enabled();
4779 STRV_FOREACH(name, names) {
4780 _cleanup_free_ char *fragment_path = NULL;
4781 _cleanup_strv_free_ char **dropin_paths = NULL;
4784 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4788 log_warning("Unit %s does not have any files on disk", *name);
4797 if (fragment_path) {
4798 printf("%s# %s%s\n",
4799 ansi_highlight_blue(),
4801 ansi_highlight_off());
4804 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4806 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4811 STRV_FOREACH(path, dropin_paths) {
4812 printf("%s%s# %s%s\n",
4813 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4814 ansi_highlight_blue(),
4816 ansi_highlight_off());
4819 r = copy_file_fd(*path, STDOUT_FILENO, false);
4821 log_warning_errno(r, "Failed to cat %s: %m", *path);
4827 return r < 0 ? r : 0;
4830 static int set_property(sd_bus *bus, char **args) {
4831 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4832 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4833 _cleanup_free_ char *n = NULL;
4837 r = sd_bus_message_new_method_call(
4840 "org.freedesktop.systemd1",
4841 "/org/freedesktop/systemd1",
4842 "org.freedesktop.systemd1.Manager",
4843 "SetUnitProperties");
4845 return bus_log_create_error(r);
4847 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4849 return bus_log_create_error(r);
4851 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4855 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4857 return bus_log_create_error(r);
4859 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4861 return bus_log_create_error(r);
4863 STRV_FOREACH(i, args + 2) {
4864 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4866 return bus_log_create_error(r);
4868 r = bus_append_unit_property_assignment(m, *i);
4872 r = sd_bus_message_close_container(m);
4874 return bus_log_create_error(r);
4877 r = sd_bus_message_close_container(m);
4879 return bus_log_create_error(r);
4881 r = sd_bus_call(bus, m, 0, &error, NULL);
4883 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4890 static int snapshot(sd_bus *bus, char **args) {
4891 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4892 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4893 _cleanup_free_ char *n = NULL, *id = NULL;
4897 if (strv_length(args) > 1)
4898 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4904 r = sd_bus_message_new_method_call(
4907 "org.freedesktop.systemd1",
4908 "/org/freedesktop/systemd1",
4909 "org.freedesktop.systemd1.Manager",
4912 return bus_log_create_error(r);
4914 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4916 return bus_log_create_error(r);
4918 r = sd_bus_message_append(m, "sb", n, false);
4920 return bus_log_create_error(r);
4922 r = sd_bus_call(bus, m, 0, &error, &reply);
4924 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4928 r = sd_bus_message_read(reply, "o", &path);
4930 return bus_log_parse_error(r);
4932 r = sd_bus_get_property_string(
4934 "org.freedesktop.systemd1",
4936 "org.freedesktop.systemd1.Unit",
4941 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4951 static int delete_snapshot(sd_bus *bus, char **args) {
4952 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4953 _cleanup_strv_free_ char **names = NULL;
4959 r = expand_names(bus, args + 1, ".snapshot", &names);
4961 log_error_errno(r, "Failed to expand names: %m");
4963 STRV_FOREACH(name, names) {
4964 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4967 q = sd_bus_message_new_method_call(
4970 "org.freedesktop.systemd1",
4971 "/org/freedesktop/systemd1",
4972 "org.freedesktop.systemd1.Manager",
4975 return bus_log_create_error(q);
4977 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4979 return bus_log_create_error(q);
4981 q = sd_bus_message_append(m, "s", *name);
4983 return bus_log_create_error(q);
4985 q = sd_bus_call(bus, m, 0, &error, NULL);
4987 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4996 static int daemon_reload(sd_bus *bus, char **args) {
4997 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4998 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5002 if (arg_action == ACTION_RELOAD)
5004 else if (arg_action == ACTION_REEXEC)
5005 method = "Reexecute";
5007 assert(arg_action == ACTION_SYSTEMCTL);
5010 streq(args[0], "clear-jobs") ||
5011 streq(args[0], "cancel") ? "ClearJobs" :
5012 streq(args[0], "daemon-reexec") ? "Reexecute" :
5013 streq(args[0], "reset-failed") ? "ResetFailed" :
5014 streq(args[0], "halt") ? "Halt" :
5015 streq(args[0], "poweroff") ? "PowerOff" :
5016 streq(args[0], "reboot") ? "Reboot" :
5017 streq(args[0], "kexec") ? "KExec" :
5018 streq(args[0], "exit") ? "Exit" :
5019 /* "daemon-reload" */ "Reload";
5022 r = sd_bus_message_new_method_call(
5025 "org.freedesktop.systemd1",
5026 "/org/freedesktop/systemd1",
5027 "org.freedesktop.systemd1.Manager",
5030 return bus_log_create_error(r);
5032 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5034 return bus_log_create_error(r);
5036 r = sd_bus_call(bus, m, 0, &error, NULL);
5037 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
5038 /* There's always a fallback possible for
5039 * legacy actions. */
5041 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
5042 /* On reexecution, we expect a disconnect, not a
5046 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5048 return r < 0 ? r : 0;
5051 static int reset_failed(sd_bus *bus, char **args) {
5052 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5053 _cleanup_strv_free_ char **names = NULL;
5057 if (strv_length(args) <= 1)
5058 return daemon_reload(bus, args);
5060 r = expand_names(bus, args + 1, NULL, &names);
5062 log_error_errno(r, "Failed to expand names: %m");
5064 STRV_FOREACH(name, names) {
5065 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5067 q = sd_bus_message_new_method_call(
5070 "org.freedesktop.systemd1",
5071 "/org/freedesktop/systemd1",
5072 "org.freedesktop.systemd1.Manager",
5075 return bus_log_create_error(q);
5077 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5079 return bus_log_create_error(q);
5081 q = sd_bus_message_append(m, "s", *name);
5083 return bus_log_create_error(q);
5085 q = sd_bus_call(bus, m, 0, &error, NULL);
5087 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
5096 static int show_environment(sd_bus *bus, char **args) {
5097 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5098 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5102 pager_open_if_enabled();
5104 r = sd_bus_get_property(
5106 "org.freedesktop.systemd1",
5107 "/org/freedesktop/systemd1",
5108 "org.freedesktop.systemd1.Manager",
5114 log_error("Failed to get environment: %s", bus_error_message(&error, r));
5118 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
5120 return bus_log_parse_error(r);
5122 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
5125 return bus_log_parse_error(r);
5127 r = sd_bus_message_exit_container(reply);
5129 return bus_log_parse_error(r);
5134 static int switch_root(sd_bus *bus, char **args) {
5135 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5136 _cleanup_free_ char *cmdline_init = NULL;
5137 const char *root, *init;
5141 l = strv_length(args);
5142 if (l < 2 || l > 3) {
5143 log_error("Wrong number of arguments.");
5152 r = parse_env_file("/proc/cmdline", WHITESPACE,
5153 "init", &cmdline_init,
5156 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
5158 init = cmdline_init;
5165 const char *root_systemd_path = NULL, *root_init_path = NULL;
5167 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
5168 root_init_path = strappenda(root, "/", init);
5170 /* If the passed init is actually the same as the
5171 * systemd binary, then let's suppress it. */
5172 if (files_same(root_init_path, root_systemd_path) > 0)
5176 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5178 r = sd_bus_call_method(
5180 "org.freedesktop.systemd1",
5181 "/org/freedesktop/systemd1",
5182 "org.freedesktop.systemd1.Manager",
5188 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5195 static int set_environment(sd_bus *bus, char **args) {
5196 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5197 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5204 method = streq(args[0], "set-environment")
5206 : "UnsetEnvironment";
5208 r = sd_bus_message_new_method_call(
5211 "org.freedesktop.systemd1",
5212 "/org/freedesktop/systemd1",
5213 "org.freedesktop.systemd1.Manager",
5216 return bus_log_create_error(r);
5218 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5220 return bus_log_create_error(r);
5222 r = sd_bus_message_append_strv(m, args + 1);
5224 return bus_log_create_error(r);
5226 r = sd_bus_call(bus, m, 0, &error, NULL);
5228 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5235 static int import_environment(sd_bus *bus, char **args) {
5236 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5237 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5243 r = sd_bus_message_new_method_call(
5246 "org.freedesktop.systemd1",
5247 "/org/freedesktop/systemd1",
5248 "org.freedesktop.systemd1.Manager",
5251 return bus_log_create_error(r);
5253 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5255 return bus_log_create_error(r);
5257 if (strv_isempty(args + 1))
5258 r = sd_bus_message_append_strv(m, environ);
5262 r = sd_bus_message_open_container(m, 'a', "s");
5264 return bus_log_create_error(r);
5266 STRV_FOREACH(a, args + 1) {
5268 if (!env_name_is_valid(*a)) {
5269 log_error("Not a valid environment variable name: %s", *a);
5273 STRV_FOREACH(b, environ) {
5276 eq = startswith(*b, *a);
5277 if (eq && *eq == '=') {
5279 r = sd_bus_message_append(m, "s", *b);
5281 return bus_log_create_error(r);
5288 r = sd_bus_message_close_container(m);
5291 return bus_log_create_error(r);
5293 r = sd_bus_call(bus, m, 0, &error, NULL);
5295 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5302 static int enable_sysv_units(const char *verb, char **args) {
5305 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5307 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5309 if (arg_scope != UNIT_FILE_SYSTEM)
5312 if (!streq(verb, "enable") &&
5313 !streq(verb, "disable") &&
5314 !streq(verb, "is-enabled"))
5317 /* Processes all SysV units, and reshuffles the array so that
5318 * afterwards only the native units remain */
5320 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5327 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5328 bool found_native = false, found_sysv;
5330 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5338 if (!endswith(name, ".service"))
5341 if (path_is_absolute(name))
5344 STRV_FOREACH(k, paths.unit_path) {
5345 _cleanup_free_ char *path = NULL;
5347 path = path_join(arg_root, *k, name);
5351 found_native = access(path, F_OK) >= 0;
5359 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5363 p[strlen(p) - strlen(".service")] = 0;
5364 found_sysv = access(p, F_OK) >= 0;
5368 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5370 if (!isempty(arg_root))
5371 argv[c++] = q = strappend("--root=", arg_root);
5373 argv[c++] = basename(p);
5375 streq(verb, "enable") ? "on" :
5376 streq(verb, "disable") ? "off" : "--level=5";
5379 l = strv_join((char**)argv, " ");
5383 log_info("Executing %s", l);
5387 return log_error_errno(errno, "Failed to fork: %m");
5388 else if (pid == 0) {
5391 execv(argv[0], (char**) argv);
5392 _exit(EXIT_FAILURE);
5395 j = wait_for_terminate(pid, &status);
5397 log_error_errno(r, "Failed to wait for child: %m");
5401 if (status.si_code == CLD_EXITED) {
5402 if (streq(verb, "is-enabled")) {
5403 if (status.si_status == 0) {
5412 } else if (status.si_status != 0)
5417 /* Remove this entry, so that we don't try enabling it as native unit */
5418 assert(f > 0 && streq(args[f-1], name));
5419 assert_se(strv_remove(args + f - 1, name));
5426 static int mangle_names(char **original_names, char ***mangled_names) {
5427 char **i, **l, **name;
5429 l = new(char*, strv_length(original_names) + 1);
5434 STRV_FOREACH(name, original_names) {
5436 /* When enabling units qualified path names are OK,
5437 * too, hence allow them explicitly. */
5442 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5458 static int enable_unit(sd_bus *bus, char **args) {
5459 _cleanup_strv_free_ char **names = NULL;
5460 const char *verb = args[0];
5461 UnitFileChange *changes = NULL;
5462 unsigned n_changes = 0;
5463 int carries_install_info = -1;
5469 r = mangle_names(args+1, &names);
5473 r = enable_sysv_units(verb, names);
5477 /* If the operation was fully executed by the SysV compat,
5478 * let's finish early */
5479 if (strv_isempty(names))
5482 if (!bus || avoid_bus()) {
5483 if (streq(verb, "enable")) {
5484 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5485 carries_install_info = r;
5486 } else if (streq(verb, "disable"))
5487 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5488 else if (streq(verb, "reenable")) {
5489 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5490 carries_install_info = r;
5491 } else if (streq(verb, "link"))
5492 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5493 else if (streq(verb, "preset")) {
5494 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5495 carries_install_info = r;
5496 } else if (streq(verb, "mask"))
5497 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5498 else if (streq(verb, "unmask"))
5499 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5501 assert_not_reached("Unknown verb");
5504 log_error_errno(r, "Operation failed: %m");
5509 dump_unit_file_changes(changes, n_changes);
5513 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5514 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5515 int expect_carries_install_info = false;
5516 bool send_force = true, send_preset_mode = false;
5519 if (streq(verb, "enable")) {
5520 method = "EnableUnitFiles";
5521 expect_carries_install_info = true;
5522 } else if (streq(verb, "disable")) {
5523 method = "DisableUnitFiles";
5525 } else if (streq(verb, "reenable")) {
5526 method = "ReenableUnitFiles";
5527 expect_carries_install_info = true;
5528 } else if (streq(verb, "link"))
5529 method = "LinkUnitFiles";
5530 else if (streq(verb, "preset")) {
5532 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5533 method = "PresetUnitFilesWithMode";
5534 send_preset_mode = true;
5536 method = "PresetUnitFiles";
5538 expect_carries_install_info = true;
5539 } else if (streq(verb, "mask"))
5540 method = "MaskUnitFiles";
5541 else if (streq(verb, "unmask")) {
5542 method = "UnmaskUnitFiles";
5545 assert_not_reached("Unknown verb");
5547 r = sd_bus_message_new_method_call(
5550 "org.freedesktop.systemd1",
5551 "/org/freedesktop/systemd1",
5552 "org.freedesktop.systemd1.Manager",
5555 return bus_log_create_error(r);
5557 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5559 return bus_log_create_error(r);
5561 r = sd_bus_message_append_strv(m, names);
5563 return bus_log_create_error(r);
5565 if (send_preset_mode) {
5566 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5568 return bus_log_create_error(r);
5571 r = sd_bus_message_append(m, "b", arg_runtime);
5573 return bus_log_create_error(r);
5576 r = sd_bus_message_append(m, "b", arg_force);
5578 return bus_log_create_error(r);
5581 r = sd_bus_call(bus, m, 0, &error, &reply);
5583 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5587 if (expect_carries_install_info) {
5588 r = sd_bus_message_read(reply, "b", &carries_install_info);
5590 return bus_log_parse_error(r);
5593 r = deserialize_and_dump_unit_file_changes(reply);
5597 /* Try to reload if enabled */
5599 r = daemon_reload(bus, args);
5604 if (carries_install_info == 0)
5605 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5606 "using systemctl.\n"
5607 "Possible reasons for having this kind of units are:\n"
5608 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5609 " .wants/ or .requires/ directory.\n"
5610 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5611 " a requirement dependency on it.\n"
5612 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5613 " D-Bus, udev, scripted systemctl call, ...).\n");
5616 unit_file_changes_free(changes, n_changes);
5621 static int add_dependency(sd_bus *bus, char **args) {
5622 _cleanup_strv_free_ char **names = NULL;
5623 _cleanup_free_ char *target = NULL;
5624 const char *verb = args[0];
5631 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5635 r = mangle_names(args+2, &names);
5639 if (streq(verb, "add-wants"))
5641 else if (streq(verb, "add-requires"))
5642 dep = UNIT_REQUIRES;
5644 assert_not_reached("Unknown verb");
5646 if (!bus || avoid_bus()) {
5647 UnitFileChange *changes = NULL;
5648 unsigned n_changes = 0;
5650 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5653 return log_error_errno(r, "Can't add dependency: %m");
5656 dump_unit_file_changes(changes, n_changes);
5658 unit_file_changes_free(changes, n_changes);
5661 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5662 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5664 r = sd_bus_message_new_method_call(
5667 "org.freedesktop.systemd1",
5668 "/org/freedesktop/systemd1",
5669 "org.freedesktop.systemd1.Manager",
5670 "AddDependencyUnitFiles");
5672 return bus_log_create_error(r);
5674 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5676 return bus_log_create_error(r);
5678 r = sd_bus_message_append_strv(m, names);
5680 return bus_log_create_error(r);
5682 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5684 return bus_log_create_error(r);
5686 r = sd_bus_call(bus, m, 0, &error, &reply);
5688 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5692 r = deserialize_and_dump_unit_file_changes(reply);
5697 r = daemon_reload(bus, args);
5705 static int preset_all(sd_bus *bus, char **args) {
5706 UnitFileChange *changes = NULL;
5707 unsigned n_changes = 0;
5710 if (!bus || avoid_bus()) {
5712 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5714 log_error_errno(r, "Operation failed: %m");
5719 dump_unit_file_changes(changes, n_changes);
5724 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5725 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5727 r = sd_bus_message_new_method_call(
5730 "org.freedesktop.systemd1",
5731 "/org/freedesktop/systemd1",
5732 "org.freedesktop.systemd1.Manager",
5733 "PresetAllUnitFiles");
5735 return bus_log_create_error(r);
5737 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5739 return bus_log_create_error(r);
5741 r = sd_bus_message_append(
5744 unit_file_preset_mode_to_string(arg_preset_mode),
5748 return bus_log_create_error(r);
5750 r = sd_bus_call(bus, m, 0, &error, &reply);
5752 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5756 r = deserialize_and_dump_unit_file_changes(reply);
5761 r = daemon_reload(bus, args);
5767 unit_file_changes_free(changes, n_changes);
5772 static int unit_is_enabled(sd_bus *bus, char **args) {
5774 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5775 _cleanup_strv_free_ char **names = NULL;
5780 r = mangle_names(args+1, &names);
5784 r = enable_sysv_units(args[0], names);
5790 if (!bus || avoid_bus()) {
5792 STRV_FOREACH(name, names) {
5793 UnitFileState state;
5795 state = unit_file_get_state(arg_scope, arg_root, *name);
5797 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5799 if (state == UNIT_FILE_ENABLED ||
5800 state == UNIT_FILE_ENABLED_RUNTIME ||
5801 state == UNIT_FILE_STATIC ||
5802 state == UNIT_FILE_INDIRECT)
5806 puts(unit_file_state_to_string(state));
5810 STRV_FOREACH(name, names) {
5811 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5814 r = sd_bus_call_method(
5816 "org.freedesktop.systemd1",
5817 "/org/freedesktop/systemd1",
5818 "org.freedesktop.systemd1.Manager",
5824 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5828 r = sd_bus_message_read(reply, "s", &s);
5830 return bus_log_parse_error(r);
5832 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5843 static int is_system_running(sd_bus *bus, char **args) {
5844 _cleanup_free_ char *state = NULL;
5847 r = sd_bus_get_property_string(
5849 "org.freedesktop.systemd1",
5850 "/org/freedesktop/systemd1",
5851 "org.freedesktop.systemd1.Manager",
5864 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5867 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5872 assert(original_path);
5875 r = tempfn_random(new_path, &t);
5877 return log_error_errno(r, "Failed to determine temporary filename for %s: %m", new_path);
5879 r = mkdir_parents(new_path, 0755);
5881 log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5886 r = copy_file(original_path, t, 0, 0644);
5890 log_error_errno(r, "Failed to create temporary file %s: %m", t);
5895 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5905 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5906 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5908 switch (arg_scope) {
5909 case UNIT_FILE_SYSTEM:
5910 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5912 run = path_join(arg_root, "/run/systemd/system/", name);
5914 case UNIT_FILE_GLOBAL:
5915 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5917 run = path_join(arg_root, "/run/systemd/user/", name);
5919 case UNIT_FILE_USER:
5921 assert(user_runtime);
5923 path = path_join(arg_root, user_home, name);
5925 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5928 run = path_join(arg_root, user_runtime, name);
5932 assert_not_reached("Invalid scope");
5934 if (!path || (arg_runtime && !run))
5938 if (access(path, F_OK) >= 0)
5939 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5941 if (path2 && access(path2, F_OK) >= 0)
5942 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5955 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) {
5956 char *tmp_new_path, *ending;
5961 assert(ret_new_path);
5962 assert(ret_tmp_path);
5964 ending = strappenda(unit_name, ".d/override.conf");
5965 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5969 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5975 *ret_new_path = tmp_new_path;
5976 *ret_tmp_path = tmp_tmp_path;
5981 static int unit_file_create_copy(const char *unit_name,
5982 const char *fragment_path,
5983 const char *user_home,
5984 const char *user_runtime,
5985 char **ret_new_path,
5986 char **ret_tmp_path) {
5991 assert(fragment_path);
5993 assert(ret_new_path);
5994 assert(ret_tmp_path);
5996 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
6000 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
6003 r = ask_char(&response, "yn", "%s already exists, are you sure to overwrite it with %s? [(y)es, (n)o] ", tmp_new_path, fragment_path);
6008 if (response != 'y') {
6009 log_warning("%s ignored", unit_name);
6015 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
6017 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
6022 *ret_new_path = tmp_new_path;
6023 *ret_tmp_path = tmp_tmp_path;
6028 static int run_editor(char **paths) {
6036 log_error_errno(errno, "Failed to fork: %m");
6042 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
6044 char **tmp_path, **original_path, **p;
6048 argc = strv_length(paths)/2 + 1;
6049 args = newa(const char*, argc + 1);
6052 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
6053 args[i] = *tmp_path;
6058 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6059 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6060 * we try to execute well known editors
6062 editor = getenv("SYSTEMD_EDITOR");
6064 editor = getenv("EDITOR");
6066 editor = getenv("VISUAL");
6068 if (!isempty(editor)) {
6070 execvp(editor, (char* const*) args);
6073 STRV_FOREACH(p, backup_editors) {
6075 execvp(*p, (char* const*) args);
6076 /* We do not fail if the editor doesn't exist
6077 * because we want to try each one of them before
6080 if (errno != ENOENT) {
6081 log_error("Failed to execute %s: %m", editor);
6082 _exit(EXIT_FAILURE);
6086 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
6087 _exit(EXIT_FAILURE);
6090 r = wait_for_terminate_and_warn("editor", pid, true);
6092 return log_error_errno(r, "Failed to wait for child: %m");
6097 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6098 _cleanup_free_ char *user_home = NULL;
6099 _cleanup_free_ char *user_runtime = NULL;
6100 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6101 bool avoid_bus_cache;
6108 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
6112 avoid_bus_cache = !bus || avoid_bus();
6114 STRV_FOREACH(name, names) {
6115 _cleanup_free_ char *path = NULL;
6116 char *new_path, *tmp_path;
6118 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
6121 else if (r == 0 || !path)
6122 // FIXME: support units with path==NULL (no FragmentPath)
6123 return log_error_errno(ENOENT, "Unit %s not found, cannot edit.", *name);
6126 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
6128 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
6132 r = strv_push_pair(paths, new_path, tmp_path);
6140 static int edit(sd_bus *bus, char **args) {
6141 _cleanup_strv_free_ char **names = NULL;
6142 _cleanup_strv_free_ char **paths = NULL;
6143 char **original, **tmp;
6149 log_error("Cannot edit units if we are not on a tty");
6153 if (arg_transport != BUS_TRANSPORT_LOCAL) {
6154 log_error("Cannot remotely edit units");
6158 r = expand_names(bus, args + 1, NULL, &names);
6160 return log_error_errno(r, "Failed to expand names: %m");
6163 log_error("No unit name found by expanding names");
6167 r = find_paths_to_edit(bus, names, &paths);
6171 if (strv_isempty(paths)) {
6172 log_error("Cannot find any units to edit");
6176 r = run_editor(paths);
6180 STRV_FOREACH_PAIR(original, tmp, paths) {
6181 /* If the temporary file is empty we ignore it.
6182 * It's useful if the user wants to cancel its modification
6184 if (null_or_empty_path(*tmp)) {
6185 log_warning("Edition of %s canceled: temporary file empty", *original);
6188 r = rename(*tmp, *original);
6190 r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
6195 if (!arg_no_reload && bus && !avoid_bus())
6196 r = daemon_reload(bus, args);
6199 STRV_FOREACH_PAIR(original, tmp, paths)
6200 unlink_noerrno(*tmp);
6205 static void systemctl_help(void) {
6207 pager_open_if_enabled();
6209 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6210 "Query or send control commands to the systemd manager.\n\n"
6211 " -h --help Show this help\n"
6212 " --version Show package version\n"
6213 " --system Connect to system manager\n"
6214 " --user Connect to user service manager\n"
6215 " -H --host=[USER@]HOST\n"
6216 " Operate on remote host\n"
6217 " -M --machine=CONTAINER\n"
6218 " Operate on local container\n"
6219 " -t --type=TYPE List only units of a particular type\n"
6220 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
6221 " -p --property=NAME Show only properties by this name\n"
6222 " -a --all Show all loaded units/properties, including dead/empty\n"
6223 " ones. To list all units installed on the system, use\n"
6224 " the 'list-unit-files' command instead.\n"
6225 " -l --full Don't ellipsize unit names on output\n"
6226 " -r --recursive Show unit list of host and local containers\n"
6227 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6228 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6229 " queueing a new job\n"
6230 " --show-types When showing sockets, explicitly show their type\n"
6231 " -i --ignore-inhibitors\n"
6232 " When shutting down or sleeping, ignore inhibitors\n"
6233 " --kill-who=WHO Who to send signal to\n"
6234 " -s --signal=SIGNAL Which signal to send\n"
6235 " -q --quiet Suppress output\n"
6236 " --no-block Do not wait until operation finished\n"
6237 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6238 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
6240 " --no-legend Do not print a legend (column headers and hints)\n"
6241 " --no-pager Do not pipe output into a pager\n"
6242 " --no-ask-password\n"
6243 " Do not ask for system passwords\n"
6244 " --global Enable/disable unit files globally\n"
6245 " --runtime Enable unit files only temporarily until next reboot\n"
6246 " -f --force When enabling unit files, override existing symlinks\n"
6247 " When shutting down, execute action immediately\n"
6248 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
6249 " or only disable\n"
6250 " --root=PATH Enable unit files in the specified root directory\n"
6251 " -n --lines=INTEGER Number of journal entries to show\n"
6252 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
6253 " verbose, export, json, json-pretty, json-sse, cat)\n"
6254 " --plain Print unit dependencies as a list instead of a tree\n\n"
6256 " list-units [PATTERN...] List loaded units\n"
6257 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6258 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6259 " start NAME... Start (activate) one or more units\n"
6260 " stop NAME... Stop (deactivate) one or more units\n"
6261 " reload NAME... Reload one or more units\n"
6262 " restart NAME... Start or restart one or more units\n"
6263 " try-restart NAME... Restart one or more units if active\n"
6264 " reload-or-restart NAME... Reload one or more units if possible,\n"
6265 " otherwise start or restart\n"
6266 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6267 " otherwise restart if active\n"
6268 " isolate NAME Start one unit and stop all others\n"
6269 " kill NAME... Send signal to processes of a unit\n"
6270 " is-active PATTERN... Check whether units are active\n"
6271 " is-failed PATTERN... Check whether units are failed\n"
6272 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6273 " show [PATTERN...|JOB...] Show properties of one or more\n"
6274 " units/jobs or the manager\n"
6275 " cat PATTERN... Show files and drop-ins of one or more units\n"
6276 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6277 " help PATTERN...|PID... Show manual for one or more units\n"
6278 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6280 " list-dependencies [NAME] Recursively show units which are required\n"
6281 " or wanted by this unit or by which this\n"
6282 " unit is required or wanted\n\n"
6283 "Unit File Commands:\n"
6284 " list-unit-files [PATTERN...] List installed unit files\n"
6285 " enable NAME... Enable one or more unit files\n"
6286 " disable NAME... Disable one or more unit files\n"
6287 " reenable NAME... Reenable one or more unit files\n"
6288 " preset NAME... Enable/disable one or more unit files\n"
6289 " based on preset configuration\n"
6290 " preset-all Enable/disable all unit files based on\n"
6291 " preset configuration\n"
6292 " is-enabled NAME... Check whether unit files are enabled\n\n"
6293 " mask NAME... Mask one or more units\n"
6294 " unmask NAME... Unmask one or more units\n"
6295 " link PATH... Link one or more units files into\n"
6296 " the search path\n"
6297 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6298 " on specified one or more units\n"
6299 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6300 " on specified one or more units\n"
6301 " get-default Get the name of the default target\n"
6302 " set-default NAME Set the default target\n"
6303 " edit NAME... Edit one or more unit files\n"
6305 "Machine Commands:\n"
6306 " list-machines [PATTERN...] List local containers and host\n\n"
6308 " list-jobs [PATTERN...] List jobs\n"
6309 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6310 "Snapshot Commands:\n"
6311 " snapshot [NAME] Create a snapshot\n"
6312 " delete NAME... Remove one or more snapshots\n\n"
6313 "Environment Commands:\n"
6314 " show-environment Dump environment\n"
6315 " set-environment NAME=VALUE... Set one or more environment variables\n"
6316 " unset-environment NAME... Unset one or more environment variables\n"
6317 " import-environment NAME... Import all, one or more environment variables\n\n"
6318 "Manager Lifecycle Commands:\n"
6319 " daemon-reload Reload systemd manager configuration\n"
6320 " daemon-reexec Reexecute systemd manager\n\n"
6321 "System Commands:\n"
6322 " is-system-running Check whether system is fully running\n"
6323 " default Enter system default mode\n"
6324 " rescue Enter system rescue mode\n"
6325 " emergency Enter system emergency mode\n"
6326 " halt Shut down and halt the system\n"
6327 " poweroff Shut down and power-off the system\n"
6328 " reboot [ARG] Shut down and reboot the system\n"
6329 " kexec Shut down and reboot the system with kexec\n"
6330 " exit Request user instance exit\n"
6331 " switch-root ROOT [INIT] Change to a different root file system\n"
6332 " suspend Suspend the system\n"
6333 " hibernate Hibernate the system\n"
6334 " hybrid-sleep Hibernate and suspend the system\n",
6335 program_invocation_short_name);
6338 static void halt_help(void) {
6339 printf("%s [OPTIONS...]%s\n\n"
6340 "%s the system.\n\n"
6341 " --help Show this help\n"
6342 " --halt Halt the machine\n"
6343 " -p --poweroff Switch off the machine\n"
6344 " --reboot Reboot the machine\n"
6345 " -f --force Force immediate halt/power-off/reboot\n"
6346 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6347 " -d --no-wtmp Don't write wtmp record\n"
6348 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6349 program_invocation_short_name,
6350 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6351 arg_action == ACTION_REBOOT ? "Reboot" :
6352 arg_action == ACTION_POWEROFF ? "Power off" :
6356 static void shutdown_help(void) {
6357 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6358 "Shut down the system.\n\n"
6359 " --help Show this help\n"
6360 " -H --halt Halt the machine\n"
6361 " -P --poweroff Power-off the machine\n"
6362 " -r --reboot Reboot the machine\n"
6363 " -h Equivalent to --poweroff, overridden by --halt\n"
6364 " -k Don't halt/power-off/reboot, just send warnings\n"
6365 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6366 " -c Cancel a pending shutdown\n",
6367 program_invocation_short_name);
6370 static void telinit_help(void) {
6371 printf("%s [OPTIONS...] {COMMAND}\n\n"
6372 "Send control commands to the init daemon.\n\n"
6373 " --help Show this help\n"
6374 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6376 " 0 Power-off the machine\n"
6377 " 6 Reboot the machine\n"
6378 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6379 " 1, s, S Enter rescue mode\n"
6380 " q, Q Reload init daemon configuration\n"
6381 " u, U Reexecute init daemon\n",
6382 program_invocation_short_name);
6385 static void runlevel_help(void) {
6386 printf("%s [OPTIONS...]\n\n"
6387 "Prints the previous and current runlevel of the init system.\n\n"
6388 " --help Show this help\n",
6389 program_invocation_short_name);
6392 static void help_types(void) {
6397 puts("Available unit types:");
6398 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6399 t = unit_type_to_string(i);
6405 static int systemctl_parse_argv(int argc, char *argv[]) {
6414 ARG_IGNORE_DEPENDENCIES,
6426 ARG_NO_ASK_PASSWORD,
6436 static const struct option options[] = {
6437 { "help", no_argument, NULL, 'h' },
6438 { "version", no_argument, NULL, ARG_VERSION },
6439 { "type", required_argument, NULL, 't' },
6440 { "property", required_argument, NULL, 'p' },
6441 { "all", no_argument, NULL, 'a' },
6442 { "reverse", no_argument, NULL, ARG_REVERSE },
6443 { "after", no_argument, NULL, ARG_AFTER },
6444 { "before", no_argument, NULL, ARG_BEFORE },
6445 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6446 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6447 { "full", no_argument, NULL, 'l' },
6448 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6449 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6450 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6451 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6452 { "ignore-inhibitors", no_argument, NULL, 'i' },
6453 { "user", no_argument, NULL, ARG_USER },
6454 { "system", no_argument, NULL, ARG_SYSTEM },
6455 { "global", no_argument, NULL, ARG_GLOBAL },
6456 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6457 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6458 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6459 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6460 { "quiet", no_argument, NULL, 'q' },
6461 { "root", required_argument, NULL, ARG_ROOT },
6462 { "force", no_argument, NULL, ARG_FORCE },
6463 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6464 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6465 { "signal", required_argument, NULL, 's' },
6466 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6467 { "host", required_argument, NULL, 'H' },
6468 { "machine", required_argument, NULL, 'M' },
6469 { "runtime", no_argument, NULL, ARG_RUNTIME },
6470 { "lines", required_argument, NULL, 'n' },
6471 { "output", required_argument, NULL, 'o' },
6472 { "plain", no_argument, NULL, ARG_PLAIN },
6473 { "state", required_argument, NULL, ARG_STATE },
6474 { "recursive", no_argument, NULL, 'r' },
6475 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6484 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6493 puts(PACKAGE_STRING);
6494 puts(SYSTEMD_FEATURES);
6498 const char *word, *state;
6501 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6502 _cleanup_free_ char *type;
6504 type = strndup(word, size);
6508 if (streq(type, "help")) {
6513 if (unit_type_from_string(type) >= 0) {
6514 if (strv_push(&arg_types, type))
6520 /* It's much nicer to use --state= for
6521 * load states, but let's support this
6522 * in --types= too for compatibility
6523 * with old versions */
6524 if (unit_load_state_from_string(optarg) >= 0) {
6525 if (strv_push(&arg_states, type) < 0)
6531 log_error("Unknown unit type or load state '%s'.", type);
6532 log_info("Use -t help to see a list of allowed values.");
6540 /* Make sure that if the empty property list
6541 was specified, we won't show any properties. */
6542 if (isempty(optarg) && !arg_properties) {
6543 arg_properties = new0(char*, 1);
6544 if (!arg_properties)
6547 const char *word, *state;
6550 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6553 prop = strndup(word, size);
6557 if (strv_consume(&arg_properties, prop) < 0)
6562 /* If the user asked for a particular
6563 * property, show it to him, even if it is
6575 arg_dependency = DEPENDENCY_REVERSE;
6579 arg_dependency = DEPENDENCY_AFTER;
6583 arg_dependency = DEPENDENCY_BEFORE;
6586 case ARG_SHOW_TYPES:
6587 arg_show_types = true;
6591 arg_job_mode = optarg;
6595 arg_job_mode = "fail";
6598 case ARG_IRREVERSIBLE:
6599 arg_job_mode = "replace-irreversibly";
6602 case ARG_IGNORE_DEPENDENCIES:
6603 arg_job_mode = "ignore-dependencies";
6607 arg_scope = UNIT_FILE_USER;
6611 arg_scope = UNIT_FILE_SYSTEM;
6615 arg_scope = UNIT_FILE_GLOBAL;
6619 arg_no_block = true;
6623 arg_no_legend = true;
6627 arg_no_pager = true;
6643 if (strv_extend(&arg_states, "failed") < 0)
6661 arg_no_reload = true;
6665 arg_kill_who = optarg;
6669 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6670 log_error("Failed to parse signal string %s.", optarg);
6675 case ARG_NO_ASK_PASSWORD:
6676 arg_ask_password = false;
6680 arg_transport = BUS_TRANSPORT_REMOTE;
6685 arg_transport = BUS_TRANSPORT_CONTAINER;
6694 if (safe_atou(optarg, &arg_lines) < 0) {
6695 log_error("Failed to parse lines '%s'", optarg);
6701 arg_output = output_mode_from_string(optarg);
6702 if (arg_output < 0) {
6703 log_error("Unknown output '%s'.", optarg);
6709 arg_ignore_inhibitors = true;
6717 const char *word, *state;
6720 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6723 s = strndup(word, size);
6727 if (strv_consume(&arg_states, s) < 0)
6734 if (geteuid() != 0) {
6735 log_error("--recursive requires root privileges.");
6739 arg_recursive = true;
6742 case ARG_PRESET_MODE:
6744 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6745 if (arg_preset_mode < 0) {
6746 log_error("Failed to parse preset mode: %s.", optarg);
6756 assert_not_reached("Unhandled option");
6759 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6760 log_error("Cannot access user instance remotely.");
6767 static int halt_parse_argv(int argc, char *argv[]) {
6776 static const struct option options[] = {
6777 { "help", no_argument, NULL, ARG_HELP },
6778 { "halt", no_argument, NULL, ARG_HALT },
6779 { "poweroff", no_argument, NULL, 'p' },
6780 { "reboot", no_argument, NULL, ARG_REBOOT },
6781 { "force", no_argument, NULL, 'f' },
6782 { "wtmp-only", no_argument, NULL, 'w' },
6783 { "no-wtmp", no_argument, NULL, 'd' },
6784 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6793 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6794 if (runlevel == '0' || runlevel == '6')
6797 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6805 arg_action = ACTION_HALT;
6809 if (arg_action != ACTION_REBOOT)
6810 arg_action = ACTION_POWEROFF;
6814 arg_action = ACTION_REBOOT;
6836 /* Compatibility nops */
6843 assert_not_reached("Unhandled option");
6846 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6847 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6850 } else if (optind < argc) {
6851 log_error("Too many arguments.");
6858 static int parse_time_spec(const char *t, usec_t *_u) {
6862 if (streq(t, "now"))
6864 else if (!strchr(t, ':')) {
6867 if (safe_atou64(t, &u) < 0)
6870 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6879 hour = strtol(t, &e, 10);
6880 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6883 minute = strtol(e+1, &e, 10);
6884 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6887 n = now(CLOCK_REALTIME);
6888 s = (time_t) (n / USEC_PER_SEC);
6890 assert_se(localtime_r(&s, &tm));
6892 tm.tm_hour = (int) hour;
6893 tm.tm_min = (int) minute;
6896 assert_se(s = mktime(&tm));
6898 *_u = (usec_t) s * USEC_PER_SEC;
6901 *_u += USEC_PER_DAY;
6907 static int shutdown_parse_argv(int argc, char *argv[]) {
6914 static const struct option options[] = {
6915 { "help", no_argument, NULL, ARG_HELP },
6916 { "halt", no_argument, NULL, 'H' },
6917 { "poweroff", no_argument, NULL, 'P' },
6918 { "reboot", no_argument, NULL, 'r' },
6919 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6920 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6929 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6937 arg_action = ACTION_HALT;
6941 arg_action = ACTION_POWEROFF;
6946 arg_action = ACTION_KEXEC;
6948 arg_action = ACTION_REBOOT;
6952 arg_action = ACTION_KEXEC;
6956 if (arg_action != ACTION_HALT)
6957 arg_action = ACTION_POWEROFF;
6972 /* Compatibility nops */
6976 arg_action = ACTION_CANCEL_SHUTDOWN;
6983 assert_not_reached("Unhandled option");
6986 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6987 r = parse_time_spec(argv[optind], &arg_when);
6989 log_error("Failed to parse time specification: %s", argv[optind]);
6993 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6995 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6996 /* No time argument for shutdown cancel */
6997 arg_wall = argv + optind;
6998 else if (argc > optind + 1)
6999 /* We skip the time argument */
7000 arg_wall = argv + optind + 1;
7007 static int telinit_parse_argv(int argc, char *argv[]) {
7014 static const struct option options[] = {
7015 { "help", no_argument, NULL, ARG_HELP },
7016 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7020 static const struct {
7024 { '0', ACTION_POWEROFF },
7025 { '6', ACTION_REBOOT },
7026 { '1', ACTION_RESCUE },
7027 { '2', ACTION_RUNLEVEL2 },
7028 { '3', ACTION_RUNLEVEL3 },
7029 { '4', ACTION_RUNLEVEL4 },
7030 { '5', ACTION_RUNLEVEL5 },
7031 { 's', ACTION_RESCUE },
7032 { 'S', ACTION_RESCUE },
7033 { 'q', ACTION_RELOAD },
7034 { 'Q', ACTION_RELOAD },
7035 { 'u', ACTION_REEXEC },
7036 { 'U', ACTION_REEXEC }
7045 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7060 assert_not_reached("Unhandled option");
7063 if (optind >= argc) {
7064 log_error("%s: required argument missing.",
7065 program_invocation_short_name);
7069 if (optind + 1 < argc) {
7070 log_error("Too many arguments.");
7074 if (strlen(argv[optind]) != 1) {
7075 log_error("Expected single character argument.");
7079 for (i = 0; i < ELEMENTSOF(table); i++)
7080 if (table[i].from == argv[optind][0])
7083 if (i >= ELEMENTSOF(table)) {
7084 log_error("Unknown command '%s'.", argv[optind]);
7088 arg_action = table[i].to;
7095 static int runlevel_parse_argv(int argc, char *argv[]) {
7101 static const struct option options[] = {
7102 { "help", no_argument, NULL, ARG_HELP },
7111 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7122 assert_not_reached("Unhandled option");
7125 if (optind < argc) {
7126 log_error("Too many arguments.");
7133 static int parse_argv(int argc, char *argv[]) {
7137 if (program_invocation_short_name) {
7139 if (strstr(program_invocation_short_name, "halt")) {
7140 arg_action = ACTION_HALT;
7141 return halt_parse_argv(argc, argv);
7142 } else if (strstr(program_invocation_short_name, "poweroff")) {
7143 arg_action = ACTION_POWEROFF;
7144 return halt_parse_argv(argc, argv);
7145 } else if (strstr(program_invocation_short_name, "reboot")) {
7147 arg_action = ACTION_KEXEC;
7149 arg_action = ACTION_REBOOT;
7150 return halt_parse_argv(argc, argv);
7151 } else if (strstr(program_invocation_short_name, "shutdown")) {
7152 arg_action = ACTION_POWEROFF;
7153 return shutdown_parse_argv(argc, argv);
7154 } else if (strstr(program_invocation_short_name, "init")) {
7156 if (sd_booted() > 0) {
7157 arg_action = _ACTION_INVALID;
7158 return telinit_parse_argv(argc, argv);
7160 /* Hmm, so some other init system is
7161 * running, we need to forward this
7162 * request to it. For now we simply
7163 * guess that it is Upstart. */
7165 execv(TELINIT, argv);
7167 log_error("Couldn't find an alternative telinit implementation to spawn.");
7171 } else if (strstr(program_invocation_short_name, "runlevel")) {
7172 arg_action = ACTION_RUNLEVEL;
7173 return runlevel_parse_argv(argc, argv);
7177 arg_action = ACTION_SYSTEMCTL;
7178 return systemctl_parse_argv(argc, argv);
7181 _pure_ static int action_to_runlevel(void) {
7183 static const char table[_ACTION_MAX] = {
7184 [ACTION_HALT] = '0',
7185 [ACTION_POWEROFF] = '0',
7186 [ACTION_REBOOT] = '6',
7187 [ACTION_RUNLEVEL2] = '2',
7188 [ACTION_RUNLEVEL3] = '3',
7189 [ACTION_RUNLEVEL4] = '4',
7190 [ACTION_RUNLEVEL5] = '5',
7191 [ACTION_RESCUE] = '1'
7194 assert(arg_action < _ACTION_MAX);
7196 return table[arg_action];
7199 static int talk_initctl(void) {
7201 struct init_request request = {
7202 .magic = INIT_MAGIC,
7204 .cmd = INIT_CMD_RUNLVL
7207 _cleanup_close_ int fd = -1;
7211 rl = action_to_runlevel();
7215 request.runlevel = rl;
7217 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7219 if (errno == ENOENT)
7222 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7226 r = loop_write(fd, &request, sizeof(request), false);
7228 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7233 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7235 static const struct {
7243 int (* const dispatch)(sd_bus *bus, char **args);
7249 { "list-units", MORE, 0, list_units },
7250 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7251 { "list-sockets", MORE, 1, list_sockets },
7252 { "list-timers", MORE, 1, list_timers },
7253 { "list-jobs", MORE, 1, list_jobs },
7254 { "list-machines", MORE, 1, list_machines },
7255 { "clear-jobs", EQUAL, 1, daemon_reload },
7256 { "cancel", MORE, 2, cancel_job },
7257 { "start", MORE, 2, start_unit },
7258 { "stop", MORE, 2, start_unit },
7259 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7260 { "reload", MORE, 2, start_unit },
7261 { "restart", MORE, 2, start_unit },
7262 { "try-restart", MORE, 2, start_unit },
7263 { "reload-or-restart", MORE, 2, start_unit },
7264 { "reload-or-try-restart", MORE, 2, start_unit },
7265 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7266 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7267 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7268 { "isolate", EQUAL, 2, start_unit },
7269 { "kill", MORE, 2, kill_unit },
7270 { "is-active", MORE, 2, check_unit_active },
7271 { "check", MORE, 2, check_unit_active },
7272 { "is-failed", MORE, 2, check_unit_failed },
7273 { "show", MORE, 1, show },
7274 { "cat", MORE, 2, cat, NOBUS },
7275 { "status", MORE, 1, show },
7276 { "help", MORE, 2, show },
7277 { "snapshot", LESS, 2, snapshot },
7278 { "delete", MORE, 2, delete_snapshot },
7279 { "daemon-reload", EQUAL, 1, daemon_reload },
7280 { "daemon-reexec", EQUAL, 1, daemon_reload },
7281 { "show-environment", EQUAL, 1, show_environment },
7282 { "set-environment", MORE, 2, set_environment },
7283 { "unset-environment", MORE, 2, set_environment },
7284 { "import-environment", MORE, 1, import_environment},
7285 { "halt", EQUAL, 1, start_special, FORCE },
7286 { "poweroff", EQUAL, 1, start_special, FORCE },
7287 { "reboot", EQUAL, 1, start_special, FORCE },
7288 { "kexec", EQUAL, 1, start_special },
7289 { "suspend", EQUAL, 1, start_special },
7290 { "hibernate", EQUAL, 1, start_special },
7291 { "hybrid-sleep", EQUAL, 1, start_special },
7292 { "default", EQUAL, 1, start_special },
7293 { "rescue", EQUAL, 1, start_special },
7294 { "emergency", EQUAL, 1, start_special },
7295 { "exit", EQUAL, 1, start_special },
7296 { "reset-failed", MORE, 1, reset_failed },
7297 { "enable", MORE, 2, enable_unit, NOBUS },
7298 { "disable", MORE, 2, enable_unit, NOBUS },
7299 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7300 { "reenable", MORE, 2, enable_unit, NOBUS },
7301 { "preset", MORE, 2, enable_unit, NOBUS },
7302 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7303 { "mask", MORE, 2, enable_unit, NOBUS },
7304 { "unmask", MORE, 2, enable_unit, NOBUS },
7305 { "link", MORE, 2, enable_unit, NOBUS },
7306 { "switch-root", MORE, 2, switch_root },
7307 { "list-dependencies", LESS, 2, list_dependencies },
7308 { "set-default", EQUAL, 2, set_default, NOBUS },
7309 { "get-default", EQUAL, 1, get_default, NOBUS },
7310 { "set-property", MORE, 3, set_property },
7311 { "is-system-running", EQUAL, 1, is_system_running },
7312 { "add-wants", MORE, 3, add_dependency, NOBUS },
7313 { "add-requires", MORE, 3, add_dependency, NOBUS },
7314 { "edit", MORE, 2, edit, NOBUS },
7323 left = argc - optind;
7325 /* Special rule: no arguments (left == 0) means "list-units" */
7327 if (streq(argv[optind], "help") && !argv[optind+1]) {
7328 log_error("This command expects one or more "
7329 "unit names. Did you mean --help?");
7333 for (; verb->verb; verb++)
7334 if (streq(argv[optind], verb->verb))
7337 log_error("Unknown operation '%s'.", argv[optind]);
7342 switch (verb->argc_cmp) {
7345 if (left != verb->argc) {
7346 log_error("Invalid number of arguments.");
7353 if (left < verb->argc) {
7354 log_error("Too few arguments.");
7361 if (left > verb->argc) {
7362 log_error("Too many arguments.");
7369 assert_not_reached("Unknown comparison operator.");
7372 /* Require a bus connection for all operations but
7374 if (verb->bus == NOBUS) {
7375 if (!bus && !avoid_bus()) {
7376 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7381 if (running_in_chroot() > 0) {
7382 log_info("Running in chroot, ignoring request.");
7386 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7387 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7392 return verb->dispatch(bus, argv + optind);
7395 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7397 struct sd_shutdown_command c = {
7404 union sockaddr_union sockaddr = {
7405 .un.sun_family = AF_UNIX,
7406 .un.sun_path = "/run/systemd/shutdownd",
7409 struct iovec iovec[2] = {{
7410 .iov_base = (char*) &c,
7411 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7414 struct msghdr msghdr = {
7415 .msg_name = &sockaddr,
7416 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7417 + strlen("/run/systemd/shutdownd"),
7422 _cleanup_close_ int fd;
7424 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7428 if (!isempty(message)) {
7429 iovec[1].iov_base = (char*) message;
7430 iovec[1].iov_len = strlen(message);
7431 msghdr.msg_iovlen++;
7434 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7440 static int reload_with_fallback(sd_bus *bus) {
7443 /* First, try systemd via D-Bus. */
7444 if (daemon_reload(bus, NULL) >= 0)
7448 /* Nothing else worked, so let's try signals */
7449 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7451 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7452 return log_error_errno(errno, "kill() failed: %m");
7457 static int start_with_fallback(sd_bus *bus) {
7460 /* First, try systemd via D-Bus. */
7461 if (start_unit(bus, NULL) >= 0)
7465 /* Nothing else worked, so let's try
7467 if (talk_initctl() > 0)
7470 log_error("Failed to talk to init daemon.");
7474 warn_wall(arg_action);
7478 static int halt_now(enum action a) {
7480 /* The kernel will automaticall flush ATA disks and suchlike
7481 * on reboot(), but the file systems need to be synce'd
7482 * explicitly in advance. */
7485 /* Make sure C-A-D is handled by the kernel from this point
7487 reboot(RB_ENABLE_CAD);
7492 log_info("Halting.");
7493 reboot(RB_HALT_SYSTEM);
7496 case ACTION_POWEROFF:
7497 log_info("Powering off.");
7498 reboot(RB_POWER_OFF);
7501 case ACTION_REBOOT: {
7502 _cleanup_free_ char *param = NULL;
7504 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7505 log_info("Rebooting with argument '%s'.", param);
7506 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7507 LINUX_REBOOT_CMD_RESTART2, param);
7510 log_info("Rebooting.");
7511 reboot(RB_AUTOBOOT);
7516 assert_not_reached("Unknown action.");
7520 static int halt_main(sd_bus *bus) {
7523 r = check_inhibitors(bus, arg_action);
7527 if (geteuid() != 0) {
7528 /* Try logind if we are a normal user and no special
7529 * mode applies. Maybe PolicyKit allows us to shutdown
7532 if (arg_when <= 0 &&
7535 (arg_action == ACTION_POWEROFF ||
7536 arg_action == ACTION_REBOOT)) {
7537 r = reboot_with_logind(bus, arg_action);
7542 log_error("Must be root.");
7547 _cleanup_free_ char *m;
7549 m = strv_join(arg_wall, " ");
7553 r = send_shutdownd(arg_when,
7554 arg_action == ACTION_HALT ? 'H' :
7555 arg_action == ACTION_POWEROFF ? 'P' :
7556 arg_action == ACTION_KEXEC ? 'K' :
7563 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7565 char date[FORMAT_TIMESTAMP_MAX];
7567 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7568 format_timestamp(date, sizeof(date), arg_when));
7573 if (!arg_dry && !arg_force)
7574 return start_with_fallback(bus);
7577 if (sd_booted() > 0)
7578 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7580 r = utmp_put_shutdown();
7582 log_warning_errno(r, "Failed to write utmp record: %m");
7589 r = halt_now(arg_action);
7590 log_error_errno(r, "Failed to reboot: %m");
7595 static int runlevel_main(void) {
7596 int r, runlevel, previous;
7598 r = utmp_get_runlevel(&runlevel, &previous);
7605 previous <= 0 ? 'N' : previous,
7606 runlevel <= 0 ? 'N' : runlevel);
7611 int main(int argc, char*argv[]) {
7612 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7615 setlocale(LC_ALL, "");
7616 log_parse_environment();
7619 /* Explicitly not on_tty() to avoid setting cached value.
7620 * This becomes relevant for piping output which might be
7622 original_stdout_is_tty = isatty(STDOUT_FILENO);
7624 r = parse_argv(argc, argv);
7628 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7629 * let's shortcut this */
7630 if (arg_action == ACTION_RUNLEVEL) {
7631 r = runlevel_main();
7635 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7636 log_info("Running in chroot, ignoring request.");
7642 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7644 /* systemctl_main() will print an error message for the bus
7645 * connection, but only if it needs to */
7647 switch (arg_action) {
7649 case ACTION_SYSTEMCTL:
7650 r = systemctl_main(bus, argc, argv, r);
7654 case ACTION_POWEROFF:
7660 case ACTION_RUNLEVEL2:
7661 case ACTION_RUNLEVEL3:
7662 case ACTION_RUNLEVEL4:
7663 case ACTION_RUNLEVEL5:
7665 case ACTION_EMERGENCY:
7666 case ACTION_DEFAULT:
7667 r = start_with_fallback(bus);
7672 r = reload_with_fallback(bus);
7675 case ACTION_CANCEL_SHUTDOWN: {
7676 _cleanup_free_ char *m = NULL;
7679 m = strv_join(arg_wall, " ");
7686 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7688 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7692 case ACTION_RUNLEVEL:
7693 case _ACTION_INVALID:
7695 assert_not_reached("Unknown action");
7700 ask_password_agent_close();
7701 polkit_agent_close();
7703 strv_free(arg_types);
7704 strv_free(arg_states);
7705 strv_free(arg_properties);
7707 return r < 0 ? EXIT_FAILURE : r;