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-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 typedef struct WaitData {
2281 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2288 log_debug("Got D-Bus request: %s.%s() on %s",
2289 sd_bus_message_get_interface(m),
2290 sd_bus_message_get_member(m),
2291 sd_bus_message_get_path(m));
2293 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2294 log_error("Warning! D-Bus connection terminated.");
2296 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2298 const char *path, *result, *unit;
2302 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2304 ret = set_remove(d->set, (char*) path);
2310 if (!isempty(result))
2311 d->result = strdup(result);
2314 d->name = strdup(unit);
2319 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2321 ret = set_remove(d->set, (char*) path);
2328 d->result = strdup(result);
2334 bus_log_parse_error(r);
2340 static int enable_wait_for_jobs(sd_bus *bus) {
2345 r = sd_bus_add_match(
2349 "sender='org.freedesktop.systemd1',"
2350 "interface='org.freedesktop.systemd1.Manager',"
2351 "member='JobRemoved',"
2352 "path='/org/freedesktop/systemd1'",
2355 log_error("Failed to add match");
2359 /* This is slightly dirty, since we don't undo the match registrations. */
2363 static int bus_process_wait(sd_bus *bus) {
2367 r = sd_bus_process(bus, NULL);
2372 r = sd_bus_wait(bus, (uint64_t) -1);
2378 static int check_wait_response(WaitData *d) {
2384 if (streq(d->result, "timeout"))
2385 log_error("Job for %s timed out.", strna(d->name));
2386 else if (streq(d->result, "canceled"))
2387 log_error("Job for %s canceled.", strna(d->name));
2388 else if (streq(d->result, "dependency"))
2389 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
2390 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
2394 quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
2396 log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
2398 quotes ? "'" : "", d->name, quotes ? "'" : "");
2400 log_error("Job failed. See \"journalctl -xe\" for details.");
2404 if (streq(d->result, "timeout"))
2406 else if (streq(d->result, "canceled"))
2408 else if (streq(d->result, "dependency"))
2410 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2416 static int wait_for_jobs(sd_bus *bus, Set *s) {
2417 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2418 WaitData d = { .set = s };
2424 q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2428 while (!set_isempty(s)) {
2429 q = bus_process_wait(bus);
2431 return log_error_errno(q, "Failed to wait for response: %m");
2434 q = check_wait_response(&d);
2435 /* Return the first error as it is most likely to be
2437 if (q < 0 && r == 0)
2439 log_debug("Got result %s/%s for job %s",
2440 strna(d.result), strerror(-q), strna(d.name));
2453 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2454 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2455 _cleanup_free_ char *n = NULL, *state = NULL;
2461 n = unit_name_mangle(name, MANGLE_NOGLOB);
2465 /* We don't use unit_dbus_path_from_name() directly since we
2466 * don't want to load the unit if it isn't loaded. */
2468 r = sd_bus_call_method(
2470 "org.freedesktop.systemd1",
2471 "/org/freedesktop/systemd1",
2472 "org.freedesktop.systemd1.Manager",
2483 r = sd_bus_message_read(reply, "o", &path);
2485 return bus_log_parse_error(r);
2487 r = sd_bus_get_property_string(
2489 "org.freedesktop.systemd1",
2491 "org.freedesktop.systemd1.Unit",
2504 return nulstr_contains(good_states, state);
2507 static int check_triggering_units(
2511 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2512 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2513 _cleanup_strv_free_ char **triggered_by = NULL;
2514 bool print_warning_label = true;
2518 n = unit_name_mangle(name, MANGLE_NOGLOB);
2522 path = unit_dbus_path_from_name(n);
2526 r = sd_bus_get_property_string(
2528 "org.freedesktop.systemd1",
2530 "org.freedesktop.systemd1.Unit",
2535 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2539 if (streq(state, "masked"))
2542 r = sd_bus_get_property_strv(
2544 "org.freedesktop.systemd1",
2546 "org.freedesktop.systemd1.Unit",
2551 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2555 STRV_FOREACH(i, triggered_by) {
2556 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2558 return log_error_errno(r, "Failed to check unit: %m");
2563 if (print_warning_label) {
2564 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2565 print_warning_label = false;
2568 log_warning(" %s", *i);
2574 static const struct {
2577 } unit_actions[] = {
2578 { "start", "StartUnit" },
2579 { "stop", "StopUnit" },
2580 { "condstop", "StopUnit" },
2581 { "reload", "ReloadUnit" },
2582 { "restart", "RestartUnit" },
2583 { "try-restart", "TryRestartUnit" },
2584 { "condrestart", "TryRestartUnit" },
2585 { "reload-or-restart", "ReloadOrRestartUnit" },
2586 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2587 { "condreload", "ReloadOrTryRestartUnit" },
2588 { "force-reload", "ReloadOrTryRestartUnit" }
2591 static const char *verb_to_method(const char *verb) {
2594 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2595 if (streq_ptr(unit_actions[i].verb, verb))
2596 return unit_actions[i].method;
2601 static const char *method_to_verb(const char *method) {
2604 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2605 if (streq_ptr(unit_actions[i].method, method))
2606 return unit_actions[i].verb;
2611 static int start_unit_one(
2616 sd_bus_error *error,
2619 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2628 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2630 r = sd_bus_message_new_method_call(
2633 "org.freedesktop.systemd1",
2634 "/org/freedesktop/systemd1",
2635 "org.freedesktop.systemd1.Manager",
2638 return bus_log_create_error(r);
2640 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2642 return bus_log_create_error(r);
2644 r = sd_bus_message_append(m, "ss", name, mode);
2646 return bus_log_create_error(r);
2648 r = sd_bus_call(bus, m, 0, error, &reply);
2652 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2653 /* There's always a fallback possible for
2654 * legacy actions. */
2655 return -EADDRNOTAVAIL;
2657 verb = method_to_verb(method);
2659 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2663 r = sd_bus_message_read(reply, "o", &path);
2665 return bus_log_parse_error(r);
2667 if (need_daemon_reload(bus, name) > 0)
2668 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2669 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2678 log_debug("Adding %s to the set", p);
2679 r = set_consume(s, p);
2687 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2689 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2693 STRV_FOREACH(name, names) {
2697 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2699 t = unit_name_mangle(*name, MANGLE_GLOB);
2703 if (string_is_glob(t))
2704 r = strv_consume(&globs, t);
2706 r = strv_consume(&mangled, t);
2711 /* Query the manager only if any of the names are a glob, since
2712 * this is fairly expensive */
2713 if (!strv_isempty(globs)) {
2714 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2715 _cleanup_free_ UnitInfo *unit_infos = NULL;
2717 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2721 for (i = 0; i < r; i++)
2722 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2727 mangled = NULL; /* do not free */
2732 static const struct {
2736 } action_table[_ACTION_MAX] = {
2737 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2738 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2739 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2740 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2741 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2742 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2743 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2744 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2745 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2746 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2747 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2748 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2749 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2750 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2751 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2754 static enum action verb_to_action(const char *verb) {
2757 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2758 if (streq_ptr(action_table[i].verb, verb))
2761 return _ACTION_INVALID;
2764 static int start_unit(sd_bus *bus, char **args) {
2765 _cleanup_set_free_free_ Set *s = NULL;
2766 _cleanup_strv_free_ char **names = NULL;
2767 const char *method, *mode, *one_name, *suffix = NULL;
2773 ask_password_agent_open_if_enabled();
2775 if (arg_action == ACTION_SYSTEMCTL) {
2777 method = verb_to_method(args[0]);
2778 action = verb_to_action(args[0]);
2780 if (streq(args[0], "isolate")) {
2784 mode = action_table[action].mode ?: arg_job_mode;
2786 one_name = action_table[action].target;
2788 assert(arg_action < ELEMENTSOF(action_table));
2789 assert(action_table[arg_action].target);
2791 method = "StartUnit";
2793 mode = action_table[arg_action].mode;
2794 one_name = action_table[arg_action].target;
2798 names = strv_new(one_name, NULL);
2800 r = expand_names(bus, args + 1, suffix, &names);
2802 log_error_errno(r, "Failed to expand names: %m");
2805 if (!arg_no_block) {
2806 r = enable_wait_for_jobs(bus);
2808 return log_error_errno(r, "Could not watch jobs: %m");
2810 s = set_new(&string_hash_ops);
2815 STRV_FOREACH(name, names) {
2816 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2819 q = start_unit_one(bus, method, *name, mode, &error, s);
2820 if (r >= 0 && q < 0)
2821 r = translate_bus_error_to_exit_status(q, &error);
2824 if (!arg_no_block) {
2827 q = wait_for_jobs(bus, s);
2831 /* When stopping units, warn if they can still be triggered by
2832 * another active unit (socket, path, timer) */
2833 if (!arg_quiet && streq(method, "StopUnit"))
2834 STRV_FOREACH(name, names)
2835 check_triggering_units(bus, *name);
2841 /* Ask systemd-logind, which might grant access to unprivileged users
2842 * through PolicyKit */
2843 static int reboot_with_logind(sd_bus *bus, enum action a) {
2845 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2852 polkit_agent_open_if_enabled();
2860 case ACTION_POWEROFF:
2861 method = "PowerOff";
2864 case ACTION_SUSPEND:
2868 case ACTION_HIBERNATE:
2869 method = "Hibernate";
2872 case ACTION_HYBRID_SLEEP:
2873 method = "HybridSleep";
2880 r = sd_bus_call_method(
2882 "org.freedesktop.login1",
2883 "/org/freedesktop/login1",
2884 "org.freedesktop.login1.Manager",
2888 "b", arg_ask_password);
2890 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2898 static int check_inhibitors(sd_bus *bus, enum action a) {
2900 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2901 _cleanup_strv_free_ char **sessions = NULL;
2902 const char *what, *who, *why, *mode;
2911 if (arg_ignore_inhibitors || arg_force > 0)
2923 r = sd_bus_call_method(
2925 "org.freedesktop.login1",
2926 "/org/freedesktop/login1",
2927 "org.freedesktop.login1.Manager",
2933 /* If logind is not around, then there are no inhibitors... */
2936 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2938 return bus_log_parse_error(r);
2940 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2941 _cleanup_free_ char *comm = NULL, *user = NULL;
2942 _cleanup_strv_free_ char **sv = NULL;
2944 if (!streq(mode, "block"))
2947 sv = strv_split(what, ":");
2951 if (!strv_contains(sv,
2953 a == ACTION_POWEROFF ||
2954 a == ACTION_REBOOT ||
2955 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2958 get_process_comm(pid, &comm);
2959 user = uid_to_name(uid);
2961 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2962 who, pid, strna(comm), strna(user), why);
2967 return bus_log_parse_error(r);
2969 r = sd_bus_message_exit_container(reply);
2971 return bus_log_parse_error(r);
2973 /* Check for current sessions */
2974 sd_get_sessions(&sessions);
2975 STRV_FOREACH(s, sessions) {
2976 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2978 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2981 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2984 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2987 sd_session_get_tty(*s, &tty);
2988 sd_session_get_seat(*s, &seat);
2989 sd_session_get_service(*s, &service);
2990 user = uid_to_name(uid);
2992 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2999 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3000 action_table[a].verb);
3008 static int start_special(sd_bus *bus, char **args) {
3014 a = verb_to_action(args[0]);
3016 r = check_inhibitors(bus, a);
3020 if (arg_force >= 2 && geteuid() != 0) {
3021 log_error("Must be root.");
3025 if (arg_force >= 2 &&
3026 (a == ACTION_HALT ||
3027 a == ACTION_POWEROFF ||
3028 a == ACTION_REBOOT))
3031 if (arg_force >= 1 &&
3032 (a == ACTION_HALT ||
3033 a == ACTION_POWEROFF ||
3034 a == ACTION_REBOOT ||
3035 a == ACTION_KEXEC ||
3037 return daemon_reload(bus, args);
3039 /* first try logind, to allow authentication with polkit */
3040 if (geteuid() != 0 &&
3041 (a == ACTION_POWEROFF ||
3042 a == ACTION_REBOOT ||
3043 a == ACTION_SUSPEND ||
3044 a == ACTION_HIBERNATE ||
3045 a == ACTION_HYBRID_SLEEP)) {
3046 r = reboot_with_logind(bus, a);
3051 r = start_unit(bus, args);
3052 if (r == EXIT_SUCCESS)
3058 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3059 _cleanup_strv_free_ char **names = NULL;
3066 r = expand_names(bus, args, NULL, &names);
3068 return log_error_errno(r, "Failed to expand names: %m");
3070 STRV_FOREACH(name, names) {
3073 state = check_one_unit(bus, *name, good_states, arg_quiet);
3083 static int check_unit_active(sd_bus *bus, char **args) {
3084 /* According to LSB: 3, "program is not running" */
3085 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3088 static int check_unit_failed(sd_bus *bus, char **args) {
3089 return check_unit_generic(bus, 1, "failed\0", args + 1);
3092 static int kill_unit(sd_bus *bus, char **args) {
3093 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3094 _cleanup_strv_free_ char **names = NULL;
3102 arg_kill_who = "all";
3104 r = expand_names(bus, args + 1, NULL, &names);
3106 log_error_errno(r, "Failed to expand names: %m");
3108 STRV_FOREACH(name, names) {
3109 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3111 q = sd_bus_message_new_method_call(
3114 "org.freedesktop.systemd1",
3115 "/org/freedesktop/systemd1",
3116 "org.freedesktop.systemd1.Manager",
3119 return bus_log_create_error(q);
3121 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3123 return bus_log_create_error(q);
3125 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3127 return bus_log_create_error(q);
3129 q = sd_bus_call(bus, m, 0, &error, NULL);
3131 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3140 typedef struct ExecStatusInfo {
3148 usec_t start_timestamp;
3149 usec_t exit_timestamp;
3154 LIST_FIELDS(struct ExecStatusInfo, exec);
3157 static void exec_status_info_free(ExecStatusInfo *i) {
3166 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3167 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3170 int32_t code, status;
3176 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3178 return bus_log_parse_error(r);
3182 r = sd_bus_message_read(m, "s", &path);
3184 return bus_log_parse_error(r);
3186 i->path = strdup(path);
3190 r = sd_bus_message_read_strv(m, &i->argv);
3192 return bus_log_parse_error(r);
3194 r = sd_bus_message_read(m,
3197 &start_timestamp, &start_timestamp_monotonic,
3198 &exit_timestamp, &exit_timestamp_monotonic,
3202 return bus_log_parse_error(r);
3205 i->start_timestamp = (usec_t) start_timestamp;
3206 i->exit_timestamp = (usec_t) exit_timestamp;
3207 i->pid = (pid_t) pid;
3211 r = sd_bus_message_exit_container(m);
3213 return bus_log_parse_error(r);
3218 typedef struct UnitStatusInfo {
3220 const char *load_state;
3221 const char *active_state;
3222 const char *sub_state;
3223 const char *unit_file_state;
3225 const char *description;
3226 const char *following;
3228 char **documentation;
3230 const char *fragment_path;
3231 const char *source_path;
3232 const char *control_group;
3234 char **dropin_paths;
3236 const char *load_error;
3239 usec_t inactive_exit_timestamp;
3240 usec_t inactive_exit_timestamp_monotonic;
3241 usec_t active_enter_timestamp;
3242 usec_t active_exit_timestamp;
3243 usec_t inactive_enter_timestamp;
3245 bool need_daemon_reload;
3250 const char *status_text;
3251 const char *pid_file;
3255 usec_t start_timestamp;
3256 usec_t exit_timestamp;
3258 int exit_code, exit_status;
3260 usec_t condition_timestamp;
3261 bool condition_result;
3262 bool failed_condition_trigger;
3263 bool failed_condition_negate;
3264 const char *failed_condition;
3265 const char *failed_condition_parameter;
3267 usec_t assert_timestamp;
3269 bool failed_assert_trigger;
3270 bool failed_assert_negate;
3271 const char *failed_assert;
3272 const char *failed_assert_parameter;
3275 unsigned n_accepted;
3276 unsigned n_connections;
3279 /* Pairs of type, path */
3283 const char *sysfs_path;
3285 /* Mount, Automount */
3291 LIST_HEAD(ExecStatusInfo, exec);
3294 static void print_status_info(
3299 const char *active_on, *active_off, *on, *off, *ss;
3301 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3302 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3305 arg_all * OUTPUT_SHOW_ALL |
3306 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3307 on_tty() * OUTPUT_COLOR |
3308 !arg_quiet * OUTPUT_WARN_CUTOFF |
3309 arg_full * OUTPUT_FULL_WIDTH;
3314 /* This shows pretty information about a unit. See
3315 * print_property() for a low-level property printer */
3317 if (streq_ptr(i->active_state, "failed")) {
3318 active_on = ansi_highlight_red();
3319 active_off = ansi_highlight_off();
3320 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3321 active_on = ansi_highlight_green();
3322 active_off = ansi_highlight_off();
3324 active_on = active_off = "";
3326 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3328 if (i->description && !streq_ptr(i->id, i->description))
3329 printf(" - %s", i->description);
3334 printf(" Follow: unit currently follows state of %s\n", i->following);
3336 if (streq_ptr(i->load_state, "error")) {
3337 on = ansi_highlight_red();
3338 off = ansi_highlight_off();
3342 path = i->source_path ? i->source_path : i->fragment_path;
3345 printf(" Loaded: %s%s%s (Reason: %s)\n",
3346 on, strna(i->load_state), off, i->load_error);
3347 else if (path && i->unit_file_state)
3348 printf(" Loaded: %s%s%s (%s; %s)\n",
3349 on, strna(i->load_state), off, path, i->unit_file_state);
3351 printf(" Loaded: %s%s%s (%s)\n",
3352 on, strna(i->load_state), off, path);
3354 printf(" Loaded: %s%s%s\n",
3355 on, strna(i->load_state), off);
3357 if (!strv_isempty(i->dropin_paths)) {
3358 _cleanup_free_ char *dir = NULL;
3362 STRV_FOREACH(dropin, i->dropin_paths) {
3363 if (! dir || last) {
3364 printf(dir ? " " : " Drop-In: ");
3369 if (path_get_parent(*dropin, &dir) < 0) {
3374 printf("%s\n %s", dir,
3375 draw_special_char(DRAW_TREE_RIGHT));
3378 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3380 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3384 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3386 printf(" Active: %s%s (%s)%s",
3387 active_on, strna(i->active_state), ss, active_off);
3389 printf(" Active: %s%s%s",
3390 active_on, strna(i->active_state), active_off);
3392 if (!isempty(i->result) && !streq(i->result, "success"))
3393 printf(" (Result: %s)", i->result);
3395 timestamp = (streq_ptr(i->active_state, "active") ||
3396 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3397 (streq_ptr(i->active_state, "inactive") ||
3398 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3399 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3400 i->active_exit_timestamp;
3402 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3403 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3406 printf(" since %s; %s\n", s2, s1);
3408 printf(" since %s\n", s2);
3412 if (!i->condition_result && i->condition_timestamp > 0) {
3413 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3414 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3416 printf("Condition: start %scondition failed%s at %s%s%s\n",
3417 ansi_highlight_yellow(), ansi_highlight_off(),
3418 s2, s1 ? "; " : "", s1 ? s1 : "");
3419 if (i->failed_condition_trigger)
3420 printf(" none of the trigger conditions were met\n");
3421 else if (i->failed_condition)
3422 printf(" %s=%s%s was not met\n",
3423 i->failed_condition,
3424 i->failed_condition_negate ? "!" : "",
3425 i->failed_condition_parameter);
3428 if (!i->assert_result && i->assert_timestamp > 0) {
3429 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3430 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3432 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3433 ansi_highlight_red(), ansi_highlight_off(),
3434 s2, s1 ? "; " : "", s1 ? s1 : "");
3435 if (i->failed_assert_trigger)
3436 printf(" none of the trigger assertions were met\n");
3437 else if (i->failed_assert)
3438 printf(" %s=%s%s was not met\n",
3440 i->failed_assert_negate ? "!" : "",
3441 i->failed_assert_parameter);
3445 printf(" Device: %s\n", i->sysfs_path);
3447 printf(" Where: %s\n", i->where);
3449 printf(" What: %s\n", i->what);
3451 STRV_FOREACH(t, i->documentation)
3452 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3454 STRV_FOREACH_PAIR(t, t2, i->listen)
3455 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3458 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3460 LIST_FOREACH(exec, p, i->exec) {
3461 _cleanup_free_ char *argv = NULL;
3464 /* Only show exited processes here */
3468 argv = strv_join(p->argv, " ");
3469 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3471 good = is_clean_exit_lsb(p->code, p->status, NULL);
3473 on = ansi_highlight_red();
3474 off = ansi_highlight_off();
3478 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3480 if (p->code == CLD_EXITED) {
3483 printf("status=%i", p->status);
3485 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3490 printf("signal=%s", signal_to_string(p->status));
3492 printf(")%s\n", off);
3494 if (i->main_pid == p->pid &&
3495 i->start_timestamp == p->start_timestamp &&
3496 i->exit_timestamp == p->start_timestamp)
3497 /* Let's not show this twice */
3500 if (p->pid == i->control_pid)
3504 if (i->main_pid > 0 || i->control_pid > 0) {
3505 if (i->main_pid > 0) {
3506 printf(" Main PID: "PID_FMT, i->main_pid);
3509 _cleanup_free_ char *comm = NULL;
3510 get_process_comm(i->main_pid, &comm);
3512 printf(" (%s)", comm);
3513 } else if (i->exit_code > 0) {
3514 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3516 if (i->exit_code == CLD_EXITED) {
3519 printf("status=%i", i->exit_status);
3521 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3526 printf("signal=%s", signal_to_string(i->exit_status));
3530 if (i->control_pid > 0)
3534 if (i->control_pid > 0) {
3535 _cleanup_free_ char *c = NULL;
3537 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3539 get_process_comm(i->control_pid, &c);
3548 printf(" Status: \"%s\"\n", i->status_text);
3549 if (i->status_errno > 0)
3550 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3552 if (i->control_group &&
3553 (i->main_pid > 0 || i->control_pid > 0 ||
3554 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3557 printf(" CGroup: %s\n", i->control_group);
3559 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3562 static const char prefix[] = " ";
3565 if (c > sizeof(prefix) - 1)
3566 c -= sizeof(prefix) - 1;
3570 if (i->main_pid > 0)
3571 extra[k++] = i->main_pid;
3573 if (i->control_pid > 0)
3574 extra[k++] = i->control_pid;
3576 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3580 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3581 show_journal_by_unit(stdout,
3585 i->inactive_exit_timestamp_monotonic,
3588 flags | OUTPUT_BEGIN_NEWLINE,
3589 arg_scope == UNIT_FILE_SYSTEM,
3593 if (i->need_daemon_reload)
3594 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3595 ansi_highlight_red(),
3596 ansi_highlight_off(),
3597 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3600 static void show_unit_help(UnitStatusInfo *i) {
3605 if (!i->documentation) {
3606 log_info("Documentation for %s not known.", i->id);
3610 STRV_FOREACH(p, i->documentation)
3611 if (startswith(*p, "man:"))
3612 show_man_page(*p + 4, false);
3614 log_info("Can't show: %s", *p);
3617 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3624 switch (contents[0]) {
3626 case SD_BUS_TYPE_STRING: {
3629 r = sd_bus_message_read(m, "s", &s);
3631 return bus_log_parse_error(r);
3634 if (streq(name, "Id"))
3636 else if (streq(name, "LoadState"))
3638 else if (streq(name, "ActiveState"))
3639 i->active_state = s;
3640 else if (streq(name, "SubState"))
3642 else if (streq(name, "Description"))
3644 else if (streq(name, "FragmentPath"))
3645 i->fragment_path = s;
3646 else if (streq(name, "SourcePath"))
3649 else if (streq(name, "DefaultControlGroup")) {
3651 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3653 i->control_group = e;
3656 else if (streq(name, "ControlGroup"))
3657 i->control_group = s;
3658 else if (streq(name, "StatusText"))
3660 else if (streq(name, "PIDFile"))
3662 else if (streq(name, "SysFSPath"))
3664 else if (streq(name, "Where"))
3666 else if (streq(name, "What"))
3668 else if (streq(name, "Following"))
3670 else if (streq(name, "UnitFileState"))
3671 i->unit_file_state = s;
3672 else if (streq(name, "Result"))
3679 case SD_BUS_TYPE_BOOLEAN: {
3682 r = sd_bus_message_read(m, "b", &b);
3684 return bus_log_parse_error(r);
3686 if (streq(name, "Accept"))
3688 else if (streq(name, "NeedDaemonReload"))
3689 i->need_daemon_reload = b;
3690 else if (streq(name, "ConditionResult"))
3691 i->condition_result = b;
3692 else if (streq(name, "AssertResult"))
3693 i->assert_result = b;
3698 case SD_BUS_TYPE_UINT32: {
3701 r = sd_bus_message_read(m, "u", &u);
3703 return bus_log_parse_error(r);
3705 if (streq(name, "MainPID")) {
3707 i->main_pid = (pid_t) u;
3710 } else if (streq(name, "ControlPID"))
3711 i->control_pid = (pid_t) u;
3712 else if (streq(name, "ExecMainPID")) {
3714 i->main_pid = (pid_t) u;
3715 } else if (streq(name, "NAccepted"))
3717 else if (streq(name, "NConnections"))
3718 i->n_connections = u;
3723 case SD_BUS_TYPE_INT32: {
3726 r = sd_bus_message_read(m, "i", &j);
3728 return bus_log_parse_error(r);
3730 if (streq(name, "ExecMainCode"))
3731 i->exit_code = (int) j;
3732 else if (streq(name, "ExecMainStatus"))
3733 i->exit_status = (int) j;
3734 else if (streq(name, "StatusErrno"))
3735 i->status_errno = (int) j;
3740 case SD_BUS_TYPE_UINT64: {
3743 r = sd_bus_message_read(m, "t", &u);
3745 return bus_log_parse_error(r);
3747 if (streq(name, "ExecMainStartTimestamp"))
3748 i->start_timestamp = (usec_t) u;
3749 else if (streq(name, "ExecMainExitTimestamp"))
3750 i->exit_timestamp = (usec_t) u;
3751 else if (streq(name, "ActiveEnterTimestamp"))
3752 i->active_enter_timestamp = (usec_t) u;
3753 else if (streq(name, "InactiveEnterTimestamp"))
3754 i->inactive_enter_timestamp = (usec_t) u;
3755 else if (streq(name, "InactiveExitTimestamp"))
3756 i->inactive_exit_timestamp = (usec_t) u;
3757 else if (streq(name, "InactiveExitTimestampMonotonic"))
3758 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3759 else if (streq(name, "ActiveExitTimestamp"))
3760 i->active_exit_timestamp = (usec_t) u;
3761 else if (streq(name, "ConditionTimestamp"))
3762 i->condition_timestamp = (usec_t) u;
3763 else if (streq(name, "AssertTimestamp"))
3764 i->assert_timestamp = (usec_t) u;
3769 case SD_BUS_TYPE_ARRAY:
3771 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3772 _cleanup_free_ ExecStatusInfo *info = NULL;
3774 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3776 return bus_log_parse_error(r);
3778 info = new0(ExecStatusInfo, 1);
3782 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3784 info->name = strdup(name);
3788 LIST_PREPEND(exec, i->exec, info);
3790 info = new0(ExecStatusInfo, 1);
3796 return bus_log_parse_error(r);
3798 r = sd_bus_message_exit_container(m);
3800 return bus_log_parse_error(r);
3804 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3805 const char *type, *path;
3807 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3809 return bus_log_parse_error(r);
3811 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3813 r = strv_extend(&i->listen, type);
3817 r = strv_extend(&i->listen, path);
3822 return bus_log_parse_error(r);
3824 r = sd_bus_message_exit_container(m);
3826 return bus_log_parse_error(r);
3830 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3832 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3834 return bus_log_parse_error(r);
3836 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3838 r = sd_bus_message_read_strv(m, &i->documentation);
3840 return bus_log_parse_error(r);
3842 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3843 const char *cond, *param;
3844 int trigger, negate;
3847 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3849 return bus_log_parse_error(r);
3851 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3852 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3853 if (state < 0 && (!trigger || !i->failed_condition)) {
3854 i->failed_condition = cond;
3855 i->failed_condition_trigger = trigger;
3856 i->failed_condition_negate = negate;
3857 i->failed_condition_parameter = param;
3861 return bus_log_parse_error(r);
3863 r = sd_bus_message_exit_container(m);
3865 return bus_log_parse_error(r);
3867 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3868 const char *cond, *param;
3869 int trigger, negate;
3872 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3874 return bus_log_parse_error(r);
3876 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3877 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3878 if (state < 0 && (!trigger || !i->failed_assert)) {
3879 i->failed_assert = cond;
3880 i->failed_assert_trigger = trigger;
3881 i->failed_assert_negate = negate;
3882 i->failed_assert_parameter = param;
3886 return bus_log_parse_error(r);
3888 r = sd_bus_message_exit_container(m);
3890 return bus_log_parse_error(r);
3897 case SD_BUS_TYPE_STRUCT_BEGIN:
3899 if (streq(name, "LoadError")) {
3900 const char *n, *message;
3902 r = sd_bus_message_read(m, "(ss)", &n, &message);
3904 return bus_log_parse_error(r);
3906 if (!isempty(message))
3907 i->load_error = message;
3920 r = sd_bus_message_skip(m, contents);
3922 return bus_log_parse_error(r);
3927 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3933 /* This is a low-level property printer, see
3934 * print_status_info() for the nicer output */
3936 if (arg_properties && !strv_find(arg_properties, name)) {
3937 /* skip what we didn't read */
3938 r = sd_bus_message_skip(m, contents);
3942 switch (contents[0]) {
3944 case SD_BUS_TYPE_STRUCT_BEGIN:
3946 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3949 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3951 return bus_log_parse_error(r);
3954 printf("%s=%"PRIu32"\n", name, u);
3956 printf("%s=\n", name);
3960 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3963 r = sd_bus_message_read(m, "(so)", &s, NULL);
3965 return bus_log_parse_error(r);
3967 if (arg_all || !isempty(s))
3968 printf("%s=%s\n", name, s);
3972 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3973 const char *a = NULL, *b = NULL;
3975 r = sd_bus_message_read(m, "(ss)", &a, &b);
3977 return bus_log_parse_error(r);
3979 if (arg_all || !isempty(a) || !isempty(b))
3980 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3983 } else if (streq_ptr(name, "SystemCallFilter")) {
3984 _cleanup_strv_free_ char **l = NULL;
3987 r = sd_bus_message_enter_container(m, 'r', "bas");
3989 return bus_log_parse_error(r);
3991 r = sd_bus_message_read(m, "b", &whitelist);
3993 return bus_log_parse_error(r);
3995 r = sd_bus_message_read_strv(m, &l);
3997 return bus_log_parse_error(r);
3999 r = sd_bus_message_exit_container(m);
4001 return bus_log_parse_error(r);
4003 if (arg_all || whitelist || !strv_isempty(l)) {
4007 fputs(name, stdout);
4013 STRV_FOREACH(i, l) {
4021 fputc('\n', stdout);
4029 case SD_BUS_TYPE_ARRAY:
4031 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
4035 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
4037 return bus_log_parse_error(r);
4039 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
4040 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4043 return bus_log_parse_error(r);
4045 r = sd_bus_message_exit_container(m);
4047 return bus_log_parse_error(r);
4051 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4052 const char *type, *path;
4054 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4056 return bus_log_parse_error(r);
4058 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4059 printf("%s=%s\n", type, path);
4061 return bus_log_parse_error(r);
4063 r = sd_bus_message_exit_container(m);
4065 return bus_log_parse_error(r);
4069 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4070 const char *type, *path;
4072 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4074 return bus_log_parse_error(r);
4076 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4077 printf("Listen%s=%s\n", type, path);
4079 return bus_log_parse_error(r);
4081 r = sd_bus_message_exit_container(m);
4083 return bus_log_parse_error(r);
4087 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4089 uint64_t value, next_elapse;
4091 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4093 return bus_log_parse_error(r);
4095 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4096 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4098 printf("%s={ value=%s ; next_elapse=%s }\n",
4100 format_timespan(timespan1, sizeof(timespan1), value, 0),
4101 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4104 return bus_log_parse_error(r);
4106 r = sd_bus_message_exit_container(m);
4108 return bus_log_parse_error(r);
4112 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4113 ExecStatusInfo info = {};
4115 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4117 return bus_log_parse_error(r);
4119 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4120 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4121 _cleanup_free_ char *tt;
4123 tt = strv_join(info.argv, " ");
4125 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",
4129 yes_no(info.ignore),
4130 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4131 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4133 sigchld_code_to_string(info.code),
4135 info.code == CLD_EXITED ? "" : "/",
4136 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4139 strv_free(info.argv);
4143 r = sd_bus_message_exit_container(m);
4145 return bus_log_parse_error(r);
4149 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4150 const char *path, *rwm;
4152 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4154 return bus_log_parse_error(r);
4156 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4157 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4159 return bus_log_parse_error(r);
4161 r = sd_bus_message_exit_container(m);
4163 return bus_log_parse_error(r);
4167 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4171 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4173 return bus_log_parse_error(r);
4175 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4176 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4178 return bus_log_parse_error(r);
4180 r = sd_bus_message_exit_container(m);
4182 return bus_log_parse_error(r);
4186 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4190 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4192 return bus_log_parse_error(r);
4194 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4195 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4197 return bus_log_parse_error(r);
4199 r = sd_bus_message_exit_container(m);
4201 return bus_log_parse_error(r);
4209 r = bus_print_property(name, m, arg_all);
4211 return bus_log_parse_error(r);
4214 r = sd_bus_message_skip(m, contents);
4216 return bus_log_parse_error(r);
4219 printf("%s=[unprintable]\n", name);
4225 static int show_one(
4229 bool show_properties,
4233 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4234 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4235 UnitStatusInfo info = {};
4242 log_debug("Showing one %s", path);
4244 r = sd_bus_call_method(
4246 "org.freedesktop.systemd1",
4248 "org.freedesktop.DBus.Properties",
4254 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4258 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4260 return bus_log_parse_error(r);
4267 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4268 const char *name, *contents;
4270 r = sd_bus_message_read(reply, "s", &name);
4272 return bus_log_parse_error(r);
4274 r = sd_bus_message_peek_type(reply, NULL, &contents);
4276 return bus_log_parse_error(r);
4278 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4280 return bus_log_parse_error(r);
4282 if (show_properties)
4283 r = print_property(name, reply, contents);
4285 r = status_property(name, reply, &info, contents);
4289 r = sd_bus_message_exit_container(reply);
4291 return bus_log_parse_error(r);
4293 r = sd_bus_message_exit_container(reply);
4295 return bus_log_parse_error(r);
4298 return bus_log_parse_error(r);
4300 r = sd_bus_message_exit_container(reply);
4302 return bus_log_parse_error(r);
4306 if (!show_properties) {
4307 if (streq(verb, "help"))
4308 show_unit_help(&info);
4310 print_status_info(&info, ellipsized);
4313 strv_free(info.documentation);
4314 strv_free(info.dropin_paths);
4315 strv_free(info.listen);
4317 if (!streq_ptr(info.active_state, "active") &&
4318 !streq_ptr(info.active_state, "reloading") &&
4319 streq(verb, "status")) {
4320 /* According to LSB: "program not running" */
4321 /* 0: program is running or service is OK
4322 * 1: program is dead and /run PID file exists
4323 * 2: program is dead and /run/lock lock file exists
4324 * 3: program is not running
4325 * 4: program or service status is unknown
4327 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4333 while ((p = info.exec)) {
4334 LIST_REMOVE(exec, info.exec, p);
4335 exec_status_info_free(p);
4341 static int get_unit_dbus_path_by_pid(
4346 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4347 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4351 r = sd_bus_call_method(
4353 "org.freedesktop.systemd1",
4354 "/org/freedesktop/systemd1",
4355 "org.freedesktop.systemd1.Manager",
4361 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4365 r = sd_bus_message_read(reply, "o", &u);
4367 return bus_log_parse_error(r);
4377 static int show_all(
4380 bool show_properties,
4384 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4385 _cleanup_free_ UnitInfo *unit_infos = NULL;
4390 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4394 pager_open_if_enabled();
4398 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4400 for (u = unit_infos; u < unit_infos + c; u++) {
4401 _cleanup_free_ char *p = NULL;
4403 p = unit_dbus_path_from_name(u->id);
4407 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4410 else if (r > 0 && ret == 0)
4417 static int show_system_status(sd_bus *bus) {
4418 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4419 _cleanup_free_ char *hn = NULL;
4420 struct machine_info mi = {};
4421 const char *on, *off;
4424 hn = gethostname_malloc();
4428 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4430 return log_error_errno(r, "Failed to read server status: %m");
4432 if (streq_ptr(mi.state, "degraded")) {
4433 on = ansi_highlight_red();
4434 off = ansi_highlight_off();
4435 } else if (!streq_ptr(mi.state, "running")) {
4436 on = ansi_highlight_yellow();
4437 off = ansi_highlight_off();
4441 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4443 printf(" State: %s%s%s\n",
4444 on, strna(mi.state), off);
4446 printf(" Jobs: %u queued\n", mi.n_jobs);
4447 printf(" Failed: %u units\n", mi.n_failed_units);
4449 printf(" Since: %s; %s\n",
4450 format_timestamp(since2, sizeof(since2), mi.timestamp),
4451 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4453 printf(" CGroup: %s\n", mi.control_group ?: "/");
4454 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4456 arg_all * OUTPUT_SHOW_ALL |
4457 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4458 on_tty() * OUTPUT_COLOR |
4459 !arg_quiet * OUTPUT_WARN_CUTOFF |
4460 arg_full * OUTPUT_FULL_WIDTH;
4462 static const char prefix[] = " ";
4466 if (c > sizeof(prefix) - 1)
4467 c -= sizeof(prefix) - 1;
4471 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4475 free(mi.control_group);
4480 static int show(sd_bus *bus, char **args) {
4481 bool show_properties, show_status, new_line = false;
4482 bool ellipsized = false;
4488 show_properties = streq(args[0], "show");
4489 show_status = streq(args[0], "status");
4491 if (show_properties)
4492 pager_open_if_enabled();
4494 /* If no argument is specified inspect the manager itself */
4496 if (show_properties && strv_length(args) <= 1)
4497 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4499 if (show_status && strv_length(args) <= 1) {
4501 pager_open_if_enabled();
4502 show_system_status(bus);
4506 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4508 _cleanup_free_ char **patterns = NULL;
4511 STRV_FOREACH(name, args + 1) {
4512 _cleanup_free_ char *unit = NULL;
4515 if (safe_atou32(*name, &id) < 0) {
4516 if (strv_push(&patterns, *name) < 0)
4520 } else if (show_properties) {
4521 /* Interpret as job id */
4522 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4526 /* Interpret as PID */
4527 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4534 r = show_one(args[0], bus, unit, show_properties,
4535 &new_line, &ellipsized);
4538 else if (r > 0 && ret == 0)
4542 if (!strv_isempty(patterns)) {
4543 _cleanup_strv_free_ char **names = NULL;
4545 r = expand_names(bus, patterns, NULL, &names);
4547 log_error_errno(r, "Failed to expand names: %m");
4549 STRV_FOREACH(name, names) {
4550 _cleanup_free_ char *unit;
4552 unit = unit_dbus_path_from_name(*name);
4556 r = show_one(args[0], bus, unit, show_properties,
4557 &new_line, &ellipsized);
4560 else if (r > 0 && ret == 0)
4566 if (ellipsized && !arg_quiet)
4567 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4572 static int cat(sd_bus *bus, char **args) {
4573 _cleanup_strv_free_ char **names = NULL;
4581 r = expand_names(bus, args + 1, NULL, &names);
4583 log_error_errno(r, "Failed to expand names: %m");
4585 pager_open_if_enabled();
4587 STRV_FOREACH(name, names) {
4588 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4589 _cleanup_strv_free_ char **dropin_paths = NULL;
4590 _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
4593 unit = unit_dbus_path_from_name(*name);
4597 if (need_daemon_reload(bus, *name) > 0)
4598 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4599 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4601 r = sd_bus_get_property_string(
4603 "org.freedesktop.systemd1",
4605 "org.freedesktop.systemd1.Unit",
4610 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4614 r = sd_bus_get_property_strv(
4616 "org.freedesktop.systemd1",
4618 "org.freedesktop.systemd1.Unit",
4623 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4632 if (!isempty(fragment_path)) {
4633 printf("%s# %s%s\n",
4634 ansi_highlight_blue(),
4636 ansi_highlight_off());
4639 r = copy_file_fd(fragment_path, STDOUT_FILENO);
4641 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4646 STRV_FOREACH(path, dropin_paths) {
4647 printf("%s%s# %s%s\n",
4648 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4649 ansi_highlight_blue(),
4651 ansi_highlight_off());
4654 r = copy_file_fd(*path, STDOUT_FILENO);
4656 log_warning_errno(r, "Failed to cat %s: %m", *path);
4662 return r < 0 ? r : 0;
4665 static int set_property(sd_bus *bus, char **args) {
4666 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4667 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4668 _cleanup_free_ char *n = NULL;
4672 r = sd_bus_message_new_method_call(
4675 "org.freedesktop.systemd1",
4676 "/org/freedesktop/systemd1",
4677 "org.freedesktop.systemd1.Manager",
4678 "SetUnitProperties");
4680 return bus_log_create_error(r);
4682 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4684 return bus_log_create_error(r);
4686 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4690 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4692 return bus_log_create_error(r);
4694 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4696 return bus_log_create_error(r);
4698 STRV_FOREACH(i, args + 2) {
4699 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4701 return bus_log_create_error(r);
4703 r = bus_append_unit_property_assignment(m, *i);
4707 r = sd_bus_message_close_container(m);
4709 return bus_log_create_error(r);
4712 r = sd_bus_message_close_container(m);
4714 return bus_log_create_error(r);
4716 r = sd_bus_call(bus, m, 0, &error, NULL);
4718 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4725 static int snapshot(sd_bus *bus, char **args) {
4726 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4727 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4728 _cleanup_free_ char *n = NULL, *id = NULL;
4732 if (strv_length(args) > 1)
4733 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4739 r = sd_bus_message_new_method_call(
4742 "org.freedesktop.systemd1",
4743 "/org/freedesktop/systemd1",
4744 "org.freedesktop.systemd1.Manager",
4747 return bus_log_create_error(r);
4749 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4751 return bus_log_create_error(r);
4753 r = sd_bus_message_append(m, "sb", n, false);
4755 return bus_log_create_error(r);
4757 r = sd_bus_call(bus, m, 0, &error, &reply);
4759 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4763 r = sd_bus_message_read(reply, "o", &path);
4765 return bus_log_parse_error(r);
4767 r = sd_bus_get_property_string(
4769 "org.freedesktop.systemd1",
4771 "org.freedesktop.systemd1.Unit",
4776 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4786 static int delete_snapshot(sd_bus *bus, char **args) {
4787 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4788 _cleanup_strv_free_ char **names = NULL;
4794 r = expand_names(bus, args + 1, ".snapshot", &names);
4796 log_error_errno(r, "Failed to expand names: %m");
4798 STRV_FOREACH(name, names) {
4799 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4802 q = sd_bus_message_new_method_call(
4805 "org.freedesktop.systemd1",
4806 "/org/freedesktop/systemd1",
4807 "org.freedesktop.systemd1.Manager",
4810 return bus_log_create_error(q);
4812 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4814 return bus_log_create_error(q);
4816 q = sd_bus_message_append(m, "s", *name);
4818 return bus_log_create_error(q);
4820 q = sd_bus_call(bus, m, 0, &error, NULL);
4822 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4831 static int daemon_reload(sd_bus *bus, char **args) {
4832 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4833 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4837 if (arg_action == ACTION_RELOAD)
4839 else if (arg_action == ACTION_REEXEC)
4840 method = "Reexecute";
4842 assert(arg_action == ACTION_SYSTEMCTL);
4845 streq(args[0], "clear-jobs") ||
4846 streq(args[0], "cancel") ? "ClearJobs" :
4847 streq(args[0], "daemon-reexec") ? "Reexecute" :
4848 streq(args[0], "reset-failed") ? "ResetFailed" :
4849 streq(args[0], "halt") ? "Halt" :
4850 streq(args[0], "poweroff") ? "PowerOff" :
4851 streq(args[0], "reboot") ? "Reboot" :
4852 streq(args[0], "kexec") ? "KExec" :
4853 streq(args[0], "exit") ? "Exit" :
4854 /* "daemon-reload" */ "Reload";
4857 r = sd_bus_message_new_method_call(
4860 "org.freedesktop.systemd1",
4861 "/org/freedesktop/systemd1",
4862 "org.freedesktop.systemd1.Manager",
4865 return bus_log_create_error(r);
4867 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4869 return bus_log_create_error(r);
4871 r = sd_bus_call(bus, m, 0, &error, NULL);
4872 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4873 /* There's always a fallback possible for
4874 * legacy actions. */
4876 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4877 /* On reexecution, we expect a disconnect, not a
4881 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4883 return r < 0 ? r : 0;
4886 static int reset_failed(sd_bus *bus, char **args) {
4887 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4888 _cleanup_strv_free_ char **names = NULL;
4892 if (strv_length(args) <= 1)
4893 return daemon_reload(bus, args);
4895 r = expand_names(bus, args + 1, NULL, &names);
4897 log_error_errno(r, "Failed to expand names: %m");
4899 STRV_FOREACH(name, names) {
4900 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4902 q = sd_bus_message_new_method_call(
4905 "org.freedesktop.systemd1",
4906 "/org/freedesktop/systemd1",
4907 "org.freedesktop.systemd1.Manager",
4910 return bus_log_create_error(q);
4912 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4914 return bus_log_create_error(q);
4916 q = sd_bus_message_append(m, "s", *name);
4918 return bus_log_create_error(q);
4920 q = sd_bus_call(bus, m, 0, &error, NULL);
4922 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4931 static int show_environment(sd_bus *bus, char **args) {
4932 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4933 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4937 pager_open_if_enabled();
4939 r = sd_bus_get_property(
4941 "org.freedesktop.systemd1",
4942 "/org/freedesktop/systemd1",
4943 "org.freedesktop.systemd1.Manager",
4949 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4953 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4955 return bus_log_parse_error(r);
4957 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4960 return bus_log_parse_error(r);
4962 r = sd_bus_message_exit_container(reply);
4964 return bus_log_parse_error(r);
4969 static int switch_root(sd_bus *bus, char **args) {
4970 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4971 _cleanup_free_ char *cmdline_init = NULL;
4972 const char *root, *init;
4976 l = strv_length(args);
4977 if (l < 2 || l > 3) {
4978 log_error("Wrong number of arguments.");
4987 r = parse_env_file("/proc/cmdline", WHITESPACE,
4988 "init", &cmdline_init,
4991 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4993 init = cmdline_init;
5000 const char *root_systemd_path = NULL, *root_init_path = NULL;
5002 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
5003 root_init_path = strappenda(root, "/", init);
5005 /* If the passed init is actually the same as the
5006 * systemd binary, then let's suppress it. */
5007 if (files_same(root_init_path, root_systemd_path) > 0)
5011 log_debug("Switching root - root: %s; init: %s", root, strna(init));
5013 r = sd_bus_call_method(
5015 "org.freedesktop.systemd1",
5016 "/org/freedesktop/systemd1",
5017 "org.freedesktop.systemd1.Manager",
5023 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5030 static int set_environment(sd_bus *bus, char **args) {
5031 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5032 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5039 method = streq(args[0], "set-environment")
5041 : "UnsetEnvironment";
5043 r = sd_bus_message_new_method_call(
5046 "org.freedesktop.systemd1",
5047 "/org/freedesktop/systemd1",
5048 "org.freedesktop.systemd1.Manager",
5051 return bus_log_create_error(r);
5053 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5055 return bus_log_create_error(r);
5057 r = sd_bus_message_append_strv(m, args + 1);
5059 return bus_log_create_error(r);
5061 r = sd_bus_call(bus, m, 0, &error, NULL);
5063 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5070 static int import_environment(sd_bus *bus, char **args) {
5071 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5072 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5078 r = sd_bus_message_new_method_call(
5081 "org.freedesktop.systemd1",
5082 "/org/freedesktop/systemd1",
5083 "org.freedesktop.systemd1.Manager",
5086 return bus_log_create_error(r);
5088 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5090 return bus_log_create_error(r);
5092 if (strv_isempty(args + 1))
5093 r = sd_bus_message_append_strv(m, environ);
5097 r = sd_bus_message_open_container(m, 'a', "s");
5099 return bus_log_create_error(r);
5101 STRV_FOREACH(a, args + 1) {
5103 if (!env_name_is_valid(*a)) {
5104 log_error("Not a valid environment variable name: %s", *a);
5108 STRV_FOREACH(b, environ) {
5111 eq = startswith(*b, *a);
5112 if (eq && *eq == '=') {
5114 r = sd_bus_message_append(m, "s", *b);
5116 return bus_log_create_error(r);
5123 r = sd_bus_message_close_container(m);
5126 return bus_log_create_error(r);
5128 r = sd_bus_call(bus, m, 0, &error, NULL);
5130 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5137 static int enable_sysv_units(const char *verb, char **args) {
5140 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5141 unsigned f = 1, t = 1;
5142 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5144 if (arg_scope != UNIT_FILE_SYSTEM)
5147 if (!streq(verb, "enable") &&
5148 !streq(verb, "disable") &&
5149 !streq(verb, "is-enabled"))
5152 /* Processes all SysV units, and reshuffles the array so that
5153 * afterwards only the native units remain */
5155 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5160 for (f = 0; args[f]; f++) {
5162 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5163 bool found_native = false, found_sysv;
5165 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5173 if (!endswith(name, ".service"))
5176 if (path_is_absolute(name))
5179 STRV_FOREACH(k, paths.unit_path) {
5180 _cleanup_free_ char *path = NULL;
5182 path = path_join(arg_root, *k, name);
5186 found_native = access(path, F_OK) >= 0;
5194 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5198 p[strlen(p) - strlen(".service")] = 0;
5199 found_sysv = access(p, F_OK) >= 0;
5203 /* Mark this entry, so that we don't try enabling it as native unit */
5204 args[f] = (char*) "";
5206 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5208 if (!isempty(arg_root))
5209 argv[c++] = q = strappend("--root=", arg_root);
5211 argv[c++] = basename(p);
5213 streq(verb, "enable") ? "on" :
5214 streq(verb, "disable") ? "off" : "--level=5";
5217 l = strv_join((char**)argv, " ");
5221 log_info("Executing %s", l);
5225 return log_error_errno(errno, "Failed to fork: %m");
5226 else if (pid == 0) {
5229 execv(argv[0], (char**) argv);
5230 _exit(EXIT_FAILURE);
5233 j = wait_for_terminate(pid, &status);
5235 log_error_errno(r, "Failed to wait for child: %m");
5239 if (status.si_code == CLD_EXITED) {
5240 if (streq(verb, "is-enabled")) {
5241 if (status.si_status == 0) {
5250 } else if (status.si_status != 0)
5256 /* Drop all SysV units */
5257 for (f = 0, t = 0; args[f]; f++) {
5259 if (isempty(args[f]))
5262 args[t++] = args[f];
5271 static int mangle_names(char **original_names, char ***mangled_names) {
5272 char **i, **l, **name;
5274 l = new(char*, strv_length(original_names) + 1);
5279 STRV_FOREACH(name, original_names) {
5281 /* When enabling units qualified path names are OK,
5282 * too, hence allow them explicitly. */
5287 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5303 static int enable_unit(sd_bus *bus, char **args) {
5304 _cleanup_strv_free_ char **names = NULL;
5305 const char *verb = args[0];
5306 UnitFileChange *changes = NULL;
5307 unsigned n_changes = 0;
5308 int carries_install_info = -1;
5314 r = mangle_names(args+1, &names);
5318 r = enable_sysv_units(verb, names);
5322 /* If the operation was fully executed by the SysV compat,
5323 * let's finish early */
5324 if (strv_isempty(names))
5327 if (!bus || avoid_bus()) {
5328 if (streq(verb, "enable")) {
5329 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5330 carries_install_info = r;
5331 } else if (streq(verb, "disable"))
5332 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5333 else if (streq(verb, "reenable")) {
5334 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5335 carries_install_info = r;
5336 } else if (streq(verb, "link"))
5337 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5338 else if (streq(verb, "preset")) {
5339 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5340 carries_install_info = r;
5341 } else if (streq(verb, "mask"))
5342 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5343 else if (streq(verb, "unmask"))
5344 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5346 assert_not_reached("Unknown verb");
5349 log_error_errno(r, "Operation failed: %m");
5354 dump_unit_file_changes(changes, n_changes);
5358 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5359 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5360 int expect_carries_install_info = false;
5361 bool send_force = true, send_preset_mode = false;
5364 if (streq(verb, "enable")) {
5365 method = "EnableUnitFiles";
5366 expect_carries_install_info = true;
5367 } else if (streq(verb, "disable")) {
5368 method = "DisableUnitFiles";
5370 } else if (streq(verb, "reenable")) {
5371 method = "ReenableUnitFiles";
5372 expect_carries_install_info = true;
5373 } else if (streq(verb, "link"))
5374 method = "LinkUnitFiles";
5375 else if (streq(verb, "preset")) {
5377 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5378 method = "PresetUnitFilesWithMode";
5379 send_preset_mode = true;
5381 method = "PresetUnitFiles";
5383 expect_carries_install_info = true;
5384 } else if (streq(verb, "mask"))
5385 method = "MaskUnitFiles";
5386 else if (streq(verb, "unmask")) {
5387 method = "UnmaskUnitFiles";
5390 assert_not_reached("Unknown verb");
5392 r = sd_bus_message_new_method_call(
5395 "org.freedesktop.systemd1",
5396 "/org/freedesktop/systemd1",
5397 "org.freedesktop.systemd1.Manager",
5400 return bus_log_create_error(r);
5402 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5404 return bus_log_create_error(r);
5406 r = sd_bus_message_append_strv(m, names);
5408 return bus_log_create_error(r);
5410 if (send_preset_mode) {
5411 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5413 return bus_log_create_error(r);
5416 r = sd_bus_message_append(m, "b", arg_runtime);
5418 return bus_log_create_error(r);
5421 r = sd_bus_message_append(m, "b", arg_force);
5423 return bus_log_create_error(r);
5426 r = sd_bus_call(bus, m, 0, &error, &reply);
5428 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5432 if (expect_carries_install_info) {
5433 r = sd_bus_message_read(reply, "b", &carries_install_info);
5435 return bus_log_parse_error(r);
5438 r = deserialize_and_dump_unit_file_changes(reply);
5442 /* Try to reload if enabled */
5444 r = daemon_reload(bus, args);
5449 if (carries_install_info == 0)
5450 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5451 "using systemctl.\n"
5452 "Possible reasons for having this kind of units are:\n"
5453 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5454 " .wants/ or .requires/ directory.\n"
5455 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5456 " a requirement dependency on it.\n"
5457 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5458 " D-Bus, udev, scripted systemctl call, ...).\n");
5461 unit_file_changes_free(changes, n_changes);
5466 static int add_dependency(sd_bus *bus, char **args) {
5467 _cleanup_strv_free_ char **names = NULL;
5468 _cleanup_free_ char *target = NULL;
5469 const char *verb = args[0];
5476 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5480 r = mangle_names(args+2, &names);
5484 if (streq(verb, "add-wants"))
5486 else if (streq(verb, "add-requires"))
5487 dep = UNIT_REQUIRES;
5489 assert_not_reached("Unknown verb");
5491 if (!bus || avoid_bus()) {
5492 UnitFileChange *changes = NULL;
5493 unsigned n_changes = 0;
5495 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5498 return log_error_errno(r, "Can't add dependency: %m");
5501 dump_unit_file_changes(changes, n_changes);
5503 unit_file_changes_free(changes, n_changes);
5506 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5507 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5509 r = sd_bus_message_new_method_call(
5512 "org.freedesktop.systemd1",
5513 "/org/freedesktop/systemd1",
5514 "org.freedesktop.systemd1.Manager",
5515 "AddDependencyUnitFiles");
5517 return bus_log_create_error(r);
5519 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5521 return bus_log_create_error(r);
5523 r = sd_bus_message_append_strv(m, names);
5525 return bus_log_create_error(r);
5527 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5529 return bus_log_create_error(r);
5531 r = sd_bus_call(bus, m, 0, &error, &reply);
5533 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5537 r = deserialize_and_dump_unit_file_changes(reply);
5542 r = daemon_reload(bus, args);
5550 static int preset_all(sd_bus *bus, char **args) {
5551 UnitFileChange *changes = NULL;
5552 unsigned n_changes = 0;
5555 if (!bus || avoid_bus()) {
5557 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5559 log_error_errno(r, "Operation failed: %m");
5564 dump_unit_file_changes(changes, n_changes);
5569 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5570 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5572 r = sd_bus_message_new_method_call(
5575 "org.freedesktop.systemd1",
5576 "/org/freedesktop/systemd1",
5577 "org.freedesktop.systemd1.Manager",
5578 "PresetAllUnitFiles");
5580 return bus_log_create_error(r);
5582 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5584 return bus_log_create_error(r);
5586 r = sd_bus_message_append(
5589 unit_file_preset_mode_to_string(arg_preset_mode),
5593 return bus_log_create_error(r);
5595 r = sd_bus_call(bus, m, 0, &error, &reply);
5597 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5601 r = deserialize_and_dump_unit_file_changes(reply);
5606 r = daemon_reload(bus, args);
5612 unit_file_changes_free(changes, n_changes);
5617 static int unit_is_enabled(sd_bus *bus, char **args) {
5619 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5620 _cleanup_strv_free_ char **names = NULL;
5625 r = mangle_names(args+1, &names);
5629 r = enable_sysv_units(args[0], names);
5635 if (!bus || avoid_bus()) {
5637 STRV_FOREACH(name, names) {
5638 UnitFileState state;
5640 state = unit_file_get_state(arg_scope, arg_root, *name);
5642 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5644 if (state == UNIT_FILE_ENABLED ||
5645 state == UNIT_FILE_ENABLED_RUNTIME ||
5646 state == UNIT_FILE_STATIC ||
5647 state == UNIT_FILE_INDIRECT)
5651 puts(unit_file_state_to_string(state));
5655 STRV_FOREACH(name, names) {
5656 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5659 r = sd_bus_call_method(
5661 "org.freedesktop.systemd1",
5662 "/org/freedesktop/systemd1",
5663 "org.freedesktop.systemd1.Manager",
5669 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5673 r = sd_bus_message_read(reply, "s", &s);
5675 return bus_log_parse_error(r);
5677 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5688 static int is_system_running(sd_bus *bus, char **args) {
5689 _cleanup_free_ char *state = NULL;
5692 r = sd_bus_get_property_string(
5694 "org.freedesktop.systemd1",
5695 "/org/freedesktop/systemd1",
5696 "org.freedesktop.systemd1.Manager",
5709 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5712 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
5719 STRV_FOREACH(p, lp->unit_path) {
5722 path = path_join(arg_root, *p, unit_name);
5726 if (access(path, F_OK) == 0) {
5737 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5742 assert(original_path);
5745 t = tempfn_random(new_path);
5749 r = mkdir_parents(new_path, 0755);
5751 return log_error_errno(r, "Failed to create directories for %s: %m", new_path);
5753 r = copy_file(original_path, t, 0, 0644);
5757 log_error_errno(r, "Failed to create temporary file %s: %m", t);
5762 log_error_errno(r, "Failed to copy %s to %s: %m", original_path, t);
5772 static int get_drop_in_to_edit(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_path) {
5779 switch (arg_scope) {
5780 case UNIT_FILE_SYSTEM:
5781 tmp = strappenda(arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
5783 case UNIT_FILE_GLOBAL:
5784 tmp = strappenda(arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH "/", unit_name, ".d/override.conf");
5786 case UNIT_FILE_USER:
5788 assert(user_runtime);
5790 tmp = strappenda(arg_runtime ? user_runtime : user_home, "/", unit_name, ".d/override.conf");
5793 assert_not_reached("Invalid scope");
5796 tmp_new_path = path_join(arg_root, tmp, NULL);
5800 *ret_path = tmp_new_path;
5805 static int unit_file_create_drop_in(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
5811 assert(ret_new_path);
5812 assert(ret_tmp_path);
5814 r = get_drop_in_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5818 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5824 *ret_new_path = tmp_new_path;
5825 *ret_tmp_path = tmp_tmp_path;
5830 static bool unit_is_editable(const char *unit_name, const char *fragment_path, const char *user_home) {
5831 bool editable = true;
5832 const char *invalid_path;
5839 switch (arg_scope) {
5840 case UNIT_FILE_SYSTEM:
5841 if (path_startswith(fragment_path, "/etc/systemd/system")) {
5843 invalid_path = "/etc/systemd/system";
5844 } else if (path_startswith(fragment_path, SYSTEM_CONFIG_UNIT_PATH)) {
5846 invalid_path = SYSTEM_CONFIG_UNIT_PATH;
5849 case UNIT_FILE_GLOBAL:
5850 if (path_startswith(fragment_path, "/etc/systemd/user")) {
5852 invalid_path = "/etc/systemd/user";
5853 } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
5855 invalid_path = USER_CONFIG_UNIT_PATH;
5858 case UNIT_FILE_USER:
5861 if (path_startswith(fragment_path, "/etc/systemd/user")) {
5863 invalid_path = "/etc/systemd/user";
5864 } else if (path_startswith(fragment_path, USER_CONFIG_UNIT_PATH)) {
5866 invalid_path = USER_CONFIG_UNIT_PATH;
5867 } else if (path_startswith(fragment_path, user_home)) {
5869 invalid_path = user_home;
5873 assert_not_reached("Invalid scope");
5877 log_error("%s ignored: cannot temporarily edit units from %s", unit_name, invalid_path);
5882 static int get_copy_to_edit(const char *unit_name, const char *fragment_path, const char *user_home, const char *user_runtime, char **ret_path) {
5888 if (!unit_is_editable(unit_name, fragment_path, user_home))
5891 switch (arg_scope) {
5892 case UNIT_FILE_SYSTEM:
5893 tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/system/" : SYSTEM_CONFIG_UNIT_PATH, unit_name);
5895 case UNIT_FILE_GLOBAL:
5896 tmp_new_path = path_join(arg_root, arg_runtime ? "/run/systemd/user/" : USER_CONFIG_UNIT_PATH, unit_name);
5898 case UNIT_FILE_USER:
5900 assert(user_runtime);
5902 tmp_new_path = path_join(arg_root, arg_runtime ? user_runtime : user_home, unit_name);
5905 assert_not_reached("Invalid scope");
5910 *ret_path = tmp_new_path;
5915 static int unit_file_create_copy(const char *unit_name,
5916 const char *fragment_path,
5917 const char *user_home,
5918 const char *user_runtime,
5919 char **ret_new_path,
5920 char **ret_tmp_path) {
5925 assert(fragment_path);
5927 assert(ret_new_path);
5928 assert(ret_tmp_path);
5930 r = get_copy_to_edit(unit_name, fragment_path, user_home, user_runtime, &tmp_new_path);
5934 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5937 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);
5942 if (response != 'y') {
5943 log_warning("%s ignored", unit_name);
5949 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5951 log_error_errno(r, "Failed to create temporary file for %s: %m", tmp_new_path);
5956 *ret_new_path = tmp_new_path;
5957 *ret_tmp_path = tmp_tmp_path;
5962 static int run_editor(char **paths) {
5970 log_error_errno(errno, "Failed to fork: %m");
5976 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5978 char **tmp_path, **original_path, **p;
5982 argc = strv_length(paths)/2 + 1;
5983 args = newa(const char*, argc + 1);
5986 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5987 args[i] = *tmp_path;
5992 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5993 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5994 * we try to execute well known editors
5996 editor = getenv("SYSTEMD_EDITOR");
5998 editor = getenv("EDITOR");
6000 editor = getenv("VISUAL");
6002 if (!isempty(editor)) {
6004 execvp(editor, (char* const*) args);
6007 STRV_FOREACH(p, backup_editors) {
6009 execvp(*p, (char* const*) args);
6010 /* We do not fail if the editor doesn't exist
6011 * because we want to try each one of them before
6014 if (errno != ENOENT) {
6015 log_error("Failed to execute %s: %m", editor);
6016 _exit(EXIT_FAILURE);
6020 log_error("Cannot edit unit(s): No editor available. Please set either SYSTEMD_EDITOR or EDITOR or VISUAL environment variable");
6021 _exit(EXIT_FAILURE);
6024 r = wait_for_terminate_and_warn("editor", pid, true);
6026 return log_error_errno(r, "Failed to wait for child: %m");
6031 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
6032 _cleanup_free_ char *user_home = NULL;
6033 _cleanup_free_ char *user_runtime = NULL;
6040 if (arg_scope == UNIT_FILE_USER) {
6041 r = user_config_home(&user_home);
6045 log_error("Cannot edit units for the user instance: home directory unknown");
6049 r = user_runtime_dir(&user_runtime);
6053 log_error("Cannot edit units for the user instance: runtime directory unknown");
6058 if (!bus || avoid_bus()) {
6059 _cleanup_lookup_paths_free_ LookupPaths lp = {};
6061 /* If there is no bus, we try to find the units by testing each available directory
6062 * according to the scope.
6064 r = lookup_paths_init(&lp,
6065 arg_scope == UNIT_FILE_SYSTEM ? SYSTEMD_SYSTEM : SYSTEMD_USER,
6066 arg_scope == UNIT_FILE_USER,
6070 log_error_errno(r, "Failed get lookup paths: %m");
6074 STRV_FOREACH(name, names) {
6075 _cleanup_free_ char *path = NULL;
6076 char *new_path, *tmp_path;
6078 r = unit_file_find_path(&lp, *name, &path);
6082 log_warning("%s ignored: not found", *name);
6087 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
6089 r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
6094 r = strv_push(paths, new_path);
6098 r = strv_push(paths, tmp_path);
6103 STRV_FOREACH(name, names) {
6104 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
6105 _cleanup_free_ char *fragment_path = NULL;
6106 _cleanup_free_ char *unit = NULL;
6107 char *new_path, *tmp_path;
6109 unit = unit_dbus_path_from_name(*name);
6113 if (need_daemon_reload(bus, *name) > 0) {
6114 log_warning("%s ignored: unit file changed on disk. Run 'systemctl%s daemon-reload'.",
6115 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
6119 r = sd_bus_get_property_string(
6121 "org.freedesktop.systemd1",
6123 "org.freedesktop.systemd1.Unit",
6128 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
6132 if (isempty(fragment_path)) {
6133 log_warning("%s ignored: not found", *name);
6138 r = unit_file_create_copy(*name, fragment_path, user_home, user_runtime, &new_path, &tmp_path);
6140 r = unit_file_create_drop_in(*name, user_home, user_runtime, &new_path, &tmp_path);
6144 r = strv_push(paths, new_path);
6148 r = strv_push(paths, tmp_path);
6157 static int edit(sd_bus *bus, char **args) {
6158 _cleanup_strv_free_ char **names = NULL;
6159 _cleanup_strv_free_ char **paths = NULL;
6160 char **original, **tmp;
6166 log_error("Cannot edit units if we are not on a tty");
6170 if (arg_transport != BUS_TRANSPORT_LOCAL) {
6171 log_error("Cannot remotely edit units");
6175 r = expand_names(bus, args + 1, NULL, &names);
6177 return log_error_errno(r, "Failed to expand names: %m");
6180 log_error("No unit name found by expanding names");
6184 r = find_paths_to_edit(bus, names, &paths);
6188 if (strv_isempty(paths)) {
6189 log_error("Cannot find any units to edit");
6193 r = run_editor(paths);
6197 STRV_FOREACH_PAIR(original, tmp, paths) {
6198 /* If the temporary file is empty we ignore it.
6199 * It's useful if the user wants to cancel its modification
6201 if (null_or_empty_path(*tmp)) {
6202 log_warning("Edition of %s canceled: temporary file empty", *original);
6205 r = rename(*tmp, *original);
6207 r = log_error_errno(errno, "Failed to rename %s to %s: %m", *tmp, *original);
6212 if (!arg_no_reload && bus && !avoid_bus())
6213 r = daemon_reload(bus, args);
6216 STRV_FOREACH_PAIR(original, tmp, paths)
6217 unlink_noerrno(*tmp);
6222 static void systemctl_help(void) {
6224 pager_open_if_enabled();
6226 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6227 "Query or send control commands to the systemd manager.\n\n"
6228 " -h --help Show this help\n"
6229 " --version Show package version\n"
6230 " --system Connect to system manager\n"
6231 " --user Connect to user service manager\n"
6232 " -H --host=[USER@]HOST\n"
6233 " Operate on remote host\n"
6234 " -M --machine=CONTAINER\n"
6235 " Operate on local container\n"
6236 " -t --type=TYPE List only units of a particular type\n"
6237 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
6238 " -p --property=NAME Show only properties by this name\n"
6239 " -a --all Show all loaded units/properties, including dead/empty\n"
6240 " ones. To list all units installed on the system, use\n"
6241 " the 'list-unit-files' command instead.\n"
6242 " -l --full Don't ellipsize unit names on output\n"
6243 " -r --recursive Show unit list of host and local containers\n"
6244 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6245 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6246 " queueing a new job\n"
6247 " --show-types When showing sockets, explicitly show their type\n"
6248 " -i --ignore-inhibitors\n"
6249 " When shutting down or sleeping, ignore inhibitors\n"
6250 " --kill-who=WHO Who to send signal to\n"
6251 " -s --signal=SIGNAL Which signal to send\n"
6252 " -q --quiet Suppress output\n"
6253 " --no-block Do not wait until operation finished\n"
6254 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6255 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
6257 " --no-legend Do not print a legend (column headers and hints)\n"
6258 " --no-pager Do not pipe output into a pager\n"
6259 " --no-ask-password\n"
6260 " Do not ask for system passwords\n"
6261 " --global Enable/disable unit files globally\n"
6262 " --runtime Enable unit files only temporarily until next reboot\n"
6263 " -f --force When enabling unit files, override existing symlinks\n"
6264 " When shutting down, execute action immediately\n"
6265 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
6266 " or only disable\n"
6267 " --root=PATH Enable unit files in the specified root directory\n"
6268 " -n --lines=INTEGER Number of journal entries to show\n"
6269 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
6270 " verbose, export, json, json-pretty, json-sse, cat)\n"
6271 " --plain Print unit dependencies as a list instead of a tree\n\n"
6273 " list-units [PATTERN...] List loaded units\n"
6274 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6275 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6276 " start NAME... Start (activate) one or more units\n"
6277 " stop NAME... Stop (deactivate) one or more units\n"
6278 " reload NAME... Reload one or more units\n"
6279 " restart NAME... Start or restart one or more units\n"
6280 " try-restart NAME... Restart one or more units if active\n"
6281 " reload-or-restart NAME... Reload one or more units if possible,\n"
6282 " otherwise start or restart\n"
6283 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6284 " otherwise restart if active\n"
6285 " isolate NAME Start one unit and stop all others\n"
6286 " kill NAME... Send signal to processes of a unit\n"
6287 " is-active PATTERN... Check whether units are active\n"
6288 " is-failed PATTERN... Check whether units are failed\n"
6289 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6290 " show [PATTERN...|JOB...] Show properties of one or more\n"
6291 " units/jobs or the manager\n"
6292 " cat PATTERN... Show files and drop-ins of one or more units\n"
6293 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6294 " help PATTERN...|PID... Show manual for one or more units\n"
6295 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6297 " list-dependencies [NAME] Recursively show units which are required\n"
6298 " or wanted by this unit or by which this\n"
6299 " unit is required or wanted\n\n"
6300 "Unit File Commands:\n"
6301 " list-unit-files [PATTERN...] List installed unit files\n"
6302 " enable NAME... Enable one or more unit files\n"
6303 " disable NAME... Disable one or more unit files\n"
6304 " reenable NAME... Reenable one or more unit files\n"
6305 " preset NAME... Enable/disable one or more unit files\n"
6306 " based on preset configuration\n"
6307 " preset-all Enable/disable all unit files based on\n"
6308 " preset configuration\n"
6309 " is-enabled NAME... Check whether unit files are enabled\n\n"
6310 " mask NAME... Mask one or more units\n"
6311 " unmask NAME... Unmask one or more units\n"
6312 " link PATH... Link one or more units files into\n"
6313 " the search path\n"
6314 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6315 " on specified one or more units\n"
6316 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6317 " on specified one or more units\n"
6318 " get-default Get the name of the default target\n"
6319 " set-default NAME Set the default target\n"
6320 " edit NAME... Edit one or more unit files\n"
6322 "Machine Commands:\n"
6323 " list-machines [PATTERN...] List local containers and host\n\n"
6325 " list-jobs [PATTERN...] List jobs\n"
6326 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6327 "Snapshot Commands:\n"
6328 " snapshot [NAME] Create a snapshot\n"
6329 " delete NAME... Remove one or more snapshots\n\n"
6330 "Environment Commands:\n"
6331 " show-environment Dump environment\n"
6332 " set-environment NAME=VALUE... Set one or more environment variables\n"
6333 " unset-environment NAME... Unset one or more environment variables\n"
6334 " import-environment NAME... Import all, one or more environment variables\n\n"
6335 "Manager Lifecycle Commands:\n"
6336 " daemon-reload Reload systemd manager configuration\n"
6337 " daemon-reexec Reexecute systemd manager\n\n"
6338 "System Commands:\n"
6339 " is-system-running Check whether system is fully running\n"
6340 " default Enter system default mode\n"
6341 " rescue Enter system rescue mode\n"
6342 " emergency Enter system emergency mode\n"
6343 " halt Shut down and halt the system\n"
6344 " poweroff Shut down and power-off the system\n"
6345 " reboot [ARG] Shut down and reboot the system\n"
6346 " kexec Shut down and reboot the system with kexec\n"
6347 " exit Request user instance exit\n"
6348 " switch-root ROOT [INIT] Change to a different root file system\n"
6349 " suspend Suspend the system\n"
6350 " hibernate Hibernate the system\n"
6351 " hybrid-sleep Hibernate and suspend the system\n",
6352 program_invocation_short_name);
6355 static void halt_help(void) {
6356 printf("%s [OPTIONS...]%s\n\n"
6357 "%s the system.\n\n"
6358 " --help Show this help\n"
6359 " --halt Halt the machine\n"
6360 " -p --poweroff Switch off the machine\n"
6361 " --reboot Reboot the machine\n"
6362 " -f --force Force immediate halt/power-off/reboot\n"
6363 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6364 " -d --no-wtmp Don't write wtmp record\n"
6365 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6366 program_invocation_short_name,
6367 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6368 arg_action == ACTION_REBOOT ? "Reboot" :
6369 arg_action == ACTION_POWEROFF ? "Power off" :
6373 static void shutdown_help(void) {
6374 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6375 "Shut down the system.\n\n"
6376 " --help Show this help\n"
6377 " -H --halt Halt the machine\n"
6378 " -P --poweroff Power-off the machine\n"
6379 " -r --reboot Reboot the machine\n"
6380 " -h Equivalent to --poweroff, overridden by --halt\n"
6381 " -k Don't halt/power-off/reboot, just send warnings\n"
6382 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6383 " -c Cancel a pending shutdown\n",
6384 program_invocation_short_name);
6387 static void telinit_help(void) {
6388 printf("%s [OPTIONS...] {COMMAND}\n\n"
6389 "Send control commands to the init daemon.\n\n"
6390 " --help Show this help\n"
6391 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6393 " 0 Power-off the machine\n"
6394 " 6 Reboot the machine\n"
6395 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6396 " 1, s, S Enter rescue mode\n"
6397 " q, Q Reload init daemon configuration\n"
6398 " u, U Reexecute init daemon\n",
6399 program_invocation_short_name);
6402 static void runlevel_help(void) {
6403 printf("%s [OPTIONS...]\n\n"
6404 "Prints the previous and current runlevel of the init system.\n\n"
6405 " --help Show this help\n",
6406 program_invocation_short_name);
6409 static void help_types(void) {
6414 puts("Available unit types:");
6415 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6416 t = unit_type_to_string(i);
6422 static int systemctl_parse_argv(int argc, char *argv[]) {
6431 ARG_IGNORE_DEPENDENCIES,
6443 ARG_NO_ASK_PASSWORD,
6453 static const struct option options[] = {
6454 { "help", no_argument, NULL, 'h' },
6455 { "version", no_argument, NULL, ARG_VERSION },
6456 { "type", required_argument, NULL, 't' },
6457 { "property", required_argument, NULL, 'p' },
6458 { "all", no_argument, NULL, 'a' },
6459 { "reverse", no_argument, NULL, ARG_REVERSE },
6460 { "after", no_argument, NULL, ARG_AFTER },
6461 { "before", no_argument, NULL, ARG_BEFORE },
6462 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6463 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6464 { "full", no_argument, NULL, 'l' },
6465 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6466 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6467 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6468 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6469 { "ignore-inhibitors", no_argument, NULL, 'i' },
6470 { "user", no_argument, NULL, ARG_USER },
6471 { "system", no_argument, NULL, ARG_SYSTEM },
6472 { "global", no_argument, NULL, ARG_GLOBAL },
6473 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6474 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6475 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6476 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6477 { "quiet", no_argument, NULL, 'q' },
6478 { "root", required_argument, NULL, ARG_ROOT },
6479 { "force", no_argument, NULL, ARG_FORCE },
6480 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6481 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6482 { "signal", required_argument, NULL, 's' },
6483 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6484 { "host", required_argument, NULL, 'H' },
6485 { "machine", required_argument, NULL, 'M' },
6486 { "runtime", no_argument, NULL, ARG_RUNTIME },
6487 { "lines", required_argument, NULL, 'n' },
6488 { "output", required_argument, NULL, 'o' },
6489 { "plain", no_argument, NULL, ARG_PLAIN },
6490 { "state", required_argument, NULL, ARG_STATE },
6491 { "recursive", no_argument, NULL, 'r' },
6492 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6501 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6510 puts(PACKAGE_STRING);
6511 puts(SYSTEMD_FEATURES);
6515 const char *word, *state;
6518 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6519 _cleanup_free_ char *type;
6521 type = strndup(word, size);
6525 if (streq(type, "help")) {
6530 if (unit_type_from_string(type) >= 0) {
6531 if (strv_push(&arg_types, type))
6537 /* It's much nicer to use --state= for
6538 * load states, but let's support this
6539 * in --types= too for compatibility
6540 * with old versions */
6541 if (unit_load_state_from_string(optarg) >= 0) {
6542 if (strv_push(&arg_states, type) < 0)
6548 log_error("Unknown unit type or load state '%s'.", type);
6549 log_info("Use -t help to see a list of allowed values.");
6557 /* Make sure that if the empty property list
6558 was specified, we won't show any properties. */
6559 if (isempty(optarg) && !arg_properties) {
6560 arg_properties = new0(char*, 1);
6561 if (!arg_properties)
6564 const char *word, *state;
6567 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6570 prop = strndup(word, size);
6574 if (strv_consume(&arg_properties, prop) < 0)
6579 /* If the user asked for a particular
6580 * property, show it to him, even if it is
6592 arg_dependency = DEPENDENCY_REVERSE;
6596 arg_dependency = DEPENDENCY_AFTER;
6600 arg_dependency = DEPENDENCY_BEFORE;
6603 case ARG_SHOW_TYPES:
6604 arg_show_types = true;
6608 arg_job_mode = optarg;
6612 arg_job_mode = "fail";
6615 case ARG_IRREVERSIBLE:
6616 arg_job_mode = "replace-irreversibly";
6619 case ARG_IGNORE_DEPENDENCIES:
6620 arg_job_mode = "ignore-dependencies";
6624 arg_scope = UNIT_FILE_USER;
6628 arg_scope = UNIT_FILE_SYSTEM;
6632 arg_scope = UNIT_FILE_GLOBAL;
6636 arg_no_block = true;
6640 arg_no_legend = true;
6644 arg_no_pager = true;
6660 if (strv_extend(&arg_states, "failed") < 0)
6678 arg_no_reload = true;
6682 arg_kill_who = optarg;
6686 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6687 log_error("Failed to parse signal string %s.", optarg);
6692 case ARG_NO_ASK_PASSWORD:
6693 arg_ask_password = false;
6697 arg_transport = BUS_TRANSPORT_REMOTE;
6702 arg_transport = BUS_TRANSPORT_CONTAINER;
6711 if (safe_atou(optarg, &arg_lines) < 0) {
6712 log_error("Failed to parse lines '%s'", optarg);
6718 arg_output = output_mode_from_string(optarg);
6719 if (arg_output < 0) {
6720 log_error("Unknown output '%s'.", optarg);
6726 arg_ignore_inhibitors = true;
6734 const char *word, *state;
6737 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6740 s = strndup(word, size);
6744 if (strv_consume(&arg_states, s) < 0)
6751 if (geteuid() != 0) {
6752 log_error("--recursive requires root privileges.");
6756 arg_recursive = true;
6759 case ARG_PRESET_MODE:
6761 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6762 if (arg_preset_mode < 0) {
6763 log_error("Failed to parse preset mode: %s.", optarg);
6773 assert_not_reached("Unhandled option");
6776 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6777 log_error("Cannot access user instance remotely.");
6784 static int halt_parse_argv(int argc, char *argv[]) {
6793 static const struct option options[] = {
6794 { "help", no_argument, NULL, ARG_HELP },
6795 { "halt", no_argument, NULL, ARG_HALT },
6796 { "poweroff", no_argument, NULL, 'p' },
6797 { "reboot", no_argument, NULL, ARG_REBOOT },
6798 { "force", no_argument, NULL, 'f' },
6799 { "wtmp-only", no_argument, NULL, 'w' },
6800 { "no-wtmp", no_argument, NULL, 'd' },
6801 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6810 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6811 if (runlevel == '0' || runlevel == '6')
6814 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6822 arg_action = ACTION_HALT;
6826 if (arg_action != ACTION_REBOOT)
6827 arg_action = ACTION_POWEROFF;
6831 arg_action = ACTION_REBOOT;
6853 /* Compatibility nops */
6860 assert_not_reached("Unhandled option");
6863 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6864 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6867 } else if (optind < argc) {
6868 log_error("Too many arguments.");
6875 static int parse_time_spec(const char *t, usec_t *_u) {
6879 if (streq(t, "now"))
6881 else if (!strchr(t, ':')) {
6884 if (safe_atou64(t, &u) < 0)
6887 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6896 hour = strtol(t, &e, 10);
6897 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6900 minute = strtol(e+1, &e, 10);
6901 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6904 n = now(CLOCK_REALTIME);
6905 s = (time_t) (n / USEC_PER_SEC);
6907 assert_se(localtime_r(&s, &tm));
6909 tm.tm_hour = (int) hour;
6910 tm.tm_min = (int) minute;
6913 assert_se(s = mktime(&tm));
6915 *_u = (usec_t) s * USEC_PER_SEC;
6918 *_u += USEC_PER_DAY;
6924 static int shutdown_parse_argv(int argc, char *argv[]) {
6931 static const struct option options[] = {
6932 { "help", no_argument, NULL, ARG_HELP },
6933 { "halt", no_argument, NULL, 'H' },
6934 { "poweroff", no_argument, NULL, 'P' },
6935 { "reboot", no_argument, NULL, 'r' },
6936 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6937 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6946 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6954 arg_action = ACTION_HALT;
6958 arg_action = ACTION_POWEROFF;
6963 arg_action = ACTION_KEXEC;
6965 arg_action = ACTION_REBOOT;
6969 arg_action = ACTION_KEXEC;
6973 if (arg_action != ACTION_HALT)
6974 arg_action = ACTION_POWEROFF;
6987 /* Compatibility nops */
6991 arg_action = ACTION_CANCEL_SHUTDOWN;
6998 assert_not_reached("Unhandled option");
7001 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
7002 r = parse_time_spec(argv[optind], &arg_when);
7004 log_error("Failed to parse time specification: %s", argv[optind]);
7008 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
7010 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
7011 /* No time argument for shutdown cancel */
7012 arg_wall = argv + optind;
7013 else if (argc > optind + 1)
7014 /* We skip the time argument */
7015 arg_wall = argv + optind + 1;
7022 static int telinit_parse_argv(int argc, char *argv[]) {
7029 static const struct option options[] = {
7030 { "help", no_argument, NULL, ARG_HELP },
7031 { "no-wall", no_argument, NULL, ARG_NO_WALL },
7035 static const struct {
7039 { '0', ACTION_POWEROFF },
7040 { '6', ACTION_REBOOT },
7041 { '1', ACTION_RESCUE },
7042 { '2', ACTION_RUNLEVEL2 },
7043 { '3', ACTION_RUNLEVEL3 },
7044 { '4', ACTION_RUNLEVEL4 },
7045 { '5', ACTION_RUNLEVEL5 },
7046 { 's', ACTION_RESCUE },
7047 { 'S', ACTION_RESCUE },
7048 { 'q', ACTION_RELOAD },
7049 { 'Q', ACTION_RELOAD },
7050 { 'u', ACTION_REEXEC },
7051 { 'U', ACTION_REEXEC }
7060 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7075 assert_not_reached("Unhandled option");
7078 if (optind >= argc) {
7079 log_error("%s: required argument missing.",
7080 program_invocation_short_name);
7084 if (optind + 1 < argc) {
7085 log_error("Too many arguments.");
7089 if (strlen(argv[optind]) != 1) {
7090 log_error("Expected single character argument.");
7094 for (i = 0; i < ELEMENTSOF(table); i++)
7095 if (table[i].from == argv[optind][0])
7098 if (i >= ELEMENTSOF(table)) {
7099 log_error("Unknown command '%s'.", argv[optind]);
7103 arg_action = table[i].to;
7110 static int runlevel_parse_argv(int argc, char *argv[]) {
7116 static const struct option options[] = {
7117 { "help", no_argument, NULL, ARG_HELP },
7126 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
7137 assert_not_reached("Unhandled option");
7140 if (optind < argc) {
7141 log_error("Too many arguments.");
7148 static int parse_argv(int argc, char *argv[]) {
7152 if (program_invocation_short_name) {
7154 if (strstr(program_invocation_short_name, "halt")) {
7155 arg_action = ACTION_HALT;
7156 return halt_parse_argv(argc, argv);
7157 } else if (strstr(program_invocation_short_name, "poweroff")) {
7158 arg_action = ACTION_POWEROFF;
7159 return halt_parse_argv(argc, argv);
7160 } else if (strstr(program_invocation_short_name, "reboot")) {
7162 arg_action = ACTION_KEXEC;
7164 arg_action = ACTION_REBOOT;
7165 return halt_parse_argv(argc, argv);
7166 } else if (strstr(program_invocation_short_name, "shutdown")) {
7167 arg_action = ACTION_POWEROFF;
7168 return shutdown_parse_argv(argc, argv);
7169 } else if (strstr(program_invocation_short_name, "init")) {
7171 if (sd_booted() > 0) {
7172 arg_action = _ACTION_INVALID;
7173 return telinit_parse_argv(argc, argv);
7175 /* Hmm, so some other init system is
7176 * running, we need to forward this
7177 * request to it. For now we simply
7178 * guess that it is Upstart. */
7180 execv(TELINIT, argv);
7182 log_error("Couldn't find an alternative telinit implementation to spawn.");
7186 } else if (strstr(program_invocation_short_name, "runlevel")) {
7187 arg_action = ACTION_RUNLEVEL;
7188 return runlevel_parse_argv(argc, argv);
7192 arg_action = ACTION_SYSTEMCTL;
7193 return systemctl_parse_argv(argc, argv);
7196 _pure_ static int action_to_runlevel(void) {
7198 static const char table[_ACTION_MAX] = {
7199 [ACTION_HALT] = '0',
7200 [ACTION_POWEROFF] = '0',
7201 [ACTION_REBOOT] = '6',
7202 [ACTION_RUNLEVEL2] = '2',
7203 [ACTION_RUNLEVEL3] = '3',
7204 [ACTION_RUNLEVEL4] = '4',
7205 [ACTION_RUNLEVEL5] = '5',
7206 [ACTION_RESCUE] = '1'
7209 assert(arg_action < _ACTION_MAX);
7211 return table[arg_action];
7214 static int talk_initctl(void) {
7216 struct init_request request = {
7217 .magic = INIT_MAGIC,
7219 .cmd = INIT_CMD_RUNLVL
7222 _cleanup_close_ int fd = -1;
7226 rl = action_to_runlevel();
7230 request.runlevel = rl;
7232 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7234 if (errno == ENOENT)
7237 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7242 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
7244 log_error_errno(errno, "Failed to write to "INIT_FIFO": %m");
7245 return errno > 0 ? -errno : -EIO;
7251 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7253 static const struct {
7261 int (* const dispatch)(sd_bus *bus, char **args);
7267 { "list-units", MORE, 0, list_units },
7268 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7269 { "list-sockets", MORE, 1, list_sockets },
7270 { "list-timers", MORE, 1, list_timers },
7271 { "list-jobs", MORE, 1, list_jobs },
7272 { "list-machines", MORE, 1, list_machines },
7273 { "clear-jobs", EQUAL, 1, daemon_reload },
7274 { "cancel", MORE, 2, cancel_job },
7275 { "start", MORE, 2, start_unit },
7276 { "stop", MORE, 2, start_unit },
7277 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7278 { "reload", MORE, 2, start_unit },
7279 { "restart", MORE, 2, start_unit },
7280 { "try-restart", MORE, 2, start_unit },
7281 { "reload-or-restart", MORE, 2, start_unit },
7282 { "reload-or-try-restart", MORE, 2, start_unit },
7283 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7284 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7285 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7286 { "isolate", EQUAL, 2, start_unit },
7287 { "kill", MORE, 2, kill_unit },
7288 { "is-active", MORE, 2, check_unit_active },
7289 { "check", MORE, 2, check_unit_active },
7290 { "is-failed", MORE, 2, check_unit_failed },
7291 { "show", MORE, 1, show },
7292 { "cat", MORE, 2, cat },
7293 { "status", MORE, 1, show },
7294 { "help", MORE, 2, show },
7295 { "snapshot", LESS, 2, snapshot },
7296 { "delete", MORE, 2, delete_snapshot },
7297 { "daemon-reload", EQUAL, 1, daemon_reload },
7298 { "daemon-reexec", EQUAL, 1, daemon_reload },
7299 { "show-environment", EQUAL, 1, show_environment },
7300 { "set-environment", MORE, 2, set_environment },
7301 { "unset-environment", MORE, 2, set_environment },
7302 { "import-environment", MORE, 1, import_environment},
7303 { "halt", EQUAL, 1, start_special, FORCE },
7304 { "poweroff", EQUAL, 1, start_special, FORCE },
7305 { "reboot", EQUAL, 1, start_special, FORCE },
7306 { "kexec", EQUAL, 1, start_special },
7307 { "suspend", EQUAL, 1, start_special },
7308 { "hibernate", EQUAL, 1, start_special },
7309 { "hybrid-sleep", EQUAL, 1, start_special },
7310 { "default", EQUAL, 1, start_special },
7311 { "rescue", EQUAL, 1, start_special },
7312 { "emergency", EQUAL, 1, start_special },
7313 { "exit", EQUAL, 1, start_special },
7314 { "reset-failed", MORE, 1, reset_failed },
7315 { "enable", MORE, 2, enable_unit, NOBUS },
7316 { "disable", MORE, 2, enable_unit, NOBUS },
7317 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7318 { "reenable", MORE, 2, enable_unit, NOBUS },
7319 { "preset", MORE, 2, enable_unit, NOBUS },
7320 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7321 { "mask", MORE, 2, enable_unit, NOBUS },
7322 { "unmask", MORE, 2, enable_unit, NOBUS },
7323 { "link", MORE, 2, enable_unit, NOBUS },
7324 { "switch-root", MORE, 2, switch_root },
7325 { "list-dependencies", LESS, 2, list_dependencies },
7326 { "set-default", EQUAL, 2, set_default, NOBUS },
7327 { "get-default", EQUAL, 1, get_default, NOBUS },
7328 { "set-property", MORE, 3, set_property },
7329 { "is-system-running", EQUAL, 1, is_system_running },
7330 { "add-wants", MORE, 3, add_dependency, NOBUS },
7331 { "add-requires", MORE, 3, add_dependency, NOBUS },
7332 { "edit", MORE, 2, edit, NOBUS },
7341 left = argc - optind;
7343 /* Special rule: no arguments (left == 0) means "list-units" */
7345 if (streq(argv[optind], "help") && !argv[optind+1]) {
7346 log_error("This command expects one or more "
7347 "unit names. Did you mean --help?");
7351 for (; verb->verb; verb++)
7352 if (streq(argv[optind], verb->verb))
7355 log_error("Unknown operation '%s'.", argv[optind]);
7360 switch (verb->argc_cmp) {
7363 if (left != verb->argc) {
7364 log_error("Invalid number of arguments.");
7371 if (left < verb->argc) {
7372 log_error("Too few arguments.");
7379 if (left > verb->argc) {
7380 log_error("Too many arguments.");
7387 assert_not_reached("Unknown comparison operator.");
7390 /* Require a bus connection for all operations but
7392 if (verb->bus == NOBUS) {
7393 if (!bus && !avoid_bus()) {
7394 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7399 if (running_in_chroot() > 0) {
7400 log_info("Running in chroot, ignoring request.");
7404 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7405 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7410 return verb->dispatch(bus, argv + optind);
7413 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7415 struct sd_shutdown_command c = {
7422 union sockaddr_union sockaddr = {
7423 .un.sun_family = AF_UNIX,
7424 .un.sun_path = "/run/systemd/shutdownd",
7427 struct iovec iovec[2] = {{
7428 .iov_base = (char*) &c,
7429 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7432 struct msghdr msghdr = {
7433 .msg_name = &sockaddr,
7434 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7435 + strlen("/run/systemd/shutdownd"),
7440 _cleanup_close_ int fd;
7442 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7446 if (!isempty(message)) {
7447 iovec[1].iov_base = (char*) message;
7448 iovec[1].iov_len = strlen(message);
7449 msghdr.msg_iovlen++;
7452 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7458 static int reload_with_fallback(sd_bus *bus) {
7461 /* First, try systemd via D-Bus. */
7462 if (daemon_reload(bus, NULL) >= 0)
7466 /* Nothing else worked, so let's try signals */
7467 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7469 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7470 return log_error_errno(errno, "kill() failed: %m");
7475 static int start_with_fallback(sd_bus *bus) {
7478 /* First, try systemd via D-Bus. */
7479 if (start_unit(bus, NULL) >= 0)
7483 /* Nothing else worked, so let's try
7485 if (talk_initctl() > 0)
7488 log_error("Failed to talk to init daemon.");
7492 warn_wall(arg_action);
7496 static int halt_now(enum action a) {
7498 /* The kernel will automaticall flush ATA disks and suchlike
7499 * on reboot(), but the file systems need to be synce'd
7500 * explicitly in advance. */
7503 /* Make sure C-A-D is handled by the kernel from this point
7505 reboot(RB_ENABLE_CAD);
7510 log_info("Halting.");
7511 reboot(RB_HALT_SYSTEM);
7514 case ACTION_POWEROFF:
7515 log_info("Powering off.");
7516 reboot(RB_POWER_OFF);
7519 case ACTION_REBOOT: {
7520 _cleanup_free_ char *param = NULL;
7522 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7523 log_info("Rebooting with argument '%s'.", param);
7524 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7525 LINUX_REBOOT_CMD_RESTART2, param);
7528 log_info("Rebooting.");
7529 reboot(RB_AUTOBOOT);
7534 assert_not_reached("Unknown action.");
7538 static int halt_main(sd_bus *bus) {
7541 r = check_inhibitors(bus, arg_action);
7545 if (geteuid() != 0) {
7546 /* Try logind if we are a normal user and no special
7547 * mode applies. Maybe PolicyKit allows us to shutdown
7550 if (arg_when <= 0 &&
7553 (arg_action == ACTION_POWEROFF ||
7554 arg_action == ACTION_REBOOT)) {
7555 r = reboot_with_logind(bus, arg_action);
7560 log_error("Must be root.");
7565 _cleanup_free_ char *m;
7567 m = strv_join(arg_wall, " ");
7571 r = send_shutdownd(arg_when,
7572 arg_action == ACTION_HALT ? 'H' :
7573 arg_action == ACTION_POWEROFF ? 'P' :
7574 arg_action == ACTION_KEXEC ? 'K' :
7581 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7583 char date[FORMAT_TIMESTAMP_MAX];
7585 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7586 format_timestamp(date, sizeof(date), arg_when));
7591 if (!arg_dry && !arg_force)
7592 return start_with_fallback(bus);
7595 if (sd_booted() > 0)
7596 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7598 r = utmp_put_shutdown();
7600 log_warning_errno(r, "Failed to write utmp record: %m");
7607 r = halt_now(arg_action);
7608 log_error_errno(r, "Failed to reboot: %m");
7613 static int runlevel_main(void) {
7614 int r, runlevel, previous;
7616 r = utmp_get_runlevel(&runlevel, &previous);
7623 previous <= 0 ? 'N' : previous,
7624 runlevel <= 0 ? 'N' : runlevel);
7629 int main(int argc, char*argv[]) {
7630 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7633 setlocale(LC_ALL, "");
7634 log_parse_environment();
7637 /* Explicitly not on_tty() to avoid setting cached value.
7638 * This becomes relevant for piping output which might be
7640 original_stdout_is_tty = isatty(STDOUT_FILENO);
7642 r = parse_argv(argc, argv);
7646 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7647 * let's shortcut this */
7648 if (arg_action == ACTION_RUNLEVEL) {
7649 r = runlevel_main();
7653 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7654 log_info("Running in chroot, ignoring request.");
7660 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7662 /* systemctl_main() will print an error message for the bus
7663 * connection, but only if it needs to */
7665 switch (arg_action) {
7667 case ACTION_SYSTEMCTL:
7668 r = systemctl_main(bus, argc, argv, r);
7672 case ACTION_POWEROFF:
7678 case ACTION_RUNLEVEL2:
7679 case ACTION_RUNLEVEL3:
7680 case ACTION_RUNLEVEL4:
7681 case ACTION_RUNLEVEL5:
7683 case ACTION_EMERGENCY:
7684 case ACTION_DEFAULT:
7685 r = start_with_fallback(bus);
7690 r = reload_with_fallback(bus);
7693 case ACTION_CANCEL_SHUTDOWN: {
7694 _cleanup_free_ char *m = NULL;
7697 m = strv_join(arg_wall, " ");
7704 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7706 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7710 case ACTION_RUNLEVEL:
7711 case _ACTION_INVALID:
7713 assert_not_reached("Unknown action");
7718 ask_password_agent_close();
7719 polkit_agent_close();
7721 strv_free(arg_types);
7722 strv_free(arg_states);
7723 strv_free(arg_properties);
7725 return r < 0 ? EXIT_FAILURE : r;