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"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
76 static char **arg_types = NULL;
77 static char **arg_states = NULL;
78 static char **arg_properties = NULL;
79 static bool arg_all = false;
80 static enum dependency {
86 } arg_dependency = DEPENDENCY_FORWARD;
87 static const char *arg_job_mode = "replace";
88 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
89 static bool arg_no_block = false;
90 static bool arg_no_legend = false;
91 static bool arg_no_pager = false;
92 static bool arg_no_wtmp = false;
93 static bool arg_no_wall = false;
94 static bool arg_no_reload = false;
95 static bool arg_show_types = false;
96 static bool arg_ignore_inhibitors = false;
97 static bool arg_dry = false;
98 static bool arg_quiet = false;
99 static bool arg_full = false;
100 static bool arg_recursive = false;
101 static int arg_force = 0;
102 static bool arg_ask_password = true;
103 static bool arg_runtime = false;
104 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
105 static char **arg_wall = NULL;
106 static const char *arg_kill_who = NULL;
107 static int arg_signal = SIGTERM;
108 static const char *arg_root = NULL;
109 static usec_t arg_when = 0;
131 ACTION_CANCEL_SHUTDOWN,
133 } arg_action = ACTION_SYSTEMCTL;
134 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
135 static char *arg_host = NULL;
136 static unsigned arg_lines = 10;
137 static OutputMode arg_output = OUTPUT_SHORT;
138 static bool arg_plain = false;
140 static bool original_stdout_is_tty;
142 static int daemon_reload(sd_bus *bus, char **args);
143 static int halt_now(enum action a);
144 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
146 static char** strv_skip_first(char **strv) {
147 if (strv_length(strv) > 0)
152 static void pager_open_if_enabled(void) {
160 static void ask_password_agent_open_if_enabled(void) {
162 /* Open the password agent as a child process if necessary */
164 if (!arg_ask_password)
167 if (arg_scope != UNIT_FILE_SYSTEM)
170 if (arg_transport != BUS_TRANSPORT_LOCAL)
173 ask_password_agent_open();
177 static void polkit_agent_open_if_enabled(void) {
179 /* Open the polkit agent as a child process if necessary */
181 if (!arg_ask_password)
184 if (arg_scope != UNIT_FILE_SYSTEM)
187 if (arg_transport != BUS_TRANSPORT_LOCAL)
194 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
197 if (!sd_bus_error_is_set(error))
200 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
201 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
202 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
203 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
204 return EXIT_NOPERMISSION;
206 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
207 return EXIT_NOTINSTALLED;
209 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
210 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
211 return EXIT_NOTIMPLEMENTED;
213 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
214 return EXIT_NOTCONFIGURED;
222 static void warn_wall(enum action a) {
223 static const char *table[_ACTION_MAX] = {
224 [ACTION_HALT] = "The system is going down for system halt NOW!",
225 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
226 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
227 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
228 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
229 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
230 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
237 _cleanup_free_ char *p;
239 p = strv_join(arg_wall, " ");
246 utmp_wall(p, NULL, NULL);
254 utmp_wall(table[a], NULL, NULL);
257 static bool avoid_bus(void) {
259 if (running_in_chroot() > 0)
262 if (sd_booted() <= 0)
265 if (!isempty(arg_root))
268 if (arg_scope == UNIT_FILE_GLOBAL)
274 static int compare_unit_info(const void *a, const void *b) {
275 const UnitInfo *u = a, *v = b;
279 /* First, order by machine */
280 if (!u->machine && v->machine)
282 if (u->machine && !v->machine)
284 if (u->machine && v->machine) {
285 r = strcasecmp(u->machine, v->machine);
290 /* Second, order by unit type */
291 d1 = strrchr(u->id, '.');
292 d2 = strrchr(v->id, '.');
294 r = strcasecmp(d1, d2);
299 /* Third, order by name */
300 return strcasecmp(u->id, v->id);
303 static bool output_show_unit(const UnitInfo *u, char **patterns) {
304 if (!strv_isempty(patterns)) {
307 STRV_FOREACH(pattern, patterns)
308 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
317 dot = strrchr(u->id, '.');
321 if (!strv_find(arg_types, dot+1))
331 if (streq(u->active_state, "inactive") || u->following[0])
337 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
338 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
340 unsigned n_shown = 0;
343 max_id_len = strlen("UNIT");
344 load_len = strlen("LOAD");
345 active_len = strlen("ACTIVE");
346 sub_len = strlen("SUB");
347 job_len = strlen("JOB");
350 for (u = unit_infos; u < unit_infos + c; u++) {
351 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
352 load_len = MAX(load_len, strlen(u->load_state));
353 active_len = MAX(active_len, strlen(u->active_state));
354 sub_len = MAX(sub_len, strlen(u->sub_state));
356 if (u->job_id != 0) {
357 job_len = MAX(job_len, strlen(u->job_type));
361 if (!arg_no_legend &&
362 (streq(u->active_state, "failed") ||
363 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
367 if (!arg_full && original_stdout_is_tty) {
370 id_len = MIN(max_id_len, 25u);
371 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
374 basic_len += job_len + 1;
376 if (basic_len < (unsigned) columns()) {
377 unsigned extra_len, incr;
378 extra_len = columns() - basic_len;
380 /* Either UNIT already got 25, or is fully satisfied.
381 * Grant up to 25 to DESC now. */
382 incr = MIN(extra_len, 25u);
386 /* split the remaining space between UNIT and DESC,
387 * but do not give UNIT more than it needs. */
389 incr = MIN(extra_len / 2, max_id_len - id_len);
391 desc_len += extra_len - incr;
397 for (u = unit_infos; u < unit_infos + c; u++) {
398 _cleanup_free_ char *e = NULL, *j = NULL;
399 const char *on_loaded = "", *off_loaded = "";
400 const char *on_active = "", *off_active = "";
401 const char *on_circle = "", *off_circle = "";
405 if (!n_shown && !arg_no_legend) {
410 printf("%-*s %-*s %-*s %-*s ",
413 active_len, "ACTIVE",
417 printf("%-*s ", job_len, "JOB");
419 if (!arg_full && arg_no_pager)
420 printf("%.*s\n", desc_len, "DESCRIPTION");
422 printf("%s\n", "DESCRIPTION");
427 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
428 on_loaded = ansi_highlight_red();
429 on_circle = ansi_highlight_yellow();
430 off_loaded = off_circle = ansi_highlight_off();
434 if (streq(u->active_state, "failed")) {
435 on_circle = on_active = ansi_highlight_red();
436 off_circle = off_active = ansi_highlight_off();
441 j = strjoin(u->machine, ":", u->id, NULL);
450 e = ellipsize(id, id_len, 33);
458 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
460 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
461 on_active, id_len, id, off_active,
462 on_loaded, load_len, u->load_state, off_loaded,
463 on_active, active_len, u->active_state,
464 sub_len, u->sub_state, off_active,
465 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
468 printf("%.*s\n", desc_len, u->description);
470 printf("%s\n", u->description);
473 if (!arg_no_legend) {
474 const char *on, *off;
478 "LOAD = Reflects whether the unit definition was properly loaded.\n"
479 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
480 "SUB = The low-level unit activation state, values depend on unit type.");
481 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
482 on = ansi_highlight();
483 off = ansi_highlight_off();
485 on = ansi_highlight_red();
486 off = ansi_highlight_off();
490 printf("%s%u loaded units listed.%s\n"
491 "To show all installed unit files use 'systemctl list-unit-files'.\n",
494 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
495 "To show all installed unit files use 'systemctl list-unit-files'.\n",
502 static int get_unit_list(
506 UnitInfo **unit_infos,
508 sd_bus_message **_reply) {
510 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
511 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
521 r = sd_bus_message_new_method_call(
524 "org.freedesktop.systemd1",
525 "/org/freedesktop/systemd1",
526 "org.freedesktop.systemd1.Manager",
527 "ListUnitsFiltered");
530 return bus_log_create_error(r);
532 r = sd_bus_message_append_strv(m, arg_states);
534 return bus_log_create_error(r);
536 r = sd_bus_call(bus, m, 0, &error, &reply);
538 log_error("Failed to list units: %s", bus_error_message(&error, r));
542 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
544 return bus_log_parse_error(r);
546 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
549 if (!output_show_unit(&u, patterns))
552 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
555 (*unit_infos)[c++] = u;
558 return bus_log_parse_error(r);
560 r = sd_bus_message_exit_container(reply);
562 return bus_log_parse_error(r);
570 static void message_set_freep(Set **set) {
573 while ((m = set_steal_first(*set)))
574 sd_bus_message_unref(m);
579 static int get_unit_list_recursive(
582 UnitInfo **_unit_infos,
586 _cleanup_free_ UnitInfo *unit_infos = NULL;
587 _cleanup_(message_set_freep) Set *replies;
588 sd_bus_message *reply;
596 replies = set_new(NULL);
600 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
604 r = set_put(replies, reply);
606 sd_bus_message_unref(reply);
611 _cleanup_strv_free_ char **machines = NULL;
614 r = sd_get_machine_names(&machines);
618 STRV_FOREACH(i, machines) {
619 _cleanup_bus_close_unref_ sd_bus *container = NULL;
622 r = sd_bus_open_system_container(&container, *i);
624 log_error("Failed to connect to container %s: %s", *i, strerror(-r));
628 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
634 r = set_put(replies, reply);
636 sd_bus_message_unref(reply);
641 *_machines = machines;
646 *_unit_infos = unit_infos;
655 static int list_units(sd_bus *bus, char **args) {
656 _cleanup_free_ UnitInfo *unit_infos = NULL;
657 _cleanup_(message_set_freep) Set *replies = NULL;
658 _cleanup_strv_free_ char **machines = NULL;
661 pager_open_if_enabled();
663 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
667 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
668 return output_units_list(unit_infos, r);
671 static int get_triggered_units(
676 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
679 r = sd_bus_get_property_strv(
681 "org.freedesktop.systemd1",
683 "org.freedesktop.systemd1.Unit",
689 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
694 static int get_listening(
696 const char* unit_path,
699 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
700 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
701 const char *type, *path;
704 r = sd_bus_get_property(
706 "org.freedesktop.systemd1",
708 "org.freedesktop.systemd1.Socket",
714 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
718 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
720 return bus_log_parse_error(r);
722 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
724 r = strv_extend(listening, type);
728 r = strv_extend(listening, path);
735 return bus_log_parse_error(r);
737 r = sd_bus_message_exit_container(reply);
739 return bus_log_parse_error(r);
751 /* Note: triggered is a list here, although it almost certainly
752 * will always be one unit. Nevertheless, dbus API allows for multiple
753 * values, so let's follow that.*/
756 /* The strv above is shared. free is set only in the first one. */
760 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
766 if (!a->machine && b->machine)
768 if (a->machine && !b->machine)
770 if (a->machine && b->machine) {
771 o = strcasecmp(a->machine, b->machine);
776 o = strcmp(a->path, b->path);
778 o = strcmp(a->type, b->type);
783 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
784 struct socket_info *s;
785 unsigned pathlen = strlen("LISTEN"),
786 typelen = strlen("TYPE") * arg_show_types,
787 socklen = strlen("UNIT"),
788 servlen = strlen("ACTIVATES");
789 const char *on, *off;
791 for (s = socket_infos; s < socket_infos + cs; s++) {
795 socklen = MAX(socklen, strlen(s->id));
797 typelen = MAX(typelen, strlen(s->type));
798 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
800 STRV_FOREACH(a, s->triggered)
801 tmp += strlen(*a) + 2*(a != s->triggered);
802 servlen = MAX(servlen, tmp);
807 printf("%-*s %-*.*s%-*s %s\n",
809 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
813 for (s = socket_infos; s < socket_infos + cs; s++) {
814 _cleanup_free_ char *j = NULL;
819 j = strjoin(s->machine, ":", s->path, NULL);
827 printf("%-*s %-*s %-*s",
828 pathlen, path, typelen, s->type, socklen, s->id);
831 pathlen, path, socklen, s->id);
832 STRV_FOREACH(a, s->triggered)
834 a == s->triggered ? "" : ",", *a);
838 on = ansi_highlight();
839 off = ansi_highlight_off();
843 on = ansi_highlight_red();
844 off = ansi_highlight_off();
847 if (!arg_no_legend) {
848 printf("%s%u sockets listed.%s\n", on, cs, off);
850 printf("Pass --all to see loaded but inactive sockets, too.\n");
856 static int list_sockets(sd_bus *bus, char **args) {
857 _cleanup_(message_set_freep) Set *replies = NULL;
858 _cleanup_strv_free_ char **machines = NULL;
859 _cleanup_free_ UnitInfo *unit_infos = NULL;
860 _cleanup_free_ struct socket_info *socket_infos = NULL;
862 struct socket_info *s;
867 pager_open_if_enabled();
869 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
873 for (u = unit_infos; u < unit_infos + n; u++) {
874 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
877 if (!endswith(u->id, ".socket"))
880 r = get_triggered_units(bus, u->unit_path, &triggered);
884 c = get_listening(bus, u->unit_path, &listening);
890 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
895 for (i = 0; i < c; i++)
896 socket_infos[cs + i] = (struct socket_info) {
897 .machine = u->machine,
899 .type = listening[i*2],
900 .path = listening[i*2 + 1],
901 .triggered = triggered,
902 .own_triggered = i==0,
905 /* from this point on we will cleanup those socket_infos */
908 listening = triggered = NULL; /* avoid cleanup */
911 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
912 (__compar_fn_t) socket_info_compare);
914 output_sockets_list(socket_infos, cs);
917 assert(cs == 0 || socket_infos);
918 for (s = socket_infos; s < socket_infos + cs; s++) {
921 if (s->own_triggered)
922 strv_free(s->triggered);
928 static int get_next_elapse(
931 dual_timestamp *next) {
933 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
941 r = sd_bus_get_property_trivial(
943 "org.freedesktop.systemd1",
945 "org.freedesktop.systemd1.Timer",
946 "NextElapseUSecMonotonic",
951 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
955 r = sd_bus_get_property_trivial(
957 "org.freedesktop.systemd1",
959 "org.freedesktop.systemd1.Timer",
960 "NextElapseUSecRealtime",
965 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
973 static int get_last_trigger(
978 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
985 r = sd_bus_get_property_trivial(
987 "org.freedesktop.systemd1",
989 "org.freedesktop.systemd1.Timer",
995 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1003 const char* machine;
1006 usec_t last_trigger;
1010 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1016 if (!a->machine && b->machine)
1018 if (a->machine && !b->machine)
1020 if (a->machine && b->machine) {
1021 o = strcasecmp(a->machine, b->machine);
1026 if (a->next_elapse < b->next_elapse)
1028 if (a->next_elapse > b->next_elapse)
1031 return strcmp(a->id, b->id);
1034 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1035 struct timer_info *t;
1037 nextlen = strlen("NEXT"),
1038 leftlen = strlen("LEFT"),
1039 lastlen = strlen("LAST"),
1040 passedlen = strlen("PASSED"),
1041 unitlen = strlen("UNIT"),
1042 activatelen = strlen("ACTIVATES");
1044 const char *on, *off;
1046 assert(timer_infos || n == 0);
1048 for (t = timer_infos; t < timer_infos + n; t++) {
1052 if (t->next_elapse > 0) {
1053 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1055 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1056 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1058 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1059 leftlen = MAX(leftlen, strlen(trel));
1062 if (t->last_trigger > 0) {
1063 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1065 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1066 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1068 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1069 passedlen = MAX(passedlen, strlen(trel));
1072 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1074 STRV_FOREACH(a, t->triggered)
1075 ul += strlen(*a) + 2*(a != t->triggered);
1077 activatelen = MAX(activatelen, ul);
1082 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1086 passedlen, "PASSED",
1090 for (t = timer_infos; t < timer_infos + n; t++) {
1091 _cleanup_free_ char *j = NULL;
1093 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1094 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1097 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1098 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1100 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1101 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1104 j = strjoin(t->machine, ":", t->id, NULL);
1111 printf("%-*s %-*s %-*s %-*s %-*s",
1112 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1114 STRV_FOREACH(a, t->triggered)
1116 a == t->triggered ? "" : ",", *a);
1120 on = ansi_highlight();
1121 off = ansi_highlight_off();
1125 on = ansi_highlight_red();
1126 off = ansi_highlight_off();
1129 if (!arg_no_legend) {
1130 printf("%s%u timers listed.%s\n", on, n, off);
1132 printf("Pass --all to see loaded but inactive timers, too.\n");
1138 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1144 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1147 if (next->monotonic > nw->monotonic)
1148 converted = nw->realtime + (next->monotonic - nw->monotonic);
1150 converted = nw->realtime - (nw->monotonic - next->monotonic);
1152 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1153 next_elapse = MIN(converted, next->realtime);
1155 next_elapse = converted;
1158 next_elapse = next->realtime;
1163 static int list_timers(sd_bus *bus, char **args) {
1164 _cleanup_(message_set_freep) Set *replies = NULL;
1165 _cleanup_strv_free_ char **machines = NULL;
1166 _cleanup_free_ struct timer_info *timer_infos = NULL;
1167 _cleanup_free_ UnitInfo *unit_infos = NULL;
1168 struct timer_info *t;
1175 pager_open_if_enabled();
1177 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1181 dual_timestamp_get(&nw);
1183 for (u = unit_infos; u < unit_infos + n; u++) {
1184 _cleanup_strv_free_ char **triggered = NULL;
1185 dual_timestamp next = {};
1188 if (!endswith(u->id, ".timer"))
1191 r = get_triggered_units(bus, u->unit_path, &triggered);
1195 r = get_next_elapse(bus, u->unit_path, &next);
1199 get_last_trigger(bus, u->unit_path, &last);
1201 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1206 m = calc_next_elapse(&nw, &next);
1208 timer_infos[c++] = (struct timer_info) {
1209 .machine = u->machine,
1212 .last_trigger = last,
1213 .triggered = triggered,
1216 triggered = NULL; /* avoid cleanup */
1219 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1220 (__compar_fn_t) timer_info_compare);
1222 output_timers_list(timer_infos, c);
1225 for (t = timer_infos; t < timer_infos + c; t++)
1226 strv_free(t->triggered);
1231 static int compare_unit_file_list(const void *a, const void *b) {
1232 const char *d1, *d2;
1233 const UnitFileList *u = a, *v = b;
1235 d1 = strrchr(u->path, '.');
1236 d2 = strrchr(v->path, '.');
1241 r = strcasecmp(d1, d2);
1246 return strcasecmp(basename(u->path), basename(v->path));
1249 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1250 if (!strv_isempty(patterns)) {
1253 STRV_FOREACH(pattern, patterns)
1254 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1260 if (!strv_isempty(arg_types)) {
1263 dot = strrchr(u->path, '.');
1267 if (!strv_find(arg_types, dot+1))
1274 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1275 unsigned max_id_len, id_cols, state_cols;
1276 const UnitFileList *u;
1278 max_id_len = strlen("UNIT FILE");
1279 state_cols = strlen("STATE");
1281 for (u = units; u < units + c; u++) {
1282 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1283 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1287 unsigned basic_cols;
1289 id_cols = MIN(max_id_len, 25u);
1290 basic_cols = 1 + id_cols + state_cols;
1291 if (basic_cols < (unsigned) columns())
1292 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1294 id_cols = max_id_len;
1297 printf("%-*s %-*s\n",
1298 id_cols, "UNIT FILE",
1299 state_cols, "STATE");
1301 for (u = units; u < units + c; u++) {
1302 _cleanup_free_ char *e = NULL;
1303 const char *on, *off;
1306 if (u->state == UNIT_FILE_MASKED ||
1307 u->state == UNIT_FILE_MASKED_RUNTIME ||
1308 u->state == UNIT_FILE_DISABLED ||
1309 u->state == UNIT_FILE_INVALID) {
1310 on = ansi_highlight_red();
1311 off = ansi_highlight_off();
1312 } else if (u->state == UNIT_FILE_ENABLED) {
1313 on = ansi_highlight_green();
1314 off = ansi_highlight_off();
1318 id = basename(u->path);
1320 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1322 printf("%-*s %s%-*s%s\n",
1323 id_cols, e ? e : id,
1324 on, state_cols, unit_file_state_to_string(u->state), off);
1328 printf("\n%u unit files listed.\n", c);
1331 static int list_unit_files(sd_bus *bus, char **args) {
1332 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1333 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1334 _cleanup_free_ UnitFileList *units = NULL;
1342 pager_open_if_enabled();
1350 h = hashmap_new(&string_hash_ops);
1354 r = unit_file_get_list(arg_scope, arg_root, h);
1356 unit_file_list_free(h);
1357 log_error("Failed to get unit file list: %s", strerror(-r));
1361 n_units = hashmap_size(h);
1363 units = new(UnitFileList, n_units);
1364 if (!units && n_units > 0) {
1365 unit_file_list_free(h);
1369 HASHMAP_FOREACH(u, h, i) {
1370 if (!output_show_unit_file(u, strv_skip_first(args)))
1377 assert(c <= n_units);
1380 r = sd_bus_call_method(
1382 "org.freedesktop.systemd1",
1383 "/org/freedesktop/systemd1",
1384 "org.freedesktop.systemd1.Manager",
1390 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1394 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1396 return bus_log_parse_error(r);
1398 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1400 if (!GREEDY_REALLOC(units, size, c + 1))
1403 units[c] = (struct UnitFileList) {
1405 unit_file_state_from_string(state)
1408 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1413 return bus_log_parse_error(r);
1415 r = sd_bus_message_exit_container(reply);
1417 return bus_log_parse_error(r);
1420 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1421 output_unit_file_list(units, c);
1424 for (unit = units; unit < units + c; unit++)
1431 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1432 _cleanup_free_ char *n = NULL;
1433 size_t max_len = MAX(columns(),20u);
1439 for (i = level - 1; i >= 0; i--) {
1441 if (len > max_len - 3 && !arg_full) {
1442 printf("%s...\n",max_len % 2 ? "" : " ");
1445 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1449 if (len > max_len - 3 && !arg_full) {
1450 printf("%s...\n",max_len % 2 ? "" : " ");
1454 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1458 printf("%s\n", name);
1462 n = ellipsize(name, max_len-len, 100);
1470 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1472 static const char *dependencies[_DEPENDENCY_MAX] = {
1473 [DEPENDENCY_FORWARD] = "Requires\0"
1474 "RequiresOverridable\0"
1476 "RequisiteOverridable\0"
1478 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1479 "RequiredByOverridable\0"
1482 [DEPENDENCY_AFTER] = "After\0",
1483 [DEPENDENCY_BEFORE] = "Before\0",
1486 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1487 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1488 _cleanup_strv_free_ char **ret = NULL;
1489 _cleanup_free_ char *path = NULL;
1495 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1497 path = unit_dbus_path_from_name(name);
1501 r = sd_bus_call_method(
1503 "org.freedesktop.systemd1",
1505 "org.freedesktop.DBus.Properties",
1509 "s", "org.freedesktop.systemd1.Unit");
1511 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1515 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1517 return bus_log_parse_error(r);
1519 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1522 r = sd_bus_message_read(reply, "s", &prop);
1524 return bus_log_parse_error(r);
1526 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1527 r = sd_bus_message_skip(reply, "v");
1529 return bus_log_parse_error(r);
1532 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1534 return bus_log_parse_error(r);
1536 r = bus_message_read_strv_extend(reply, &ret);
1538 return bus_log_parse_error(r);
1540 r = sd_bus_message_exit_container(reply);
1542 return bus_log_parse_error(r);
1545 r = sd_bus_message_exit_container(reply);
1547 return bus_log_parse_error(r);
1551 return bus_log_parse_error(r);
1553 r = sd_bus_message_exit_container(reply);
1555 return bus_log_parse_error(r);
1563 static int list_dependencies_compare(const void *_a, const void *_b) {
1564 const char **a = (const char**) _a, **b = (const char**) _b;
1566 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1568 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1571 return strcasecmp(*a, *b);
1574 static int list_dependencies_one(
1579 unsigned int branches) {
1581 _cleanup_strv_free_ char **deps = NULL;
1589 r = strv_extend(units, name);
1593 r = list_dependencies_get_dependencies(bus, name, &deps);
1597 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1599 STRV_FOREACH(c, deps) {
1602 if (strv_contains(*units, *c)) {
1604 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1611 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1613 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1615 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1617 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1621 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1622 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1629 strv_remove(*units, name);
1634 static int list_dependencies(sd_bus *bus, char **args) {
1635 _cleanup_strv_free_ char **units = NULL;
1636 _cleanup_free_ char *unit = NULL;
1642 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1647 u = SPECIAL_DEFAULT_TARGET;
1649 pager_open_if_enabled();
1653 return list_dependencies_one(bus, u, 0, &units, 0);
1656 struct machine_info {
1660 char *control_group;
1661 uint32_t n_failed_units;
1666 static const struct bus_properties_map machine_info_property_map[] = {
1667 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1668 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1669 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1670 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1671 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1675 static void free_machines_list(struct machine_info *machine_infos, int n) {
1681 for (i = 0; i < n; i++) {
1682 free(machine_infos[i].name);
1683 free(machine_infos[i].state);
1684 free(machine_infos[i].control_group);
1687 free(machine_infos);
1690 static int compare_machine_info(const void *a, const void *b) {
1691 const struct machine_info *u = a, *v = b;
1693 if (u->is_host != v->is_host)
1694 return u->is_host > v->is_host ? -1 : 1;
1696 return strcasecmp(u->name, v->name);
1699 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1700 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1706 r = sd_bus_open_system_container(&container, mi->name);
1713 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1720 static bool output_show_machine(const char *name, char **patterns) {
1725 if (strv_isempty(patterns))
1728 STRV_FOREACH(i, patterns)
1729 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1735 static int get_machine_list(
1737 struct machine_info **_machine_infos,
1740 struct machine_info *machine_infos = NULL;
1741 _cleanup_strv_free_ char **m = NULL;
1742 _cleanup_free_ char *hn = NULL;
1747 hn = gethostname_malloc();
1751 if (output_show_machine(hn, patterns)) {
1752 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1755 machine_infos[c].is_host = true;
1756 machine_infos[c].name = hn;
1759 get_machine_properties(bus, &machine_infos[c]);
1763 sd_get_machine_names(&m);
1764 STRV_FOREACH(i, m) {
1765 _cleanup_free_ char *class = NULL;
1767 if (!output_show_machine(*i, patterns))
1770 sd_machine_get_class(*i, &class);
1771 if (!streq_ptr(class, "container"))
1774 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1775 free_machines_list(machine_infos, c);
1779 machine_infos[c].is_host = false;
1780 machine_infos[c].name = strdup(*i);
1781 if (!machine_infos[c].name) {
1782 free_machines_list(machine_infos, c);
1786 get_machine_properties(NULL, &machine_infos[c]);
1790 *_machine_infos = machine_infos;
1794 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1795 struct machine_info *m;
1798 namelen = sizeof("NAME") - 1,
1799 statelen = sizeof("STATE") - 1,
1800 failedlen = sizeof("FAILED") - 1,
1801 jobslen = sizeof("JOBS") - 1;
1803 assert(machine_infos || n == 0);
1805 for (m = machine_infos; m < machine_infos + n; m++) {
1806 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1807 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1808 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1809 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1811 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1815 if (!arg_no_legend) {
1819 printf("%-*s %-*s %-*s %-*s\n",
1822 failedlen, "FAILED",
1826 for (m = machine_infos; m < machine_infos + n; m++) {
1827 const char *on_state = "", *off_state = "";
1828 const char *on_failed = "", *off_failed = "";
1829 bool circle = false;
1831 if (streq_ptr(m->state, "degraded")) {
1832 on_state = ansi_highlight_red();
1833 off_state = ansi_highlight_off();
1835 } else if (!streq_ptr(m->state, "running")) {
1836 on_state = ansi_highlight_yellow();
1837 off_state = ansi_highlight_off();
1841 if (m->n_failed_units > 0) {
1842 on_failed = ansi_highlight_red();
1843 off_failed = ansi_highlight_off();
1845 on_failed = off_failed = "";
1848 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1851 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1852 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1853 on_state, statelen, strna(m->state), off_state,
1854 on_failed, failedlen, m->n_failed_units, off_failed,
1855 jobslen, m->n_jobs);
1857 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1858 namelen, strna(m->name),
1859 on_state, statelen, strna(m->state), off_state,
1860 on_failed, failedlen, m->n_failed_units, off_failed,
1861 jobslen, m->n_jobs);
1865 printf("\n%u machines listed.\n", n);
1868 static int list_machines(sd_bus *bus, char **args) {
1869 struct machine_info *machine_infos = NULL;
1874 if (geteuid() != 0) {
1875 log_error("Must be root.");
1879 pager_open_if_enabled();
1881 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1885 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1886 output_machines_list(machine_infos, r);
1887 free_machines_list(machine_infos, r);
1892 static int get_default(sd_bus *bus, char **args) {
1893 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1894 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1895 _cleanup_free_ char *_path = NULL;
1899 if (!bus || avoid_bus()) {
1900 r = unit_file_get_default(arg_scope, arg_root, &_path);
1902 log_error("Failed to get default target: %s", strerror(-r));
1908 r = sd_bus_call_method(
1910 "org.freedesktop.systemd1",
1911 "/org/freedesktop/systemd1",
1912 "org.freedesktop.systemd1.Manager",
1918 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1922 r = sd_bus_message_read(reply, "s", &path);
1924 return bus_log_parse_error(r);
1928 printf("%s\n", path);
1933 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1936 assert(changes || n_changes == 0);
1938 for (i = 0; i < n_changes; i++) {
1939 if (changes[i].type == UNIT_FILE_SYMLINK)
1940 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1942 log_info("Removed symlink %s.", changes[i].path);
1946 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1947 const char *type, *path, *source;
1950 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1952 return bus_log_parse_error(r);
1954 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1956 if (streq(type, "symlink"))
1957 log_info("Created symlink from %s to %s.", path, source);
1959 log_info("Removed symlink %s.", path);
1963 return bus_log_parse_error(r);
1965 r = sd_bus_message_exit_container(m);
1967 return bus_log_parse_error(r);
1972 static int set_default(sd_bus *bus, char **args) {
1973 _cleanup_free_ char *unit = NULL;
1974 UnitFileChange *changes = NULL;
1975 unsigned n_changes = 0;
1978 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1982 if (!bus || avoid_bus()) {
1983 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1985 log_error("Failed to set default target: %s", strerror(-r));
1990 dump_unit_file_changes(changes, n_changes);
1994 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1995 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1997 r = sd_bus_message_new_method_call(
2000 "org.freedesktop.systemd1",
2001 "/org/freedesktop/systemd1",
2002 "org.freedesktop.systemd1.Manager",
2003 "SetDefaultTarget");
2005 return bus_log_create_error(r);
2007 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2009 return bus_log_create_error(r);
2011 r = sd_bus_message_append(m, "sb", unit, 1);
2013 return bus_log_create_error(r);
2015 r = sd_bus_call(bus, m, 0, &error, &reply);
2017 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2021 r = deserialize_and_dump_unit_file_changes(reply);
2025 /* Try to reload if enabled */
2027 r = daemon_reload(bus, args);
2032 unit_file_changes_free(changes, n_changes);
2039 const char *name, *type, *state;
2042 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2043 unsigned id_len, unit_len, type_len, state_len;
2044 const struct job_info *j;
2045 const char *on, *off;
2046 bool shorten = false;
2048 assert(n == 0 || jobs);
2051 on = ansi_highlight_green();
2052 off = ansi_highlight_off();
2054 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2058 pager_open_if_enabled();
2060 id_len = strlen("JOB");
2061 unit_len = strlen("UNIT");
2062 type_len = strlen("TYPE");
2063 state_len = strlen("STATE");
2065 for (j = jobs; j < jobs + n; j++) {
2066 uint32_t id = j->id;
2067 assert(j->name && j->type && j->state);
2069 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2070 unit_len = MAX(unit_len, strlen(j->name));
2071 type_len = MAX(type_len, strlen(j->type));
2072 state_len = MAX(state_len, strlen(j->state));
2075 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2076 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2081 printf("%*s %-*s %-*s %-*s\n",
2085 state_len, "STATE");
2087 for (j = jobs; j < jobs + n; j++) {
2088 _cleanup_free_ char *e = NULL;
2090 if (streq(j->state, "running")) {
2091 on = ansi_highlight();
2092 off = ansi_highlight_off();
2096 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2097 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2099 on, unit_len, e ? e : j->name, off,
2101 on, state_len, j->state, off);
2104 if (!arg_no_legend) {
2105 on = ansi_highlight();
2106 off = ansi_highlight_off();
2108 printf("\n%s%u jobs listed%s.\n", on, n, off);
2112 static bool output_show_job(struct job_info *job, char **patterns) {
2117 if (strv_isempty(patterns))
2120 STRV_FOREACH(pattern, patterns)
2121 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2126 static int list_jobs(sd_bus *bus, char **args) {
2127 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2128 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2129 const char *name, *type, *state, *job_path, *unit_path;
2130 _cleanup_free_ struct job_info *jobs = NULL;
2135 bool skipped = false;
2137 r = sd_bus_call_method(
2139 "org.freedesktop.systemd1",
2140 "/org/freedesktop/systemd1",
2141 "org.freedesktop.systemd1.Manager",
2147 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2151 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2153 return bus_log_parse_error(r);
2155 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2156 struct job_info job = { id, name, type, state };
2158 if (!output_show_job(&job, strv_skip_first(args))) {
2163 if (!GREEDY_REALLOC(jobs, size, c + 1))
2169 return bus_log_parse_error(r);
2171 r = sd_bus_message_exit_container(reply);
2173 return bus_log_parse_error(r);
2175 output_jobs_list(jobs, c, skipped);
2179 static int cancel_job(sd_bus *bus, char **args) {
2180 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2186 if (strv_length(args) <= 1)
2187 return daemon_reload(bus, args);
2189 STRV_FOREACH(name, args+1) {
2190 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2194 q = safe_atou32(*name, &id);
2196 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-q));
2200 q = sd_bus_message_new_method_call(
2203 "org.freedesktop.systemd1",
2204 "/org/freedesktop/systemd1",
2205 "org.freedesktop.systemd1.Manager",
2208 return bus_log_create_error(q);
2210 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2212 return bus_log_create_error(1);
2214 q = sd_bus_message_append(m, "u", id);
2216 return bus_log_create_error(q);
2218 q = sd_bus_call(bus, m, 0, &error, NULL);
2220 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2229 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2230 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2234 /* We ignore all errors here, since this is used to show a
2237 /* We don't use unit_dbus_path_from_name() directly since we
2238 * don't want to load the unit if it isn't loaded. */
2240 r = sd_bus_call_method(
2242 "org.freedesktop.systemd1",
2243 "/org/freedesktop/systemd1",
2244 "org.freedesktop.systemd1.Manager",
2252 r = sd_bus_message_read(reply, "o", &path);
2256 r = sd_bus_get_property_trivial(
2258 "org.freedesktop.systemd1",
2260 "org.freedesktop.systemd1.Unit",
2270 typedef struct WaitData {
2277 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2284 log_debug("Got D-Bus request: %s.%s() on %s",
2285 sd_bus_message_get_interface(m),
2286 sd_bus_message_get_member(m),
2287 sd_bus_message_get_path(m));
2289 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2290 log_error("Warning! D-Bus connection terminated.");
2292 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2294 const char *path, *result, *unit;
2298 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2300 ret = set_remove(d->set, (char*) path);
2306 if (!isempty(result))
2307 d->result = strdup(result);
2310 d->name = strdup(unit);
2315 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2317 ret = set_remove(d->set, (char*) path);
2324 d->result = strdup(result);
2330 bus_log_parse_error(r);
2336 static int enable_wait_for_jobs(sd_bus *bus) {
2341 r = sd_bus_add_match(
2345 "sender='org.freedesktop.systemd1',"
2346 "interface='org.freedesktop.systemd1.Manager',"
2347 "member='JobRemoved',"
2348 "path='/org/freedesktop/systemd1'",
2351 log_error("Failed to add match");
2355 /* This is slightly dirty, since we don't undo the match registrations. */
2359 static int bus_process_wait(sd_bus *bus) {
2363 r = sd_bus_process(bus, NULL);
2368 r = sd_bus_wait(bus, (uint64_t) -1);
2374 static int check_wait_response(WaitData *d) {
2380 if (streq(d->result, "timeout"))
2381 log_error("Job for %s timed out.", strna(d->name));
2382 else if (streq(d->result, "canceled"))
2383 log_error("Job for %s canceled.", strna(d->name));
2384 else if (streq(d->result, "dependency"))
2385 log_error("A dependency job for %s failed. See 'journalctl -xe' for details.", strna(d->name));
2386 else if (!streq(d->result, "done") && !streq(d->result, "skipped")) {
2390 quotes = chars_intersect(d->name, SHELL_NEED_QUOTES);
2392 log_error("Job for %s failed. See \"systemctl status %s%s%s\" and \"journalctl -xe\" for details.",
2394 quotes ? "'" : "", d->name, quotes ? "'" : "");
2396 log_error("Job failed. See \"journalctl -xe\" for details.");
2400 if (streq(d->result, "timeout"))
2402 else if (streq(d->result, "canceled"))
2404 else if (streq(d->result, "dependency"))
2406 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2412 static int wait_for_jobs(sd_bus *bus, Set *s) {
2413 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2414 WaitData d = { .set = s };
2420 q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2424 while (!set_isempty(s)) {
2425 q = bus_process_wait(bus);
2427 log_error("Failed to wait for response: %s", strerror(-q));
2432 q = check_wait_response(&d);
2433 /* Return the first error as it is most likely to be
2435 if (q < 0 && r == 0)
2437 log_debug("Got result %s/%s for job %s",
2438 strna(d.result), strerror(-q), strna(d.name));
2451 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2452 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2453 _cleanup_free_ char *n = NULL, *state = NULL;
2459 n = unit_name_mangle(name, MANGLE_NOGLOB);
2463 /* We don't use unit_dbus_path_from_name() directly since we
2464 * don't want to load the unit if it isn't loaded. */
2466 r = sd_bus_call_method(
2468 "org.freedesktop.systemd1",
2469 "/org/freedesktop/systemd1",
2470 "org.freedesktop.systemd1.Manager",
2481 r = sd_bus_message_read(reply, "o", &path);
2483 return bus_log_parse_error(r);
2485 r = sd_bus_get_property_string(
2487 "org.freedesktop.systemd1",
2489 "org.freedesktop.systemd1.Unit",
2502 return nulstr_contains(good_states, state);
2505 static int check_triggering_units(
2509 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2510 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2511 _cleanup_strv_free_ char **triggered_by = NULL;
2512 bool print_warning_label = true;
2516 n = unit_name_mangle(name, MANGLE_NOGLOB);
2520 path = unit_dbus_path_from_name(n);
2524 r = sd_bus_get_property_string(
2526 "org.freedesktop.systemd1",
2528 "org.freedesktop.systemd1.Unit",
2533 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2537 if (streq(state, "masked"))
2540 r = sd_bus_get_property_strv(
2542 "org.freedesktop.systemd1",
2544 "org.freedesktop.systemd1.Unit",
2549 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2553 STRV_FOREACH(i, triggered_by) {
2554 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2556 log_error("Failed to check unit: %s", strerror(-r));
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("Failed to expand names: %s", strerror(-r));
2805 if (!arg_no_block) {
2806 r = enable_wait_for_jobs(bus);
2808 log_error("Could not watch jobs: %s", strerror(-r));
2812 s = set_new(&string_hash_ops);
2817 STRV_FOREACH(name, names) {
2818 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2821 q = start_unit_one(bus, method, *name, mode, &error, s);
2822 if (r >= 0 && q < 0)
2823 r = translate_bus_error_to_exit_status(q, &error);
2826 if (!arg_no_block) {
2829 q = wait_for_jobs(bus, s);
2833 /* When stopping units, warn if they can still be triggered by
2834 * another active unit (socket, path, timer) */
2835 if (!arg_quiet && streq(method, "StopUnit"))
2836 STRV_FOREACH(name, names)
2837 check_triggering_units(bus, *name);
2843 /* Ask systemd-logind, which might grant access to unprivileged users
2844 * through PolicyKit */
2845 static int reboot_with_logind(sd_bus *bus, enum action a) {
2847 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2854 polkit_agent_open_if_enabled();
2862 case ACTION_POWEROFF:
2863 method = "PowerOff";
2866 case ACTION_SUSPEND:
2870 case ACTION_HIBERNATE:
2871 method = "Hibernate";
2874 case ACTION_HYBRID_SLEEP:
2875 method = "HybridSleep";
2882 r = sd_bus_call_method(
2884 "org.freedesktop.login1",
2885 "/org/freedesktop/login1",
2886 "org.freedesktop.login1.Manager",
2890 "b", arg_ask_password);
2892 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2900 static int check_inhibitors(sd_bus *bus, enum action a) {
2902 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2903 _cleanup_strv_free_ char **sessions = NULL;
2904 const char *what, *who, *why, *mode;
2913 if (arg_ignore_inhibitors || arg_force > 0)
2925 r = sd_bus_call_method(
2927 "org.freedesktop.login1",
2928 "/org/freedesktop/login1",
2929 "org.freedesktop.login1.Manager",
2935 /* If logind is not around, then there are no inhibitors... */
2938 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2940 return bus_log_parse_error(r);
2942 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2943 _cleanup_free_ char *comm = NULL, *user = NULL;
2944 _cleanup_strv_free_ char **sv = NULL;
2946 if (!streq(mode, "block"))
2949 sv = strv_split(what, ":");
2953 if (!strv_contains(sv,
2955 a == ACTION_POWEROFF ||
2956 a == ACTION_REBOOT ||
2957 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2960 get_process_comm(pid, &comm);
2961 user = uid_to_name(uid);
2963 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2964 who, pid, strna(comm), strna(user), why);
2969 return bus_log_parse_error(r);
2971 r = sd_bus_message_exit_container(reply);
2973 return bus_log_parse_error(r);
2975 /* Check for current sessions */
2976 sd_get_sessions(&sessions);
2977 STRV_FOREACH(s, sessions) {
2978 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2980 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2983 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2986 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2989 sd_session_get_tty(*s, &tty);
2990 sd_session_get_seat(*s, &seat);
2991 sd_session_get_service(*s, &service);
2992 user = uid_to_name(uid);
2994 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
3001 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3002 action_table[a].verb);
3010 static int start_special(sd_bus *bus, char **args) {
3016 a = verb_to_action(args[0]);
3018 r = check_inhibitors(bus, a);
3022 if (arg_force >= 2 && geteuid() != 0) {
3023 log_error("Must be root.");
3027 if (arg_force >= 2 &&
3028 (a == ACTION_HALT ||
3029 a == ACTION_POWEROFF ||
3030 a == ACTION_REBOOT))
3033 if (arg_force >= 1 &&
3034 (a == ACTION_HALT ||
3035 a == ACTION_POWEROFF ||
3036 a == ACTION_REBOOT ||
3037 a == ACTION_KEXEC ||
3039 return daemon_reload(bus, args);
3041 /* first try logind, to allow authentication with polkit */
3042 if (geteuid() != 0 &&
3043 (a == ACTION_POWEROFF ||
3044 a == ACTION_REBOOT ||
3045 a == ACTION_SUSPEND ||
3046 a == ACTION_HIBERNATE ||
3047 a == ACTION_HYBRID_SLEEP)) {
3048 r = reboot_with_logind(bus, a);
3053 r = start_unit(bus, args);
3054 if (r == EXIT_SUCCESS)
3060 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
3061 _cleanup_strv_free_ char **names = NULL;
3068 r = expand_names(bus, args, NULL, &names);
3070 log_error("Failed to expand names: %s", strerror(-r));
3074 STRV_FOREACH(name, names) {
3077 state = check_one_unit(bus, *name, good_states, arg_quiet);
3087 static int check_unit_active(sd_bus *bus, char **args) {
3088 /* According to LSB: 3, "program is not running" */
3089 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3092 static int check_unit_failed(sd_bus *bus, char **args) {
3093 return check_unit_generic(bus, 1, "failed\0", args + 1);
3096 static int kill_unit(sd_bus *bus, char **args) {
3097 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3098 _cleanup_strv_free_ char **names = NULL;
3106 arg_kill_who = "all";
3108 r = expand_names(bus, args + 1, NULL, &names);
3110 log_error("Failed to expand names: %s", strerror(-r));
3112 STRV_FOREACH(name, names) {
3113 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3115 q = sd_bus_message_new_method_call(
3118 "org.freedesktop.systemd1",
3119 "/org/freedesktop/systemd1",
3120 "org.freedesktop.systemd1.Manager",
3123 return bus_log_create_error(q);
3125 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3127 return bus_log_create_error(q);
3129 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3131 return bus_log_create_error(q);
3133 q = sd_bus_call(bus, m, 0, &error, NULL);
3135 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3144 typedef struct ExecStatusInfo {
3152 usec_t start_timestamp;
3153 usec_t exit_timestamp;
3158 LIST_FIELDS(struct ExecStatusInfo, exec);
3161 static void exec_status_info_free(ExecStatusInfo *i) {
3170 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3171 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3174 int32_t code, status;
3180 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3182 return bus_log_parse_error(r);
3186 r = sd_bus_message_read(m, "s", &path);
3188 return bus_log_parse_error(r);
3190 i->path = strdup(path);
3194 r = sd_bus_message_read_strv(m, &i->argv);
3196 return bus_log_parse_error(r);
3198 r = sd_bus_message_read(m,
3201 &start_timestamp, &start_timestamp_monotonic,
3202 &exit_timestamp, &exit_timestamp_monotonic,
3206 return bus_log_parse_error(r);
3209 i->start_timestamp = (usec_t) start_timestamp;
3210 i->exit_timestamp = (usec_t) exit_timestamp;
3211 i->pid = (pid_t) pid;
3215 r = sd_bus_message_exit_container(m);
3217 return bus_log_parse_error(r);
3222 typedef struct UnitStatusInfo {
3224 const char *load_state;
3225 const char *active_state;
3226 const char *sub_state;
3227 const char *unit_file_state;
3229 const char *description;
3230 const char *following;
3232 char **documentation;
3234 const char *fragment_path;
3235 const char *source_path;
3236 const char *control_group;
3238 char **dropin_paths;
3240 const char *load_error;
3243 usec_t inactive_exit_timestamp;
3244 usec_t inactive_exit_timestamp_monotonic;
3245 usec_t active_enter_timestamp;
3246 usec_t active_exit_timestamp;
3247 usec_t inactive_enter_timestamp;
3249 bool need_daemon_reload;
3254 const char *status_text;
3255 const char *pid_file;
3259 usec_t start_timestamp;
3260 usec_t exit_timestamp;
3262 int exit_code, exit_status;
3264 usec_t condition_timestamp;
3265 bool condition_result;
3266 bool failed_condition_trigger;
3267 bool failed_condition_negate;
3268 const char *failed_condition;
3269 const char *failed_condition_param;
3272 unsigned n_accepted;
3273 unsigned n_connections;
3276 /* Pairs of type, path */
3280 const char *sysfs_path;
3282 /* Mount, Automount */
3288 LIST_HEAD(ExecStatusInfo, exec);
3291 static void print_status_info(
3296 const char *active_on, *active_off, *on, *off, *ss;
3298 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3299 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3302 arg_all * OUTPUT_SHOW_ALL |
3303 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3304 on_tty() * OUTPUT_COLOR |
3305 !arg_quiet * OUTPUT_WARN_CUTOFF |
3306 arg_full * OUTPUT_FULL_WIDTH;
3311 /* This shows pretty information about a unit. See
3312 * print_property() for a low-level property printer */
3314 if (streq_ptr(i->active_state, "failed")) {
3315 active_on = ansi_highlight_red();
3316 active_off = ansi_highlight_off();
3317 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3318 active_on = ansi_highlight_green();
3319 active_off = ansi_highlight_off();
3321 active_on = active_off = "";
3323 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3325 if (i->description && !streq_ptr(i->id, i->description))
3326 printf(" - %s", i->description);
3331 printf(" Follow: unit currently follows state of %s\n", i->following);
3333 if (streq_ptr(i->load_state, "error")) {
3334 on = ansi_highlight_red();
3335 off = ansi_highlight_off();
3339 path = i->source_path ? i->source_path : i->fragment_path;
3342 printf(" Loaded: %s%s%s (Reason: %s)\n",
3343 on, strna(i->load_state), off, i->load_error);
3344 else if (path && i->unit_file_state)
3345 printf(" Loaded: %s%s%s (%s; %s)\n",
3346 on, strna(i->load_state), off, path, i->unit_file_state);
3348 printf(" Loaded: %s%s%s (%s)\n",
3349 on, strna(i->load_state), off, path);
3351 printf(" Loaded: %s%s%s\n",
3352 on, strna(i->load_state), off);
3354 if (!strv_isempty(i->dropin_paths)) {
3355 _cleanup_free_ char *dir = NULL;
3359 STRV_FOREACH(dropin, i->dropin_paths) {
3360 if (! dir || last) {
3361 printf(dir ? " " : " Drop-In: ");
3366 if (path_get_parent(*dropin, &dir) < 0) {
3371 printf("%s\n %s", dir,
3372 draw_special_char(DRAW_TREE_RIGHT));
3375 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3377 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3381 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3383 printf(" Active: %s%s (%s)%s",
3384 active_on, strna(i->active_state), ss, active_off);
3386 printf(" Active: %s%s%s",
3387 active_on, strna(i->active_state), active_off);
3389 if (!isempty(i->result) && !streq(i->result, "success"))
3390 printf(" (Result: %s)", i->result);
3392 timestamp = (streq_ptr(i->active_state, "active") ||
3393 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3394 (streq_ptr(i->active_state, "inactive") ||
3395 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3396 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3397 i->active_exit_timestamp;
3399 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3400 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3403 printf(" since %s; %s\n", s2, s1);
3405 printf(" since %s\n", s2);
3409 if (!i->condition_result && i->condition_timestamp > 0) {
3410 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3411 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3413 printf(" start condition failed at %s%s%s\n",
3414 s2, s1 ? "; " : "", s1 ? s1 : "");
3415 if (i->failed_condition_trigger)
3416 printf(" none of the trigger conditions were met\n");
3417 else if (i->failed_condition)
3418 printf(" %s=%s%s was not met\n",
3419 i->failed_condition,
3420 i->failed_condition_negate ? "!" : "",
3421 i->failed_condition_param);
3425 printf(" Device: %s\n", i->sysfs_path);
3427 printf(" Where: %s\n", i->where);
3429 printf(" What: %s\n", i->what);
3431 STRV_FOREACH(t, i->documentation)
3432 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3434 STRV_FOREACH_PAIR(t, t2, i->listen)
3435 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3438 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3440 LIST_FOREACH(exec, p, i->exec) {
3441 _cleanup_free_ char *argv = NULL;
3444 /* Only show exited processes here */
3448 argv = strv_join(p->argv, " ");
3449 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3451 good = is_clean_exit_lsb(p->code, p->status, NULL);
3453 on = ansi_highlight_red();
3454 off = ansi_highlight_off();
3458 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3460 if (p->code == CLD_EXITED) {
3463 printf("status=%i", p->status);
3465 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3470 printf("signal=%s", signal_to_string(p->status));
3472 printf(")%s\n", off);
3474 if (i->main_pid == p->pid &&
3475 i->start_timestamp == p->start_timestamp &&
3476 i->exit_timestamp == p->start_timestamp)
3477 /* Let's not show this twice */
3480 if (p->pid == i->control_pid)
3484 if (i->main_pid > 0 || i->control_pid > 0) {
3485 if (i->main_pid > 0) {
3486 printf(" Main PID: "PID_FMT, i->main_pid);
3489 _cleanup_free_ char *comm = NULL;
3490 get_process_comm(i->main_pid, &comm);
3492 printf(" (%s)", comm);
3493 } else if (i->exit_code > 0) {
3494 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3496 if (i->exit_code == CLD_EXITED) {
3499 printf("status=%i", i->exit_status);
3501 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3506 printf("signal=%s", signal_to_string(i->exit_status));
3510 if (i->control_pid > 0)
3514 if (i->control_pid > 0) {
3515 _cleanup_free_ char *c = NULL;
3517 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3519 get_process_comm(i->control_pid, &c);
3528 printf(" Status: \"%s\"\n", i->status_text);
3529 if (i->status_errno > 0)
3530 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3532 if (i->control_group &&
3533 (i->main_pid > 0 || i->control_pid > 0 ||
3534 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3537 printf(" CGroup: %s\n", i->control_group);
3539 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3542 static const char prefix[] = " ";
3545 if (c > sizeof(prefix) - 1)
3546 c -= sizeof(prefix) - 1;
3550 if (i->main_pid > 0)
3551 extra[k++] = i->main_pid;
3553 if (i->control_pid > 0)
3554 extra[k++] = i->control_pid;
3556 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3560 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3561 show_journal_by_unit(stdout,
3565 i->inactive_exit_timestamp_monotonic,
3568 flags | OUTPUT_BEGIN_NEWLINE,
3569 arg_scope == UNIT_FILE_SYSTEM,
3573 if (i->need_daemon_reload)
3574 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3575 ansi_highlight_red(),
3576 ansi_highlight_off(),
3577 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3580 static void show_unit_help(UnitStatusInfo *i) {
3585 if (!i->documentation) {
3586 log_info("Documentation for %s not known.", i->id);
3590 STRV_FOREACH(p, i->documentation)
3591 if (startswith(*p, "man:"))
3592 show_man_page(*p + 4, false);
3594 log_info("Can't show: %s", *p);
3597 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3604 switch (contents[0]) {
3606 case SD_BUS_TYPE_STRING: {
3609 r = sd_bus_message_read(m, "s", &s);
3611 return bus_log_parse_error(r);
3614 if (streq(name, "Id"))
3616 else if (streq(name, "LoadState"))
3618 else if (streq(name, "ActiveState"))
3619 i->active_state = s;
3620 else if (streq(name, "SubState"))
3622 else if (streq(name, "Description"))
3624 else if (streq(name, "FragmentPath"))
3625 i->fragment_path = s;
3626 else if (streq(name, "SourcePath"))
3629 else if (streq(name, "DefaultControlGroup")) {
3631 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3633 i->control_group = e;
3636 else if (streq(name, "ControlGroup"))
3637 i->control_group = s;
3638 else if (streq(name, "StatusText"))
3640 else if (streq(name, "PIDFile"))
3642 else if (streq(name, "SysFSPath"))
3644 else if (streq(name, "Where"))
3646 else if (streq(name, "What"))
3648 else if (streq(name, "Following"))
3650 else if (streq(name, "UnitFileState"))
3651 i->unit_file_state = s;
3652 else if (streq(name, "Result"))
3659 case SD_BUS_TYPE_BOOLEAN: {
3662 r = sd_bus_message_read(m, "b", &b);
3664 return bus_log_parse_error(r);
3666 if (streq(name, "Accept"))
3668 else if (streq(name, "NeedDaemonReload"))
3669 i->need_daemon_reload = b;
3670 else if (streq(name, "ConditionResult"))
3671 i->condition_result = b;
3676 case SD_BUS_TYPE_UINT32: {
3679 r = sd_bus_message_read(m, "u", &u);
3681 return bus_log_parse_error(r);
3683 if (streq(name, "MainPID")) {
3685 i->main_pid = (pid_t) u;
3688 } else if (streq(name, "ControlPID"))
3689 i->control_pid = (pid_t) u;
3690 else if (streq(name, "ExecMainPID")) {
3692 i->main_pid = (pid_t) u;
3693 } else if (streq(name, "NAccepted"))
3695 else if (streq(name, "NConnections"))
3696 i->n_connections = u;
3701 case SD_BUS_TYPE_INT32: {
3704 r = sd_bus_message_read(m, "i", &j);
3706 return bus_log_parse_error(r);
3708 if (streq(name, "ExecMainCode"))
3709 i->exit_code = (int) j;
3710 else if (streq(name, "ExecMainStatus"))
3711 i->exit_status = (int) j;
3712 else if (streq(name, "StatusErrno"))
3713 i->status_errno = (int) j;
3718 case SD_BUS_TYPE_UINT64: {
3721 r = sd_bus_message_read(m, "t", &u);
3723 return bus_log_parse_error(r);
3725 if (streq(name, "ExecMainStartTimestamp"))
3726 i->start_timestamp = (usec_t) u;
3727 else if (streq(name, "ExecMainExitTimestamp"))
3728 i->exit_timestamp = (usec_t) u;
3729 else if (streq(name, "ActiveEnterTimestamp"))
3730 i->active_enter_timestamp = (usec_t) u;
3731 else if (streq(name, "InactiveEnterTimestamp"))
3732 i->inactive_enter_timestamp = (usec_t) u;
3733 else if (streq(name, "InactiveExitTimestamp"))
3734 i->inactive_exit_timestamp = (usec_t) u;
3735 else if (streq(name, "InactiveExitTimestampMonotonic"))
3736 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3737 else if (streq(name, "ActiveExitTimestamp"))
3738 i->active_exit_timestamp = (usec_t) u;
3739 else if (streq(name, "ConditionTimestamp"))
3740 i->condition_timestamp = (usec_t) u;
3745 case SD_BUS_TYPE_ARRAY:
3747 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3748 _cleanup_free_ ExecStatusInfo *info = NULL;
3750 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3752 return bus_log_parse_error(r);
3754 info = new0(ExecStatusInfo, 1);
3758 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3760 info->name = strdup(name);
3764 LIST_PREPEND(exec, i->exec, info);
3766 info = new0(ExecStatusInfo, 1);
3772 return bus_log_parse_error(r);
3774 r = sd_bus_message_exit_container(m);
3776 return bus_log_parse_error(r);
3780 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3781 const char *type, *path;
3783 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3785 return bus_log_parse_error(r);
3787 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3789 r = strv_extend(&i->listen, type);
3793 r = strv_extend(&i->listen, path);
3798 return bus_log_parse_error(r);
3800 r = sd_bus_message_exit_container(m);
3802 return bus_log_parse_error(r);
3806 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3808 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3810 return bus_log_parse_error(r);
3812 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3814 r = sd_bus_message_read_strv(m, &i->documentation);
3816 return bus_log_parse_error(r);
3818 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3819 const char *cond, *param;
3820 int trigger, negate;
3823 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3825 return bus_log_parse_error(r);
3827 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3828 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3829 if (state < 0 && (!trigger || !i->failed_condition)) {
3830 i->failed_condition = cond;
3831 i->failed_condition_trigger = trigger;
3832 i->failed_condition_negate = negate;
3833 i->failed_condition_param = param;
3837 return bus_log_parse_error(r);
3839 r = sd_bus_message_exit_container(m);
3841 return bus_log_parse_error(r);
3848 case SD_BUS_TYPE_STRUCT_BEGIN:
3850 if (streq(name, "LoadError")) {
3851 const char *n, *message;
3853 r = sd_bus_message_read(m, "(ss)", &n, &message);
3855 return bus_log_parse_error(r);
3857 if (!isempty(message))
3858 i->load_error = message;
3871 r = sd_bus_message_skip(m, contents);
3873 return bus_log_parse_error(r);
3878 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3884 /* This is a low-level property printer, see
3885 * print_status_info() for the nicer output */
3887 if (arg_properties && !strv_find(arg_properties, name)) {
3888 /* skip what we didn't read */
3889 r = sd_bus_message_skip(m, contents);
3893 switch (contents[0]) {
3895 case SD_BUS_TYPE_STRUCT_BEGIN:
3897 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3900 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3902 return bus_log_parse_error(r);
3905 printf("%s=%"PRIu32"\n", name, u);
3907 printf("%s=\n", name);
3911 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3914 r = sd_bus_message_read(m, "(so)", &s, NULL);
3916 return bus_log_parse_error(r);
3918 if (arg_all || !isempty(s))
3919 printf("%s=%s\n", name, s);
3923 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3924 const char *a = NULL, *b = NULL;
3926 r = sd_bus_message_read(m, "(ss)", &a, &b);
3928 return bus_log_parse_error(r);
3930 if (arg_all || !isempty(a) || !isempty(b))
3931 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3934 } else if (streq_ptr(name, "SystemCallFilter")) {
3935 _cleanup_strv_free_ char **l = NULL;
3938 r = sd_bus_message_enter_container(m, 'r', "bas");
3940 return bus_log_parse_error(r);
3942 r = sd_bus_message_read(m, "b", &whitelist);
3944 return bus_log_parse_error(r);
3946 r = sd_bus_message_read_strv(m, &l);
3948 return bus_log_parse_error(r);
3950 r = sd_bus_message_exit_container(m);
3952 return bus_log_parse_error(r);
3954 if (arg_all || whitelist || !strv_isempty(l)) {
3958 fputs(name, stdout);
3964 STRV_FOREACH(i, l) {
3972 fputc('\n', stdout);
3980 case SD_BUS_TYPE_ARRAY:
3982 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3986 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3988 return bus_log_parse_error(r);
3990 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3991 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3994 return bus_log_parse_error(r);
3996 r = sd_bus_message_exit_container(m);
3998 return bus_log_parse_error(r);
4002 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4003 const char *type, *path;
4005 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4007 return bus_log_parse_error(r);
4009 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4010 printf("%s=%s\n", type, path);
4012 return bus_log_parse_error(r);
4014 r = sd_bus_message_exit_container(m);
4016 return bus_log_parse_error(r);
4020 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4021 const char *type, *path;
4023 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4025 return bus_log_parse_error(r);
4027 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4028 printf("Listen%s=%s\n", type, path);
4030 return bus_log_parse_error(r);
4032 r = sd_bus_message_exit_container(m);
4034 return bus_log_parse_error(r);
4038 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4040 uint64_t value, next_elapse;
4042 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4044 return bus_log_parse_error(r);
4046 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4047 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4049 printf("%s={ value=%s ; next_elapse=%s }\n",
4051 format_timespan(timespan1, sizeof(timespan1), value, 0),
4052 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4055 return bus_log_parse_error(r);
4057 r = sd_bus_message_exit_container(m);
4059 return bus_log_parse_error(r);
4063 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4064 ExecStatusInfo info = {};
4066 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4068 return bus_log_parse_error(r);
4070 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4071 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4072 _cleanup_free_ char *tt;
4074 tt = strv_join(info.argv, " ");
4076 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4080 yes_no(info.ignore),
4081 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4082 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4084 sigchld_code_to_string(info.code),
4086 info.code == CLD_EXITED ? "" : "/",
4087 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4090 strv_free(info.argv);
4094 r = sd_bus_message_exit_container(m);
4096 return bus_log_parse_error(r);
4100 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4101 const char *path, *rwm;
4103 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4105 return bus_log_parse_error(r);
4107 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4108 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4110 return bus_log_parse_error(r);
4112 r = sd_bus_message_exit_container(m);
4114 return bus_log_parse_error(r);
4118 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4122 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4124 return bus_log_parse_error(r);
4126 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4127 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4129 return bus_log_parse_error(r);
4131 r = sd_bus_message_exit_container(m);
4133 return bus_log_parse_error(r);
4137 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4141 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4143 return bus_log_parse_error(r);
4145 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4146 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4148 return bus_log_parse_error(r);
4150 r = sd_bus_message_exit_container(m);
4152 return bus_log_parse_error(r);
4160 r = bus_print_property(name, m, arg_all);
4162 return bus_log_parse_error(r);
4165 r = sd_bus_message_skip(m, contents);
4167 return bus_log_parse_error(r);
4170 printf("%s=[unprintable]\n", name);
4176 static int show_one(
4180 bool show_properties,
4184 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4185 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4186 UnitStatusInfo info = {};
4193 log_debug("Showing one %s", path);
4195 r = sd_bus_call_method(
4197 "org.freedesktop.systemd1",
4199 "org.freedesktop.DBus.Properties",
4205 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4209 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4211 return bus_log_parse_error(r);
4218 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4219 const char *name, *contents;
4221 r = sd_bus_message_read(reply, "s", &name);
4223 return bus_log_parse_error(r);
4225 r = sd_bus_message_peek_type(reply, NULL, &contents);
4227 return bus_log_parse_error(r);
4229 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4231 return bus_log_parse_error(r);
4233 if (show_properties)
4234 r = print_property(name, reply, contents);
4236 r = status_property(name, reply, &info, contents);
4240 r = sd_bus_message_exit_container(reply);
4242 return bus_log_parse_error(r);
4244 r = sd_bus_message_exit_container(reply);
4246 return bus_log_parse_error(r);
4249 return bus_log_parse_error(r);
4251 r = sd_bus_message_exit_container(reply);
4253 return bus_log_parse_error(r);
4257 if (!show_properties) {
4258 if (streq(verb, "help"))
4259 show_unit_help(&info);
4261 print_status_info(&info, ellipsized);
4264 strv_free(info.documentation);
4265 strv_free(info.dropin_paths);
4266 strv_free(info.listen);
4268 if (!streq_ptr(info.active_state, "active") &&
4269 !streq_ptr(info.active_state, "reloading") &&
4270 streq(verb, "status")) {
4271 /* According to LSB: "program not running" */
4272 /* 0: program is running or service is OK
4273 * 1: program is dead and /run PID file exists
4274 * 2: program is dead and /run/lock lock file exists
4275 * 3: program is not running
4276 * 4: program or service status is unknown
4278 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4284 while ((p = info.exec)) {
4285 LIST_REMOVE(exec, info.exec, p);
4286 exec_status_info_free(p);
4292 static int get_unit_dbus_path_by_pid(
4297 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4298 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4302 r = sd_bus_call_method(
4304 "org.freedesktop.systemd1",
4305 "/org/freedesktop/systemd1",
4306 "org.freedesktop.systemd1.Manager",
4312 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4316 r = sd_bus_message_read(reply, "o", &u);
4318 return bus_log_parse_error(r);
4328 static int show_all(
4331 bool show_properties,
4335 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4336 _cleanup_free_ UnitInfo *unit_infos = NULL;
4341 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4345 pager_open_if_enabled();
4349 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4351 for (u = unit_infos; u < unit_infos + c; u++) {
4352 _cleanup_free_ char *p = NULL;
4354 p = unit_dbus_path_from_name(u->id);
4358 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4361 else if (r > 0 && ret == 0)
4368 static int show_system_status(sd_bus *bus) {
4369 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4370 _cleanup_free_ char *hn = NULL;
4371 struct machine_info mi = {};
4372 const char *on, *off;
4375 hn = gethostname_malloc();
4379 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4381 log_error("Failed to read server status: %s", strerror(-r));
4385 if (streq_ptr(mi.state, "degraded")) {
4386 on = ansi_highlight_red();
4387 off = ansi_highlight_off();
4388 } else if (!streq_ptr(mi.state, "running")) {
4389 on = ansi_highlight_yellow();
4390 off = ansi_highlight_off();
4394 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4396 printf(" State: %s%s%s\n",
4397 on, strna(mi.state), off);
4399 printf(" Jobs: %u queued\n", mi.n_jobs);
4400 printf(" Failed: %u units\n", mi.n_failed_units);
4402 printf(" Since: %s; %s\n",
4403 format_timestamp(since2, sizeof(since2), mi.timestamp),
4404 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4406 printf(" CGroup: %s\n", mi.control_group ?: "/");
4407 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4409 arg_all * OUTPUT_SHOW_ALL |
4410 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4411 on_tty() * OUTPUT_COLOR |
4412 !arg_quiet * OUTPUT_WARN_CUTOFF |
4413 arg_full * OUTPUT_FULL_WIDTH;
4415 static const char prefix[] = " ";
4419 if (c > sizeof(prefix) - 1)
4420 c -= sizeof(prefix) - 1;
4424 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4428 free(mi.control_group);
4433 static int show(sd_bus *bus, char **args) {
4434 bool show_properties, show_status, new_line = false;
4435 bool ellipsized = false;
4441 show_properties = streq(args[0], "show");
4442 show_status = streq(args[0], "status");
4444 if (show_properties)
4445 pager_open_if_enabled();
4447 /* If no argument is specified inspect the manager itself */
4449 if (show_properties && strv_length(args) <= 1)
4450 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4452 if (show_status && strv_length(args) <= 1) {
4454 pager_open_if_enabled();
4455 show_system_status(bus);
4459 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4461 _cleanup_free_ char **patterns = NULL;
4464 STRV_FOREACH(name, args + 1) {
4465 _cleanup_free_ char *unit = NULL;
4468 if (safe_atou32(*name, &id) < 0) {
4469 if (strv_push(&patterns, *name) < 0)
4473 } else if (show_properties) {
4474 /* Interpret as job id */
4475 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4479 /* Interpret as PID */
4480 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4487 r = show_one(args[0], bus, unit, show_properties,
4488 &new_line, &ellipsized);
4491 else if (r > 0 && ret == 0)
4495 if (!strv_isempty(patterns)) {
4496 _cleanup_strv_free_ char **names = NULL;
4498 r = expand_names(bus, patterns, NULL, &names);
4500 log_error("Failed to expand names: %s", strerror(-r));
4502 STRV_FOREACH(name, names) {
4503 _cleanup_free_ char *unit;
4505 unit = unit_dbus_path_from_name(*name);
4509 r = show_one(args[0], bus, unit, show_properties,
4510 &new_line, &ellipsized);
4513 else if (r > 0 && ret == 0)
4519 if (ellipsized && !arg_quiet)
4520 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4525 static int cat(sd_bus *bus, char **args) {
4526 _cleanup_strv_free_ char **names = NULL;
4534 r = expand_names(bus, args + 1, NULL, &names);
4536 log_error("Failed to expand names: %s", strerror(-r));
4538 pager_open_if_enabled();
4540 STRV_FOREACH(name, names) {
4541 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4542 _cleanup_strv_free_ char **dropin_paths = NULL;
4543 _cleanup_free_ char *fragment_path = NULL, *unit = NULL;
4546 unit = unit_dbus_path_from_name(*name);
4550 if (need_daemon_reload(bus, *name) > 0)
4551 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4552 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4554 r = sd_bus_get_property_string(
4556 "org.freedesktop.systemd1",
4558 "org.freedesktop.systemd1.Unit",
4563 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4567 r = sd_bus_get_property_strv(
4569 "org.freedesktop.systemd1",
4571 "org.freedesktop.systemd1.Unit",
4576 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4585 if (!isempty(fragment_path)) {
4586 printf("%s# %s%s\n",
4587 ansi_highlight_blue(),
4589 ansi_highlight_off());
4592 r = sendfile_full(STDOUT_FILENO, fragment_path);
4594 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4599 STRV_FOREACH(path, dropin_paths) {
4600 printf("%s%s# %s%s\n",
4601 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4602 ansi_highlight_blue(),
4604 ansi_highlight_off());
4607 r = sendfile_full(STDOUT_FILENO, *path);
4609 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4615 return r < 0 ? r : 0;
4618 static int set_property(sd_bus *bus, char **args) {
4619 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4620 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4621 _cleanup_free_ char *n = NULL;
4625 r = sd_bus_message_new_method_call(
4628 "org.freedesktop.systemd1",
4629 "/org/freedesktop/systemd1",
4630 "org.freedesktop.systemd1.Manager",
4631 "SetUnitProperties");
4633 return bus_log_create_error(r);
4635 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4637 return bus_log_create_error(r);
4639 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4643 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4645 return bus_log_create_error(r);
4647 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4649 return bus_log_create_error(r);
4651 STRV_FOREACH(i, args + 2) {
4652 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4654 return bus_log_create_error(r);
4656 r = bus_append_unit_property_assignment(m, *i);
4660 r = sd_bus_message_close_container(m);
4662 return bus_log_create_error(r);
4665 r = sd_bus_message_close_container(m);
4667 return bus_log_create_error(r);
4669 r = sd_bus_call(bus, m, 0, &error, NULL);
4671 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4678 static int snapshot(sd_bus *bus, char **args) {
4679 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4680 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4681 _cleanup_free_ char *n = NULL, *id = NULL;
4685 if (strv_length(args) > 1)
4686 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4692 r = sd_bus_message_new_method_call(
4695 "org.freedesktop.systemd1",
4696 "/org/freedesktop/systemd1",
4697 "org.freedesktop.systemd1.Manager",
4700 return bus_log_create_error(r);
4702 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4704 return bus_log_create_error(r);
4706 r = sd_bus_message_append(m, "sb", n, false);
4708 return bus_log_create_error(r);
4710 r = sd_bus_call(bus, m, 0, &error, &reply);
4712 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4716 r = sd_bus_message_read(reply, "o", &path);
4718 return bus_log_parse_error(r);
4720 r = sd_bus_get_property_string(
4722 "org.freedesktop.systemd1",
4724 "org.freedesktop.systemd1.Unit",
4729 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4739 static int delete_snapshot(sd_bus *bus, char **args) {
4740 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4741 _cleanup_strv_free_ char **names = NULL;
4747 r = expand_names(bus, args + 1, ".snapshot", &names);
4749 log_error("Failed to expand names: %s", strerror(-r));
4751 STRV_FOREACH(name, names) {
4752 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4755 q = sd_bus_message_new_method_call(
4758 "org.freedesktop.systemd1",
4759 "/org/freedesktop/systemd1",
4760 "org.freedesktop.systemd1.Manager",
4763 return bus_log_create_error(q);
4765 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4767 return bus_log_create_error(q);
4769 q = sd_bus_message_append(m, "s", *name);
4771 return bus_log_create_error(q);
4773 q = sd_bus_call(bus, m, 0, &error, NULL);
4775 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4784 static int daemon_reload(sd_bus *bus, char **args) {
4785 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4786 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4790 if (arg_action == ACTION_RELOAD)
4792 else if (arg_action == ACTION_REEXEC)
4793 method = "Reexecute";
4795 assert(arg_action == ACTION_SYSTEMCTL);
4798 streq(args[0], "clear-jobs") ||
4799 streq(args[0], "cancel") ? "ClearJobs" :
4800 streq(args[0], "daemon-reexec") ? "Reexecute" :
4801 streq(args[0], "reset-failed") ? "ResetFailed" :
4802 streq(args[0], "halt") ? "Halt" :
4803 streq(args[0], "poweroff") ? "PowerOff" :
4804 streq(args[0], "reboot") ? "Reboot" :
4805 streq(args[0], "kexec") ? "KExec" :
4806 streq(args[0], "exit") ? "Exit" :
4807 /* "daemon-reload" */ "Reload";
4810 r = sd_bus_message_new_method_call(
4813 "org.freedesktop.systemd1",
4814 "/org/freedesktop/systemd1",
4815 "org.freedesktop.systemd1.Manager",
4818 return bus_log_create_error(r);
4820 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4822 return bus_log_create_error(r);
4824 r = sd_bus_call(bus, m, 0, &error, NULL);
4825 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4826 /* There's always a fallback possible for
4827 * legacy actions. */
4829 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4830 /* On reexecution, we expect a disconnect, not a
4834 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4836 return r < 0 ? r : 0;
4839 static int reset_failed(sd_bus *bus, char **args) {
4840 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4841 _cleanup_strv_free_ char **names = NULL;
4845 if (strv_length(args) <= 1)
4846 return daemon_reload(bus, args);
4848 r = expand_names(bus, args + 1, NULL, &names);
4850 log_error("Failed to expand names: %s", strerror(-r));
4852 STRV_FOREACH(name, names) {
4853 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4855 q = sd_bus_message_new_method_call(
4858 "org.freedesktop.systemd1",
4859 "/org/freedesktop/systemd1",
4860 "org.freedesktop.systemd1.Manager",
4863 return bus_log_create_error(q);
4865 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4867 return bus_log_create_error(q);
4869 q = sd_bus_message_append(m, "s", *name);
4871 return bus_log_create_error(q);
4873 q = sd_bus_call(bus, m, 0, &error, NULL);
4875 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4884 static int show_environment(sd_bus *bus, char **args) {
4885 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4886 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4890 pager_open_if_enabled();
4892 r = sd_bus_get_property(
4894 "org.freedesktop.systemd1",
4895 "/org/freedesktop/systemd1",
4896 "org.freedesktop.systemd1.Manager",
4902 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4906 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4908 return bus_log_parse_error(r);
4910 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4913 return bus_log_parse_error(r);
4915 r = sd_bus_message_exit_container(reply);
4917 return bus_log_parse_error(r);
4922 static int switch_root(sd_bus *bus, char **args) {
4923 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4924 _cleanup_free_ char *cmdline_init = NULL;
4925 const char *root, *init;
4929 l = strv_length(args);
4930 if (l < 2 || l > 3) {
4931 log_error("Wrong number of arguments.");
4940 r = parse_env_file("/proc/cmdline", WHITESPACE,
4941 "init", &cmdline_init,
4944 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4946 init = cmdline_init;
4953 const char *root_systemd_path = NULL, *root_init_path = NULL;
4955 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4956 root_init_path = strappenda(root, "/", init);
4958 /* If the passed init is actually the same as the
4959 * systemd binary, then let's suppress it. */
4960 if (files_same(root_init_path, root_systemd_path) > 0)
4964 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4966 r = sd_bus_call_method(
4968 "org.freedesktop.systemd1",
4969 "/org/freedesktop/systemd1",
4970 "org.freedesktop.systemd1.Manager",
4976 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4983 static int set_environment(sd_bus *bus, char **args) {
4984 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4985 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4992 method = streq(args[0], "set-environment")
4994 : "UnsetEnvironment";
4996 r = sd_bus_message_new_method_call(
4999 "org.freedesktop.systemd1",
5000 "/org/freedesktop/systemd1",
5001 "org.freedesktop.systemd1.Manager",
5004 return bus_log_create_error(r);
5006 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5008 return bus_log_create_error(r);
5010 r = sd_bus_message_append_strv(m, args + 1);
5012 return bus_log_create_error(r);
5014 r = sd_bus_call(bus, m, 0, &error, NULL);
5016 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5023 static int import_environment(sd_bus *bus, char **args) {
5024 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5025 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5031 r = sd_bus_message_new_method_call(
5034 "org.freedesktop.systemd1",
5035 "/org/freedesktop/systemd1",
5036 "org.freedesktop.systemd1.Manager",
5039 return bus_log_create_error(r);
5041 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5043 return bus_log_create_error(r);
5045 if (strv_isempty(args + 1))
5046 r = sd_bus_message_append_strv(m, environ);
5050 r = sd_bus_message_open_container(m, 'a', "s");
5052 return bus_log_create_error(r);
5054 STRV_FOREACH(a, args + 1) {
5056 if (!env_name_is_valid(*a)) {
5057 log_error("Not a valid environment variable name: %s", *a);
5061 STRV_FOREACH(b, environ) {
5064 eq = startswith(*b, *a);
5065 if (eq && *eq == '=') {
5067 r = sd_bus_message_append(m, "s", *b);
5069 return bus_log_create_error(r);
5076 r = sd_bus_message_close_container(m);
5079 return bus_log_create_error(r);
5081 r = sd_bus_call(bus, m, 0, &error, NULL);
5083 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5090 static int enable_sysv_units(const char *verb, char **args) {
5093 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5094 unsigned f = 1, t = 1;
5095 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5097 if (arg_scope != UNIT_FILE_SYSTEM)
5100 if (!streq(verb, "enable") &&
5101 !streq(verb, "disable") &&
5102 !streq(verb, "is-enabled"))
5105 /* Processes all SysV units, and reshuffles the array so that
5106 * afterwards only the native units remain */
5108 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5113 for (f = 0; args[f]; f++) {
5115 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5116 bool found_native = false, found_sysv;
5118 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5126 if (!endswith(name, ".service"))
5129 if (path_is_absolute(name))
5132 STRV_FOREACH(k, paths.unit_path) {
5133 _cleanup_free_ char *path = NULL;
5135 path = path_join(arg_root, *k, name);
5139 found_native = access(path, F_OK) >= 0;
5147 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5151 p[strlen(p) - strlen(".service")] = 0;
5152 found_sysv = access(p, F_OK) >= 0;
5156 /* Mark this entry, so that we don't try enabling it as native unit */
5157 args[f] = (char*) "";
5159 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5161 if (!isempty(arg_root))
5162 argv[c++] = q = strappend("--root=", arg_root);
5164 argv[c++] = basename(p);
5166 streq(verb, "enable") ? "on" :
5167 streq(verb, "disable") ? "off" : "--level=5";
5170 l = strv_join((char**)argv, " ");
5174 log_info("Executing %s", l);
5178 log_error("Failed to fork: %m");
5180 } else if (pid == 0) {
5183 execv(argv[0], (char**) argv);
5184 _exit(EXIT_FAILURE);
5187 j = wait_for_terminate(pid, &status);
5189 log_error("Failed to wait for child: %s", strerror(-r));
5193 if (status.si_code == CLD_EXITED) {
5194 if (streq(verb, "is-enabled")) {
5195 if (status.si_status == 0) {
5204 } else if (status.si_status != 0)
5210 /* Drop all SysV units */
5211 for (f = 0, t = 0; args[f]; f++) {
5213 if (isempty(args[f]))
5216 args[t++] = args[f];
5225 static int mangle_names(char **original_names, char ***mangled_names) {
5226 char **i, **l, **name;
5228 l = new(char*, strv_length(original_names) + 1);
5233 STRV_FOREACH(name, original_names) {
5235 /* When enabling units qualified path names are OK,
5236 * too, hence allow them explicitly. */
5241 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5257 static int enable_unit(sd_bus *bus, char **args) {
5258 _cleanup_strv_free_ char **names = NULL;
5259 const char *verb = args[0];
5260 UnitFileChange *changes = NULL;
5261 unsigned n_changes = 0;
5262 int carries_install_info = -1;
5268 r = mangle_names(args+1, &names);
5272 r = enable_sysv_units(verb, names);
5276 /* If the operation was fully executed by the SysV compat,
5277 * let's finish early */
5278 if (strv_isempty(names))
5281 if (!bus || avoid_bus()) {
5282 if (streq(verb, "enable")) {
5283 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5284 carries_install_info = r;
5285 } else if (streq(verb, "disable"))
5286 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5287 else if (streq(verb, "reenable")) {
5288 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5289 carries_install_info = r;
5290 } else if (streq(verb, "link"))
5291 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5292 else if (streq(verb, "preset")) {
5293 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5294 carries_install_info = r;
5295 } else if (streq(verb, "mask"))
5296 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5297 else if (streq(verb, "unmask"))
5298 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5300 assert_not_reached("Unknown verb");
5303 log_error("Operation failed: %s", strerror(-r));
5308 dump_unit_file_changes(changes, n_changes);
5312 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5313 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5314 int expect_carries_install_info = false;
5315 bool send_force = true, send_preset_mode = false;
5318 if (streq(verb, "enable")) {
5319 method = "EnableUnitFiles";
5320 expect_carries_install_info = true;
5321 } else if (streq(verb, "disable")) {
5322 method = "DisableUnitFiles";
5324 } else if (streq(verb, "reenable")) {
5325 method = "ReenableUnitFiles";
5326 expect_carries_install_info = true;
5327 } else if (streq(verb, "link"))
5328 method = "LinkUnitFiles";
5329 else if (streq(verb, "preset")) {
5331 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5332 method = "PresetUnitFilesWithMode";
5333 send_preset_mode = true;
5335 method = "PresetUnitFiles";
5337 expect_carries_install_info = true;
5338 } else if (streq(verb, "mask"))
5339 method = "MaskUnitFiles";
5340 else if (streq(verb, "unmask")) {
5341 method = "UnmaskUnitFiles";
5344 assert_not_reached("Unknown verb");
5346 r = sd_bus_message_new_method_call(
5349 "org.freedesktop.systemd1",
5350 "/org/freedesktop/systemd1",
5351 "org.freedesktop.systemd1.Manager",
5354 return bus_log_create_error(r);
5356 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5358 return bus_log_create_error(r);
5360 r = sd_bus_message_append_strv(m, names);
5362 return bus_log_create_error(r);
5364 if (send_preset_mode) {
5365 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5367 return bus_log_create_error(r);
5370 r = sd_bus_message_append(m, "b", arg_runtime);
5372 return bus_log_create_error(r);
5375 r = sd_bus_message_append(m, "b", arg_force);
5377 return bus_log_create_error(r);
5380 r = sd_bus_call(bus, m, 0, &error, &reply);
5382 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5386 if (expect_carries_install_info) {
5387 r = sd_bus_message_read(reply, "b", &carries_install_info);
5389 return bus_log_parse_error(r);
5392 r = deserialize_and_dump_unit_file_changes(reply);
5396 /* Try to reload if enabled */
5398 r = daemon_reload(bus, args);
5403 if (carries_install_info == 0)
5404 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5405 "using systemctl.\n"
5406 "Possible reasons for having this kind of units are:\n"
5407 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5408 " .wants/ or .requires/ directory.\n"
5409 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5410 " a requirement dependency on it.\n"
5411 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5412 " D-Bus, udev, scripted systemctl call, ...).\n");
5415 unit_file_changes_free(changes, n_changes);
5420 static int add_dependency(sd_bus *bus, char **args) {
5421 _cleanup_strv_free_ char **names = NULL;
5422 _cleanup_free_ char *target = NULL;
5423 const char *verb = args[0];
5430 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5434 r = mangle_names(args+2, &names);
5438 if (streq(verb, "add-wants"))
5440 else if (streq(verb, "add-requires"))
5441 dep = UNIT_REQUIRES;
5443 assert_not_reached("Unknown verb");
5445 if (!bus || avoid_bus()) {
5446 UnitFileChange *changes = NULL;
5447 unsigned n_changes = 0;
5449 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5452 log_error("Can't add dependency: %s", strerror(-r));
5457 dump_unit_file_changes(changes, n_changes);
5459 unit_file_changes_free(changes, n_changes);
5462 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5463 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5465 r = sd_bus_message_new_method_call(
5468 "org.freedesktop.systemd1",
5469 "/org/freedesktop/systemd1",
5470 "org.freedesktop.systemd1.Manager",
5471 "AddDependencyUnitFiles");
5473 return bus_log_create_error(r);
5475 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5477 return bus_log_create_error(r);
5479 r = sd_bus_message_append_strv(m, names);
5481 return bus_log_create_error(r);
5483 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5485 return bus_log_create_error(r);
5487 r = sd_bus_call(bus, m, 0, &error, &reply);
5489 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5493 r = deserialize_and_dump_unit_file_changes(reply);
5498 r = daemon_reload(bus, args);
5506 static int preset_all(sd_bus *bus, char **args) {
5507 UnitFileChange *changes = NULL;
5508 unsigned n_changes = 0;
5511 if (!bus || avoid_bus()) {
5513 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5515 log_error("Operation failed: %s", strerror(-r));
5520 dump_unit_file_changes(changes, n_changes);
5525 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5526 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5528 r = sd_bus_message_new_method_call(
5531 "org.freedesktop.systemd1",
5532 "/org/freedesktop/systemd1",
5533 "org.freedesktop.systemd1.Manager",
5534 "PresetAllUnitFiles");
5536 return bus_log_create_error(r);
5538 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5540 return bus_log_create_error(r);
5542 r = sd_bus_message_append(
5545 unit_file_preset_mode_to_string(arg_preset_mode),
5549 return bus_log_create_error(r);
5551 r = sd_bus_call(bus, m, 0, &error, &reply);
5553 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5557 r = deserialize_and_dump_unit_file_changes(reply);
5562 r = daemon_reload(bus, args);
5568 unit_file_changes_free(changes, n_changes);
5573 static int unit_is_enabled(sd_bus *bus, char **args) {
5575 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5576 _cleanup_strv_free_ char **names = NULL;
5581 r = mangle_names(args+1, &names);
5585 r = enable_sysv_units(args[0], names);
5591 if (!bus || avoid_bus()) {
5593 STRV_FOREACH(name, names) {
5594 UnitFileState state;
5596 state = unit_file_get_state(arg_scope, arg_root, *name);
5598 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5602 if (state == UNIT_FILE_ENABLED ||
5603 state == UNIT_FILE_ENABLED_RUNTIME ||
5604 state == UNIT_FILE_STATIC)
5608 puts(unit_file_state_to_string(state));
5612 STRV_FOREACH(name, names) {
5613 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5616 r = sd_bus_call_method(
5618 "org.freedesktop.systemd1",
5619 "/org/freedesktop/systemd1",
5620 "org.freedesktop.systemd1.Manager",
5626 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5630 r = sd_bus_message_read(reply, "s", &s);
5632 return bus_log_parse_error(r);
5634 if (streq(s, "enabled") ||
5635 streq(s, "enabled-runtime") ||
5647 static int is_system_running(sd_bus *bus, char **args) {
5648 _cleanup_free_ char *state = NULL;
5651 r = sd_bus_get_property_string(
5653 "org.freedesktop.systemd1",
5654 "/org/freedesktop/systemd1",
5655 "org.freedesktop.systemd1.Manager",
5668 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5671 static void systemctl_help(void) {
5673 pager_open_if_enabled();
5675 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5676 "Query or send control commands to the systemd manager.\n\n"
5677 " -h --help Show this help\n"
5678 " --version Show package version\n"
5679 " --system Connect to system manager\n"
5680 " --user Connect to user service manager\n"
5681 " -H --host=[USER@]HOST\n"
5682 " Operate on remote host\n"
5683 " -M --machine=CONTAINER\n"
5684 " Operate on local container\n"
5685 " -t --type=TYPE List only units of a particular type\n"
5686 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5687 " -p --property=NAME Show only properties by this name\n"
5688 " -a --all Show all loaded units/properties, including dead/empty\n"
5689 " ones. To list all units installed on the system, use\n"
5690 " the 'list-unit-files' command instead.\n"
5691 " -l --full Don't ellipsize unit names on output\n"
5692 " -r --recursive Show unit list of host and local containers\n"
5693 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5694 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5695 " queueing a new job\n"
5696 " --show-types When showing sockets, explicitly show their type\n"
5697 " -i --ignore-inhibitors\n"
5698 " When shutting down or sleeping, ignore inhibitors\n"
5699 " --kill-who=WHO Who to send signal to\n"
5700 " -s --signal=SIGNAL Which signal to send\n"
5701 " -q --quiet Suppress output\n"
5702 " --no-block Do not wait until operation finished\n"
5703 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5704 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5706 " --no-legend Do not print a legend (column headers and hints)\n"
5707 " --no-pager Do not pipe output into a pager\n"
5708 " --no-ask-password\n"
5709 " Do not ask for system passwords\n"
5710 " --global Enable/disable unit files globally\n"
5711 " --runtime Enable unit files only temporarily until next reboot\n"
5712 " -f --force When enabling unit files, override existing symlinks\n"
5713 " When shutting down, execute action immediately\n"
5714 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
5715 " or only disable\n"
5716 " --root=PATH Enable unit files in the specified root directory\n"
5717 " -n --lines=INTEGER Number of journal entries to show\n"
5718 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5719 " verbose, export, json, json-pretty, json-sse, cat)\n"
5720 " --plain Print unit dependencies as a list instead of a tree\n\n"
5722 " list-units [PATTERN...] List loaded units\n"
5723 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5724 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5725 " start NAME... Start (activate) one or more units\n"
5726 " stop NAME... Stop (deactivate) one or more units\n"
5727 " reload NAME... Reload one or more units\n"
5728 " restart NAME... Start or restart one or more units\n"
5729 " try-restart NAME... Restart one or more units if active\n"
5730 " reload-or-restart NAME... Reload one or more units if possible,\n"
5731 " otherwise start or restart\n"
5732 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5733 " otherwise restart if active\n"
5734 " isolate NAME Start one unit and stop all others\n"
5735 " kill NAME... Send signal to processes of a unit\n"
5736 " is-active PATTERN... Check whether units are active\n"
5737 " is-failed PATTERN... Check whether units are failed\n"
5738 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5739 " show [PATTERN...|JOB...] Show properties of one or more\n"
5740 " units/jobs or the manager\n"
5741 " cat PATTERN... Show files and drop-ins of one or more units\n"
5742 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5743 " help PATTERN...|PID... Show manual for one or more units\n"
5744 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5746 " list-dependencies [NAME] Recursively show units which are required\n"
5747 " or wanted by this unit or by which this\n"
5748 " unit is required or wanted\n\n"
5749 "Unit File Commands:\n"
5750 " list-unit-files [PATTERN...] List installed unit files\n"
5751 " enable NAME... Enable one or more unit files\n"
5752 " disable NAME... Disable one or more unit files\n"
5753 " reenable NAME... Reenable one or more unit files\n"
5754 " preset NAME... Enable/disable one or more unit files\n"
5755 " based on preset configuration\n"
5756 " preset-all Enable/disable all unit files based on\n"
5757 " preset configuration\n"
5758 " is-enabled NAME... Check whether unit files are enabled\n\n"
5759 " mask NAME... Mask one or more units\n"
5760 " unmask NAME... Unmask one or more units\n"
5761 " link PATH... Link one or more units files into\n"
5762 " the search path\n"
5763 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
5764 " on specified one or more units\n"
5765 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
5766 " on specified one or more units\n"
5767 " get-default Get the name of the default target\n"
5768 " set-default NAME Set the default target\n\n"
5769 "Machine Commands:\n"
5770 " list-machines [PATTERN...] List local containers and host\n\n"
5772 " list-jobs [PATTERN...] List jobs\n"
5773 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5774 "Snapshot Commands:\n"
5775 " snapshot [NAME] Create a snapshot\n"
5776 " delete NAME... Remove one or more snapshots\n\n"
5777 "Environment Commands:\n"
5778 " show-environment Dump environment\n"
5779 " set-environment NAME=VALUE... Set one or more environment variables\n"
5780 " unset-environment NAME... Unset one or more environment variables\n"
5781 " import-environment NAME... Import all, one or more environment variables\n\n"
5782 "Manager Lifecycle Commands:\n"
5783 " daemon-reload Reload systemd manager configuration\n"
5784 " daemon-reexec Reexecute systemd manager\n\n"
5785 "System Commands:\n"
5786 " is-system-running Check whether system is fully running\n"
5787 " default Enter system default mode\n"
5788 " rescue Enter system rescue mode\n"
5789 " emergency Enter system emergency mode\n"
5790 " halt Shut down and halt the system\n"
5791 " poweroff Shut down and power-off the system\n"
5792 " reboot [ARG] Shut down and reboot the system\n"
5793 " kexec Shut down and reboot the system with kexec\n"
5794 " exit Request user instance exit\n"
5795 " switch-root ROOT [INIT] Change to a different root file system\n"
5796 " suspend Suspend the system\n"
5797 " hibernate Hibernate the system\n"
5798 " hybrid-sleep Hibernate and suspend the system\n",
5799 program_invocation_short_name);
5802 static void halt_help(void) {
5803 printf("%s [OPTIONS...]%s\n\n"
5804 "%s the system.\n\n"
5805 " --help Show this help\n"
5806 " --halt Halt the machine\n"
5807 " -p --poweroff Switch off the machine\n"
5808 " --reboot Reboot the machine\n"
5809 " -f --force Force immediate halt/power-off/reboot\n"
5810 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5811 " -d --no-wtmp Don't write wtmp record\n"
5812 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5813 program_invocation_short_name,
5814 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5815 arg_action == ACTION_REBOOT ? "Reboot" :
5816 arg_action == ACTION_POWEROFF ? "Power off" :
5820 static void shutdown_help(void) {
5821 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5822 "Shut down the system.\n\n"
5823 " --help Show this help\n"
5824 " -H --halt Halt the machine\n"
5825 " -P --poweroff Power-off the machine\n"
5826 " -r --reboot Reboot the machine\n"
5827 " -h Equivalent to --poweroff, overridden by --halt\n"
5828 " -k Don't halt/power-off/reboot, just send warnings\n"
5829 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5830 " -c Cancel a pending shutdown\n",
5831 program_invocation_short_name);
5834 static void telinit_help(void) {
5835 printf("%s [OPTIONS...] {COMMAND}\n\n"
5836 "Send control commands to the init daemon.\n\n"
5837 " --help Show this help\n"
5838 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5840 " 0 Power-off the machine\n"
5841 " 6 Reboot the machine\n"
5842 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5843 " 1, s, S Enter rescue mode\n"
5844 " q, Q Reload init daemon configuration\n"
5845 " u, U Reexecute init daemon\n",
5846 program_invocation_short_name);
5849 static void runlevel_help(void) {
5850 printf("%s [OPTIONS...]\n\n"
5851 "Prints the previous and current runlevel of the init system.\n\n"
5852 " --help Show this help\n",
5853 program_invocation_short_name);
5856 static void help_types(void) {
5861 puts("Available unit types:");
5862 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5863 t = unit_type_to_string(i);
5869 static int systemctl_parse_argv(int argc, char *argv[]) {
5878 ARG_IGNORE_DEPENDENCIES,
5890 ARG_NO_ASK_PASSWORD,
5900 static const struct option options[] = {
5901 { "help", no_argument, NULL, 'h' },
5902 { "version", no_argument, NULL, ARG_VERSION },
5903 { "type", required_argument, NULL, 't' },
5904 { "property", required_argument, NULL, 'p' },
5905 { "all", no_argument, NULL, 'a' },
5906 { "reverse", no_argument, NULL, ARG_REVERSE },
5907 { "after", no_argument, NULL, ARG_AFTER },
5908 { "before", no_argument, NULL, ARG_BEFORE },
5909 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5910 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5911 { "full", no_argument, NULL, 'l' },
5912 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5913 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5914 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5915 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5916 { "ignore-inhibitors", no_argument, NULL, 'i' },
5917 { "user", no_argument, NULL, ARG_USER },
5918 { "system", no_argument, NULL, ARG_SYSTEM },
5919 { "global", no_argument, NULL, ARG_GLOBAL },
5920 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5921 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5922 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5923 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5924 { "quiet", no_argument, NULL, 'q' },
5925 { "root", required_argument, NULL, ARG_ROOT },
5926 { "force", no_argument, NULL, ARG_FORCE },
5927 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5928 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5929 { "signal", required_argument, NULL, 's' },
5930 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5931 { "host", required_argument, NULL, 'H' },
5932 { "machine", required_argument, NULL, 'M' },
5933 { "runtime", no_argument, NULL, ARG_RUNTIME },
5934 { "lines", required_argument, NULL, 'n' },
5935 { "output", required_argument, NULL, 'o' },
5936 { "plain", no_argument, NULL, ARG_PLAIN },
5937 { "state", required_argument, NULL, ARG_STATE },
5938 { "recursive", no_argument, NULL, 'r' },
5939 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
5948 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
5957 puts(PACKAGE_STRING);
5958 puts(SYSTEMD_FEATURES);
5962 const char *word, *state;
5965 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5966 _cleanup_free_ char *type;
5968 type = strndup(word, size);
5972 if (streq(type, "help")) {
5977 if (unit_type_from_string(type) >= 0) {
5978 if (strv_push(&arg_types, type))
5984 /* It's much nicer to use --state= for
5985 * load states, but let's support this
5986 * in --types= too for compatibility
5987 * with old versions */
5988 if (unit_load_state_from_string(optarg) >= 0) {
5989 if (strv_push(&arg_states, type) < 0)
5995 log_error("Unknown unit type or load state '%s'.", type);
5996 log_info("Use -t help to see a list of allowed values.");
6004 /* Make sure that if the empty property list
6005 was specified, we won't show any properties. */
6006 if (isempty(optarg) && !arg_properties) {
6007 arg_properties = new0(char*, 1);
6008 if (!arg_properties)
6011 const char *word, *state;
6014 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6017 prop = strndup(word, size);
6021 if (strv_consume(&arg_properties, prop) < 0)
6026 /* If the user asked for a particular
6027 * property, show it to him, even if it is
6039 arg_dependency = DEPENDENCY_REVERSE;
6043 arg_dependency = DEPENDENCY_AFTER;
6047 arg_dependency = DEPENDENCY_BEFORE;
6050 case ARG_SHOW_TYPES:
6051 arg_show_types = true;
6055 arg_job_mode = optarg;
6059 arg_job_mode = "fail";
6062 case ARG_IRREVERSIBLE:
6063 arg_job_mode = "replace-irreversibly";
6066 case ARG_IGNORE_DEPENDENCIES:
6067 arg_job_mode = "ignore-dependencies";
6071 arg_scope = UNIT_FILE_USER;
6075 arg_scope = UNIT_FILE_SYSTEM;
6079 arg_scope = UNIT_FILE_GLOBAL;
6083 arg_no_block = true;
6087 arg_no_legend = true;
6091 arg_no_pager = true;
6107 if (strv_extend(&arg_states, "failed") < 0)
6125 arg_no_reload = true;
6129 arg_kill_who = optarg;
6133 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6134 log_error("Failed to parse signal string %s.", optarg);
6139 case ARG_NO_ASK_PASSWORD:
6140 arg_ask_password = false;
6144 arg_transport = BUS_TRANSPORT_REMOTE;
6149 arg_transport = BUS_TRANSPORT_CONTAINER;
6158 if (safe_atou(optarg, &arg_lines) < 0) {
6159 log_error("Failed to parse lines '%s'", optarg);
6165 arg_output = output_mode_from_string(optarg);
6166 if (arg_output < 0) {
6167 log_error("Unknown output '%s'.", optarg);
6173 arg_ignore_inhibitors = true;
6181 const char *word, *state;
6184 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6187 s = strndup(word, size);
6191 if (strv_consume(&arg_states, s) < 0)
6198 if (geteuid() != 0) {
6199 log_error("--recursive requires root privileges.");
6203 arg_recursive = true;
6206 case ARG_PRESET_MODE:
6208 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6209 if (arg_preset_mode < 0) {
6210 log_error("Failed to parse preset mode: %s.", optarg);
6220 assert_not_reached("Unhandled option");
6223 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6224 log_error("Cannot access user instance remotely.");
6231 static int halt_parse_argv(int argc, char *argv[]) {
6240 static const struct option options[] = {
6241 { "help", no_argument, NULL, ARG_HELP },
6242 { "halt", no_argument, NULL, ARG_HALT },
6243 { "poweroff", no_argument, NULL, 'p' },
6244 { "reboot", no_argument, NULL, ARG_REBOOT },
6245 { "force", no_argument, NULL, 'f' },
6246 { "wtmp-only", no_argument, NULL, 'w' },
6247 { "no-wtmp", no_argument, NULL, 'd' },
6248 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6257 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6258 if (runlevel == '0' || runlevel == '6')
6261 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6269 arg_action = ACTION_HALT;
6273 if (arg_action != ACTION_REBOOT)
6274 arg_action = ACTION_POWEROFF;
6278 arg_action = ACTION_REBOOT;
6300 /* Compatibility nops */
6307 assert_not_reached("Unhandled option");
6310 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6311 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6314 } else if (optind < argc) {
6315 log_error("Too many arguments.");
6322 static int parse_time_spec(const char *t, usec_t *_u) {
6326 if (streq(t, "now"))
6328 else if (!strchr(t, ':')) {
6331 if (safe_atou64(t, &u) < 0)
6334 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6343 hour = strtol(t, &e, 10);
6344 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6347 minute = strtol(e+1, &e, 10);
6348 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6351 n = now(CLOCK_REALTIME);
6352 s = (time_t) (n / USEC_PER_SEC);
6354 assert_se(localtime_r(&s, &tm));
6356 tm.tm_hour = (int) hour;
6357 tm.tm_min = (int) minute;
6360 assert_se(s = mktime(&tm));
6362 *_u = (usec_t) s * USEC_PER_SEC;
6365 *_u += USEC_PER_DAY;
6371 static int shutdown_parse_argv(int argc, char *argv[]) {
6378 static const struct option options[] = {
6379 { "help", no_argument, NULL, ARG_HELP },
6380 { "halt", no_argument, NULL, 'H' },
6381 { "poweroff", no_argument, NULL, 'P' },
6382 { "reboot", no_argument, NULL, 'r' },
6383 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6384 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6393 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6401 arg_action = ACTION_HALT;
6405 arg_action = ACTION_POWEROFF;
6410 arg_action = ACTION_KEXEC;
6412 arg_action = ACTION_REBOOT;
6416 arg_action = ACTION_KEXEC;
6420 if (arg_action != ACTION_HALT)
6421 arg_action = ACTION_POWEROFF;
6434 /* Compatibility nops */
6438 arg_action = ACTION_CANCEL_SHUTDOWN;
6445 assert_not_reached("Unhandled option");
6448 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6449 r = parse_time_spec(argv[optind], &arg_when);
6451 log_error("Failed to parse time specification: %s", argv[optind]);
6455 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6457 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6458 /* No time argument for shutdown cancel */
6459 arg_wall = argv + optind;
6460 else if (argc > optind + 1)
6461 /* We skip the time argument */
6462 arg_wall = argv + optind + 1;
6469 static int telinit_parse_argv(int argc, char *argv[]) {
6476 static const struct option options[] = {
6477 { "help", no_argument, NULL, ARG_HELP },
6478 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6482 static const struct {
6486 { '0', ACTION_POWEROFF },
6487 { '6', ACTION_REBOOT },
6488 { '1', ACTION_RESCUE },
6489 { '2', ACTION_RUNLEVEL2 },
6490 { '3', ACTION_RUNLEVEL3 },
6491 { '4', ACTION_RUNLEVEL4 },
6492 { '5', ACTION_RUNLEVEL5 },
6493 { 's', ACTION_RESCUE },
6494 { 'S', ACTION_RESCUE },
6495 { 'q', ACTION_RELOAD },
6496 { 'Q', ACTION_RELOAD },
6497 { 'u', ACTION_REEXEC },
6498 { 'U', ACTION_REEXEC }
6507 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6522 assert_not_reached("Unhandled option");
6525 if (optind >= argc) {
6526 log_error("%s: required argument missing.",
6527 program_invocation_short_name);
6531 if (optind + 1 < argc) {
6532 log_error("Too many arguments.");
6536 if (strlen(argv[optind]) != 1) {
6537 log_error("Expected single character argument.");
6541 for (i = 0; i < ELEMENTSOF(table); i++)
6542 if (table[i].from == argv[optind][0])
6545 if (i >= ELEMENTSOF(table)) {
6546 log_error("Unknown command '%s'.", argv[optind]);
6550 arg_action = table[i].to;
6557 static int runlevel_parse_argv(int argc, char *argv[]) {
6563 static const struct option options[] = {
6564 { "help", no_argument, NULL, ARG_HELP },
6573 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6584 assert_not_reached("Unhandled option");
6587 if (optind < argc) {
6588 log_error("Too many arguments.");
6595 static int parse_argv(int argc, char *argv[]) {
6599 if (program_invocation_short_name) {
6601 if (strstr(program_invocation_short_name, "halt")) {
6602 arg_action = ACTION_HALT;
6603 return halt_parse_argv(argc, argv);
6604 } else if (strstr(program_invocation_short_name, "poweroff")) {
6605 arg_action = ACTION_POWEROFF;
6606 return halt_parse_argv(argc, argv);
6607 } else if (strstr(program_invocation_short_name, "reboot")) {
6609 arg_action = ACTION_KEXEC;
6611 arg_action = ACTION_REBOOT;
6612 return halt_parse_argv(argc, argv);
6613 } else if (strstr(program_invocation_short_name, "shutdown")) {
6614 arg_action = ACTION_POWEROFF;
6615 return shutdown_parse_argv(argc, argv);
6616 } else if (strstr(program_invocation_short_name, "init")) {
6618 if (sd_booted() > 0) {
6619 arg_action = _ACTION_INVALID;
6620 return telinit_parse_argv(argc, argv);
6622 /* Hmm, so some other init system is
6623 * running, we need to forward this
6624 * request to it. For now we simply
6625 * guess that it is Upstart. */
6627 execv(TELINIT, argv);
6629 log_error("Couldn't find an alternative telinit implementation to spawn.");
6633 } else if (strstr(program_invocation_short_name, "runlevel")) {
6634 arg_action = ACTION_RUNLEVEL;
6635 return runlevel_parse_argv(argc, argv);
6639 arg_action = ACTION_SYSTEMCTL;
6640 return systemctl_parse_argv(argc, argv);
6643 _pure_ static int action_to_runlevel(void) {
6645 static const char table[_ACTION_MAX] = {
6646 [ACTION_HALT] = '0',
6647 [ACTION_POWEROFF] = '0',
6648 [ACTION_REBOOT] = '6',
6649 [ACTION_RUNLEVEL2] = '2',
6650 [ACTION_RUNLEVEL3] = '3',
6651 [ACTION_RUNLEVEL4] = '4',
6652 [ACTION_RUNLEVEL5] = '5',
6653 [ACTION_RESCUE] = '1'
6656 assert(arg_action < _ACTION_MAX);
6658 return table[arg_action];
6661 static int talk_initctl(void) {
6663 struct init_request request = {
6664 .magic = INIT_MAGIC,
6666 .cmd = INIT_CMD_RUNLVL
6669 _cleanup_close_ int fd = -1;
6673 rl = action_to_runlevel();
6677 request.runlevel = rl;
6679 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6681 if (errno == ENOENT)
6684 log_error("Failed to open "INIT_FIFO": %m");
6689 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6691 log_error("Failed to write to "INIT_FIFO": %m");
6692 return errno > 0 ? -errno : -EIO;
6698 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6700 static const struct {
6708 int (* const dispatch)(sd_bus *bus, char **args);
6714 { "list-units", MORE, 0, list_units },
6715 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6716 { "list-sockets", MORE, 1, list_sockets },
6717 { "list-timers", MORE, 1, list_timers },
6718 { "list-jobs", MORE, 1, list_jobs },
6719 { "list-machines", MORE, 1, list_machines },
6720 { "clear-jobs", EQUAL, 1, daemon_reload },
6721 { "cancel", MORE, 2, cancel_job },
6722 { "start", MORE, 2, start_unit },
6723 { "stop", MORE, 2, start_unit },
6724 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6725 { "reload", MORE, 2, start_unit },
6726 { "restart", MORE, 2, start_unit },
6727 { "try-restart", MORE, 2, start_unit },
6728 { "reload-or-restart", MORE, 2, start_unit },
6729 { "reload-or-try-restart", MORE, 2, start_unit },
6730 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6731 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6732 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6733 { "isolate", EQUAL, 2, start_unit },
6734 { "kill", MORE, 2, kill_unit },
6735 { "is-active", MORE, 2, check_unit_active },
6736 { "check", MORE, 2, check_unit_active },
6737 { "is-failed", MORE, 2, check_unit_failed },
6738 { "show", MORE, 1, show },
6739 { "cat", MORE, 2, cat },
6740 { "status", MORE, 1, show },
6741 { "help", MORE, 2, show },
6742 { "snapshot", LESS, 2, snapshot },
6743 { "delete", MORE, 2, delete_snapshot },
6744 { "daemon-reload", EQUAL, 1, daemon_reload },
6745 { "daemon-reexec", EQUAL, 1, daemon_reload },
6746 { "show-environment", EQUAL, 1, show_environment },
6747 { "set-environment", MORE, 2, set_environment },
6748 { "unset-environment", MORE, 2, set_environment },
6749 { "import-environment", MORE, 1, import_environment},
6750 { "halt", EQUAL, 1, start_special, FORCE },
6751 { "poweroff", EQUAL, 1, start_special, FORCE },
6752 { "reboot", EQUAL, 1, start_special, FORCE },
6753 { "kexec", EQUAL, 1, start_special },
6754 { "suspend", EQUAL, 1, start_special },
6755 { "hibernate", EQUAL, 1, start_special },
6756 { "hybrid-sleep", EQUAL, 1, start_special },
6757 { "default", EQUAL, 1, start_special },
6758 { "rescue", EQUAL, 1, start_special },
6759 { "emergency", EQUAL, 1, start_special },
6760 { "exit", EQUAL, 1, start_special },
6761 { "reset-failed", MORE, 1, reset_failed },
6762 { "enable", MORE, 2, enable_unit, NOBUS },
6763 { "disable", MORE, 2, enable_unit, NOBUS },
6764 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6765 { "reenable", MORE, 2, enable_unit, NOBUS },
6766 { "preset", MORE, 2, enable_unit, NOBUS },
6767 { "preset-all", EQUAL, 1, preset_all, NOBUS },
6768 { "mask", MORE, 2, enable_unit, NOBUS },
6769 { "unmask", MORE, 2, enable_unit, NOBUS },
6770 { "link", MORE, 2, enable_unit, NOBUS },
6771 { "switch-root", MORE, 2, switch_root },
6772 { "list-dependencies", LESS, 2, list_dependencies },
6773 { "set-default", EQUAL, 2, set_default, NOBUS },
6774 { "get-default", EQUAL, 1, get_default, NOBUS },
6775 { "set-property", MORE, 3, set_property },
6776 { "is-system-running", EQUAL, 1, is_system_running },
6777 { "add-wants", MORE, 3, add_dependency, NOBUS },
6778 { "add-requires", MORE, 3, add_dependency, NOBUS },
6787 left = argc - optind;
6789 /* Special rule: no arguments (left == 0) means "list-units" */
6791 if (streq(argv[optind], "help") && !argv[optind+1]) {
6792 log_error("This command expects one or more "
6793 "unit names. Did you mean --help?");
6797 for (; verb->verb; verb++)
6798 if (streq(argv[optind], verb->verb))
6801 log_error("Unknown operation '%s'.", argv[optind]);
6806 switch (verb->argc_cmp) {
6809 if (left != verb->argc) {
6810 log_error("Invalid number of arguments.");
6817 if (left < verb->argc) {
6818 log_error("Too few arguments.");
6825 if (left > verb->argc) {
6826 log_error("Too many arguments.");
6833 assert_not_reached("Unknown comparison operator.");
6836 /* Require a bus connection for all operations but
6838 if (verb->bus == NOBUS) {
6839 if (!bus && !avoid_bus()) {
6840 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6845 if (running_in_chroot() > 0) {
6846 log_info("Running in chroot, ignoring request.");
6850 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6851 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6856 return verb->dispatch(bus, argv + optind);
6859 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6861 struct sd_shutdown_command c = {
6868 union sockaddr_union sockaddr = {
6869 .un.sun_family = AF_UNIX,
6870 .un.sun_path = "/run/systemd/shutdownd",
6873 struct iovec iovec[2] = {{
6874 .iov_base = (char*) &c,
6875 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6878 struct msghdr msghdr = {
6879 .msg_name = &sockaddr,
6880 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6881 + strlen("/run/systemd/shutdownd"),
6886 _cleanup_close_ int fd;
6888 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6892 if (!isempty(message)) {
6893 iovec[1].iov_base = (char*) message;
6894 iovec[1].iov_len = strlen(message);
6895 msghdr.msg_iovlen++;
6898 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6904 static int reload_with_fallback(sd_bus *bus) {
6907 /* First, try systemd via D-Bus. */
6908 if (daemon_reload(bus, NULL) >= 0)
6912 /* Nothing else worked, so let's try signals */
6913 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6915 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6916 log_error("kill() failed: %m");
6923 static int start_with_fallback(sd_bus *bus) {
6926 /* First, try systemd via D-Bus. */
6927 if (start_unit(bus, NULL) >= 0)
6931 /* Nothing else worked, so let's try
6933 if (talk_initctl() > 0)
6936 log_error("Failed to talk to init daemon.");
6940 warn_wall(arg_action);
6944 static int halt_now(enum action a) {
6946 /* Make sure C-A-D is handled by the kernel from this
6948 reboot(RB_ENABLE_CAD);
6953 log_info("Halting.");
6954 reboot(RB_HALT_SYSTEM);
6957 case ACTION_POWEROFF:
6958 log_info("Powering off.");
6959 reboot(RB_POWER_OFF);
6962 case ACTION_REBOOT: {
6963 _cleanup_free_ char *param = NULL;
6965 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6966 log_info("Rebooting with argument '%s'.", param);
6967 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6968 LINUX_REBOOT_CMD_RESTART2, param);
6971 log_info("Rebooting.");
6972 reboot(RB_AUTOBOOT);
6977 assert_not_reached("Unknown action.");
6981 static int halt_main(sd_bus *bus) {
6984 r = check_inhibitors(bus, arg_action);
6988 if (geteuid() != 0) {
6989 /* Try logind if we are a normal user and no special
6990 * mode applies. Maybe PolicyKit allows us to shutdown
6993 if (arg_when <= 0 &&
6996 (arg_action == ACTION_POWEROFF ||
6997 arg_action == ACTION_REBOOT)) {
6998 r = reboot_with_logind(bus, arg_action);
7003 log_error("Must be root.");
7008 _cleanup_free_ char *m;
7010 m = strv_join(arg_wall, " ");
7014 r = send_shutdownd(arg_when,
7015 arg_action == ACTION_HALT ? 'H' :
7016 arg_action == ACTION_POWEROFF ? 'P' :
7017 arg_action == ACTION_KEXEC ? 'K' :
7024 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
7026 char date[FORMAT_TIMESTAMP_MAX];
7028 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7029 format_timestamp(date, sizeof(date), arg_when));
7034 if (!arg_dry && !arg_force)
7035 return start_with_fallback(bus);
7038 if (sd_booted() > 0)
7039 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7041 r = utmp_put_shutdown();
7043 log_warning("Failed to write utmp record: %s", strerror(-r));
7050 r = halt_now(arg_action);
7051 log_error("Failed to reboot: %s", strerror(-r));
7056 static int runlevel_main(void) {
7057 int r, runlevel, previous;
7059 r = utmp_get_runlevel(&runlevel, &previous);
7066 previous <= 0 ? 'N' : previous,
7067 runlevel <= 0 ? 'N' : runlevel);
7072 int main(int argc, char*argv[]) {
7073 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7076 setlocale(LC_ALL, "");
7077 log_parse_environment();
7080 /* Explicitly not on_tty() to avoid setting cached value.
7081 * This becomes relevant for piping output which might be
7083 original_stdout_is_tty = isatty(STDOUT_FILENO);
7085 r = parse_argv(argc, argv);
7089 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7090 * let's shortcut this */
7091 if (arg_action == ACTION_RUNLEVEL) {
7092 r = runlevel_main();
7096 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7097 log_info("Running in chroot, ignoring request.");
7103 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7105 /* systemctl_main() will print an error message for the bus
7106 * connection, but only if it needs to */
7108 switch (arg_action) {
7110 case ACTION_SYSTEMCTL:
7111 r = systemctl_main(bus, argc, argv, r);
7115 case ACTION_POWEROFF:
7121 case ACTION_RUNLEVEL2:
7122 case ACTION_RUNLEVEL3:
7123 case ACTION_RUNLEVEL4:
7124 case ACTION_RUNLEVEL5:
7126 case ACTION_EMERGENCY:
7127 case ACTION_DEFAULT:
7128 r = start_with_fallback(bus);
7133 r = reload_with_fallback(bus);
7136 case ACTION_CANCEL_SHUTDOWN: {
7137 _cleanup_free_ char *m = NULL;
7140 m = strv_join(arg_wall, " ");
7147 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7149 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
7153 case ACTION_RUNLEVEL:
7154 case _ACTION_INVALID:
7156 assert_not_reached("Unknown action");
7161 ask_password_agent_close();
7162 polkit_agent_close();
7164 strv_free(arg_types);
7165 strv_free(arg_states);
7166 strv_free(arg_properties);
7168 return r < 0 ? EXIT_FAILURE : r;