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 const struct {
144 { "start", "StartUnit" },
145 { "stop", "StopUnit" },
146 { "condstop", "StopUnit" },
147 { "reload", "ReloadUnit" },
148 { "restart", "RestartUnit" },
149 { "try-restart", "TryRestartUnit" },
150 { "condrestart", "TryRestartUnit" },
151 { "reload-or-restart", "ReloadOrRestartUnit" },
152 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
153 { "condreload", "ReloadOrTryRestartUnit" },
154 { "force-reload", "ReloadOrTryRestartUnit" }
157 static bool original_stdout_is_tty;
159 static int daemon_reload(sd_bus *bus, char **args);
160 static int halt_now(enum action a);
161 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
163 static char** strv_skip_first(char **strv) {
164 if (strv_length(strv) > 0)
169 static void pager_open_if_enabled(void) {
177 static void ask_password_agent_open_if_enabled(void) {
179 /* Open the password 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)
190 ask_password_agent_open();
194 static void polkit_agent_open_if_enabled(void) {
196 /* Open the polkit agent as a child process if necessary */
198 if (!arg_ask_password)
201 if (arg_scope != UNIT_FILE_SYSTEM)
204 if (arg_transport != BUS_TRANSPORT_LOCAL)
211 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
214 if (!sd_bus_error_is_set(error))
217 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
218 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
219 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
220 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
221 return EXIT_NOPERMISSION;
223 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
224 return EXIT_NOTINSTALLED;
226 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
227 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
228 return EXIT_NOTIMPLEMENTED;
230 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
231 return EXIT_NOTCONFIGURED;
239 static void warn_wall(enum action a) {
240 static const char *table[_ACTION_MAX] = {
241 [ACTION_HALT] = "The system is going down for system halt NOW!",
242 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
243 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
244 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
245 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
246 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
247 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
254 _cleanup_free_ char *p;
256 p = strv_join(arg_wall, " ");
263 utmp_wall(p, NULL, NULL);
271 utmp_wall(table[a], NULL, NULL);
274 static bool avoid_bus(void) {
276 if (running_in_chroot() > 0)
279 if (sd_booted() <= 0)
282 if (!isempty(arg_root))
285 if (arg_scope == UNIT_FILE_GLOBAL)
291 static int compare_unit_info(const void *a, const void *b) {
292 const UnitInfo *u = a, *v = b;
296 /* First, order by machine */
297 if (!u->machine && v->machine)
299 if (u->machine && !v->machine)
301 if (u->machine && v->machine) {
302 r = strcasecmp(u->machine, v->machine);
307 /* Second, order by unit type */
308 d1 = strrchr(u->id, '.');
309 d2 = strrchr(v->id, '.');
311 r = strcasecmp(d1, d2);
316 /* Third, order by name */
317 return strcasecmp(u->id, v->id);
320 static bool output_show_unit(const UnitInfo *u, char **patterns) {
323 if (!strv_isempty(patterns)) {
326 STRV_FOREACH(pattern, patterns)
327 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
332 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
333 strv_find(arg_types, dot+1))) &&
334 (arg_all || !(streq(u->active_state, "inactive")
335 || u->following[0]) || u->job_id > 0);
338 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
339 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
341 unsigned n_shown = 0;
344 max_id_len = strlen("UNIT");
345 load_len = strlen("LOAD");
346 active_len = strlen("ACTIVE");
347 sub_len = strlen("SUB");
348 job_len = strlen("JOB");
351 for (u = unit_infos; u < unit_infos + c; u++) {
352 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
353 load_len = MAX(load_len, strlen(u->load_state));
354 active_len = MAX(active_len, strlen(u->active_state));
355 sub_len = MAX(sub_len, strlen(u->sub_state));
357 if (u->job_id != 0) {
358 job_len = MAX(job_len, strlen(u->job_type));
362 if (!arg_no_legend &&
363 (streq(u->active_state, "failed") ||
364 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
368 if (!arg_full && original_stdout_is_tty) {
371 id_len = MIN(max_id_len, 25u);
372 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
375 basic_len += job_len + 1;
377 if (basic_len < (unsigned) columns()) {
378 unsigned extra_len, incr;
379 extra_len = columns() - basic_len;
381 /* Either UNIT already got 25, or is fully satisfied.
382 * Grant up to 25 to DESC now. */
383 incr = MIN(extra_len, 25u);
387 /* split the remaining space between UNIT and DESC,
388 * but do not give UNIT more than it needs. */
390 incr = MIN(extra_len / 2, max_id_len - id_len);
392 desc_len += extra_len - incr;
398 for (u = unit_infos; u < unit_infos + c; u++) {
399 _cleanup_free_ char *e = NULL, *j = NULL;
400 const char *on_loaded = "", *off_loaded = "";
401 const char *on_active = "", *off_active = "";
402 const char *on_circle = "", *off_circle = "";
406 if (!n_shown && !arg_no_legend) {
411 printf("%-*s %-*s %-*s %-*s ",
414 active_len, "ACTIVE",
418 printf("%-*s ", job_len, "JOB");
420 if (!arg_full && arg_no_pager)
421 printf("%.*s\n", desc_len, "DESCRIPTION");
423 printf("%s\n", "DESCRIPTION");
428 if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
429 on_loaded = ansi_highlight_red();
430 on_circle = ansi_highlight_yellow();
431 off_loaded = off_circle = ansi_highlight_off();
435 if (streq(u->active_state, "failed")) {
436 on_circle = on_active = ansi_highlight_red();
437 off_circle = off_active = ansi_highlight_off();
442 j = strjoin(u->machine, ":", u->id, NULL);
451 e = ellipsize(id, id_len, 33);
459 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
461 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
462 on_active, id_len, id, off_active,
463 on_loaded, load_len, u->load_state, off_loaded,
464 on_active, active_len, u->active_state,
465 sub_len, u->sub_state, off_active,
466 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
469 printf("%.*s\n", desc_len, u->description);
471 printf("%s\n", u->description);
474 if (!arg_no_legend) {
475 const char *on, *off;
479 "LOAD = Reflects whether the unit definition was properly loaded.\n"
480 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
481 "SUB = The low-level unit activation state, values depend on unit type.");
482 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
483 on = ansi_highlight();
484 off = ansi_highlight_off();
486 on = ansi_highlight_red();
487 off = ansi_highlight_off();
491 printf("%s%u loaded units listed.%s\n"
492 "To show all installed unit files use 'systemctl list-unit-files'.\n",
495 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
496 "To show all installed unit files use 'systemctl list-unit-files'.\n",
503 static int get_unit_list(
507 UnitInfo **unit_infos,
509 sd_bus_message **_reply) {
511 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
512 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
513 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
522 r = sd_bus_message_new_method_call(
525 "org.freedesktop.systemd1",
526 "/org/freedesktop/systemd1",
527 "org.freedesktop.systemd1.Manager",
528 "ListUnitsFiltered");
531 return bus_log_create_error(r);
533 r = sd_bus_message_append_strv(m, arg_states);
535 return bus_log_create_error(r);
537 r = sd_bus_call(bus, m, 0, &error, &reply);
539 log_error("Failed to list units: %s", bus_error_message(&error, r));
543 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
545 return bus_log_parse_error(r);
547 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
550 if (!output_show_unit(&u, patterns))
553 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
556 (*unit_infos)[c++] = u;
559 return bus_log_parse_error(r);
561 r = sd_bus_message_exit_container(reply);
563 return bus_log_parse_error(r);
571 static void message_set_freep(Set **set) {
574 while ((m = set_steal_first(*set)))
575 sd_bus_message_unref(m);
580 static int get_unit_list_recursive(
583 UnitInfo **_unit_infos,
587 _cleanup_free_ UnitInfo *unit_infos = NULL;
588 _cleanup_(message_set_freep) Set *replies;
589 sd_bus_message *reply;
597 replies = set_new(NULL, NULL);
601 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
605 r = set_put(replies, reply);
607 sd_bus_message_unref(reply);
612 _cleanup_strv_free_ char **machines = NULL;
615 r = sd_get_machine_names(&machines);
619 STRV_FOREACH(i, machines) {
620 _cleanup_bus_unref_ sd_bus *container = NULL;
623 r = sd_bus_open_system_container(&container, *i);
625 log_error("Failed to connect to container %s: %s", *i, strerror(-r));
629 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
635 r = set_put(replies, reply);
637 sd_bus_message_unref(reply);
642 *_machines = machines;
647 *_unit_infos = unit_infos;
656 static int list_units(sd_bus *bus, char **args) {
657 _cleanup_free_ UnitInfo *unit_infos = NULL;
658 _cleanup_(message_set_freep) Set *replies = NULL;
659 _cleanup_strv_free_ char **machines = NULL;
662 pager_open_if_enabled();
664 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
668 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
669 return output_units_list(unit_infos, r);
672 static int get_triggered_units(
677 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
680 r = sd_bus_get_property_strv(
682 "org.freedesktop.systemd1",
684 "org.freedesktop.systemd1.Unit",
690 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
695 static int get_listening(
697 const char* unit_path,
700 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
701 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
702 const char *type, *path;
705 r = sd_bus_get_property(
707 "org.freedesktop.systemd1",
709 "org.freedesktop.systemd1.Socket",
715 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
719 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
721 return bus_log_parse_error(r);
723 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
725 r = strv_extend(listening, type);
729 r = strv_extend(listening, path);
736 return bus_log_parse_error(r);
738 r = sd_bus_message_exit_container(reply);
740 return bus_log_parse_error(r);
752 /* Note: triggered is a list here, although it almost certainly
753 * will always be one unit. Nevertheless, dbus API allows for multiple
754 * values, so let's follow that.*/
757 /* The strv above is shared. free is set only in the first one. */
761 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
767 if (!a->machine && b->machine)
769 if (a->machine && !b->machine)
771 if (a->machine && b->machine) {
772 o = strcasecmp(a->machine, b->machine);
777 o = strcmp(a->path, b->path);
779 o = strcmp(a->type, b->type);
784 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
785 struct socket_info *s;
786 unsigned pathlen = strlen("LISTEN"),
787 typelen = strlen("TYPE") * arg_show_types,
788 socklen = strlen("UNIT"),
789 servlen = strlen("ACTIVATES");
790 const char *on, *off;
792 for (s = socket_infos; s < socket_infos + cs; s++) {
796 socklen = MAX(socklen, strlen(s->id));
798 typelen = MAX(typelen, strlen(s->type));
799 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
801 STRV_FOREACH(a, s->triggered)
802 tmp += strlen(*a) + 2*(a != s->triggered);
803 servlen = MAX(servlen, tmp);
808 printf("%-*s %-*.*s%-*s %s\n",
810 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
814 for (s = socket_infos; s < socket_infos + cs; s++) {
815 _cleanup_free_ char *j = NULL;
820 j = strjoin(s->machine, ":", s->path, NULL);
828 printf("%-*s %-*s %-*s",
829 pathlen, path, typelen, s->type, socklen, s->id);
832 pathlen, path, socklen, s->id);
833 STRV_FOREACH(a, s->triggered)
835 a == s->triggered ? "" : ",", *a);
839 on = ansi_highlight();
840 off = ansi_highlight_off();
844 on = ansi_highlight_red();
845 off = ansi_highlight_off();
848 if (!arg_no_legend) {
849 printf("%s%u sockets listed.%s\n", on, cs, off);
851 printf("Pass --all to see loaded but inactive sockets, too.\n");
857 static int list_sockets(sd_bus *bus, char **args) {
858 _cleanup_(message_set_freep) Set *replies = NULL;
859 _cleanup_strv_free_ char **machines = NULL;
860 _cleanup_free_ UnitInfo *unit_infos = NULL;
861 _cleanup_free_ struct socket_info *socket_infos = NULL;
863 struct socket_info *s;
868 pager_open_if_enabled();
870 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
874 for (u = unit_infos; u < unit_infos + n; u++) {
875 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
878 if (!endswith(u->id, ".socket"))
881 r = get_triggered_units(bus, u->unit_path, &triggered);
885 c = get_listening(bus, u->unit_path, &listening);
891 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
896 for (i = 0; i < c; i++)
897 socket_infos[cs + i] = (struct socket_info) {
898 .machine = u->machine,
900 .type = listening[i*2],
901 .path = listening[i*2 + 1],
902 .triggered = triggered,
903 .own_triggered = i==0,
906 /* from this point on we will cleanup those socket_infos */
909 listening = triggered = NULL; /* avoid cleanup */
912 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
913 (__compar_fn_t) socket_info_compare);
915 output_sockets_list(socket_infos, cs);
918 assert(cs == 0 || socket_infos);
919 for (s = socket_infos; s < socket_infos + cs; s++) {
922 if (s->own_triggered)
923 strv_free(s->triggered);
929 static int get_next_elapse(
932 dual_timestamp *next) {
934 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
942 r = sd_bus_get_property_trivial(
944 "org.freedesktop.systemd1",
946 "org.freedesktop.systemd1.Timer",
947 "NextElapseUSecMonotonic",
952 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
956 r = sd_bus_get_property_trivial(
958 "org.freedesktop.systemd1",
960 "org.freedesktop.systemd1.Timer",
961 "NextElapseUSecRealtime",
966 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
974 static int get_last_trigger(
979 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
986 r = sd_bus_get_property_trivial(
988 "org.freedesktop.systemd1",
990 "org.freedesktop.systemd1.Timer",
996 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1004 const char* machine;
1007 usec_t last_trigger;
1011 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1017 if (!a->machine && b->machine)
1019 if (a->machine && !b->machine)
1021 if (a->machine && b->machine) {
1022 o = strcasecmp(a->machine, b->machine);
1027 if (a->next_elapse < b->next_elapse)
1029 if (a->next_elapse > b->next_elapse)
1032 return strcmp(a->id, b->id);
1035 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1036 struct timer_info *t;
1038 nextlen = strlen("NEXT"),
1039 leftlen = strlen("LEFT"),
1040 lastlen = strlen("LAST"),
1041 passedlen = strlen("PASSED"),
1042 unitlen = strlen("UNIT"),
1043 activatelen = strlen("ACTIVATES");
1045 const char *on, *off;
1047 assert(timer_infos || n == 0);
1049 for (t = timer_infos; t < timer_infos + n; t++) {
1053 if (t->next_elapse > 0) {
1054 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1056 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1057 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1059 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1060 leftlen = MAX(leftlen, strlen(trel));
1063 if (t->last_trigger > 0) {
1064 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1066 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1067 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1069 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1070 passedlen = MAX(passedlen, strlen(trel));
1073 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1075 STRV_FOREACH(a, t->triggered)
1076 ul += strlen(*a) + 2*(a != t->triggered);
1078 activatelen = MAX(activatelen, ul);
1083 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1087 passedlen, "PASSED",
1091 for (t = timer_infos; t < timer_infos + n; t++) {
1092 _cleanup_free_ char *j = NULL;
1094 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1095 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1098 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1099 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1101 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1102 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1105 j = strjoin(t->machine, ":", t->id, NULL);
1112 printf("%-*s %-*s %-*s %-*s %-*s",
1113 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1115 STRV_FOREACH(a, t->triggered)
1117 a == t->triggered ? "" : ",", *a);
1121 on = ansi_highlight();
1122 off = ansi_highlight_off();
1126 on = ansi_highlight_red();
1127 off = ansi_highlight_off();
1130 if (!arg_no_legend) {
1131 printf("%s%u timers listed.%s\n", on, n, off);
1133 printf("Pass --all to see loaded but inactive timers, too.\n");
1139 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1145 if (next->monotonic != (usec_t) -1 && next->monotonic > 0) {
1148 if (next->monotonic > nw->monotonic)
1149 converted = nw->realtime + (next->monotonic - nw->monotonic);
1151 converted = nw->realtime - (nw->monotonic - next->monotonic);
1153 if (next->realtime != (usec_t) -1 && next->realtime > 0)
1154 next_elapse = MIN(converted, next->realtime);
1156 next_elapse = converted;
1159 next_elapse = next->realtime;
1164 static int list_timers(sd_bus *bus, char **args) {
1165 _cleanup_(message_set_freep) Set *replies = NULL;
1166 _cleanup_strv_free_ char **machines = NULL;
1167 _cleanup_free_ struct timer_info *timer_infos = NULL;
1168 _cleanup_free_ UnitInfo *unit_infos = NULL;
1169 struct timer_info *t;
1176 pager_open_if_enabled();
1178 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1182 dual_timestamp_get(&nw);
1184 for (u = unit_infos; u < unit_infos + n; u++) {
1185 _cleanup_strv_free_ char **triggered = NULL;
1186 dual_timestamp next = {};
1189 if (!endswith(u->id, ".timer"))
1192 r = get_triggered_units(bus, u->unit_path, &triggered);
1196 r = get_next_elapse(bus, u->unit_path, &next);
1200 get_last_trigger(bus, u->unit_path, &last);
1202 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1207 m = calc_next_elapse(&nw, &next);
1209 timer_infos[c++] = (struct timer_info) {
1210 .machine = u->machine,
1213 .last_trigger = last,
1214 .triggered = triggered,
1217 triggered = NULL; /* avoid cleanup */
1220 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1221 (__compar_fn_t) timer_info_compare);
1223 output_timers_list(timer_infos, c);
1226 for (t = timer_infos; t < timer_infos + c; t++)
1227 strv_free(t->triggered);
1232 static int compare_unit_file_list(const void *a, const void *b) {
1233 const char *d1, *d2;
1234 const UnitFileList *u = a, *v = b;
1236 d1 = strrchr(u->path, '.');
1237 d2 = strrchr(v->path, '.');
1242 r = strcasecmp(d1, d2);
1247 return strcasecmp(basename(u->path), basename(v->path));
1250 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1253 if (!strv_isempty(patterns)) {
1256 STRV_FOREACH(pattern, patterns)
1257 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1262 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1265 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1266 unsigned max_id_len, id_cols, state_cols;
1267 const UnitFileList *u;
1269 max_id_len = strlen("UNIT FILE");
1270 state_cols = strlen("STATE");
1272 for (u = units; u < units + c; u++) {
1273 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1274 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1278 unsigned basic_cols;
1280 id_cols = MIN(max_id_len, 25u);
1281 basic_cols = 1 + id_cols + state_cols;
1282 if (basic_cols < (unsigned) columns())
1283 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1285 id_cols = max_id_len;
1288 printf("%-*s %-*s\n",
1289 id_cols, "UNIT FILE",
1290 state_cols, "STATE");
1292 for (u = units; u < units + c; u++) {
1293 _cleanup_free_ char *e = NULL;
1294 const char *on, *off;
1297 if (u->state == UNIT_FILE_MASKED ||
1298 u->state == UNIT_FILE_MASKED_RUNTIME ||
1299 u->state == UNIT_FILE_DISABLED ||
1300 u->state == UNIT_FILE_INVALID) {
1301 on = ansi_highlight_red();
1302 off = ansi_highlight_off();
1303 } else if (u->state == UNIT_FILE_ENABLED) {
1304 on = ansi_highlight_green();
1305 off = ansi_highlight_off();
1309 id = basename(u->path);
1311 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1313 printf("%-*s %s%-*s%s\n",
1314 id_cols, e ? e : id,
1315 on, state_cols, unit_file_state_to_string(u->state), off);
1319 printf("\n%u unit files listed.\n", c);
1322 static int list_unit_files(sd_bus *bus, char **args) {
1323 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1324 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1325 _cleanup_free_ UnitFileList *units = NULL;
1333 pager_open_if_enabled();
1341 h = hashmap_new(string_hash_func, string_compare_func);
1345 r = unit_file_get_list(arg_scope, arg_root, h);
1347 unit_file_list_free(h);
1348 log_error("Failed to get unit file list: %s", strerror(-r));
1352 n_units = hashmap_size(h);
1353 units = new(UnitFileList, n_units);
1355 unit_file_list_free(h);
1359 HASHMAP_FOREACH(u, h, i) {
1360 if (!output_show_unit_file(u, strv_skip_first(args)))
1367 assert(c <= n_units);
1370 r = sd_bus_call_method(
1372 "org.freedesktop.systemd1",
1373 "/org/freedesktop/systemd1",
1374 "org.freedesktop.systemd1.Manager",
1380 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1384 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1386 return bus_log_parse_error(r);
1388 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1390 if (!GREEDY_REALLOC(units, size, c + 1))
1393 units[c] = (struct UnitFileList) {
1395 unit_file_state_from_string(state)
1398 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1403 return bus_log_parse_error(r);
1405 r = sd_bus_message_exit_container(reply);
1407 return bus_log_parse_error(r);
1411 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1412 output_unit_file_list(units, c);
1416 for (unit = units; unit < units + c; unit++)
1422 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1423 _cleanup_free_ char *n = NULL;
1424 size_t max_len = MAX(columns(),20u);
1430 for (i = level - 1; i >= 0; i--) {
1432 if (len > max_len - 3 && !arg_full) {
1433 printf("%s...\n",max_len % 2 ? "" : " ");
1436 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1440 if (len > max_len - 3 && !arg_full) {
1441 printf("%s...\n",max_len % 2 ? "" : " ");
1445 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1449 printf("%s\n", name);
1453 n = ellipsize(name, max_len-len, 100);
1461 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1463 static const char *dependencies[_DEPENDENCY_MAX] = {
1464 [DEPENDENCY_FORWARD] = "Requires\0"
1465 "RequiresOverridable\0"
1467 "RequisiteOverridable\0"
1469 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1470 "RequiredByOverridable\0"
1473 [DEPENDENCY_AFTER] = "After\0",
1474 [DEPENDENCY_BEFORE] = "Before\0",
1477 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1478 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1479 _cleanup_strv_free_ char **ret = NULL;
1480 _cleanup_free_ char *path = NULL;
1486 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1488 path = unit_dbus_path_from_name(name);
1492 r = sd_bus_call_method(
1494 "org.freedesktop.systemd1",
1496 "org.freedesktop.DBus.Properties",
1500 "s", "org.freedesktop.systemd1.Unit");
1502 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1506 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1508 return bus_log_parse_error(r);
1510 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1513 r = sd_bus_message_read(reply, "s", &prop);
1515 return bus_log_parse_error(r);
1517 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1518 r = sd_bus_message_skip(reply, "v");
1520 return bus_log_parse_error(r);
1523 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1525 return bus_log_parse_error(r);
1527 r = bus_message_read_strv_extend(reply, &ret);
1529 return bus_log_parse_error(r);
1531 r = sd_bus_message_exit_container(reply);
1533 return bus_log_parse_error(r);
1536 r = sd_bus_message_exit_container(reply);
1538 return bus_log_parse_error(r);
1542 return bus_log_parse_error(r);
1544 r = sd_bus_message_exit_container(reply);
1546 return bus_log_parse_error(r);
1554 static int list_dependencies_compare(const void *_a, const void *_b) {
1555 const char **a = (const char**) _a, **b = (const char**) _b;
1557 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1559 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1562 return strcasecmp(*a, *b);
1565 static int list_dependencies_one(
1570 unsigned int branches) {
1572 _cleanup_strv_free_ char **deps = NULL;
1580 r = strv_extend(units, name);
1584 r = list_dependencies_get_dependencies(bus, name, &deps);
1588 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1590 STRV_FOREACH(c, deps) {
1593 if (strv_contains(*units, *c)) {
1595 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1602 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1604 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1606 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1608 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1612 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1613 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1620 strv_remove(*units, name);
1625 static int list_dependencies(sd_bus *bus, char **args) {
1626 _cleanup_strv_free_ char **units = NULL;
1627 _cleanup_free_ char *unit = NULL;
1633 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1638 u = SPECIAL_DEFAULT_TARGET;
1640 pager_open_if_enabled();
1644 return list_dependencies_one(bus, u, 0, &units, 0);
1647 struct machine_info {
1651 char *control_group;
1652 uint32_t n_failed_units;
1657 static const struct bus_properties_map machine_info_property_map[] = {
1658 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1659 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1660 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1661 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1662 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1666 static void free_machines_list(struct machine_info *machine_infos, int n) {
1672 for (i = 0; i < n; i++) {
1673 free(machine_infos[i].name);
1674 free(machine_infos[i].state);
1675 free(machine_infos[i].control_group);
1678 free(machine_infos);
1681 static int compare_machine_info(const void *a, const void *b) {
1682 const struct machine_info *u = a, *v = b;
1684 if (u->is_host != v->is_host)
1685 return u->is_host > v->is_host ? -1 : 1;
1687 return strcasecmp(u->name, v->name);
1690 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1691 _cleanup_bus_unref_ sd_bus *container = NULL;
1697 r = sd_bus_open_system_container(&container, mi->name);
1704 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1711 static bool output_show_machine(const char *name, char **patterns) {
1716 if (strv_isempty(patterns))
1719 STRV_FOREACH(i, patterns)
1720 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1726 static int get_machine_list(
1728 struct machine_info **_machine_infos,
1731 struct machine_info *machine_infos = NULL;
1732 _cleanup_strv_free_ char **m = NULL;
1733 _cleanup_free_ char *hn = NULL;
1738 hn = gethostname_malloc();
1742 if (output_show_machine(hn, patterns)) {
1743 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1746 machine_infos[c].is_host = true;
1747 machine_infos[c].name = hn;
1750 get_machine_properties(bus, &machine_infos[c]);
1754 sd_get_machine_names(&m);
1755 STRV_FOREACH(i, m) {
1756 _cleanup_free_ char *class = NULL;
1758 if (!output_show_machine(*i, patterns))
1761 sd_machine_get_class(*i, &class);
1762 if (!streq_ptr(class, "container"))
1765 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1766 free_machines_list(machine_infos, c);
1770 machine_infos[c].is_host = false;
1771 machine_infos[c].name = strdup(*i);
1772 if (!machine_infos[c].name) {
1773 free_machines_list(machine_infos, c);
1777 get_machine_properties(NULL, &machine_infos[c]);
1781 *_machine_infos = machine_infos;
1785 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1786 struct machine_info *m;
1789 namelen = sizeof("NAME") - 1,
1790 statelen = sizeof("STATE") - 1,
1791 failedlen = sizeof("FAILED") - 1,
1792 jobslen = sizeof("JOBS") - 1;
1794 assert(machine_infos || n == 0);
1796 for (m = machine_infos; m < machine_infos + n; m++) {
1797 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1798 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1799 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1800 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1802 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1806 if (!arg_no_legend) {
1810 printf("%-*s %-*s %-*s %-*s\n",
1813 failedlen, "FAILED",
1817 for (m = machine_infos; m < machine_infos + n; m++) {
1818 const char *on_state = "", *off_state = "";
1819 const char *on_failed = "", *off_failed = "";
1820 bool circle = false;
1822 if (streq_ptr(m->state, "degraded")) {
1823 on_state = ansi_highlight_red();
1824 off_state = ansi_highlight_off();
1826 } else if (!streq_ptr(m->state, "running")) {
1827 on_state = ansi_highlight_yellow();
1828 off_state = ansi_highlight_off();
1832 if (m->n_failed_units > 0) {
1833 on_failed = ansi_highlight_red();
1834 off_failed = ansi_highlight_off();
1836 on_failed = off_failed = "";
1839 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1842 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1843 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1844 on_state, statelen, strna(m->state), off_state,
1845 on_failed, failedlen, m->n_failed_units, off_failed,
1846 jobslen, m->n_jobs);
1848 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1849 namelen, strna(m->name),
1850 on_state, statelen, strna(m->state), off_state,
1851 on_failed, failedlen, m->n_failed_units, off_failed,
1852 jobslen, m->n_jobs);
1856 printf("\n%u machines listed.\n", n);
1859 static int list_machines(sd_bus *bus, char **args) {
1860 struct machine_info *machine_infos = NULL;
1865 if (geteuid() != 0) {
1866 log_error("Must be root.");
1870 pager_open_if_enabled();
1872 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1876 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1877 output_machines_list(machine_infos, r);
1878 free_machines_list(machine_infos, r);
1883 static int get_default(sd_bus *bus, char **args) {
1884 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1885 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1886 _cleanup_free_ char *_path = NULL;
1890 if (!bus || avoid_bus()) {
1891 r = unit_file_get_default(arg_scope, arg_root, &_path);
1893 log_error("Failed to get default target: %s", strerror(-r));
1899 r = sd_bus_call_method(
1901 "org.freedesktop.systemd1",
1902 "/org/freedesktop/systemd1",
1903 "org.freedesktop.systemd1.Manager",
1909 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1913 r = sd_bus_message_read(reply, "s", &path);
1915 return bus_log_parse_error(r);
1919 printf("%s\n", path);
1924 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1927 assert(changes || n_changes == 0);
1929 for (i = 0; i < n_changes; i++) {
1930 if (changes[i].type == UNIT_FILE_SYMLINK)
1931 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1933 log_info("Removed symlink %s.", changes[i].path);
1937 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1938 const char *type, *path, *source;
1941 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1943 return bus_log_parse_error(r);
1945 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1947 if (streq(type, "symlink"))
1948 log_info("Created symlink from %s to %s.", path, source);
1950 log_info("Removed symlink %s.", path);
1954 return bus_log_parse_error(r);
1956 r = sd_bus_message_exit_container(m);
1958 return bus_log_parse_error(r);
1963 static int set_default(sd_bus *bus, char **args) {
1964 _cleanup_free_ char *unit = NULL;
1965 UnitFileChange *changes = NULL;
1966 unsigned n_changes = 0;
1969 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1973 if (!bus || avoid_bus()) {
1974 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1976 log_error("Failed to set default target: %s", strerror(-r));
1981 dump_unit_file_changes(changes, n_changes);
1985 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1986 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1988 r = sd_bus_call_method(
1990 "org.freedesktop.systemd1",
1991 "/org/freedesktop/systemd1",
1992 "org.freedesktop.systemd1.Manager",
1998 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2002 r = deserialize_and_dump_unit_file_changes(reply);
2006 /* Try to reload if enabled */
2008 r = daemon_reload(bus, args);
2013 unit_file_changes_free(changes, n_changes);
2020 const char *name, *type, *state;
2023 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2024 unsigned id_len, unit_len, type_len, state_len;
2025 const struct job_info *j;
2026 const char *on, *off;
2027 bool shorten = false;
2029 assert(n == 0 || jobs);
2032 on = ansi_highlight_green();
2033 off = ansi_highlight_off();
2035 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2039 pager_open_if_enabled();
2041 id_len = strlen("JOB");
2042 unit_len = strlen("UNIT");
2043 type_len = strlen("TYPE");
2044 state_len = strlen("STATE");
2046 for (j = jobs; j < jobs + n; j++) {
2047 uint32_t id = j->id;
2048 assert(j->name && j->type && j->state);
2050 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2051 unit_len = MAX(unit_len, strlen(j->name));
2052 type_len = MAX(type_len, strlen(j->type));
2053 state_len = MAX(state_len, strlen(j->state));
2056 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2057 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2062 printf("%*s %-*s %-*s %-*s\n",
2066 state_len, "STATE");
2068 for (j = jobs; j < jobs + n; j++) {
2069 _cleanup_free_ char *e = NULL;
2071 if (streq(j->state, "running")) {
2072 on = ansi_highlight();
2073 off = ansi_highlight_off();
2077 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2078 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2080 on, unit_len, e ? e : j->name, off,
2082 on, state_len, j->state, off);
2085 if (!arg_no_legend) {
2086 on = ansi_highlight();
2087 off = ansi_highlight_off();
2089 printf("\n%s%u jobs listed%s.\n", on, n, off);
2093 static bool output_show_job(struct job_info *job, char **patterns) {
2098 if (strv_isempty(patterns))
2101 STRV_FOREACH(pattern, patterns)
2102 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2107 static int list_jobs(sd_bus *bus, char **args) {
2108 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2109 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2110 const char *name, *type, *state, *job_path, *unit_path;
2111 _cleanup_free_ struct job_info *jobs = NULL;
2116 bool skipped = false;
2118 r = sd_bus_call_method(
2120 "org.freedesktop.systemd1",
2121 "/org/freedesktop/systemd1",
2122 "org.freedesktop.systemd1.Manager",
2128 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2132 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2134 return bus_log_parse_error(r);
2136 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2137 struct job_info job = { id, name, type, state };
2139 if (!output_show_job(&job, strv_skip_first(args))) {
2144 if (!GREEDY_REALLOC(jobs, size, c + 1))
2150 return bus_log_parse_error(r);
2152 r = sd_bus_message_exit_container(reply);
2154 return bus_log_parse_error(r);
2156 output_jobs_list(jobs, c, skipped);
2160 static int cancel_job(sd_bus *bus, char **args) {
2161 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2166 if (strv_length(args) <= 1)
2167 return daemon_reload(bus, args);
2169 STRV_FOREACH(name, args+1) {
2173 r = safe_atou32(*name, &id);
2175 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
2179 r = sd_bus_call_method(
2181 "org.freedesktop.systemd1",
2182 "/org/freedesktop/systemd1",
2183 "org.freedesktop.systemd1.Manager",
2189 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
2197 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2198 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2202 /* We ignore all errors here, since this is used to show a
2205 /* We don't use unit_dbus_path_from_name() directly since we
2206 * don't want to load the unit if it isn't loaded. */
2208 r = sd_bus_call_method(
2210 "org.freedesktop.systemd1",
2211 "/org/freedesktop/systemd1",
2212 "org.freedesktop.systemd1.Manager",
2220 r = sd_bus_message_read(reply, "o", &path);
2224 r = sd_bus_get_property_trivial(
2226 "org.freedesktop.systemd1",
2228 "org.freedesktop.systemd1.Unit",
2238 typedef struct WaitData {
2245 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2252 log_debug("Got D-Bus request: %s.%s() on %s",
2253 sd_bus_message_get_interface(m),
2254 sd_bus_message_get_member(m),
2255 sd_bus_message_get_path(m));
2257 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2258 log_error("Warning! D-Bus connection terminated.");
2260 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2262 const char *path, *result, *unit;
2266 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2268 ret = set_remove(d->set, (char*) path);
2274 if (!isempty(result))
2275 d->result = strdup(result);
2278 d->name = strdup(unit);
2283 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2285 ret = set_remove(d->set, (char*) path);
2292 d->result = strdup(result);
2298 bus_log_parse_error(r);
2304 static int enable_wait_for_jobs(sd_bus *bus) {
2309 r = sd_bus_add_match(
2313 "sender='org.freedesktop.systemd1',"
2314 "interface='org.freedesktop.systemd1.Manager',"
2315 "member='JobRemoved',"
2316 "path='/org/freedesktop/systemd1'",
2319 log_error("Failed to add match");
2323 /* This is slightly dirty, since we don't undo the match registrations. */
2327 static int bus_process_wait(sd_bus *bus) {
2331 r = sd_bus_process(bus, NULL);
2336 r = sd_bus_wait(bus, (uint64_t) -1);
2342 static int check_wait_response(WaitData *d) {
2348 if (streq(d->result, "timeout"))
2349 log_error("Job for %s timed out.", strna(d->name));
2350 else if (streq(d->result, "canceled"))
2351 log_error("Job for %s canceled.", strna(d->name));
2352 else if (streq(d->result, "dependency"))
2353 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2354 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2355 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2358 if (streq(d->result, "timeout"))
2360 else if (streq(d->result, "canceled"))
2362 else if (streq(d->result, "dependency"))
2364 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2370 static int wait_for_jobs(sd_bus *bus, Set *s) {
2371 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2372 WaitData d = { .set = s };
2378 q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2382 while (!set_isempty(s)) {
2383 q = bus_process_wait(bus);
2385 log_error("Failed to wait for response: %s", strerror(-r));
2390 q = check_wait_response(&d);
2391 /* Return the first error as it is most likely to be
2393 if (q < 0 && r == 0)
2395 log_debug("Got result %s/%s for job %s",
2396 strna(d.result), strerror(-q), strna(d.name));
2409 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2410 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2411 _cleanup_free_ char *n = NULL, *state = NULL;
2417 n = unit_name_mangle(name, MANGLE_NOGLOB);
2421 /* We don't use unit_dbus_path_from_name() directly since we
2422 * don't want to load the unit if it isn't loaded. */
2424 r = sd_bus_call_method(
2426 "org.freedesktop.systemd1",
2427 "/org/freedesktop/systemd1",
2428 "org.freedesktop.systemd1.Manager",
2439 r = sd_bus_message_read(reply, "o", &path);
2441 return bus_log_parse_error(r);
2443 r = sd_bus_get_property_string(
2445 "org.freedesktop.systemd1",
2447 "org.freedesktop.systemd1.Unit",
2460 return nulstr_contains(good_states, state);
2463 static int check_triggering_units(
2467 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2468 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2469 _cleanup_strv_free_ char **triggered_by = NULL;
2470 bool print_warning_label = true;
2474 n = unit_name_mangle(name, MANGLE_NOGLOB);
2478 path = unit_dbus_path_from_name(n);
2482 r = sd_bus_get_property_string(
2484 "org.freedesktop.systemd1",
2486 "org.freedesktop.systemd1.Unit",
2491 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2495 if (streq(state, "masked"))
2498 r = sd_bus_get_property_strv(
2500 "org.freedesktop.systemd1",
2502 "org.freedesktop.systemd1.Unit",
2507 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2511 STRV_FOREACH(i, triggered_by) {
2512 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2514 log_error("Failed to check unit: %s", strerror(-r));
2521 if (print_warning_label) {
2522 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2523 print_warning_label = false;
2526 log_warning(" %s", *i);
2532 static const char *verb_to_method(const char *verb) {
2535 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2536 if (streq_ptr(unit_actions[i].verb, verb))
2537 return unit_actions[i].method;
2542 static const char *method_to_verb(const char *method) {
2545 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2546 if (streq_ptr(unit_actions[i].method, method))
2547 return unit_actions[i].verb;
2552 static int start_unit_one(
2557 sd_bus_error *error,
2560 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2569 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2570 r = sd_bus_call_method(
2572 "org.freedesktop.systemd1",
2573 "/org/freedesktop/systemd1",
2574 "org.freedesktop.systemd1.Manager",
2582 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2583 /* There's always a fallback possible for
2584 * legacy actions. */
2585 return -EADDRNOTAVAIL;
2587 verb = method_to_verb(method);
2589 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2593 r = sd_bus_message_read(reply, "o", &path);
2595 return bus_log_parse_error(r);
2597 if (need_daemon_reload(bus, name) > 0)
2598 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2599 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2608 log_debug("Adding %s to the set", p);
2609 r = set_consume(s, p);
2617 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2619 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2623 STRV_FOREACH(name, names) {
2627 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2629 t = unit_name_mangle(*name, MANGLE_GLOB);
2633 if (string_is_glob(t))
2634 r = strv_consume(&globs, t);
2636 r = strv_consume(&mangled, t);
2641 /* Query the manager only if any of the names are a glob, since
2642 * this is fairly expensive */
2643 if (!strv_isempty(globs)) {
2644 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2645 _cleanup_free_ UnitInfo *unit_infos = NULL;
2647 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2651 for (i = 0; i < r; i++)
2652 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2657 mangled = NULL; /* do not free */
2662 static const struct {
2666 } action_table[_ACTION_MAX] = {
2667 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2668 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2669 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2670 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2671 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2672 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2673 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2674 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2675 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2676 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2677 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2678 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2679 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2680 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2681 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2684 static enum action verb_to_action(const char *verb) {
2687 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2688 if (streq_ptr(action_table[i].verb, verb))
2691 return _ACTION_INVALID;
2694 static int start_unit(sd_bus *bus, char **args) {
2695 _cleanup_set_free_free_ Set *s = NULL;
2696 _cleanup_strv_free_ char **names = NULL;
2697 const char *method, *mode, *one_name;
2703 ask_password_agent_open_if_enabled();
2705 if (arg_action == ACTION_SYSTEMCTL) {
2707 method = verb_to_method(args[0]);
2708 action = verb_to_action(args[0]);
2710 mode = streq(args[0], "isolate") ? "isolate" :
2711 action_table[action].mode ?: arg_job_mode;
2713 one_name = action_table[action].target;
2715 assert(arg_action < ELEMENTSOF(action_table));
2716 assert(action_table[arg_action].target);
2718 method = "StartUnit";
2720 mode = action_table[arg_action].mode;
2721 one_name = action_table[arg_action].target;
2725 names = strv_new(one_name, NULL);
2727 r = expand_names(bus, args + 1, NULL, &names);
2729 log_error("Failed to expand names: %s", strerror(-r));
2732 if (!arg_no_block) {
2733 r = enable_wait_for_jobs(bus);
2735 log_error("Could not watch jobs: %s", strerror(-r));
2739 s = set_new(string_hash_func, string_compare_func);
2744 STRV_FOREACH(name, names) {
2745 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2748 q = start_unit_one(bus, method, *name, mode, &error, s);
2749 if (r >= 0 && q < 0)
2750 r = translate_bus_error_to_exit_status(q, &error);
2753 if (!arg_no_block) {
2756 q = wait_for_jobs(bus, s);
2760 /* When stopping units, warn if they can still be triggered by
2761 * another active unit (socket, path, timer) */
2762 if (!arg_quiet && streq(method, "StopUnit"))
2763 STRV_FOREACH(name, names)
2764 check_triggering_units(bus, *name);
2770 /* Ask systemd-logind, which might grant access to unprivileged users
2771 * through PolicyKit */
2772 static int reboot_with_logind(sd_bus *bus, enum action a) {
2774 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2781 polkit_agent_open_if_enabled();
2789 case ACTION_POWEROFF:
2790 method = "PowerOff";
2793 case ACTION_SUSPEND:
2797 case ACTION_HIBERNATE:
2798 method = "Hibernate";
2801 case ACTION_HYBRID_SLEEP:
2802 method = "HybridSleep";
2809 r = sd_bus_call_method(
2811 "org.freedesktop.login1",
2812 "/org/freedesktop/login1",
2813 "org.freedesktop.login1.Manager",
2819 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2827 static int check_inhibitors(sd_bus *bus, enum action a) {
2829 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2830 _cleanup_strv_free_ char **sessions = NULL;
2831 const char *what, *who, *why, *mode;
2840 if (arg_ignore_inhibitors || arg_force > 0)
2852 r = sd_bus_call_method(
2854 "org.freedesktop.login1",
2855 "/org/freedesktop/login1",
2856 "org.freedesktop.login1.Manager",
2862 /* If logind is not around, then there are no inhibitors... */
2865 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2867 return bus_log_parse_error(r);
2869 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2870 _cleanup_free_ char *comm = NULL, *user = NULL;
2871 _cleanup_strv_free_ char **sv = NULL;
2873 if (!streq(mode, "block"))
2876 sv = strv_split(what, ":");
2880 if (!strv_contains(sv,
2882 a == ACTION_POWEROFF ||
2883 a == ACTION_REBOOT ||
2884 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2887 get_process_comm(pid, &comm);
2888 user = uid_to_name(uid);
2890 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2891 who, pid, strna(comm), strna(user), why);
2896 return bus_log_parse_error(r);
2898 r = sd_bus_message_exit_container(reply);
2900 return bus_log_parse_error(r);
2902 /* Check for current sessions */
2903 sd_get_sessions(&sessions);
2904 STRV_FOREACH(s, sessions) {
2905 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2907 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2910 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2913 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2916 sd_session_get_tty(*s, &tty);
2917 sd_session_get_seat(*s, &seat);
2918 sd_session_get_service(*s, &service);
2919 user = uid_to_name(uid);
2921 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2928 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2929 action_table[a].verb);
2937 static int start_special(sd_bus *bus, char **args) {
2943 a = verb_to_action(args[0]);
2945 r = check_inhibitors(bus, a);
2949 if (arg_force >= 2 && geteuid() != 0) {
2950 log_error("Must be root.");
2954 if (arg_force >= 2 &&
2955 (a == ACTION_HALT ||
2956 a == ACTION_POWEROFF ||
2957 a == ACTION_REBOOT))
2960 if (arg_force >= 1 &&
2961 (a == ACTION_HALT ||
2962 a == ACTION_POWEROFF ||
2963 a == ACTION_REBOOT ||
2964 a == ACTION_KEXEC ||
2966 return daemon_reload(bus, args);
2968 /* first try logind, to allow authentication with polkit */
2969 if (geteuid() != 0 &&
2970 (a == ACTION_POWEROFF ||
2971 a == ACTION_REBOOT ||
2972 a == ACTION_SUSPEND ||
2973 a == ACTION_HIBERNATE ||
2974 a == ACTION_HYBRID_SLEEP)) {
2975 r = reboot_with_logind(bus, a);
2980 r = start_unit(bus, args);
2981 if (r == EXIT_SUCCESS)
2987 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2988 _cleanup_strv_free_ char **names = NULL;
2995 r = expand_names(bus, args, NULL, &names);
2997 log_error("Failed to expand names: %s", strerror(-r));
3001 STRV_FOREACH(name, names) {
3004 state = check_one_unit(bus, *name, good_states, arg_quiet);
3014 static int check_unit_active(sd_bus *bus, char **args) {
3015 /* According to LSB: 3, "program is not running" */
3016 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3019 static int check_unit_failed(sd_bus *bus, char **args) {
3020 return check_unit_generic(bus, 1, "failed\0", args + 1);
3023 static int kill_unit(sd_bus *bus, char **args) {
3024 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3025 _cleanup_strv_free_ char **names = NULL;
3033 arg_kill_who = "all";
3035 r = expand_names(bus, args + 1, NULL, &names);
3037 log_error("Failed to expand names: %s", strerror(-r));
3039 STRV_FOREACH(name, names) {
3040 q = sd_bus_call_method(
3042 "org.freedesktop.systemd1",
3043 "/org/freedesktop/systemd1",
3044 "org.freedesktop.systemd1.Manager",
3048 "ssi", *names, arg_kill_who, arg_signal);
3050 log_error("Failed to kill unit %s: %s",
3051 *names, bus_error_message(&error, r));
3060 typedef struct ExecStatusInfo {
3068 usec_t start_timestamp;
3069 usec_t exit_timestamp;
3074 LIST_FIELDS(struct ExecStatusInfo, exec);
3077 static void exec_status_info_free(ExecStatusInfo *i) {
3086 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3087 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3090 int32_t code, status;
3096 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3098 return bus_log_parse_error(r);
3102 r = sd_bus_message_read(m, "s", &path);
3104 return bus_log_parse_error(r);
3106 i->path = strdup(path);
3110 r = sd_bus_message_read_strv(m, &i->argv);
3112 return bus_log_parse_error(r);
3114 r = sd_bus_message_read(m,
3117 &start_timestamp, &start_timestamp_monotonic,
3118 &exit_timestamp, &exit_timestamp_monotonic,
3122 return bus_log_parse_error(r);
3125 i->start_timestamp = (usec_t) start_timestamp;
3126 i->exit_timestamp = (usec_t) exit_timestamp;
3127 i->pid = (pid_t) pid;
3131 r = sd_bus_message_exit_container(m);
3133 return bus_log_parse_error(r);
3138 typedef struct UnitStatusInfo {
3140 const char *load_state;
3141 const char *active_state;
3142 const char *sub_state;
3143 const char *unit_file_state;
3145 const char *description;
3146 const char *following;
3148 char **documentation;
3150 const char *fragment_path;
3151 const char *source_path;
3152 const char *control_group;
3154 char **dropin_paths;
3156 const char *load_error;
3159 usec_t inactive_exit_timestamp;
3160 usec_t inactive_exit_timestamp_monotonic;
3161 usec_t active_enter_timestamp;
3162 usec_t active_exit_timestamp;
3163 usec_t inactive_enter_timestamp;
3165 bool need_daemon_reload;
3170 const char *status_text;
3171 const char *pid_file;
3175 usec_t start_timestamp;
3176 usec_t exit_timestamp;
3178 int exit_code, exit_status;
3180 usec_t condition_timestamp;
3181 bool condition_result;
3182 bool failed_condition_trigger;
3183 bool failed_condition_negate;
3184 const char *failed_condition;
3185 const char *failed_condition_param;
3188 unsigned n_accepted;
3189 unsigned n_connections;
3192 /* Pairs of type, path */
3196 const char *sysfs_path;
3198 /* Mount, Automount */
3204 LIST_HEAD(ExecStatusInfo, exec);
3207 static void print_status_info(
3212 const char *active_on, *active_off, *on, *off, *ss;
3214 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3215 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3218 arg_all * OUTPUT_SHOW_ALL |
3219 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3220 on_tty() * OUTPUT_COLOR |
3221 !arg_quiet * OUTPUT_WARN_CUTOFF |
3222 arg_full * OUTPUT_FULL_WIDTH;
3227 /* This shows pretty information about a unit. See
3228 * print_property() for a low-level property printer */
3230 if (streq_ptr(i->active_state, "failed")) {
3231 active_on = ansi_highlight_red();
3232 active_off = ansi_highlight_off();
3233 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3234 active_on = ansi_highlight_green();
3235 active_off = ansi_highlight_off();
3237 active_on = active_off = "";
3239 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3241 if (i->description && !streq_ptr(i->id, i->description))
3242 printf(" - %s", i->description);
3247 printf(" Follow: unit currently follows state of %s\n", i->following);
3249 if (streq_ptr(i->load_state, "error")) {
3250 on = ansi_highlight_red();
3251 off = ansi_highlight_off();
3255 path = i->source_path ? i->source_path : i->fragment_path;
3258 printf(" Loaded: %s%s%s (Reason: %s)\n",
3259 on, strna(i->load_state), off, i->load_error);
3260 else if (path && i->unit_file_state)
3261 printf(" Loaded: %s%s%s (%s; %s)\n",
3262 on, strna(i->load_state), off, path, i->unit_file_state);
3264 printf(" Loaded: %s%s%s (%s)\n",
3265 on, strna(i->load_state), off, path);
3267 printf(" Loaded: %s%s%s\n",
3268 on, strna(i->load_state), off);
3270 if (!strv_isempty(i->dropin_paths)) {
3271 _cleanup_free_ char *dir = NULL;
3275 STRV_FOREACH(dropin, i->dropin_paths) {
3276 if (! dir || last) {
3277 printf(dir ? " " : " Drop-In: ");
3282 if (path_get_parent(*dropin, &dir) < 0) {
3287 printf("%s\n %s", dir,
3288 draw_special_char(DRAW_TREE_RIGHT));
3291 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3293 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3297 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3299 printf(" Active: %s%s (%s)%s",
3300 active_on, strna(i->active_state), ss, active_off);
3302 printf(" Active: %s%s%s",
3303 active_on, strna(i->active_state), active_off);
3305 if (!isempty(i->result) && !streq(i->result, "success"))
3306 printf(" (Result: %s)", i->result);
3308 timestamp = (streq_ptr(i->active_state, "active") ||
3309 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3310 (streq_ptr(i->active_state, "inactive") ||
3311 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3312 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3313 i->active_exit_timestamp;
3315 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3316 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3319 printf(" since %s; %s\n", s2, s1);
3321 printf(" since %s\n", s2);
3325 if (!i->condition_result && i->condition_timestamp > 0) {
3326 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3327 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3329 printf(" start condition failed at %s%s%s\n",
3330 s2, s1 ? "; " : "", s1 ? s1 : "");
3331 if (i->failed_condition_trigger)
3332 printf(" none of the trigger conditions were met\n");
3333 else if (i->failed_condition)
3334 printf(" %s=%s%s was not met\n",
3335 i->failed_condition,
3336 i->failed_condition_negate ? "!" : "",
3337 i->failed_condition_param);
3341 printf(" Device: %s\n", i->sysfs_path);
3343 printf(" Where: %s\n", i->where);
3345 printf(" What: %s\n", i->what);
3347 STRV_FOREACH(t, i->documentation)
3348 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3350 STRV_FOREACH_PAIR(t, t2, i->listen)
3351 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3354 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3356 LIST_FOREACH(exec, p, i->exec) {
3357 _cleanup_free_ char *argv = NULL;
3360 /* Only show exited processes here */
3364 argv = strv_join(p->argv, " ");
3365 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3367 good = is_clean_exit_lsb(p->code, p->status, NULL);
3369 on = ansi_highlight_red();
3370 off = ansi_highlight_off();
3374 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3376 if (p->code == CLD_EXITED) {
3379 printf("status=%i", p->status);
3381 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3386 printf("signal=%s", signal_to_string(p->status));
3388 printf(")%s\n", off);
3390 if (i->main_pid == p->pid &&
3391 i->start_timestamp == p->start_timestamp &&
3392 i->exit_timestamp == p->start_timestamp)
3393 /* Let's not show this twice */
3396 if (p->pid == i->control_pid)
3400 if (i->main_pid > 0 || i->control_pid > 0) {
3401 if (i->main_pid > 0) {
3402 printf(" Main PID: %u", (unsigned) i->main_pid);
3405 _cleanup_free_ char *comm = NULL;
3406 get_process_comm(i->main_pid, &comm);
3408 printf(" (%s)", comm);
3409 } else if (i->exit_code > 0) {
3410 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3412 if (i->exit_code == CLD_EXITED) {
3415 printf("status=%i", i->exit_status);
3417 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3422 printf("signal=%s", signal_to_string(i->exit_status));
3426 if (i->control_pid > 0)
3430 if (i->control_pid > 0) {
3431 _cleanup_free_ char *c = NULL;
3433 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3435 get_process_comm(i->control_pid, &c);
3444 printf(" Status: \"%s\"\n", i->status_text);
3445 if (i->status_errno > 0)
3446 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3448 if (i->control_group &&
3449 (i->main_pid > 0 || i->control_pid > 0 ||
3450 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3453 printf(" CGroup: %s\n", i->control_group);
3455 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3458 static const char prefix[] = " ";
3461 if (c > sizeof(prefix) - 1)
3462 c -= sizeof(prefix) - 1;
3466 if (i->main_pid > 0)
3467 extra[k++] = i->main_pid;
3469 if (i->control_pid > 0)
3470 extra[k++] = i->control_pid;
3472 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3476 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3477 show_journal_by_unit(stdout,
3481 i->inactive_exit_timestamp_monotonic,
3484 flags | OUTPUT_BEGIN_NEWLINE,
3485 arg_scope == UNIT_FILE_SYSTEM,
3489 if (i->need_daemon_reload)
3490 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3491 ansi_highlight_red(),
3492 ansi_highlight_off(),
3493 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3496 static void show_unit_help(UnitStatusInfo *i) {
3501 if (!i->documentation) {
3502 log_info("Documentation for %s not known.", i->id);
3506 STRV_FOREACH(p, i->documentation) {
3508 if (startswith(*p, "man:")) {
3509 const char *args[4] = { "man", NULL, NULL, NULL };
3510 _cleanup_free_ char *page = NULL, *section = NULL;
3517 if ((*p)[k-1] == ')')
3518 e = strrchr(*p, '(');
3521 page = strndup((*p) + 4, e - *p - 4);
3522 section = strndup(e + 1, *p + k - e - 2);
3523 if (!page || !section) {
3535 log_error("Failed to fork: %m");
3541 execvp(args[0], (char**) args);
3542 log_error("Failed to execute man: %m");
3543 _exit(EXIT_FAILURE);
3546 wait_for_terminate(pid, NULL);
3548 log_info("Can't show: %s", *p);
3552 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3559 switch (contents[0]) {
3561 case SD_BUS_TYPE_STRING: {
3564 r = sd_bus_message_read(m, "s", &s);
3566 return bus_log_parse_error(r);
3569 if (streq(name, "Id"))
3571 else if (streq(name, "LoadState"))
3573 else if (streq(name, "ActiveState"))
3574 i->active_state = s;
3575 else if (streq(name, "SubState"))
3577 else if (streq(name, "Description"))
3579 else if (streq(name, "FragmentPath"))
3580 i->fragment_path = s;
3581 else if (streq(name, "SourcePath"))
3584 else if (streq(name, "DefaultControlGroup")) {
3586 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3588 i->control_group = e;
3591 else if (streq(name, "ControlGroup"))
3592 i->control_group = s;
3593 else if (streq(name, "StatusText"))
3595 else if (streq(name, "PIDFile"))
3597 else if (streq(name, "SysFSPath"))
3599 else if (streq(name, "Where"))
3601 else if (streq(name, "What"))
3603 else if (streq(name, "Following"))
3605 else if (streq(name, "UnitFileState"))
3606 i->unit_file_state = s;
3607 else if (streq(name, "Result"))
3614 case SD_BUS_TYPE_BOOLEAN: {
3617 r = sd_bus_message_read(m, "b", &b);
3619 return bus_log_parse_error(r);
3621 if (streq(name, "Accept"))
3623 else if (streq(name, "NeedDaemonReload"))
3624 i->need_daemon_reload = b;
3625 else if (streq(name, "ConditionResult"))
3626 i->condition_result = b;
3631 case SD_BUS_TYPE_UINT32: {
3634 r = sd_bus_message_read(m, "u", &u);
3636 return bus_log_parse_error(r);
3638 if (streq(name, "MainPID")) {
3640 i->main_pid = (pid_t) u;
3643 } else if (streq(name, "ControlPID"))
3644 i->control_pid = (pid_t) u;
3645 else if (streq(name, "ExecMainPID")) {
3647 i->main_pid = (pid_t) u;
3648 } else if (streq(name, "NAccepted"))
3650 else if (streq(name, "NConnections"))
3651 i->n_connections = u;
3656 case SD_BUS_TYPE_INT32: {
3659 r = sd_bus_message_read(m, "i", &j);
3661 return bus_log_parse_error(r);
3663 if (streq(name, "ExecMainCode"))
3664 i->exit_code = (int) j;
3665 else if (streq(name, "ExecMainStatus"))
3666 i->exit_status = (int) j;
3667 else if (streq(name, "StatusErrno"))
3668 i->status_errno = (int) j;
3673 case SD_BUS_TYPE_UINT64: {
3676 r = sd_bus_message_read(m, "t", &u);
3678 return bus_log_parse_error(r);
3680 if (streq(name, "ExecMainStartTimestamp"))
3681 i->start_timestamp = (usec_t) u;
3682 else if (streq(name, "ExecMainExitTimestamp"))
3683 i->exit_timestamp = (usec_t) u;
3684 else if (streq(name, "ActiveEnterTimestamp"))
3685 i->active_enter_timestamp = (usec_t) u;
3686 else if (streq(name, "InactiveEnterTimestamp"))
3687 i->inactive_enter_timestamp = (usec_t) u;
3688 else if (streq(name, "InactiveExitTimestamp"))
3689 i->inactive_exit_timestamp = (usec_t) u;
3690 else if (streq(name, "InactiveExitTimestampMonotonic"))
3691 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3692 else if (streq(name, "ActiveExitTimestamp"))
3693 i->active_exit_timestamp = (usec_t) u;
3694 else if (streq(name, "ConditionTimestamp"))
3695 i->condition_timestamp = (usec_t) u;
3700 case SD_BUS_TYPE_ARRAY:
3702 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3703 _cleanup_free_ ExecStatusInfo *info = NULL;
3705 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3707 return bus_log_parse_error(r);
3709 info = new0(ExecStatusInfo, 1);
3713 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3715 info->name = strdup(name);
3719 LIST_PREPEND(exec, i->exec, info);
3721 info = new0(ExecStatusInfo, 1);
3727 return bus_log_parse_error(r);
3729 r = sd_bus_message_exit_container(m);
3731 return bus_log_parse_error(r);
3735 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3736 const char *type, *path;
3738 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3740 return bus_log_parse_error(r);
3742 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3744 r = strv_extend(&i->listen, type);
3748 r = strv_extend(&i->listen, path);
3753 return bus_log_parse_error(r);
3755 r = sd_bus_message_exit_container(m);
3757 return bus_log_parse_error(r);
3761 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3763 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3765 return bus_log_parse_error(r);
3767 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3769 r = sd_bus_message_read_strv(m, &i->documentation);
3771 return bus_log_parse_error(r);
3773 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3774 const char *cond, *param;
3775 int trigger, negate;
3778 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3780 return bus_log_parse_error(r);
3782 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3783 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3784 if (state < 0 && (!trigger || !i->failed_condition)) {
3785 i->failed_condition = cond;
3786 i->failed_condition_trigger = trigger;
3787 i->failed_condition_negate = negate;
3788 i->failed_condition_param = param;
3792 return bus_log_parse_error(r);
3794 r = sd_bus_message_exit_container(m);
3796 return bus_log_parse_error(r);
3803 case SD_BUS_TYPE_STRUCT_BEGIN:
3805 if (streq(name, "LoadError")) {
3806 const char *n, *message;
3808 r = sd_bus_message_read(m, "(ss)", &n, &message);
3810 return bus_log_parse_error(r);
3812 if (!isempty(message))
3813 i->load_error = message;
3826 r = sd_bus_message_skip(m, contents);
3828 return bus_log_parse_error(r);
3833 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3839 /* This is a low-level property printer, see
3840 * print_status_info() for the nicer output */
3842 if (arg_properties && !strv_find(arg_properties, name)) {
3843 /* skip what we didn't read */
3844 r = sd_bus_message_skip(m, contents);
3848 switch (contents[0]) {
3850 case SD_BUS_TYPE_STRUCT_BEGIN:
3852 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3855 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3857 return bus_log_parse_error(r);
3860 printf("%s=%u\n", name, (unsigned) u);
3862 printf("%s=\n", name);
3866 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3869 r = sd_bus_message_read(m, "(so)", &s, NULL);
3871 return bus_log_parse_error(r);
3873 if (arg_all || !isempty(s))
3874 printf("%s=%s\n", name, s);
3878 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3879 const char *a = NULL, *b = NULL;
3881 r = sd_bus_message_read(m, "(ss)", &a, &b);
3883 return bus_log_parse_error(r);
3885 if (arg_all || !isempty(a) || !isempty(b))
3886 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3889 } else if (streq_ptr(name, "SystemCallFilter")) {
3890 _cleanup_strv_free_ char **l = NULL;
3893 r = sd_bus_message_enter_container(m, 'r', "bas");
3895 return bus_log_parse_error(r);
3897 r = sd_bus_message_read(m, "b", &whitelist);
3899 return bus_log_parse_error(r);
3901 r = sd_bus_message_read_strv(m, &l);
3903 return bus_log_parse_error(r);
3905 r = sd_bus_message_exit_container(m);
3907 return bus_log_parse_error(r);
3909 if (arg_all || whitelist || !strv_isempty(l)) {
3913 fputs(name, stdout);
3919 STRV_FOREACH(i, l) {
3927 fputc('\n', stdout);
3935 case SD_BUS_TYPE_ARRAY:
3937 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3941 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3943 return bus_log_parse_error(r);
3945 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3946 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3949 return bus_log_parse_error(r);
3951 r = sd_bus_message_exit_container(m);
3953 return bus_log_parse_error(r);
3957 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3958 const char *type, *path;
3960 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3962 return bus_log_parse_error(r);
3964 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3965 printf("%s=%s\n", type, path);
3967 return bus_log_parse_error(r);
3969 r = sd_bus_message_exit_container(m);
3971 return bus_log_parse_error(r);
3975 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3976 const char *type, *path;
3978 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3980 return bus_log_parse_error(r);
3982 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3983 printf("Listen%s=%s\n", type, path);
3985 return bus_log_parse_error(r);
3987 r = sd_bus_message_exit_container(m);
3989 return bus_log_parse_error(r);
3993 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3995 uint64_t value, next_elapse;
3997 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3999 return bus_log_parse_error(r);
4001 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4002 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4004 printf("%s={ value=%s ; next_elapse=%s }\n",
4006 format_timespan(timespan1, sizeof(timespan1), value, 0),
4007 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4010 return bus_log_parse_error(r);
4012 r = sd_bus_message_exit_container(m);
4014 return bus_log_parse_error(r);
4018 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4019 ExecStatusInfo info = {};
4021 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4023 return bus_log_parse_error(r);
4025 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4026 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4027 _cleanup_free_ char *tt;
4029 tt = strv_join(info.argv, " ");
4031 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
4035 yes_no(info.ignore),
4036 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4037 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4038 (unsigned) info. pid,
4039 sigchld_code_to_string(info.code),
4041 info.code == CLD_EXITED ? "" : "/",
4042 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4045 strv_free(info.argv);
4049 r = sd_bus_message_exit_container(m);
4051 return bus_log_parse_error(r);
4055 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4056 const char *path, *rwm;
4058 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4060 return bus_log_parse_error(r);
4062 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4063 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4065 return bus_log_parse_error(r);
4067 r = sd_bus_message_exit_container(m);
4069 return bus_log_parse_error(r);
4073 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4077 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4079 return bus_log_parse_error(r);
4081 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4082 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4084 return bus_log_parse_error(r);
4086 r = sd_bus_message_exit_container(m);
4088 return bus_log_parse_error(r);
4092 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4096 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4098 return bus_log_parse_error(r);
4100 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4101 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4103 return bus_log_parse_error(r);
4105 r = sd_bus_message_exit_container(m);
4107 return bus_log_parse_error(r);
4115 r = bus_print_property(name, m, arg_all);
4117 return bus_log_parse_error(r);
4120 r = sd_bus_message_skip(m, contents);
4122 return bus_log_parse_error(r);
4125 printf("%s=[unprintable]\n", name);
4131 static int show_one(
4135 bool show_properties,
4139 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4140 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4141 UnitStatusInfo info = {};
4148 log_debug("Showing one %s", path);
4150 r = sd_bus_call_method(
4152 "org.freedesktop.systemd1",
4154 "org.freedesktop.DBus.Properties",
4160 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4164 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4166 return bus_log_parse_error(r);
4173 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4174 const char *name, *contents;
4176 r = sd_bus_message_read(reply, "s", &name);
4178 return bus_log_parse_error(r);
4180 r = sd_bus_message_peek_type(reply, NULL, &contents);
4182 return bus_log_parse_error(r);
4184 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4186 return bus_log_parse_error(r);
4188 if (show_properties)
4189 r = print_property(name, reply, contents);
4191 r = status_property(name, reply, &info, contents);
4195 r = sd_bus_message_exit_container(reply);
4197 return bus_log_parse_error(r);
4199 r = sd_bus_message_exit_container(reply);
4201 return bus_log_parse_error(r);
4204 return bus_log_parse_error(r);
4206 r = sd_bus_message_exit_container(reply);
4208 return bus_log_parse_error(r);
4212 if (!show_properties) {
4213 if (streq(verb, "help"))
4214 show_unit_help(&info);
4216 print_status_info(&info, ellipsized);
4219 strv_free(info.documentation);
4220 strv_free(info.dropin_paths);
4221 strv_free(info.listen);
4223 if (!streq_ptr(info.active_state, "active") &&
4224 !streq_ptr(info.active_state, "reloading") &&
4225 streq(verb, "status")) {
4226 /* According to LSB: "program not running" */
4227 /* 0: program is running or service is OK
4228 * 1: program is dead and /run PID file exists
4229 * 2: program is dead and /run/lock lock file exists
4230 * 3: program is not running
4231 * 4: program or service status is unknown
4233 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4239 while ((p = info.exec)) {
4240 LIST_REMOVE(exec, info.exec, p);
4241 exec_status_info_free(p);
4247 static int get_unit_dbus_path_by_pid(
4252 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4253 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4257 r = sd_bus_call_method(
4259 "org.freedesktop.systemd1",
4260 "/org/freedesktop/systemd1",
4261 "org.freedesktop.systemd1.Manager",
4267 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4271 r = sd_bus_message_read(reply, "o", &u);
4273 return bus_log_parse_error(r);
4283 static int show_all(
4286 bool show_properties,
4290 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4291 _cleanup_free_ UnitInfo *unit_infos = NULL;
4296 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4300 pager_open_if_enabled();
4304 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4306 for (u = unit_infos; u < unit_infos + c; u++) {
4307 _cleanup_free_ char *p = NULL;
4309 p = unit_dbus_path_from_name(u->id);
4313 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4316 else if (r > 0 && ret == 0)
4323 static int show_system_status(sd_bus *bus) {
4324 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4325 _cleanup_free_ char *hn = NULL;
4326 struct machine_info mi = {};
4327 const char *on, *off;
4330 hn = gethostname_malloc();
4334 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4336 log_error("Failed to read server status: %s", strerror(-r));
4340 if (streq_ptr(mi.state, "degraded")) {
4341 on = ansi_highlight_red();
4342 off = ansi_highlight_off();
4343 } else if (!streq_ptr(mi.state, "running")) {
4344 on = ansi_highlight_yellow();
4345 off = ansi_highlight_off();
4349 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4351 printf(" State: %s%s%s\n",
4352 on, strna(mi.state), off);
4354 printf(" Jobs: %u queued\n", mi.n_jobs);
4355 printf(" Failed: %u units\n", mi.n_failed_units);
4357 printf(" Since: %s; %s\n",
4358 format_timestamp(since2, sizeof(since2), mi.timestamp),
4359 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4361 printf(" CGroup: %s\n", mi.control_group ?: "/");
4362 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4364 arg_all * OUTPUT_SHOW_ALL |
4365 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4366 on_tty() * OUTPUT_COLOR |
4367 !arg_quiet * OUTPUT_WARN_CUTOFF |
4368 arg_full * OUTPUT_FULL_WIDTH;
4370 static const char prefix[] = " ";
4374 if (c > sizeof(prefix) - 1)
4375 c -= sizeof(prefix) - 1;
4379 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4383 free(mi.control_group);
4388 static int show(sd_bus *bus, char **args) {
4389 bool show_properties, show_status, new_line = false;
4390 bool ellipsized = false;
4396 show_properties = streq(args[0], "show");
4397 show_status = streq(args[0], "status");
4399 if (show_properties)
4400 pager_open_if_enabled();
4402 /* If no argument is specified inspect the manager itself */
4404 if (show_properties && strv_length(args) <= 1)
4405 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4407 if (show_status && strv_length(args) <= 1) {
4409 pager_open_if_enabled();
4410 show_system_status(bus);
4414 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4416 _cleanup_free_ char **patterns = NULL;
4419 STRV_FOREACH(name, args + 1) {
4420 _cleanup_free_ char *unit = NULL;
4423 if (safe_atou32(*name, &id) < 0) {
4424 if (strv_push(&patterns, *name) < 0)
4428 } else if (show_properties) {
4429 /* Interpret as job id */
4430 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4434 /* Interpret as PID */
4435 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4442 r = show_one(args[0], bus, unit, show_properties,
4443 &new_line, &ellipsized);
4446 else if (r > 0 && ret == 0)
4450 if (!strv_isempty(patterns)) {
4451 _cleanup_strv_free_ char **names = NULL;
4453 r = expand_names(bus, patterns, NULL, &names);
4455 log_error("Failed to expand names: %s", strerror(-r));
4457 STRV_FOREACH(name, names) {
4458 _cleanup_free_ char *unit;
4460 unit = unit_dbus_path_from_name(*name);
4464 r = show_one(args[0], bus, unit, show_properties,
4465 &new_line, &ellipsized);
4468 else if (r > 0 && ret == 0)
4474 if (ellipsized && !arg_quiet)
4475 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4480 static int cat(sd_bus *bus, char **args) {
4481 _cleanup_free_ char *unit = NULL;
4482 _cleanup_strv_free_ char **names = NULL;
4490 r = expand_names(bus, args + 1, NULL, &names);
4492 log_error("Failed to expand names: %s", strerror(-r));
4494 pager_open_if_enabled();
4496 STRV_FOREACH(name, names) {
4497 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4498 _cleanup_strv_free_ char **dropin_paths = NULL;
4499 _cleanup_free_ char *fragment_path = NULL;
4502 unit = unit_dbus_path_from_name(*name);
4506 if (need_daemon_reload(bus, *name) > 0)
4507 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4508 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4510 r = sd_bus_get_property_string(
4512 "org.freedesktop.systemd1",
4514 "org.freedesktop.systemd1.Unit",
4519 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4523 r = sd_bus_get_property_strv(
4525 "org.freedesktop.systemd1",
4527 "org.freedesktop.systemd1.Unit",
4532 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4541 if (!isempty(fragment_path)) {
4542 printf("%s# %s%s\n",
4543 ansi_highlight_blue(),
4545 ansi_highlight_off());
4548 r = sendfile_full(STDOUT_FILENO, fragment_path);
4550 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4555 STRV_FOREACH(path, dropin_paths) {
4556 printf("%s%s# %s%s\n",
4557 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4558 ansi_highlight_blue(),
4560 ansi_highlight_off());
4563 r = sendfile_full(STDOUT_FILENO, *path);
4565 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4571 return r < 0 ? r : 0;
4574 static int set_property(sd_bus *bus, char **args) {
4575 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4576 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4577 _cleanup_free_ char *n = NULL;
4581 r = sd_bus_message_new_method_call(
4584 "org.freedesktop.systemd1",
4585 "/org/freedesktop/systemd1",
4586 "org.freedesktop.systemd1.Manager",
4587 "SetUnitProperties");
4589 return bus_log_create_error(r);
4591 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4595 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4597 return bus_log_create_error(r);
4599 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4601 return bus_log_create_error(r);
4603 STRV_FOREACH(i, args + 2) {
4604 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4606 return bus_log_create_error(r);
4608 r = bus_append_unit_property_assignment(m, *i);
4612 r = sd_bus_message_close_container(m);
4614 return bus_log_create_error(r);
4617 r = sd_bus_message_close_container(m);
4619 return bus_log_create_error(r);
4621 r = sd_bus_call(bus, m, 0, &error, NULL);
4623 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4630 static int snapshot(sd_bus *bus, char **args) {
4631 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4632 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4633 _cleanup_free_ char *n = NULL, *id = NULL;
4637 if (strv_length(args) > 1)
4638 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4644 r = sd_bus_call_method(
4646 "org.freedesktop.systemd1",
4647 "/org/freedesktop/systemd1",
4648 "org.freedesktop.systemd1.Manager",
4654 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4658 r = sd_bus_message_read(reply, "o", &path);
4660 return bus_log_parse_error(r);
4662 r = sd_bus_get_property_string(
4664 "org.freedesktop.systemd1",
4666 "org.freedesktop.systemd1.Unit",
4671 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4681 static int delete_snapshot(sd_bus *bus, char **args) {
4682 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4683 _cleanup_strv_free_ char **names = NULL;
4689 r = expand_names(bus, args + 1, ".snapshot", &names);
4691 log_error("Failed to expand names: %s", strerror(-r));
4693 STRV_FOREACH(name, names) {
4694 q = sd_bus_call_method(
4696 "org.freedesktop.systemd1",
4697 "/org/freedesktop/systemd1",
4698 "org.freedesktop.systemd1.Manager",
4704 log_error("Failed to remove snapshot %s: %s",
4705 *name, bus_error_message(&error, r));
4714 static int daemon_reload(sd_bus *bus, char **args) {
4715 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4719 if (arg_action == ACTION_RELOAD)
4721 else if (arg_action == ACTION_REEXEC)
4722 method = "Reexecute";
4724 assert(arg_action == ACTION_SYSTEMCTL);
4727 streq(args[0], "clear-jobs") ||
4728 streq(args[0], "cancel") ? "ClearJobs" :
4729 streq(args[0], "daemon-reexec") ? "Reexecute" :
4730 streq(args[0], "reset-failed") ? "ResetFailed" :
4731 streq(args[0], "halt") ? "Halt" :
4732 streq(args[0], "poweroff") ? "PowerOff" :
4733 streq(args[0], "reboot") ? "Reboot" :
4734 streq(args[0], "kexec") ? "KExec" :
4735 streq(args[0], "exit") ? "Exit" :
4736 /* "daemon-reload" */ "Reload";
4739 r = sd_bus_call_method(
4741 "org.freedesktop.systemd1",
4742 "/org/freedesktop/systemd1",
4743 "org.freedesktop.systemd1.Manager",
4749 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4750 /* There's always a fallback possible for
4751 * legacy actions. */
4753 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4754 /* On reexecution, we expect a disconnect, not a
4758 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4760 return r < 0 ? r : 0;
4763 static int reset_failed(sd_bus *bus, char **args) {
4764 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4765 _cleanup_strv_free_ char **names = NULL;
4769 if (strv_length(args) <= 1)
4770 return daemon_reload(bus, args);
4772 r = expand_names(bus, args + 1, NULL, &names);
4774 log_error("Failed to expand names: %s", strerror(-r));
4776 STRV_FOREACH(name, names) {
4777 q = sd_bus_call_method(
4779 "org.freedesktop.systemd1",
4780 "/org/freedesktop/systemd1",
4781 "org.freedesktop.systemd1.Manager",
4787 log_error("Failed to reset failed state of unit %s: %s",
4788 *name, bus_error_message(&error, r));
4797 static int show_environment(sd_bus *bus, char **args) {
4798 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4799 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4803 pager_open_if_enabled();
4805 r = sd_bus_get_property(
4807 "org.freedesktop.systemd1",
4808 "/org/freedesktop/systemd1",
4809 "org.freedesktop.systemd1.Manager",
4815 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4819 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4821 return bus_log_parse_error(r);
4823 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4826 return bus_log_parse_error(r);
4828 r = sd_bus_message_exit_container(reply);
4830 return bus_log_parse_error(r);
4835 static int switch_root(sd_bus *bus, char **args) {
4836 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4837 _cleanup_free_ char *cmdline_init = NULL;
4838 const char *root, *init;
4842 l = strv_length(args);
4843 if (l < 2 || l > 3) {
4844 log_error("Wrong number of arguments.");
4853 r = parse_env_file("/proc/cmdline", WHITESPACE,
4854 "init", &cmdline_init,
4857 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4859 init = cmdline_init;
4866 const char *root_systemd_path = NULL, *root_init_path = NULL;
4868 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4869 root_init_path = strappenda3(root, "/", init);
4871 /* If the passed init is actually the same as the
4872 * systemd binary, then let's suppress it. */
4873 if (files_same(root_init_path, root_systemd_path) > 0)
4877 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4879 r = sd_bus_call_method(
4881 "org.freedesktop.systemd1",
4882 "/org/freedesktop/systemd1",
4883 "org.freedesktop.systemd1.Manager",
4889 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4896 static int set_environment(sd_bus *bus, char **args) {
4897 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4898 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4905 method = streq(args[0], "set-environment")
4907 : "UnsetEnvironment";
4909 r = sd_bus_message_new_method_call(
4912 "org.freedesktop.systemd1",
4913 "/org/freedesktop/systemd1",
4914 "org.freedesktop.systemd1.Manager",
4917 return bus_log_create_error(r);
4919 r = sd_bus_message_append_strv(m, args + 1);
4921 return bus_log_create_error(r);
4923 r = sd_bus_call(bus, m, 0, &error, NULL);
4925 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4932 static int import_environment(sd_bus *bus, char **args) {
4933 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4934 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4940 r = sd_bus_message_new_method_call(
4943 "org.freedesktop.systemd1",
4944 "/org/freedesktop/systemd1",
4945 "org.freedesktop.systemd1.Manager",
4948 return bus_log_create_error(r);
4950 if (strv_isempty(args + 1))
4951 r = sd_bus_message_append_strv(m, environ);
4955 r = sd_bus_message_open_container(m, 'a', "s");
4957 return bus_log_create_error(r);
4959 STRV_FOREACH(a, args + 1) {
4961 if (!env_name_is_valid(*a)) {
4962 log_error("Not a valid environment variable name: %s", *a);
4966 STRV_FOREACH(b, environ) {
4969 eq = startswith(*b, *a);
4970 if (eq && *eq == '=') {
4972 r = sd_bus_message_append(m, "s", *b);
4974 return bus_log_create_error(r);
4981 r = sd_bus_message_close_container(m);
4984 return bus_log_create_error(r);
4986 r = sd_bus_call(bus, m, 0, &error, NULL);
4988 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4995 static int enable_sysv_units(const char *verb, char **args) {
4998 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4999 unsigned f = 1, t = 1;
5000 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5002 if (arg_scope != UNIT_FILE_SYSTEM)
5005 if (!streq(verb, "enable") &&
5006 !streq(verb, "disable") &&
5007 !streq(verb, "is-enabled"))
5010 /* Processes all SysV units, and reshuffles the array so that
5011 * afterwards only the native units remain */
5013 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5018 for (f = 0; args[f]; f++) {
5020 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5021 bool found_native = false, found_sysv;
5023 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5031 if (!endswith(name, ".service"))
5034 if (path_is_absolute(name))
5037 STRV_FOREACH(k, paths.unit_path) {
5038 _cleanup_free_ char *path = NULL;
5040 if (!isempty(arg_root))
5041 asprintf(&path, "%s/%s/%s", arg_root, *k, name);
5043 asprintf(&path, "%s/%s", *k, name);
5050 found_native = access(path, F_OK) >= 0;
5058 if (!isempty(arg_root))
5059 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
5061 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
5067 p[strlen(p) - strlen(".service")] = 0;
5068 found_sysv = access(p, F_OK) >= 0;
5072 /* Mark this entry, so that we don't try enabling it as native unit */
5073 args[f] = (char*) "";
5075 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5077 if (!isempty(arg_root))
5078 argv[c++] = q = strappend("--root=", arg_root);
5080 argv[c++] = basename(p);
5082 streq(verb, "enable") ? "on" :
5083 streq(verb, "disable") ? "off" : "--level=5";
5086 l = strv_join((char**)argv, " ");
5092 log_info("Executing %s", l);
5096 log_error("Failed to fork: %m");
5099 } else if (pid == 0) {
5102 execv(argv[0], (char**) argv);
5103 _exit(EXIT_FAILURE);
5106 j = wait_for_terminate(pid, &status);
5108 log_error("Failed to wait for child: %s", strerror(-r));
5113 if (status.si_code == CLD_EXITED) {
5114 if (streq(verb, "is-enabled")) {
5115 if (status.si_status == 0) {
5124 } else if (status.si_status != 0) {
5135 /* Drop all SysV units */
5136 for (f = 0, t = 0; args[f]; f++) {
5138 if (isempty(args[f]))
5141 args[t++] = args[f];
5150 static int mangle_names(char **original_names, char ***mangled_names) {
5151 char **i, **l, **name;
5153 l = new(char*, strv_length(original_names) + 1);
5158 STRV_FOREACH(name, original_names) {
5160 /* When enabling units qualified path names are OK,
5161 * too, hence allow them explicitly. */
5166 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5182 static int enable_unit(sd_bus *bus, char **args) {
5183 _cleanup_strv_free_ char **names = NULL;
5184 const char *verb = args[0];
5185 UnitFileChange *changes = NULL;
5186 unsigned n_changes = 0;
5187 int carries_install_info = -1;
5193 r = mangle_names(args+1, &names);
5197 r = enable_sysv_units(verb, names);
5201 /* If the operation was fully executed by the SysV compat,
5202 * let's finish early */
5203 if (strv_isempty(names))
5206 if (!bus || avoid_bus()) {
5207 if (streq(verb, "enable")) {
5208 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5209 carries_install_info = r;
5210 } else if (streq(verb, "disable"))
5211 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5212 else if (streq(verb, "reenable")) {
5213 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5214 carries_install_info = r;
5215 } else if (streq(verb, "link"))
5216 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5217 else if (streq(verb, "preset")) {
5218 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5219 carries_install_info = r;
5220 } else if (streq(verb, "mask"))
5221 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5222 else if (streq(verb, "unmask"))
5223 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5225 assert_not_reached("Unknown verb");
5228 log_error("Operation failed: %s", strerror(-r));
5233 dump_unit_file_changes(changes, n_changes);
5237 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5238 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5239 int expect_carries_install_info = false;
5240 bool send_force = true, send_preset_mode = false;
5243 if (streq(verb, "enable")) {
5244 method = "EnableUnitFiles";
5245 expect_carries_install_info = true;
5246 } else if (streq(verb, "disable")) {
5247 method = "DisableUnitFiles";
5249 } else if (streq(verb, "reenable")) {
5250 method = "ReenableUnitFiles";
5251 expect_carries_install_info = true;
5252 } else if (streq(verb, "link"))
5253 method = "LinkUnitFiles";
5254 else if (streq(verb, "preset")) {
5256 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5257 method = "PresetUnitFilesWithMode";
5258 send_preset_mode = true;
5260 method = "PresetUnitFiles";
5262 expect_carries_install_info = true;
5263 } else if (streq(verb, "mask"))
5264 method = "MaskUnitFiles";
5265 else if (streq(verb, "unmask")) {
5266 method = "UnmaskUnitFiles";
5269 assert_not_reached("Unknown verb");
5271 r = sd_bus_message_new_method_call(
5274 "org.freedesktop.systemd1",
5275 "/org/freedesktop/systemd1",
5276 "org.freedesktop.systemd1.Manager",
5279 return bus_log_create_error(r);
5281 r = sd_bus_message_append_strv(m, names);
5283 return bus_log_create_error(r);
5285 if (send_preset_mode) {
5286 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5288 return bus_log_create_error(r);
5291 r = sd_bus_message_append(m, "b", arg_runtime);
5293 return bus_log_create_error(r);
5296 r = sd_bus_message_append(m, "b", arg_force);
5298 return bus_log_create_error(r);
5301 r = sd_bus_call(bus, m, 0, &error, &reply);
5303 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5307 if (expect_carries_install_info) {
5308 r = sd_bus_message_read(reply, "b", &carries_install_info);
5310 return bus_log_parse_error(r);
5313 r = deserialize_and_dump_unit_file_changes(reply);
5317 /* Try to reload if enabled */
5319 r = daemon_reload(bus, args);
5324 if (carries_install_info == 0)
5325 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5326 "using systemctl.\n"
5327 "Possible reasons for having this kind of units are:\n"
5328 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5329 " .wants/ or .requires/ directory.\n"
5330 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5331 " a requirement dependency on it.\n"
5332 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5333 " D-Bus, udev, scripted systemctl call, ...).\n");
5336 unit_file_changes_free(changes, n_changes);
5341 static int preset_all(sd_bus *bus, char **args) {
5342 UnitFileChange *changes = NULL;
5343 unsigned n_changes = 0;
5346 if (!bus || avoid_bus()) {
5348 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5350 log_error("Operation failed: %s", strerror(-r));
5355 dump_unit_file_changes(changes, n_changes);
5360 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5361 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5363 r = sd_bus_call_method(
5365 "org.freedesktop.systemd1",
5366 "/org/freedesktop/systemd1",
5367 "org.freedesktop.systemd1.Manager",
5368 "PresetAllUnitFiles",
5372 unit_file_preset_mode_to_string(arg_preset_mode),
5376 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5380 r = deserialize_and_dump_unit_file_changes(reply);
5385 r = daemon_reload(bus, args);
5391 unit_file_changes_free(changes, n_changes);
5396 static int unit_is_enabled(sd_bus *bus, char **args) {
5398 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5399 _cleanup_strv_free_ char **names = NULL;
5404 r = mangle_names(args+1, &names);
5408 r = enable_sysv_units(args[0], names);
5414 if (!bus || avoid_bus()) {
5416 STRV_FOREACH(name, names) {
5417 UnitFileState state;
5419 state = unit_file_get_state(arg_scope, arg_root, *name);
5421 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5425 if (state == UNIT_FILE_ENABLED ||
5426 state == UNIT_FILE_ENABLED_RUNTIME ||
5427 state == UNIT_FILE_STATIC)
5431 puts(unit_file_state_to_string(state));
5435 STRV_FOREACH(name, names) {
5436 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5439 r = sd_bus_call_method(
5441 "org.freedesktop.systemd1",
5442 "/org/freedesktop/systemd1",
5443 "org.freedesktop.systemd1.Manager",
5449 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5453 r = sd_bus_message_read(reply, "s", &s);
5455 return bus_log_parse_error(r);
5457 if (streq(s, "enabled") ||
5458 streq(s, "enabled-runtime") ||
5470 static int is_system_running(sd_bus *bus, char **args) {
5471 _cleanup_free_ char *state = NULL;
5474 r = sd_bus_get_property_string(
5476 "org.freedesktop.systemd1",
5477 "/org/freedesktop/systemd1",
5478 "org.freedesktop.systemd1.Manager",
5491 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5494 static int systemctl_help(void) {
5496 pager_open_if_enabled();
5498 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5499 "Query or send control commands to the systemd manager.\n\n"
5500 " -h --help Show this help\n"
5501 " --version Show package version\n"
5502 " --system Connect to system manager\n"
5503 " --user Connect to user service manager\n"
5504 " -H --host=[USER@]HOST\n"
5505 " Operate on remote host\n"
5506 " -M --machine=CONTAINER\n"
5507 " Operate on local container\n"
5508 " -t --type=TYPE List only units of a particular type\n"
5509 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5510 " -p --property=NAME Show only properties by this name\n"
5511 " -a --all Show all loaded units/properties, including dead/empty\n"
5512 " ones. To list all units installed on the system, use\n"
5513 " the 'list-unit-files' command instead.\n"
5514 " -l --full Don't ellipsize unit names on output\n"
5515 " -r --recursive Show unit list of host and local containers\n"
5516 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5517 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5518 " queueing a new job\n"
5519 " --show-types When showing sockets, explicitly show their type\n"
5520 " -i --ignore-inhibitors\n"
5521 " When shutting down or sleeping, ignore inhibitors\n"
5522 " --kill-who=WHO Who to send signal to\n"
5523 " -s --signal=SIGNAL Which signal to send\n"
5524 " -q --quiet Suppress output\n"
5525 " --no-block Do not wait until operation finished\n"
5526 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5527 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5529 " --no-legend Do not print a legend (column headers and hints)\n"
5530 " --no-pager Do not pipe output into a pager\n"
5531 " --no-ask-password\n"
5532 " Do not ask for system passwords\n"
5533 " --global Enable/disable unit files globally\n"
5534 " --runtime Enable unit files only temporarily until next reboot\n"
5535 " -f --force When enabling unit files, override existing symlinks\n"
5536 " When shutting down, execute action immediately\n"
5537 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
5538 " or only disable\n"
5539 " --root=PATH Enable unit files in the specified root directory\n"
5540 " -n --lines=INTEGER Number of journal entries to show\n"
5541 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5542 " verbose, export, json, json-pretty, json-sse, cat)\n"
5543 " --plain Print unit dependencies as a list instead of a tree\n\n"
5545 " list-units [PATTERN...] List loaded units\n"
5546 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5547 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5548 " start NAME... Start (activate) one or more units\n"
5549 " stop NAME... Stop (deactivate) one or more units\n"
5550 " reload NAME... Reload one or more units\n"
5551 " restart NAME... Start or restart one or more units\n"
5552 " try-restart NAME... Restart one or more units if active\n"
5553 " reload-or-restart NAME... Reload one or more units if possible,\n"
5554 " otherwise start or restart\n"
5555 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5556 " otherwise restart if active\n"
5557 " isolate NAME Start one unit and stop all others\n"
5558 " kill NAME... Send signal to processes of a unit\n"
5559 " is-active PATTERN... Check whether units are active\n"
5560 " is-failed PATTERN... Check whether units are failed\n"
5561 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5562 " show [PATTERN...|JOB...] Show properties of one or more\n"
5563 " units/jobs or the manager\n"
5564 " cat PATTERN... Show files and drop-ins of one or more units\n"
5565 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5566 " help PATTERN...|PID... Show manual for one or more units\n"
5567 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5569 " list-dependencies [NAME] Recursively show units which are required\n"
5570 " or wanted by this unit or by which this\n"
5571 " unit is required or wanted\n\n"
5572 "Unit File Commands:\n"
5573 " list-unit-files [PATTERN...] List installed unit files\n"
5574 " enable NAME... Enable one or more unit files\n"
5575 " disable NAME... Disable one or more unit files\n"
5576 " reenable NAME... Reenable one or more unit files\n"
5577 " preset NAME... Enable/disable one or more unit files\n"
5578 " based on preset configuration\n"
5579 " preset-all Enable/disable all unit files based on\n"
5580 " preset configuration\n"
5581 " is-enabled NAME... Check whether unit files are enabled\n\n"
5582 " mask NAME... Mask one or more units\n"
5583 " unmask NAME... Unmask one or more units\n"
5584 " link PATH... Link one or more units files into\n"
5585 " the search path\n"
5586 " get-default Get the name of the default target\n"
5587 " set-default NAME Set the default target\n\n"
5588 "Machine Commands:\n"
5589 " list-machines [PATTERN...] List local containers and host\n\n"
5591 " list-jobs [PATTERN...] List jobs\n"
5592 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5593 "Snapshot Commands:\n"
5594 " snapshot [NAME] Create a snapshot\n"
5595 " delete NAME... Remove one or more snapshots\n\n"
5596 "Environment Commands:\n"
5597 " show-environment Dump environment\n"
5598 " set-environment NAME=VALUE... Set one or more environment variables\n"
5599 " unset-environment NAME... Unset one or more environment variables\n"
5600 " import-environment NAME... Import all, one or more environment variables\n\n"
5601 "Manager Lifecycle Commands:\n"
5602 " daemon-reload Reload systemd manager configuration\n"
5603 " daemon-reexec Reexecute systemd manager\n\n"
5604 "System Commands:\n"
5605 " is-system-running Check whether system is fully running\n"
5606 " default Enter system default mode\n"
5607 " rescue Enter system rescue mode\n"
5608 " emergency Enter system emergency mode\n"
5609 " halt Shut down and halt the system\n"
5610 " poweroff Shut down and power-off the system\n"
5611 " reboot [ARG] Shut down and reboot the system\n"
5612 " kexec Shut down and reboot the system with kexec\n"
5613 " exit Request user instance exit\n"
5614 " switch-root ROOT [INIT] Change to a different root file system\n"
5615 " suspend Suspend the system\n"
5616 " hibernate Hibernate the system\n"
5617 " hybrid-sleep Hibernate and suspend the system\n",
5618 program_invocation_short_name);
5623 static int halt_help(void) {
5625 printf("%s [OPTIONS...]%s\n\n"
5626 "%s the system.\n\n"
5627 " --help Show this help\n"
5628 " --halt Halt the machine\n"
5629 " -p --poweroff Switch off the machine\n"
5630 " --reboot Reboot the machine\n"
5631 " -f --force Force immediate halt/power-off/reboot\n"
5632 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5633 " -d --no-wtmp Don't write wtmp record\n"
5634 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5635 program_invocation_short_name,
5636 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5637 arg_action == ACTION_REBOOT ? "Reboot" :
5638 arg_action == ACTION_POWEROFF ? "Power off" :
5644 static int shutdown_help(void) {
5646 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5647 "Shut down the system.\n\n"
5648 " --help Show this help\n"
5649 " -H --halt Halt the machine\n"
5650 " -P --poweroff Power-off the machine\n"
5651 " -r --reboot Reboot the machine\n"
5652 " -h Equivalent to --poweroff, overridden by --halt\n"
5653 " -k Don't halt/power-off/reboot, just send warnings\n"
5654 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5655 " -c Cancel a pending shutdown\n",
5656 program_invocation_short_name);
5661 static int telinit_help(void) {
5663 printf("%s [OPTIONS...] {COMMAND}\n\n"
5664 "Send control commands to the init daemon.\n\n"
5665 " --help Show this help\n"
5666 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5668 " 0 Power-off the machine\n"
5669 " 6 Reboot the machine\n"
5670 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5671 " 1, s, S Enter rescue mode\n"
5672 " q, Q Reload init daemon configuration\n"
5673 " u, U Reexecute init daemon\n",
5674 program_invocation_short_name);
5679 static int runlevel_help(void) {
5681 printf("%s [OPTIONS...]\n\n"
5682 "Prints the previous and current runlevel of the init system.\n\n"
5683 " --help Show this help\n",
5684 program_invocation_short_name);
5689 static int help_types(void) {
5693 puts("Available unit types:");
5694 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5695 t = unit_type_to_string(i);
5703 static int systemctl_parse_argv(int argc, char *argv[]) {
5712 ARG_IGNORE_DEPENDENCIES,
5724 ARG_NO_ASK_PASSWORD,
5734 static const struct option options[] = {
5735 { "help", no_argument, NULL, 'h' },
5736 { "version", no_argument, NULL, ARG_VERSION },
5737 { "type", required_argument, NULL, 't' },
5738 { "property", required_argument, NULL, 'p' },
5739 { "all", no_argument, NULL, 'a' },
5740 { "reverse", no_argument, NULL, ARG_REVERSE },
5741 { "after", no_argument, NULL, ARG_AFTER },
5742 { "before", no_argument, NULL, ARG_BEFORE },
5743 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5744 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5745 { "full", no_argument, NULL, 'l' },
5746 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5747 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5748 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5749 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5750 { "ignore-inhibitors", no_argument, NULL, 'i' },
5751 { "user", no_argument, NULL, ARG_USER },
5752 { "system", no_argument, NULL, ARG_SYSTEM },
5753 { "global", no_argument, NULL, ARG_GLOBAL },
5754 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5755 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5756 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5757 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5758 { "quiet", no_argument, NULL, 'q' },
5759 { "root", required_argument, NULL, ARG_ROOT },
5760 { "force", no_argument, NULL, ARG_FORCE },
5761 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5762 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5763 { "signal", required_argument, NULL, 's' },
5764 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5765 { "host", required_argument, NULL, 'H' },
5766 { "machine", required_argument, NULL, 'M' },
5767 { "runtime", no_argument, NULL, ARG_RUNTIME },
5768 { "lines", required_argument, NULL, 'n' },
5769 { "output", required_argument, NULL, 'o' },
5770 { "plain", no_argument, NULL, ARG_PLAIN },
5771 { "state", required_argument, NULL, ARG_STATE },
5772 { "recursive", no_argument, NULL, 'r' },
5773 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
5782 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0) {
5787 return systemctl_help();
5790 puts(PACKAGE_STRING);
5791 puts(SYSTEMD_FEATURES);
5798 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5799 _cleanup_free_ char *type;
5801 type = strndup(word, size);
5805 if (streq(type, "help")) {
5810 if (unit_type_from_string(type) >= 0) {
5811 if (strv_push(&arg_types, type))
5817 /* It's much nicer to use --state= for
5818 * load states, but let's support this
5819 * in --types= too for compatibility
5820 * with old versions */
5821 if (unit_load_state_from_string(optarg) >= 0) {
5822 if (strv_push(&arg_states, type) < 0)
5828 log_error("Unknown unit type or load state '%s'.", type);
5829 log_info("Use -t help to see a list of allowed values.");
5837 /* Make sure that if the empty property list
5838 was specified, we won't show any properties. */
5839 if (isempty(optarg) && !arg_properties) {
5840 arg_properties = new0(char*, 1);
5841 if (!arg_properties)
5847 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5850 prop = strndup(word, size);
5854 if (strv_consume(&arg_properties, prop) < 0)
5859 /* If the user asked for a particular
5860 * property, show it to him, even if it is
5872 arg_dependency = DEPENDENCY_REVERSE;
5876 arg_dependency = DEPENDENCY_AFTER;
5880 arg_dependency = DEPENDENCY_BEFORE;
5883 case ARG_SHOW_TYPES:
5884 arg_show_types = true;
5888 arg_job_mode = optarg;
5892 arg_job_mode = "fail";
5895 case ARG_IRREVERSIBLE:
5896 arg_job_mode = "replace-irreversibly";
5899 case ARG_IGNORE_DEPENDENCIES:
5900 arg_job_mode = "ignore-dependencies";
5904 arg_scope = UNIT_FILE_USER;
5908 arg_scope = UNIT_FILE_SYSTEM;
5912 arg_scope = UNIT_FILE_GLOBAL;
5916 arg_no_block = true;
5920 arg_no_legend = true;
5924 arg_no_pager = true;
5940 if (strv_extend(&arg_states, "failed") < 0)
5958 arg_no_reload = true;
5962 arg_kill_who = optarg;
5966 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5967 log_error("Failed to parse signal string %s.", optarg);
5972 case ARG_NO_ASK_PASSWORD:
5973 arg_ask_password = false;
5977 arg_transport = BUS_TRANSPORT_REMOTE;
5982 arg_transport = BUS_TRANSPORT_CONTAINER;
5991 if (safe_atou(optarg, &arg_lines) < 0) {
5992 log_error("Failed to parse lines '%s'", optarg);
5998 arg_output = output_mode_from_string(optarg);
5999 if (arg_output < 0) {
6000 log_error("Unknown output '%s'.", optarg);
6006 arg_ignore_inhibitors = true;
6017 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6020 s = strndup(word, size);
6024 if (strv_consume(&arg_states, s) < 0)
6031 if (geteuid() != 0) {
6032 log_error("--recursive requires root privileges.");
6036 arg_recursive = true;
6039 case ARG_PRESET_MODE:
6041 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6042 if (arg_preset_mode < 0) {
6043 log_error("Failed to parse preset mode: %s.", optarg);
6053 assert_not_reached("Unhandled option");
6057 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6058 log_error("Cannot access user instance remotely.");
6065 static int halt_parse_argv(int argc, char *argv[]) {
6074 static const struct option options[] = {
6075 { "help", no_argument, NULL, ARG_HELP },
6076 { "halt", no_argument, NULL, ARG_HALT },
6077 { "poweroff", no_argument, NULL, 'p' },
6078 { "reboot", no_argument, NULL, ARG_REBOOT },
6079 { "force", no_argument, NULL, 'f' },
6080 { "wtmp-only", no_argument, NULL, 'w' },
6081 { "no-wtmp", no_argument, NULL, 'd' },
6082 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6091 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6092 if (runlevel == '0' || runlevel == '6')
6095 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
6102 arg_action = ACTION_HALT;
6106 if (arg_action != ACTION_REBOOT)
6107 arg_action = ACTION_POWEROFF;
6111 arg_action = ACTION_REBOOT;
6133 /* Compatibility nops */
6140 assert_not_reached("Unhandled option");
6144 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6145 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6148 } else if (optind < argc) {
6149 log_error("Too many arguments.");
6156 static int parse_time_spec(const char *t, usec_t *_u) {
6160 if (streq(t, "now"))
6162 else if (!strchr(t, ':')) {
6165 if (safe_atou64(t, &u) < 0)
6168 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6177 hour = strtol(t, &e, 10);
6178 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6181 minute = strtol(e+1, &e, 10);
6182 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6185 n = now(CLOCK_REALTIME);
6186 s = (time_t) (n / USEC_PER_SEC);
6188 assert_se(localtime_r(&s, &tm));
6190 tm.tm_hour = (int) hour;
6191 tm.tm_min = (int) minute;
6194 assert_se(s = mktime(&tm));
6196 *_u = (usec_t) s * USEC_PER_SEC;
6199 *_u += USEC_PER_DAY;
6205 static int shutdown_parse_argv(int argc, char *argv[]) {
6212 static const struct option options[] = {
6213 { "help", no_argument, NULL, ARG_HELP },
6214 { "halt", no_argument, NULL, 'H' },
6215 { "poweroff", no_argument, NULL, 'P' },
6216 { "reboot", no_argument, NULL, 'r' },
6217 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6218 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6227 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
6231 return shutdown_help();
6234 arg_action = ACTION_HALT;
6238 arg_action = ACTION_POWEROFF;
6243 arg_action = ACTION_KEXEC;
6245 arg_action = ACTION_REBOOT;
6249 arg_action = ACTION_KEXEC;
6253 if (arg_action != ACTION_HALT)
6254 arg_action = ACTION_POWEROFF;
6267 /* Compatibility nops */
6271 arg_action = ACTION_CANCEL_SHUTDOWN;
6278 assert_not_reached("Unhandled option");
6282 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6283 r = parse_time_spec(argv[optind], &arg_when);
6285 log_error("Failed to parse time specification: %s", argv[optind]);
6289 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6291 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6292 /* No time argument for shutdown cancel */
6293 arg_wall = argv + optind;
6294 else if (argc > optind + 1)
6295 /* We skip the time argument */
6296 arg_wall = argv + optind + 1;
6303 static int telinit_parse_argv(int argc, char *argv[]) {
6310 static const struct option options[] = {
6311 { "help", no_argument, NULL, ARG_HELP },
6312 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6316 static const struct {
6320 { '0', ACTION_POWEROFF },
6321 { '6', ACTION_REBOOT },
6322 { '1', ACTION_RESCUE },
6323 { '2', ACTION_RUNLEVEL2 },
6324 { '3', ACTION_RUNLEVEL3 },
6325 { '4', ACTION_RUNLEVEL4 },
6326 { '5', ACTION_RUNLEVEL5 },
6327 { 's', ACTION_RESCUE },
6328 { 'S', ACTION_RESCUE },
6329 { 'q', ACTION_RELOAD },
6330 { 'Q', ACTION_RELOAD },
6331 { 'u', ACTION_REEXEC },
6332 { 'U', ACTION_REEXEC }
6341 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6345 return telinit_help();
6355 assert_not_reached("Unhandled option");
6359 if (optind >= argc) {
6364 if (optind + 1 < argc) {
6365 log_error("Too many arguments.");
6369 if (strlen(argv[optind]) != 1) {
6370 log_error("Expected single character argument.");
6374 for (i = 0; i < ELEMENTSOF(table); i++)
6375 if (table[i].from == argv[optind][0])
6378 if (i >= ELEMENTSOF(table)) {
6379 log_error("Unknown command '%s'.", argv[optind]);
6383 arg_action = table[i].to;
6390 static int runlevel_parse_argv(int argc, char *argv[]) {
6396 static const struct option options[] = {
6397 { "help", no_argument, NULL, ARG_HELP },
6406 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6410 return runlevel_help();
6416 assert_not_reached("Unhandled option");
6420 if (optind < argc) {
6421 log_error("Too many arguments.");
6428 static int parse_argv(int argc, char *argv[]) {
6432 if (program_invocation_short_name) {
6434 if (strstr(program_invocation_short_name, "halt")) {
6435 arg_action = ACTION_HALT;
6436 return halt_parse_argv(argc, argv);
6437 } else if (strstr(program_invocation_short_name, "poweroff")) {
6438 arg_action = ACTION_POWEROFF;
6439 return halt_parse_argv(argc, argv);
6440 } else if (strstr(program_invocation_short_name, "reboot")) {
6442 arg_action = ACTION_KEXEC;
6444 arg_action = ACTION_REBOOT;
6445 return halt_parse_argv(argc, argv);
6446 } else if (strstr(program_invocation_short_name, "shutdown")) {
6447 arg_action = ACTION_POWEROFF;
6448 return shutdown_parse_argv(argc, argv);
6449 } else if (strstr(program_invocation_short_name, "init")) {
6451 if (sd_booted() > 0) {
6452 arg_action = _ACTION_INVALID;
6453 return telinit_parse_argv(argc, argv);
6455 /* Hmm, so some other init system is
6456 * running, we need to forward this
6457 * request to it. For now we simply
6458 * guess that it is Upstart. */
6460 execv(TELINIT, argv);
6462 log_error("Couldn't find an alternative telinit implementation to spawn.");
6466 } else if (strstr(program_invocation_short_name, "runlevel")) {
6467 arg_action = ACTION_RUNLEVEL;
6468 return runlevel_parse_argv(argc, argv);
6472 arg_action = ACTION_SYSTEMCTL;
6473 return systemctl_parse_argv(argc, argv);
6476 _pure_ static int action_to_runlevel(void) {
6478 static const char table[_ACTION_MAX] = {
6479 [ACTION_HALT] = '0',
6480 [ACTION_POWEROFF] = '0',
6481 [ACTION_REBOOT] = '6',
6482 [ACTION_RUNLEVEL2] = '2',
6483 [ACTION_RUNLEVEL3] = '3',
6484 [ACTION_RUNLEVEL4] = '4',
6485 [ACTION_RUNLEVEL5] = '5',
6486 [ACTION_RESCUE] = '1'
6489 assert(arg_action < _ACTION_MAX);
6491 return table[arg_action];
6494 static int talk_initctl(void) {
6496 struct init_request request = {
6497 .magic = INIT_MAGIC,
6499 .cmd = INIT_CMD_RUNLVL
6502 _cleanup_close_ int fd = -1;
6506 rl = action_to_runlevel();
6510 request.runlevel = rl;
6512 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6514 if (errno == ENOENT)
6517 log_error("Failed to open "INIT_FIFO": %m");
6522 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6524 log_error("Failed to write to "INIT_FIFO": %m");
6525 return errno > 0 ? -errno : -EIO;
6531 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6533 static const struct {
6541 int (* const dispatch)(sd_bus *bus, char **args);
6547 { "list-units", MORE, 0, list_units },
6548 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6549 { "list-sockets", MORE, 1, list_sockets },
6550 { "list-timers", MORE, 1, list_timers },
6551 { "list-jobs", MORE, 1, list_jobs },
6552 { "list-machines", MORE, 1, list_machines },
6553 { "clear-jobs", EQUAL, 1, daemon_reload },
6554 { "cancel", MORE, 2, cancel_job },
6555 { "start", MORE, 2, start_unit },
6556 { "stop", MORE, 2, start_unit },
6557 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6558 { "reload", MORE, 2, start_unit },
6559 { "restart", MORE, 2, start_unit },
6560 { "try-restart", MORE, 2, start_unit },
6561 { "reload-or-restart", MORE, 2, start_unit },
6562 { "reload-or-try-restart", MORE, 2, start_unit },
6563 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6564 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6565 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6566 { "isolate", EQUAL, 2, start_unit },
6567 { "kill", MORE, 2, kill_unit },
6568 { "is-active", MORE, 2, check_unit_active },
6569 { "check", MORE, 2, check_unit_active },
6570 { "is-failed", MORE, 2, check_unit_failed },
6571 { "show", MORE, 1, show },
6572 { "cat", MORE, 2, cat },
6573 { "status", MORE, 1, show },
6574 { "help", MORE, 2, show },
6575 { "snapshot", LESS, 2, snapshot },
6576 { "delete", MORE, 2, delete_snapshot },
6577 { "daemon-reload", EQUAL, 1, daemon_reload },
6578 { "daemon-reexec", EQUAL, 1, daemon_reload },
6579 { "show-environment", EQUAL, 1, show_environment },
6580 { "set-environment", MORE, 2, set_environment },
6581 { "unset-environment", MORE, 2, set_environment },
6582 { "import-environment", MORE, 1, import_environment},
6583 { "halt", EQUAL, 1, start_special, FORCE },
6584 { "poweroff", EQUAL, 1, start_special, FORCE },
6585 { "reboot", EQUAL, 1, start_special, FORCE },
6586 { "kexec", EQUAL, 1, start_special },
6587 { "suspend", EQUAL, 1, start_special },
6588 { "hibernate", EQUAL, 1, start_special },
6589 { "hybrid-sleep", EQUAL, 1, start_special },
6590 { "default", EQUAL, 1, start_special },
6591 { "rescue", EQUAL, 1, start_special },
6592 { "emergency", EQUAL, 1, start_special },
6593 { "exit", EQUAL, 1, start_special },
6594 { "reset-failed", MORE, 1, reset_failed },
6595 { "enable", MORE, 2, enable_unit, NOBUS },
6596 { "disable", MORE, 2, enable_unit, NOBUS },
6597 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6598 { "reenable", MORE, 2, enable_unit, NOBUS },
6599 { "preset", MORE, 2, enable_unit, NOBUS },
6600 { "preset-all", EQUAL, 1, preset_all, NOBUS },
6601 { "mask", MORE, 2, enable_unit, NOBUS },
6602 { "unmask", MORE, 2, enable_unit, NOBUS },
6603 { "link", MORE, 2, enable_unit, NOBUS },
6604 { "switch-root", MORE, 2, switch_root },
6605 { "list-dependencies", LESS, 2, list_dependencies },
6606 { "set-default", EQUAL, 2, set_default, NOBUS },
6607 { "get-default", EQUAL, 1, get_default, NOBUS },
6608 { "set-property", MORE, 3, set_property },
6609 { "is-system-running", EQUAL, 1, is_system_running },
6618 left = argc - optind;
6620 /* Special rule: no arguments (left == 0) means "list-units" */
6622 if (streq(argv[optind], "help") && !argv[optind+1]) {
6623 log_error("This command expects one or more "
6624 "unit names. Did you mean --help?");
6628 for (; verb->verb; verb++)
6629 if (streq(argv[optind], verb->verb))
6632 log_error("Unknown operation '%s'.", argv[optind]);
6637 switch (verb->argc_cmp) {
6640 if (left != verb->argc) {
6641 log_error("Invalid number of arguments.");
6648 if (left < verb->argc) {
6649 log_error("Too few arguments.");
6656 if (left > verb->argc) {
6657 log_error("Too many arguments.");
6664 assert_not_reached("Unknown comparison operator.");
6667 /* Require a bus connection for all operations but
6669 if (verb->bus == NOBUS) {
6670 if (!bus && !avoid_bus()) {
6671 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6676 if (running_in_chroot() > 0) {
6677 log_info("Running in chroot, ignoring request.");
6681 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6682 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6687 return verb->dispatch(bus, argv + optind);
6690 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6692 struct sd_shutdown_command c = {
6699 union sockaddr_union sockaddr = {
6700 .un.sun_family = AF_UNIX,
6701 .un.sun_path = "/run/systemd/shutdownd",
6704 struct iovec iovec[2] = {{
6705 .iov_base = (char*) &c,
6706 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6709 struct msghdr msghdr = {
6710 .msg_name = &sockaddr,
6711 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6712 + strlen("/run/systemd/shutdownd"),
6717 _cleanup_close_ int fd;
6719 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6723 if (!isempty(message)) {
6724 iovec[1].iov_base = (char*) message;
6725 iovec[1].iov_len = strlen(message);
6726 msghdr.msg_iovlen++;
6729 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6735 static int reload_with_fallback(sd_bus *bus) {
6738 /* First, try systemd via D-Bus. */
6739 if (daemon_reload(bus, NULL) >= 0)
6743 /* Nothing else worked, so let's try signals */
6744 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6746 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6747 log_error("kill() failed: %m");
6754 static int start_with_fallback(sd_bus *bus) {
6757 /* First, try systemd via D-Bus. */
6758 if (start_unit(bus, NULL) >= 0)
6762 /* Nothing else worked, so let's try
6764 if (talk_initctl() > 0)
6767 log_error("Failed to talk to init daemon.");
6771 warn_wall(arg_action);
6775 static int halt_now(enum action a) {
6777 /* Make sure C-A-D is handled by the kernel from this
6779 reboot(RB_ENABLE_CAD);
6784 log_info("Halting.");
6785 reboot(RB_HALT_SYSTEM);
6788 case ACTION_POWEROFF:
6789 log_info("Powering off.");
6790 reboot(RB_POWER_OFF);
6793 case ACTION_REBOOT: {
6794 _cleanup_free_ char *param = NULL;
6796 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6797 log_info("Rebooting with argument '%s'.", param);
6798 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6799 LINUX_REBOOT_CMD_RESTART2, param);
6802 log_info("Rebooting.");
6803 reboot(RB_AUTOBOOT);
6808 assert_not_reached("Unknown action.");
6812 static int halt_main(sd_bus *bus) {
6815 r = check_inhibitors(bus, arg_action);
6819 if (geteuid() != 0) {
6820 /* Try logind if we are a normal user and no special
6821 * mode applies. Maybe PolicyKit allows us to shutdown
6824 if (arg_when <= 0 &&
6827 (arg_action == ACTION_POWEROFF ||
6828 arg_action == ACTION_REBOOT)) {
6829 r = reboot_with_logind(bus, arg_action);
6834 log_error("Must be root.");
6839 _cleanup_free_ char *m;
6841 m = strv_join(arg_wall, " ");
6845 r = send_shutdownd(arg_when,
6846 arg_action == ACTION_HALT ? 'H' :
6847 arg_action == ACTION_POWEROFF ? 'P' :
6848 arg_action == ACTION_KEXEC ? 'K' :
6855 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6857 char date[FORMAT_TIMESTAMP_MAX];
6859 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6860 format_timestamp(date, sizeof(date), arg_when));
6865 if (!arg_dry && !arg_force)
6866 return start_with_fallback(bus);
6869 if (sd_booted() > 0)
6870 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6872 r = utmp_put_shutdown();
6874 log_warning("Failed to write utmp record: %s", strerror(-r));
6881 r = halt_now(arg_action);
6882 log_error("Failed to reboot: %s", strerror(-r));
6887 static int runlevel_main(void) {
6888 int r, runlevel, previous;
6890 r = utmp_get_runlevel(&runlevel, &previous);
6897 previous <= 0 ? 'N' : previous,
6898 runlevel <= 0 ? 'N' : runlevel);
6903 int main(int argc, char*argv[]) {
6904 _cleanup_bus_unref_ sd_bus *bus = NULL;
6907 setlocale(LC_ALL, "");
6908 log_parse_environment();
6911 /* Explicitly not on_tty() to avoid setting cached value.
6912 * This becomes relevant for piping output which might be
6914 original_stdout_is_tty = isatty(STDOUT_FILENO);
6916 r = parse_argv(argc, argv);
6920 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6921 * let's shortcut this */
6922 if (arg_action == ACTION_RUNLEVEL) {
6923 r = runlevel_main();
6927 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6928 log_info("Running in chroot, ignoring request.");
6934 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6936 /* systemctl_main() will print an error message for the bus
6937 * connection, but only if it needs to */
6939 switch (arg_action) {
6941 case ACTION_SYSTEMCTL:
6942 r = systemctl_main(bus, argc, argv, r);
6946 case ACTION_POWEROFF:
6952 case ACTION_RUNLEVEL2:
6953 case ACTION_RUNLEVEL3:
6954 case ACTION_RUNLEVEL4:
6955 case ACTION_RUNLEVEL5:
6957 case ACTION_EMERGENCY:
6958 case ACTION_DEFAULT:
6959 r = start_with_fallback(bus);
6964 r = reload_with_fallback(bus);
6967 case ACTION_CANCEL_SHUTDOWN: {
6968 _cleanup_free_ char *m = NULL;
6971 m = strv_join(arg_wall, " ");
6978 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6980 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6984 case ACTION_RUNLEVEL:
6985 case _ACTION_INVALID:
6987 assert_not_reached("Unknown action");
6992 ask_password_agent_close();
6993 polkit_agent_close();
6995 strv_free(arg_types);
6996 strv_free(arg_states);
6997 strv_free(arg_properties);
6999 return r < 0 ? EXIT_FAILURE : r;