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_close_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_INFINITY && 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_INFINITY && 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);
1357 units = new(UnitFileList, n_units);
1359 unit_file_list_free(h);
1363 HASHMAP_FOREACH(u, h, i) {
1364 if (!output_show_unit_file(u, strv_skip_first(args)))
1371 assert(c <= n_units);
1374 r = sd_bus_call_method(
1376 "org.freedesktop.systemd1",
1377 "/org/freedesktop/systemd1",
1378 "org.freedesktop.systemd1.Manager",
1384 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1388 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1390 return bus_log_parse_error(r);
1392 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1394 if (!GREEDY_REALLOC(units, size, c + 1))
1397 units[c] = (struct UnitFileList) {
1399 unit_file_state_from_string(state)
1402 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1407 return bus_log_parse_error(r);
1409 r = sd_bus_message_exit_container(reply);
1411 return bus_log_parse_error(r);
1415 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1416 output_unit_file_list(units, c);
1420 for (unit = units; unit < units + c; unit++)
1426 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1427 _cleanup_free_ char *n = NULL;
1428 size_t max_len = MAX(columns(),20u);
1434 for (i = level - 1; i >= 0; i--) {
1436 if (len > max_len - 3 && !arg_full) {
1437 printf("%s...\n",max_len % 2 ? "" : " ");
1440 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1444 if (len > max_len - 3 && !arg_full) {
1445 printf("%s...\n",max_len % 2 ? "" : " ");
1449 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1453 printf("%s\n", name);
1457 n = ellipsize(name, max_len-len, 100);
1465 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1467 static const char *dependencies[_DEPENDENCY_MAX] = {
1468 [DEPENDENCY_FORWARD] = "Requires\0"
1469 "RequiresOverridable\0"
1471 "RequisiteOverridable\0"
1473 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1474 "RequiredByOverridable\0"
1477 [DEPENDENCY_AFTER] = "After\0",
1478 [DEPENDENCY_BEFORE] = "Before\0",
1481 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1482 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1483 _cleanup_strv_free_ char **ret = NULL;
1484 _cleanup_free_ char *path = NULL;
1490 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1492 path = unit_dbus_path_from_name(name);
1496 r = sd_bus_call_method(
1498 "org.freedesktop.systemd1",
1500 "org.freedesktop.DBus.Properties",
1504 "s", "org.freedesktop.systemd1.Unit");
1506 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1510 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1512 return bus_log_parse_error(r);
1514 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1517 r = sd_bus_message_read(reply, "s", &prop);
1519 return bus_log_parse_error(r);
1521 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1522 r = sd_bus_message_skip(reply, "v");
1524 return bus_log_parse_error(r);
1527 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1529 return bus_log_parse_error(r);
1531 r = bus_message_read_strv_extend(reply, &ret);
1533 return bus_log_parse_error(r);
1535 r = sd_bus_message_exit_container(reply);
1537 return bus_log_parse_error(r);
1540 r = sd_bus_message_exit_container(reply);
1542 return bus_log_parse_error(r);
1546 return bus_log_parse_error(r);
1548 r = sd_bus_message_exit_container(reply);
1550 return bus_log_parse_error(r);
1558 static int list_dependencies_compare(const void *_a, const void *_b) {
1559 const char **a = (const char**) _a, **b = (const char**) _b;
1561 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1563 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1566 return strcasecmp(*a, *b);
1569 static int list_dependencies_one(
1574 unsigned int branches) {
1576 _cleanup_strv_free_ char **deps = NULL;
1584 r = strv_extend(units, name);
1588 r = list_dependencies_get_dependencies(bus, name, &deps);
1592 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1594 STRV_FOREACH(c, deps) {
1597 if (strv_contains(*units, *c)) {
1599 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1606 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1608 printf("%s%s%s ", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1610 printf("%s%s%s ", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1612 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1616 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1617 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1624 strv_remove(*units, name);
1629 static int list_dependencies(sd_bus *bus, char **args) {
1630 _cleanup_strv_free_ char **units = NULL;
1631 _cleanup_free_ char *unit = NULL;
1637 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1642 u = SPECIAL_DEFAULT_TARGET;
1644 pager_open_if_enabled();
1648 return list_dependencies_one(bus, u, 0, &units, 0);
1651 struct machine_info {
1655 char *control_group;
1656 uint32_t n_failed_units;
1661 static const struct bus_properties_map machine_info_property_map[] = {
1662 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1663 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1664 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1665 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1666 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1670 static void free_machines_list(struct machine_info *machine_infos, int n) {
1676 for (i = 0; i < n; i++) {
1677 free(machine_infos[i].name);
1678 free(machine_infos[i].state);
1679 free(machine_infos[i].control_group);
1682 free(machine_infos);
1685 static int compare_machine_info(const void *a, const void *b) {
1686 const struct machine_info *u = a, *v = b;
1688 if (u->is_host != v->is_host)
1689 return u->is_host > v->is_host ? -1 : 1;
1691 return strcasecmp(u->name, v->name);
1694 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1695 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1701 r = sd_bus_open_system_container(&container, mi->name);
1708 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1715 static bool output_show_machine(const char *name, char **patterns) {
1720 if (strv_isempty(patterns))
1723 STRV_FOREACH(i, patterns)
1724 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1730 static int get_machine_list(
1732 struct machine_info **_machine_infos,
1735 struct machine_info *machine_infos = NULL;
1736 _cleanup_strv_free_ char **m = NULL;
1737 _cleanup_free_ char *hn = NULL;
1742 hn = gethostname_malloc();
1746 if (output_show_machine(hn, patterns)) {
1747 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1750 machine_infos[c].is_host = true;
1751 machine_infos[c].name = hn;
1754 get_machine_properties(bus, &machine_infos[c]);
1758 sd_get_machine_names(&m);
1759 STRV_FOREACH(i, m) {
1760 _cleanup_free_ char *class = NULL;
1762 if (!output_show_machine(*i, patterns))
1765 sd_machine_get_class(*i, &class);
1766 if (!streq_ptr(class, "container"))
1769 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1770 free_machines_list(machine_infos, c);
1774 machine_infos[c].is_host = false;
1775 machine_infos[c].name = strdup(*i);
1776 if (!machine_infos[c].name) {
1777 free_machines_list(machine_infos, c);
1781 get_machine_properties(NULL, &machine_infos[c]);
1785 *_machine_infos = machine_infos;
1789 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1790 struct machine_info *m;
1793 namelen = sizeof("NAME") - 1,
1794 statelen = sizeof("STATE") - 1,
1795 failedlen = sizeof("FAILED") - 1,
1796 jobslen = sizeof("JOBS") - 1;
1798 assert(machine_infos || n == 0);
1800 for (m = machine_infos; m < machine_infos + n; m++) {
1801 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1802 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1803 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1804 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1806 if (!arg_no_legend && !streq_ptr(m->state, "running"))
1810 if (!arg_no_legend) {
1814 printf("%-*s %-*s %-*s %-*s\n",
1817 failedlen, "FAILED",
1821 for (m = machine_infos; m < machine_infos + n; m++) {
1822 const char *on_state = "", *off_state = "";
1823 const char *on_failed = "", *off_failed = "";
1824 bool circle = false;
1826 if (streq_ptr(m->state, "degraded")) {
1827 on_state = ansi_highlight_red();
1828 off_state = ansi_highlight_off();
1830 } else if (!streq_ptr(m->state, "running")) {
1831 on_state = ansi_highlight_yellow();
1832 off_state = ansi_highlight_off();
1836 if (m->n_failed_units > 0) {
1837 on_failed = ansi_highlight_red();
1838 off_failed = ansi_highlight_off();
1840 on_failed = off_failed = "";
1843 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1846 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1847 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1848 on_state, statelen, strna(m->state), off_state,
1849 on_failed, failedlen, m->n_failed_units, off_failed,
1850 jobslen, m->n_jobs);
1852 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1853 namelen, strna(m->name),
1854 on_state, statelen, strna(m->state), off_state,
1855 on_failed, failedlen, m->n_failed_units, off_failed,
1856 jobslen, m->n_jobs);
1860 printf("\n%u machines listed.\n", n);
1863 static int list_machines(sd_bus *bus, char **args) {
1864 struct machine_info *machine_infos = NULL;
1869 if (geteuid() != 0) {
1870 log_error("Must be root.");
1874 pager_open_if_enabled();
1876 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1880 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1881 output_machines_list(machine_infos, r);
1882 free_machines_list(machine_infos, r);
1887 static int get_default(sd_bus *bus, char **args) {
1888 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1889 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1890 _cleanup_free_ char *_path = NULL;
1894 if (!bus || avoid_bus()) {
1895 r = unit_file_get_default(arg_scope, arg_root, &_path);
1897 log_error("Failed to get default target: %s", strerror(-r));
1903 r = sd_bus_call_method(
1905 "org.freedesktop.systemd1",
1906 "/org/freedesktop/systemd1",
1907 "org.freedesktop.systemd1.Manager",
1913 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1917 r = sd_bus_message_read(reply, "s", &path);
1919 return bus_log_parse_error(r);
1923 printf("%s\n", path);
1928 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1931 assert(changes || n_changes == 0);
1933 for (i = 0; i < n_changes; i++) {
1934 if (changes[i].type == UNIT_FILE_SYMLINK)
1935 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1937 log_info("Removed symlink %s.", changes[i].path);
1941 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1942 const char *type, *path, *source;
1945 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1947 return bus_log_parse_error(r);
1949 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1951 if (streq(type, "symlink"))
1952 log_info("Created symlink from %s to %s.", path, source);
1954 log_info("Removed symlink %s.", path);
1958 return bus_log_parse_error(r);
1960 r = sd_bus_message_exit_container(m);
1962 return bus_log_parse_error(r);
1967 static int set_default(sd_bus *bus, char **args) {
1968 _cleanup_free_ char *unit = NULL;
1969 UnitFileChange *changes = NULL;
1970 unsigned n_changes = 0;
1973 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1977 if (!bus || avoid_bus()) {
1978 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1980 log_error("Failed to set default target: %s", strerror(-r));
1985 dump_unit_file_changes(changes, n_changes);
1989 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1990 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1992 r = sd_bus_call_method(
1994 "org.freedesktop.systemd1",
1995 "/org/freedesktop/systemd1",
1996 "org.freedesktop.systemd1.Manager",
2002 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
2006 r = deserialize_and_dump_unit_file_changes(reply);
2010 /* Try to reload if enabled */
2012 r = daemon_reload(bus, args);
2017 unit_file_changes_free(changes, n_changes);
2024 const char *name, *type, *state;
2027 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2028 unsigned id_len, unit_len, type_len, state_len;
2029 const struct job_info *j;
2030 const char *on, *off;
2031 bool shorten = false;
2033 assert(n == 0 || jobs);
2036 on = ansi_highlight_green();
2037 off = ansi_highlight_off();
2039 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2043 pager_open_if_enabled();
2045 id_len = strlen("JOB");
2046 unit_len = strlen("UNIT");
2047 type_len = strlen("TYPE");
2048 state_len = strlen("STATE");
2050 for (j = jobs; j < jobs + n; j++) {
2051 uint32_t id = j->id;
2052 assert(j->name && j->type && j->state);
2054 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2055 unit_len = MAX(unit_len, strlen(j->name));
2056 type_len = MAX(type_len, strlen(j->type));
2057 state_len = MAX(state_len, strlen(j->state));
2060 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2061 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2066 printf("%*s %-*s %-*s %-*s\n",
2070 state_len, "STATE");
2072 for (j = jobs; j < jobs + n; j++) {
2073 _cleanup_free_ char *e = NULL;
2075 if (streq(j->state, "running")) {
2076 on = ansi_highlight();
2077 off = ansi_highlight_off();
2081 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2082 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2084 on, unit_len, e ? e : j->name, off,
2086 on, state_len, j->state, off);
2089 if (!arg_no_legend) {
2090 on = ansi_highlight();
2091 off = ansi_highlight_off();
2093 printf("\n%s%u jobs listed%s.\n", on, n, off);
2097 static bool output_show_job(struct job_info *job, char **patterns) {
2102 if (strv_isempty(patterns))
2105 STRV_FOREACH(pattern, patterns)
2106 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
2111 static int list_jobs(sd_bus *bus, char **args) {
2112 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2113 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2114 const char *name, *type, *state, *job_path, *unit_path;
2115 _cleanup_free_ struct job_info *jobs = NULL;
2120 bool skipped = false;
2122 r = sd_bus_call_method(
2124 "org.freedesktop.systemd1",
2125 "/org/freedesktop/systemd1",
2126 "org.freedesktop.systemd1.Manager",
2132 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2136 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2138 return bus_log_parse_error(r);
2140 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2141 struct job_info job = { id, name, type, state };
2143 if (!output_show_job(&job, strv_skip_first(args))) {
2148 if (!GREEDY_REALLOC(jobs, size, c + 1))
2154 return bus_log_parse_error(r);
2156 r = sd_bus_message_exit_container(reply);
2158 return bus_log_parse_error(r);
2160 output_jobs_list(jobs, c, skipped);
2164 static int cancel_job(sd_bus *bus, char **args) {
2165 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2170 if (strv_length(args) <= 1)
2171 return daemon_reload(bus, args);
2173 STRV_FOREACH(name, args+1) {
2177 r = safe_atou32(*name, &id);
2179 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
2183 r = sd_bus_call_method(
2185 "org.freedesktop.systemd1",
2186 "/org/freedesktop/systemd1",
2187 "org.freedesktop.systemd1.Manager",
2193 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
2201 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2202 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2206 /* We ignore all errors here, since this is used to show a
2209 /* We don't use unit_dbus_path_from_name() directly since we
2210 * don't want to load the unit if it isn't loaded. */
2212 r = sd_bus_call_method(
2214 "org.freedesktop.systemd1",
2215 "/org/freedesktop/systemd1",
2216 "org.freedesktop.systemd1.Manager",
2224 r = sd_bus_message_read(reply, "o", &path);
2228 r = sd_bus_get_property_trivial(
2230 "org.freedesktop.systemd1",
2232 "org.freedesktop.systemd1.Unit",
2242 typedef struct WaitData {
2249 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2256 log_debug("Got D-Bus request: %s.%s() on %s",
2257 sd_bus_message_get_interface(m),
2258 sd_bus_message_get_member(m),
2259 sd_bus_message_get_path(m));
2261 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2262 log_error("Warning! D-Bus connection terminated.");
2264 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2266 const char *path, *result, *unit;
2270 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2272 ret = set_remove(d->set, (char*) path);
2278 if (!isempty(result))
2279 d->result = strdup(result);
2282 d->name = strdup(unit);
2287 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2289 ret = set_remove(d->set, (char*) path);
2296 d->result = strdup(result);
2302 bus_log_parse_error(r);
2308 static int enable_wait_for_jobs(sd_bus *bus) {
2313 r = sd_bus_add_match(
2317 "sender='org.freedesktop.systemd1',"
2318 "interface='org.freedesktop.systemd1.Manager',"
2319 "member='JobRemoved',"
2320 "path='/org/freedesktop/systemd1'",
2323 log_error("Failed to add match");
2327 /* This is slightly dirty, since we don't undo the match registrations. */
2331 static int bus_process_wait(sd_bus *bus) {
2335 r = sd_bus_process(bus, NULL);
2340 r = sd_bus_wait(bus, (uint64_t) -1);
2346 static int check_wait_response(WaitData *d) {
2352 if (streq(d->result, "timeout"))
2353 log_error("Job for %s timed out.", strna(d->name));
2354 else if (streq(d->result, "canceled"))
2355 log_error("Job for %s canceled.", strna(d->name));
2356 else if (streq(d->result, "dependency"))
2357 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2358 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2359 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2362 if (streq(d->result, "timeout"))
2364 else if (streq(d->result, "canceled"))
2366 else if (streq(d->result, "dependency"))
2368 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2374 static int wait_for_jobs(sd_bus *bus, Set *s) {
2375 _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
2376 WaitData d = { .set = s };
2382 q = sd_bus_add_filter(bus, &slot, wait_filter, &d);
2386 while (!set_isempty(s)) {
2387 q = bus_process_wait(bus);
2389 log_error("Failed to wait for response: %s", strerror(-r));
2394 q = check_wait_response(&d);
2395 /* Return the first error as it is most likely to be
2397 if (q < 0 && r == 0)
2399 log_debug("Got result %s/%s for job %s",
2400 strna(d.result), strerror(-q), strna(d.name));
2413 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2414 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2415 _cleanup_free_ char *n = NULL, *state = NULL;
2421 n = unit_name_mangle(name, MANGLE_NOGLOB);
2425 /* We don't use unit_dbus_path_from_name() directly since we
2426 * don't want to load the unit if it isn't loaded. */
2428 r = sd_bus_call_method(
2430 "org.freedesktop.systemd1",
2431 "/org/freedesktop/systemd1",
2432 "org.freedesktop.systemd1.Manager",
2443 r = sd_bus_message_read(reply, "o", &path);
2445 return bus_log_parse_error(r);
2447 r = sd_bus_get_property_string(
2449 "org.freedesktop.systemd1",
2451 "org.freedesktop.systemd1.Unit",
2464 return nulstr_contains(good_states, state);
2467 static int check_triggering_units(
2471 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2472 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2473 _cleanup_strv_free_ char **triggered_by = NULL;
2474 bool print_warning_label = true;
2478 n = unit_name_mangle(name, MANGLE_NOGLOB);
2482 path = unit_dbus_path_from_name(n);
2486 r = sd_bus_get_property_string(
2488 "org.freedesktop.systemd1",
2490 "org.freedesktop.systemd1.Unit",
2495 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2499 if (streq(state, "masked"))
2502 r = sd_bus_get_property_strv(
2504 "org.freedesktop.systemd1",
2506 "org.freedesktop.systemd1.Unit",
2511 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2515 STRV_FOREACH(i, triggered_by) {
2516 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2518 log_error("Failed to check unit: %s", strerror(-r));
2525 if (print_warning_label) {
2526 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2527 print_warning_label = false;
2530 log_warning(" %s", *i);
2536 static const char *verb_to_method(const char *verb) {
2539 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2540 if (streq_ptr(unit_actions[i].verb, verb))
2541 return unit_actions[i].method;
2546 static const char *method_to_verb(const char *method) {
2549 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2550 if (streq_ptr(unit_actions[i].method, method))
2551 return unit_actions[i].verb;
2556 static int start_unit_one(
2561 sd_bus_error *error,
2564 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2573 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2574 r = sd_bus_call_method(
2576 "org.freedesktop.systemd1",
2577 "/org/freedesktop/systemd1",
2578 "org.freedesktop.systemd1.Manager",
2586 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2587 /* There's always a fallback possible for
2588 * legacy actions. */
2589 return -EADDRNOTAVAIL;
2591 verb = method_to_verb(method);
2593 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2597 r = sd_bus_message_read(reply, "o", &path);
2599 return bus_log_parse_error(r);
2601 if (need_daemon_reload(bus, name) > 0)
2602 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2603 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2612 log_debug("Adding %s to the set", p);
2613 r = set_consume(s, p);
2621 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2623 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2627 STRV_FOREACH(name, names) {
2631 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2633 t = unit_name_mangle(*name, MANGLE_GLOB);
2637 if (string_is_glob(t))
2638 r = strv_consume(&globs, t);
2640 r = strv_consume(&mangled, t);
2645 /* Query the manager only if any of the names are a glob, since
2646 * this is fairly expensive */
2647 if (!strv_isempty(globs)) {
2648 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2649 _cleanup_free_ UnitInfo *unit_infos = NULL;
2651 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2655 for (i = 0; i < r; i++)
2656 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2661 mangled = NULL; /* do not free */
2666 static const struct {
2670 } action_table[_ACTION_MAX] = {
2671 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2672 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2673 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2674 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2675 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2676 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2677 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2678 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2679 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2680 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2681 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2682 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2683 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2684 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2685 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2688 static enum action verb_to_action(const char *verb) {
2691 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2692 if (streq_ptr(action_table[i].verb, verb))
2695 return _ACTION_INVALID;
2698 static int start_unit(sd_bus *bus, char **args) {
2699 _cleanup_set_free_free_ Set *s = NULL;
2700 _cleanup_strv_free_ char **names = NULL;
2701 const char *method, *mode, *one_name;
2707 ask_password_agent_open_if_enabled();
2709 if (arg_action == ACTION_SYSTEMCTL) {
2711 method = verb_to_method(args[0]);
2712 action = verb_to_action(args[0]);
2714 mode = streq(args[0], "isolate") ? "isolate" :
2715 action_table[action].mode ?: arg_job_mode;
2717 one_name = action_table[action].target;
2719 assert(arg_action < ELEMENTSOF(action_table));
2720 assert(action_table[arg_action].target);
2722 method = "StartUnit";
2724 mode = action_table[arg_action].mode;
2725 one_name = action_table[arg_action].target;
2729 names = strv_new(one_name, NULL);
2731 r = expand_names(bus, args + 1, NULL, &names);
2733 log_error("Failed to expand names: %s", strerror(-r));
2736 if (!arg_no_block) {
2737 r = enable_wait_for_jobs(bus);
2739 log_error("Could not watch jobs: %s", strerror(-r));
2743 s = set_new(string_hash_func, string_compare_func);
2748 STRV_FOREACH(name, names) {
2749 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2752 q = start_unit_one(bus, method, *name, mode, &error, s);
2753 if (r >= 0 && q < 0)
2754 r = translate_bus_error_to_exit_status(q, &error);
2757 if (!arg_no_block) {
2760 q = wait_for_jobs(bus, s);
2764 /* When stopping units, warn if they can still be triggered by
2765 * another active unit (socket, path, timer) */
2766 if (!arg_quiet && streq(method, "StopUnit"))
2767 STRV_FOREACH(name, names)
2768 check_triggering_units(bus, *name);
2774 /* Ask systemd-logind, which might grant access to unprivileged users
2775 * through PolicyKit */
2776 static int reboot_with_logind(sd_bus *bus, enum action a) {
2778 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2785 polkit_agent_open_if_enabled();
2793 case ACTION_POWEROFF:
2794 method = "PowerOff";
2797 case ACTION_SUSPEND:
2801 case ACTION_HIBERNATE:
2802 method = "Hibernate";
2805 case ACTION_HYBRID_SLEEP:
2806 method = "HybridSleep";
2813 r = sd_bus_call_method(
2815 "org.freedesktop.login1",
2816 "/org/freedesktop/login1",
2817 "org.freedesktop.login1.Manager",
2823 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2831 static int check_inhibitors(sd_bus *bus, enum action a) {
2833 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2834 _cleanup_strv_free_ char **sessions = NULL;
2835 const char *what, *who, *why, *mode;
2844 if (arg_ignore_inhibitors || arg_force > 0)
2856 r = sd_bus_call_method(
2858 "org.freedesktop.login1",
2859 "/org/freedesktop/login1",
2860 "org.freedesktop.login1.Manager",
2866 /* If logind is not around, then there are no inhibitors... */
2869 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2871 return bus_log_parse_error(r);
2873 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2874 _cleanup_free_ char *comm = NULL, *user = NULL;
2875 _cleanup_strv_free_ char **sv = NULL;
2877 if (!streq(mode, "block"))
2880 sv = strv_split(what, ":");
2884 if (!strv_contains(sv,
2886 a == ACTION_POWEROFF ||
2887 a == ACTION_REBOOT ||
2888 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2891 get_process_comm(pid, &comm);
2892 user = uid_to_name(uid);
2894 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2895 who, pid, strna(comm), strna(user), why);
2900 return bus_log_parse_error(r);
2902 r = sd_bus_message_exit_container(reply);
2904 return bus_log_parse_error(r);
2906 /* Check for current sessions */
2907 sd_get_sessions(&sessions);
2908 STRV_FOREACH(s, sessions) {
2909 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2911 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2914 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2917 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2920 sd_session_get_tty(*s, &tty);
2921 sd_session_get_seat(*s, &seat);
2922 sd_session_get_service(*s, &service);
2923 user = uid_to_name(uid);
2925 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2932 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2933 action_table[a].verb);
2941 static int start_special(sd_bus *bus, char **args) {
2947 a = verb_to_action(args[0]);
2949 r = check_inhibitors(bus, a);
2953 if (arg_force >= 2 && geteuid() != 0) {
2954 log_error("Must be root.");
2958 if (arg_force >= 2 &&
2959 (a == ACTION_HALT ||
2960 a == ACTION_POWEROFF ||
2961 a == ACTION_REBOOT))
2964 if (arg_force >= 1 &&
2965 (a == ACTION_HALT ||
2966 a == ACTION_POWEROFF ||
2967 a == ACTION_REBOOT ||
2968 a == ACTION_KEXEC ||
2970 return daemon_reload(bus, args);
2972 /* first try logind, to allow authentication with polkit */
2973 if (geteuid() != 0 &&
2974 (a == ACTION_POWEROFF ||
2975 a == ACTION_REBOOT ||
2976 a == ACTION_SUSPEND ||
2977 a == ACTION_HIBERNATE ||
2978 a == ACTION_HYBRID_SLEEP)) {
2979 r = reboot_with_logind(bus, a);
2984 r = start_unit(bus, args);
2985 if (r == EXIT_SUCCESS)
2991 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2992 _cleanup_strv_free_ char **names = NULL;
2999 r = expand_names(bus, args, NULL, &names);
3001 log_error("Failed to expand names: %s", strerror(-r));
3005 STRV_FOREACH(name, names) {
3008 state = check_one_unit(bus, *name, good_states, arg_quiet);
3018 static int check_unit_active(sd_bus *bus, char **args) {
3019 /* According to LSB: 3, "program is not running" */
3020 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3023 static int check_unit_failed(sd_bus *bus, char **args) {
3024 return check_unit_generic(bus, 1, "failed\0", args + 1);
3027 static int kill_unit(sd_bus *bus, char **args) {
3028 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3029 _cleanup_strv_free_ char **names = NULL;
3037 arg_kill_who = "all";
3039 r = expand_names(bus, args + 1, NULL, &names);
3041 log_error("Failed to expand names: %s", strerror(-r));
3043 STRV_FOREACH(name, names) {
3044 q = sd_bus_call_method(
3046 "org.freedesktop.systemd1",
3047 "/org/freedesktop/systemd1",
3048 "org.freedesktop.systemd1.Manager",
3052 "ssi", *names, arg_kill_who, arg_signal);
3054 log_error("Failed to kill unit %s: %s",
3055 *names, bus_error_message(&error, r));
3064 typedef struct ExecStatusInfo {
3072 usec_t start_timestamp;
3073 usec_t exit_timestamp;
3078 LIST_FIELDS(struct ExecStatusInfo, exec);
3081 static void exec_status_info_free(ExecStatusInfo *i) {
3090 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3091 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3094 int32_t code, status;
3100 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3102 return bus_log_parse_error(r);
3106 r = sd_bus_message_read(m, "s", &path);
3108 return bus_log_parse_error(r);
3110 i->path = strdup(path);
3114 r = sd_bus_message_read_strv(m, &i->argv);
3116 return bus_log_parse_error(r);
3118 r = sd_bus_message_read(m,
3121 &start_timestamp, &start_timestamp_monotonic,
3122 &exit_timestamp, &exit_timestamp_monotonic,
3126 return bus_log_parse_error(r);
3129 i->start_timestamp = (usec_t) start_timestamp;
3130 i->exit_timestamp = (usec_t) exit_timestamp;
3131 i->pid = (pid_t) pid;
3135 r = sd_bus_message_exit_container(m);
3137 return bus_log_parse_error(r);
3142 typedef struct UnitStatusInfo {
3144 const char *load_state;
3145 const char *active_state;
3146 const char *sub_state;
3147 const char *unit_file_state;
3149 const char *description;
3150 const char *following;
3152 char **documentation;
3154 const char *fragment_path;
3155 const char *source_path;
3156 const char *control_group;
3158 char **dropin_paths;
3160 const char *load_error;
3163 usec_t inactive_exit_timestamp;
3164 usec_t inactive_exit_timestamp_monotonic;
3165 usec_t active_enter_timestamp;
3166 usec_t active_exit_timestamp;
3167 usec_t inactive_enter_timestamp;
3169 bool need_daemon_reload;
3174 const char *status_text;
3175 const char *pid_file;
3179 usec_t start_timestamp;
3180 usec_t exit_timestamp;
3182 int exit_code, exit_status;
3184 usec_t condition_timestamp;
3185 bool condition_result;
3186 bool failed_condition_trigger;
3187 bool failed_condition_negate;
3188 const char *failed_condition;
3189 const char *failed_condition_param;
3192 unsigned n_accepted;
3193 unsigned n_connections;
3196 /* Pairs of type, path */
3200 const char *sysfs_path;
3202 /* Mount, Automount */
3208 LIST_HEAD(ExecStatusInfo, exec);
3211 static void print_status_info(
3216 const char *active_on, *active_off, *on, *off, *ss;
3218 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3219 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3222 arg_all * OUTPUT_SHOW_ALL |
3223 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
3224 on_tty() * OUTPUT_COLOR |
3225 !arg_quiet * OUTPUT_WARN_CUTOFF |
3226 arg_full * OUTPUT_FULL_WIDTH;
3231 /* This shows pretty information about a unit. See
3232 * print_property() for a low-level property printer */
3234 if (streq_ptr(i->active_state, "failed")) {
3235 active_on = ansi_highlight_red();
3236 active_off = ansi_highlight_off();
3237 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3238 active_on = ansi_highlight_green();
3239 active_off = ansi_highlight_off();
3241 active_on = active_off = "";
3243 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3245 if (i->description && !streq_ptr(i->id, i->description))
3246 printf(" - %s", i->description);
3251 printf(" Follow: unit currently follows state of %s\n", i->following);
3253 if (streq_ptr(i->load_state, "error")) {
3254 on = ansi_highlight_red();
3255 off = ansi_highlight_off();
3259 path = i->source_path ? i->source_path : i->fragment_path;
3262 printf(" Loaded: %s%s%s (Reason: %s)\n",
3263 on, strna(i->load_state), off, i->load_error);
3264 else if (path && i->unit_file_state)
3265 printf(" Loaded: %s%s%s (%s; %s)\n",
3266 on, strna(i->load_state), off, path, i->unit_file_state);
3268 printf(" Loaded: %s%s%s (%s)\n",
3269 on, strna(i->load_state), off, path);
3271 printf(" Loaded: %s%s%s\n",
3272 on, strna(i->load_state), off);
3274 if (!strv_isempty(i->dropin_paths)) {
3275 _cleanup_free_ char *dir = NULL;
3279 STRV_FOREACH(dropin, i->dropin_paths) {
3280 if (! dir || last) {
3281 printf(dir ? " " : " Drop-In: ");
3286 if (path_get_parent(*dropin, &dir) < 0) {
3291 printf("%s\n %s", dir,
3292 draw_special_char(DRAW_TREE_RIGHT));
3295 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3297 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3301 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3303 printf(" Active: %s%s (%s)%s",
3304 active_on, strna(i->active_state), ss, active_off);
3306 printf(" Active: %s%s%s",
3307 active_on, strna(i->active_state), active_off);
3309 if (!isempty(i->result) && !streq(i->result, "success"))
3310 printf(" (Result: %s)", i->result);
3312 timestamp = (streq_ptr(i->active_state, "active") ||
3313 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3314 (streq_ptr(i->active_state, "inactive") ||
3315 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3316 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3317 i->active_exit_timestamp;
3319 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3320 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3323 printf(" since %s; %s\n", s2, s1);
3325 printf(" since %s\n", s2);
3329 if (!i->condition_result && i->condition_timestamp > 0) {
3330 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3331 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3333 printf(" start condition failed at %s%s%s\n",
3334 s2, s1 ? "; " : "", s1 ? s1 : "");
3335 if (i->failed_condition_trigger)
3336 printf(" none of the trigger conditions were met\n");
3337 else if (i->failed_condition)
3338 printf(" %s=%s%s was not met\n",
3339 i->failed_condition,
3340 i->failed_condition_negate ? "!" : "",
3341 i->failed_condition_param);
3345 printf(" Device: %s\n", i->sysfs_path);
3347 printf(" Where: %s\n", i->where);
3349 printf(" What: %s\n", i->what);
3351 STRV_FOREACH(t, i->documentation)
3352 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3354 STRV_FOREACH_PAIR(t, t2, i->listen)
3355 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3358 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3360 LIST_FOREACH(exec, p, i->exec) {
3361 _cleanup_free_ char *argv = NULL;
3364 /* Only show exited processes here */
3368 argv = strv_join(p->argv, " ");
3369 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3371 good = is_clean_exit_lsb(p->code, p->status, NULL);
3373 on = ansi_highlight_red();
3374 off = ansi_highlight_off();
3378 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3380 if (p->code == CLD_EXITED) {
3383 printf("status=%i", p->status);
3385 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3390 printf("signal=%s", signal_to_string(p->status));
3392 printf(")%s\n", off);
3394 if (i->main_pid == p->pid &&
3395 i->start_timestamp == p->start_timestamp &&
3396 i->exit_timestamp == p->start_timestamp)
3397 /* Let's not show this twice */
3400 if (p->pid == i->control_pid)
3404 if (i->main_pid > 0 || i->control_pid > 0) {
3405 if (i->main_pid > 0) {
3406 printf(" Main PID: %u", (unsigned) i->main_pid);
3409 _cleanup_free_ char *comm = NULL;
3410 get_process_comm(i->main_pid, &comm);
3412 printf(" (%s)", comm);
3413 } else if (i->exit_code > 0) {
3414 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3416 if (i->exit_code == CLD_EXITED) {
3419 printf("status=%i", i->exit_status);
3421 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3426 printf("signal=%s", signal_to_string(i->exit_status));
3430 if (i->control_pid > 0)
3434 if (i->control_pid > 0) {
3435 _cleanup_free_ char *c = NULL;
3437 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3439 get_process_comm(i->control_pid, &c);
3448 printf(" Status: \"%s\"\n", i->status_text);
3449 if (i->status_errno > 0)
3450 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3452 if (i->control_group &&
3453 (i->main_pid > 0 || i->control_pid > 0 ||
3454 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3457 printf(" CGroup: %s\n", i->control_group);
3459 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3462 static const char prefix[] = " ";
3465 if (c > sizeof(prefix) - 1)
3466 c -= sizeof(prefix) - 1;
3470 if (i->main_pid > 0)
3471 extra[k++] = i->main_pid;
3473 if (i->control_pid > 0)
3474 extra[k++] = i->control_pid;
3476 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3480 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3481 show_journal_by_unit(stdout,
3485 i->inactive_exit_timestamp_monotonic,
3488 flags | OUTPUT_BEGIN_NEWLINE,
3489 arg_scope == UNIT_FILE_SYSTEM,
3493 if (i->need_daemon_reload)
3494 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3495 ansi_highlight_red(),
3496 ansi_highlight_off(),
3497 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3500 static void show_unit_help(UnitStatusInfo *i) {
3505 if (!i->documentation) {
3506 log_info("Documentation for %s not known.", i->id);
3510 STRV_FOREACH(p, i->documentation)
3511 if (startswith(*p, "man:"))
3512 show_man_page(*p + 4, false);
3514 log_info("Can't show: %s", *p);
3517 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3524 switch (contents[0]) {
3526 case SD_BUS_TYPE_STRING: {
3529 r = sd_bus_message_read(m, "s", &s);
3531 return bus_log_parse_error(r);
3534 if (streq(name, "Id"))
3536 else if (streq(name, "LoadState"))
3538 else if (streq(name, "ActiveState"))
3539 i->active_state = s;
3540 else if (streq(name, "SubState"))
3542 else if (streq(name, "Description"))
3544 else if (streq(name, "FragmentPath"))
3545 i->fragment_path = s;
3546 else if (streq(name, "SourcePath"))
3549 else if (streq(name, "DefaultControlGroup")) {
3551 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3553 i->control_group = e;
3556 else if (streq(name, "ControlGroup"))
3557 i->control_group = s;
3558 else if (streq(name, "StatusText"))
3560 else if (streq(name, "PIDFile"))
3562 else if (streq(name, "SysFSPath"))
3564 else if (streq(name, "Where"))
3566 else if (streq(name, "What"))
3568 else if (streq(name, "Following"))
3570 else if (streq(name, "UnitFileState"))
3571 i->unit_file_state = s;
3572 else if (streq(name, "Result"))
3579 case SD_BUS_TYPE_BOOLEAN: {
3582 r = sd_bus_message_read(m, "b", &b);
3584 return bus_log_parse_error(r);
3586 if (streq(name, "Accept"))
3588 else if (streq(name, "NeedDaemonReload"))
3589 i->need_daemon_reload = b;
3590 else if (streq(name, "ConditionResult"))
3591 i->condition_result = b;
3596 case SD_BUS_TYPE_UINT32: {
3599 r = sd_bus_message_read(m, "u", &u);
3601 return bus_log_parse_error(r);
3603 if (streq(name, "MainPID")) {
3605 i->main_pid = (pid_t) u;
3608 } else if (streq(name, "ControlPID"))
3609 i->control_pid = (pid_t) u;
3610 else if (streq(name, "ExecMainPID")) {
3612 i->main_pid = (pid_t) u;
3613 } else if (streq(name, "NAccepted"))
3615 else if (streq(name, "NConnections"))
3616 i->n_connections = u;
3621 case SD_BUS_TYPE_INT32: {
3624 r = sd_bus_message_read(m, "i", &j);
3626 return bus_log_parse_error(r);
3628 if (streq(name, "ExecMainCode"))
3629 i->exit_code = (int) j;
3630 else if (streq(name, "ExecMainStatus"))
3631 i->exit_status = (int) j;
3632 else if (streq(name, "StatusErrno"))
3633 i->status_errno = (int) j;
3638 case SD_BUS_TYPE_UINT64: {
3641 r = sd_bus_message_read(m, "t", &u);
3643 return bus_log_parse_error(r);
3645 if (streq(name, "ExecMainStartTimestamp"))
3646 i->start_timestamp = (usec_t) u;
3647 else if (streq(name, "ExecMainExitTimestamp"))
3648 i->exit_timestamp = (usec_t) u;
3649 else if (streq(name, "ActiveEnterTimestamp"))
3650 i->active_enter_timestamp = (usec_t) u;
3651 else if (streq(name, "InactiveEnterTimestamp"))
3652 i->inactive_enter_timestamp = (usec_t) u;
3653 else if (streq(name, "InactiveExitTimestamp"))
3654 i->inactive_exit_timestamp = (usec_t) u;
3655 else if (streq(name, "InactiveExitTimestampMonotonic"))
3656 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3657 else if (streq(name, "ActiveExitTimestamp"))
3658 i->active_exit_timestamp = (usec_t) u;
3659 else if (streq(name, "ConditionTimestamp"))
3660 i->condition_timestamp = (usec_t) u;
3665 case SD_BUS_TYPE_ARRAY:
3667 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3668 _cleanup_free_ ExecStatusInfo *info = NULL;
3670 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3672 return bus_log_parse_error(r);
3674 info = new0(ExecStatusInfo, 1);
3678 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3680 info->name = strdup(name);
3684 LIST_PREPEND(exec, i->exec, info);
3686 info = new0(ExecStatusInfo, 1);
3692 return bus_log_parse_error(r);
3694 r = sd_bus_message_exit_container(m);
3696 return bus_log_parse_error(r);
3700 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3701 const char *type, *path;
3703 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3705 return bus_log_parse_error(r);
3707 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3709 r = strv_extend(&i->listen, type);
3713 r = strv_extend(&i->listen, path);
3718 return bus_log_parse_error(r);
3720 r = sd_bus_message_exit_container(m);
3722 return bus_log_parse_error(r);
3726 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3728 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3730 return bus_log_parse_error(r);
3732 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3734 r = sd_bus_message_read_strv(m, &i->documentation);
3736 return bus_log_parse_error(r);
3738 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3739 const char *cond, *param;
3740 int trigger, negate;
3743 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3745 return bus_log_parse_error(r);
3747 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3748 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3749 if (state < 0 && (!trigger || !i->failed_condition)) {
3750 i->failed_condition = cond;
3751 i->failed_condition_trigger = trigger;
3752 i->failed_condition_negate = negate;
3753 i->failed_condition_param = param;
3757 return bus_log_parse_error(r);
3759 r = sd_bus_message_exit_container(m);
3761 return bus_log_parse_error(r);
3768 case SD_BUS_TYPE_STRUCT_BEGIN:
3770 if (streq(name, "LoadError")) {
3771 const char *n, *message;
3773 r = sd_bus_message_read(m, "(ss)", &n, &message);
3775 return bus_log_parse_error(r);
3777 if (!isempty(message))
3778 i->load_error = message;
3791 r = sd_bus_message_skip(m, contents);
3793 return bus_log_parse_error(r);
3798 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3804 /* This is a low-level property printer, see
3805 * print_status_info() for the nicer output */
3807 if (arg_properties && !strv_find(arg_properties, name)) {
3808 /* skip what we didn't read */
3809 r = sd_bus_message_skip(m, contents);
3813 switch (contents[0]) {
3815 case SD_BUS_TYPE_STRUCT_BEGIN:
3817 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3820 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3822 return bus_log_parse_error(r);
3825 printf("%s=%u\n", name, (unsigned) u);
3827 printf("%s=\n", name);
3831 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3834 r = sd_bus_message_read(m, "(so)", &s, NULL);
3836 return bus_log_parse_error(r);
3838 if (arg_all || !isempty(s))
3839 printf("%s=%s\n", name, s);
3843 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3844 const char *a = NULL, *b = NULL;
3846 r = sd_bus_message_read(m, "(ss)", &a, &b);
3848 return bus_log_parse_error(r);
3850 if (arg_all || !isempty(a) || !isempty(b))
3851 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3854 } else if (streq_ptr(name, "SystemCallFilter")) {
3855 _cleanup_strv_free_ char **l = NULL;
3858 r = sd_bus_message_enter_container(m, 'r', "bas");
3860 return bus_log_parse_error(r);
3862 r = sd_bus_message_read(m, "b", &whitelist);
3864 return bus_log_parse_error(r);
3866 r = sd_bus_message_read_strv(m, &l);
3868 return bus_log_parse_error(r);
3870 r = sd_bus_message_exit_container(m);
3872 return bus_log_parse_error(r);
3874 if (arg_all || whitelist || !strv_isempty(l)) {
3878 fputs(name, stdout);
3884 STRV_FOREACH(i, l) {
3892 fputc('\n', stdout);
3900 case SD_BUS_TYPE_ARRAY:
3902 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3906 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3908 return bus_log_parse_error(r);
3910 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3911 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3914 return bus_log_parse_error(r);
3916 r = sd_bus_message_exit_container(m);
3918 return bus_log_parse_error(r);
3922 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3923 const char *type, *path;
3925 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3927 return bus_log_parse_error(r);
3929 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3930 printf("%s=%s\n", type, path);
3932 return bus_log_parse_error(r);
3934 r = sd_bus_message_exit_container(m);
3936 return bus_log_parse_error(r);
3940 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3941 const char *type, *path;
3943 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3945 return bus_log_parse_error(r);
3947 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3948 printf("Listen%s=%s\n", type, path);
3950 return bus_log_parse_error(r);
3952 r = sd_bus_message_exit_container(m);
3954 return bus_log_parse_error(r);
3958 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3960 uint64_t value, next_elapse;
3962 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3964 return bus_log_parse_error(r);
3966 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3967 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3969 printf("%s={ value=%s ; next_elapse=%s }\n",
3971 format_timespan(timespan1, sizeof(timespan1), value, 0),
3972 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3975 return bus_log_parse_error(r);
3977 r = sd_bus_message_exit_container(m);
3979 return bus_log_parse_error(r);
3983 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3984 ExecStatusInfo info = {};
3986 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3988 return bus_log_parse_error(r);
3990 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3991 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3992 _cleanup_free_ char *tt;
3994 tt = strv_join(info.argv, " ");
3996 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
4000 yes_no(info.ignore),
4001 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4002 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4003 (unsigned) info. pid,
4004 sigchld_code_to_string(info.code),
4006 info.code == CLD_EXITED ? "" : "/",
4007 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4010 strv_free(info.argv);
4014 r = sd_bus_message_exit_container(m);
4016 return bus_log_parse_error(r);
4020 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4021 const char *path, *rwm;
4023 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4025 return bus_log_parse_error(r);
4027 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4028 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4030 return bus_log_parse_error(r);
4032 r = sd_bus_message_exit_container(m);
4034 return bus_log_parse_error(r);
4038 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4042 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4044 return bus_log_parse_error(r);
4046 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4047 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4049 return bus_log_parse_error(r);
4051 r = sd_bus_message_exit_container(m);
4053 return bus_log_parse_error(r);
4057 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4061 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4063 return bus_log_parse_error(r);
4065 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4066 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4068 return bus_log_parse_error(r);
4070 r = sd_bus_message_exit_container(m);
4072 return bus_log_parse_error(r);
4080 r = bus_print_property(name, m, arg_all);
4082 return bus_log_parse_error(r);
4085 r = sd_bus_message_skip(m, contents);
4087 return bus_log_parse_error(r);
4090 printf("%s=[unprintable]\n", name);
4096 static int show_one(
4100 bool show_properties,
4104 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4105 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4106 UnitStatusInfo info = {};
4113 log_debug("Showing one %s", path);
4115 r = sd_bus_call_method(
4117 "org.freedesktop.systemd1",
4119 "org.freedesktop.DBus.Properties",
4125 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4129 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4131 return bus_log_parse_error(r);
4138 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4139 const char *name, *contents;
4141 r = sd_bus_message_read(reply, "s", &name);
4143 return bus_log_parse_error(r);
4145 r = sd_bus_message_peek_type(reply, NULL, &contents);
4147 return bus_log_parse_error(r);
4149 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4151 return bus_log_parse_error(r);
4153 if (show_properties)
4154 r = print_property(name, reply, contents);
4156 r = status_property(name, reply, &info, contents);
4160 r = sd_bus_message_exit_container(reply);
4162 return bus_log_parse_error(r);
4164 r = sd_bus_message_exit_container(reply);
4166 return bus_log_parse_error(r);
4169 return bus_log_parse_error(r);
4171 r = sd_bus_message_exit_container(reply);
4173 return bus_log_parse_error(r);
4177 if (!show_properties) {
4178 if (streq(verb, "help"))
4179 show_unit_help(&info);
4181 print_status_info(&info, ellipsized);
4184 strv_free(info.documentation);
4185 strv_free(info.dropin_paths);
4186 strv_free(info.listen);
4188 if (!streq_ptr(info.active_state, "active") &&
4189 !streq_ptr(info.active_state, "reloading") &&
4190 streq(verb, "status")) {
4191 /* According to LSB: "program not running" */
4192 /* 0: program is running or service is OK
4193 * 1: program is dead and /run PID file exists
4194 * 2: program is dead and /run/lock lock file exists
4195 * 3: program is not running
4196 * 4: program or service status is unknown
4198 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4204 while ((p = info.exec)) {
4205 LIST_REMOVE(exec, info.exec, p);
4206 exec_status_info_free(p);
4212 static int get_unit_dbus_path_by_pid(
4217 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4218 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4222 r = sd_bus_call_method(
4224 "org.freedesktop.systemd1",
4225 "/org/freedesktop/systemd1",
4226 "org.freedesktop.systemd1.Manager",
4232 log_error("Failed to get unit for PID "PID_FMT": %s", pid, bus_error_message(&error, r));
4236 r = sd_bus_message_read(reply, "o", &u);
4238 return bus_log_parse_error(r);
4248 static int show_all(
4251 bool show_properties,
4255 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4256 _cleanup_free_ UnitInfo *unit_infos = NULL;
4261 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4265 pager_open_if_enabled();
4269 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4271 for (u = unit_infos; u < unit_infos + c; u++) {
4272 _cleanup_free_ char *p = NULL;
4274 p = unit_dbus_path_from_name(u->id);
4278 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4281 else if (r > 0 && ret == 0)
4288 static int show_system_status(sd_bus *bus) {
4289 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4290 _cleanup_free_ char *hn = NULL;
4291 struct machine_info mi = {};
4292 const char *on, *off;
4295 hn = gethostname_malloc();
4299 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4301 log_error("Failed to read server status: %s", strerror(-r));
4305 if (streq_ptr(mi.state, "degraded")) {
4306 on = ansi_highlight_red();
4307 off = ansi_highlight_off();
4308 } else if (!streq_ptr(mi.state, "running")) {
4309 on = ansi_highlight_yellow();
4310 off = ansi_highlight_off();
4314 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4316 printf(" State: %s%s%s\n",
4317 on, strna(mi.state), off);
4319 printf(" Jobs: %u queued\n", mi.n_jobs);
4320 printf(" Failed: %u units\n", mi.n_failed_units);
4322 printf(" Since: %s; %s\n",
4323 format_timestamp(since2, sizeof(since2), mi.timestamp),
4324 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4326 printf(" CGroup: %s\n", mi.control_group ?: "/");
4327 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4329 arg_all * OUTPUT_SHOW_ALL |
4330 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4331 on_tty() * OUTPUT_COLOR |
4332 !arg_quiet * OUTPUT_WARN_CUTOFF |
4333 arg_full * OUTPUT_FULL_WIDTH;
4335 static const char prefix[] = " ";
4339 if (c > sizeof(prefix) - 1)
4340 c -= sizeof(prefix) - 1;
4344 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4348 free(mi.control_group);
4353 static int show(sd_bus *bus, char **args) {
4354 bool show_properties, show_status, new_line = false;
4355 bool ellipsized = false;
4361 show_properties = streq(args[0], "show");
4362 show_status = streq(args[0], "status");
4364 if (show_properties)
4365 pager_open_if_enabled();
4367 /* If no argument is specified inspect the manager itself */
4369 if (show_properties && strv_length(args) <= 1)
4370 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4372 if (show_status && strv_length(args) <= 1) {
4374 pager_open_if_enabled();
4375 show_system_status(bus);
4379 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4381 _cleanup_free_ char **patterns = NULL;
4384 STRV_FOREACH(name, args + 1) {
4385 _cleanup_free_ char *unit = NULL;
4388 if (safe_atou32(*name, &id) < 0) {
4389 if (strv_push(&patterns, *name) < 0)
4393 } else if (show_properties) {
4394 /* Interpret as job id */
4395 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4399 /* Interpret as PID */
4400 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4407 r = show_one(args[0], bus, unit, show_properties,
4408 &new_line, &ellipsized);
4411 else if (r > 0 && ret == 0)
4415 if (!strv_isempty(patterns)) {
4416 _cleanup_strv_free_ char **names = NULL;
4418 r = expand_names(bus, patterns, NULL, &names);
4420 log_error("Failed to expand names: %s", strerror(-r));
4422 STRV_FOREACH(name, names) {
4423 _cleanup_free_ char *unit;
4425 unit = unit_dbus_path_from_name(*name);
4429 r = show_one(args[0], bus, unit, show_properties,
4430 &new_line, &ellipsized);
4433 else if (r > 0 && ret == 0)
4439 if (ellipsized && !arg_quiet)
4440 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4445 static int cat(sd_bus *bus, char **args) {
4446 _cleanup_free_ char *unit = NULL;
4447 _cleanup_strv_free_ char **names = NULL;
4455 r = expand_names(bus, args + 1, NULL, &names);
4457 log_error("Failed to expand names: %s", strerror(-r));
4459 pager_open_if_enabled();
4461 STRV_FOREACH(name, names) {
4462 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4463 _cleanup_strv_free_ char **dropin_paths = NULL;
4464 _cleanup_free_ char *fragment_path = NULL;
4467 unit = unit_dbus_path_from_name(*name);
4471 if (need_daemon_reload(bus, *name) > 0)
4472 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4473 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4475 r = sd_bus_get_property_string(
4477 "org.freedesktop.systemd1",
4479 "org.freedesktop.systemd1.Unit",
4484 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4488 r = sd_bus_get_property_strv(
4490 "org.freedesktop.systemd1",
4492 "org.freedesktop.systemd1.Unit",
4497 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4506 if (!isempty(fragment_path)) {
4507 printf("%s# %s%s\n",
4508 ansi_highlight_blue(),
4510 ansi_highlight_off());
4513 r = sendfile_full(STDOUT_FILENO, fragment_path);
4515 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4520 STRV_FOREACH(path, dropin_paths) {
4521 printf("%s%s# %s%s\n",
4522 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4523 ansi_highlight_blue(),
4525 ansi_highlight_off());
4528 r = sendfile_full(STDOUT_FILENO, *path);
4530 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4536 return r < 0 ? r : 0;
4539 static int set_property(sd_bus *bus, char **args) {
4540 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4541 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4542 _cleanup_free_ char *n = NULL;
4546 r = sd_bus_message_new_method_call(
4549 "org.freedesktop.systemd1",
4550 "/org/freedesktop/systemd1",
4551 "org.freedesktop.systemd1.Manager",
4552 "SetUnitProperties");
4554 return bus_log_create_error(r);
4556 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4560 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4562 return bus_log_create_error(r);
4564 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4566 return bus_log_create_error(r);
4568 STRV_FOREACH(i, args + 2) {
4569 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4571 return bus_log_create_error(r);
4573 r = bus_append_unit_property_assignment(m, *i);
4577 r = sd_bus_message_close_container(m);
4579 return bus_log_create_error(r);
4582 r = sd_bus_message_close_container(m);
4584 return bus_log_create_error(r);
4586 r = sd_bus_call(bus, m, 0, &error, NULL);
4588 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4595 static int snapshot(sd_bus *bus, char **args) {
4596 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4597 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4598 _cleanup_free_ char *n = NULL, *id = NULL;
4602 if (strv_length(args) > 1)
4603 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4609 r = sd_bus_call_method(
4611 "org.freedesktop.systemd1",
4612 "/org/freedesktop/systemd1",
4613 "org.freedesktop.systemd1.Manager",
4619 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4623 r = sd_bus_message_read(reply, "o", &path);
4625 return bus_log_parse_error(r);
4627 r = sd_bus_get_property_string(
4629 "org.freedesktop.systemd1",
4631 "org.freedesktop.systemd1.Unit",
4636 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4646 static int delete_snapshot(sd_bus *bus, char **args) {
4647 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4648 _cleanup_strv_free_ char **names = NULL;
4654 r = expand_names(bus, args + 1, ".snapshot", &names);
4656 log_error("Failed to expand names: %s", strerror(-r));
4658 STRV_FOREACH(name, names) {
4659 q = sd_bus_call_method(
4661 "org.freedesktop.systemd1",
4662 "/org/freedesktop/systemd1",
4663 "org.freedesktop.systemd1.Manager",
4669 log_error("Failed to remove snapshot %s: %s",
4670 *name, bus_error_message(&error, r));
4679 static int daemon_reload(sd_bus *bus, char **args) {
4680 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4684 if (arg_action == ACTION_RELOAD)
4686 else if (arg_action == ACTION_REEXEC)
4687 method = "Reexecute";
4689 assert(arg_action == ACTION_SYSTEMCTL);
4692 streq(args[0], "clear-jobs") ||
4693 streq(args[0], "cancel") ? "ClearJobs" :
4694 streq(args[0], "daemon-reexec") ? "Reexecute" :
4695 streq(args[0], "reset-failed") ? "ResetFailed" :
4696 streq(args[0], "halt") ? "Halt" :
4697 streq(args[0], "poweroff") ? "PowerOff" :
4698 streq(args[0], "reboot") ? "Reboot" :
4699 streq(args[0], "kexec") ? "KExec" :
4700 streq(args[0], "exit") ? "Exit" :
4701 /* "daemon-reload" */ "Reload";
4704 r = sd_bus_call_method(
4706 "org.freedesktop.systemd1",
4707 "/org/freedesktop/systemd1",
4708 "org.freedesktop.systemd1.Manager",
4714 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4715 /* There's always a fallback possible for
4716 * legacy actions. */
4718 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4719 /* On reexecution, we expect a disconnect, not a
4723 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4725 return r < 0 ? r : 0;
4728 static int reset_failed(sd_bus *bus, char **args) {
4729 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4730 _cleanup_strv_free_ char **names = NULL;
4734 if (strv_length(args) <= 1)
4735 return daemon_reload(bus, args);
4737 r = expand_names(bus, args + 1, NULL, &names);
4739 log_error("Failed to expand names: %s", strerror(-r));
4741 STRV_FOREACH(name, names) {
4742 q = sd_bus_call_method(
4744 "org.freedesktop.systemd1",
4745 "/org/freedesktop/systemd1",
4746 "org.freedesktop.systemd1.Manager",
4752 log_error("Failed to reset failed state of unit %s: %s",
4753 *name, bus_error_message(&error, r));
4762 static int show_environment(sd_bus *bus, char **args) {
4763 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4764 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4768 pager_open_if_enabled();
4770 r = sd_bus_get_property(
4772 "org.freedesktop.systemd1",
4773 "/org/freedesktop/systemd1",
4774 "org.freedesktop.systemd1.Manager",
4780 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4784 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4786 return bus_log_parse_error(r);
4788 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4791 return bus_log_parse_error(r);
4793 r = sd_bus_message_exit_container(reply);
4795 return bus_log_parse_error(r);
4800 static int switch_root(sd_bus *bus, char **args) {
4801 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4802 _cleanup_free_ char *cmdline_init = NULL;
4803 const char *root, *init;
4807 l = strv_length(args);
4808 if (l < 2 || l > 3) {
4809 log_error("Wrong number of arguments.");
4818 r = parse_env_file("/proc/cmdline", WHITESPACE,
4819 "init", &cmdline_init,
4822 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4824 init = cmdline_init;
4831 const char *root_systemd_path = NULL, *root_init_path = NULL;
4833 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4834 root_init_path = strappenda(root, "/", init);
4836 /* If the passed init is actually the same as the
4837 * systemd binary, then let's suppress it. */
4838 if (files_same(root_init_path, root_systemd_path) > 0)
4842 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4844 r = sd_bus_call_method(
4846 "org.freedesktop.systemd1",
4847 "/org/freedesktop/systemd1",
4848 "org.freedesktop.systemd1.Manager",
4854 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4861 static int set_environment(sd_bus *bus, char **args) {
4862 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4863 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4870 method = streq(args[0], "set-environment")
4872 : "UnsetEnvironment";
4874 r = sd_bus_message_new_method_call(
4877 "org.freedesktop.systemd1",
4878 "/org/freedesktop/systemd1",
4879 "org.freedesktop.systemd1.Manager",
4882 return bus_log_create_error(r);
4884 r = sd_bus_message_append_strv(m, args + 1);
4886 return bus_log_create_error(r);
4888 r = sd_bus_call(bus, m, 0, &error, NULL);
4890 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4897 static int import_environment(sd_bus *bus, char **args) {
4898 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4899 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4905 r = sd_bus_message_new_method_call(
4908 "org.freedesktop.systemd1",
4909 "/org/freedesktop/systemd1",
4910 "org.freedesktop.systemd1.Manager",
4913 return bus_log_create_error(r);
4915 if (strv_isempty(args + 1))
4916 r = sd_bus_message_append_strv(m, environ);
4920 r = sd_bus_message_open_container(m, 'a', "s");
4922 return bus_log_create_error(r);
4924 STRV_FOREACH(a, args + 1) {
4926 if (!env_name_is_valid(*a)) {
4927 log_error("Not a valid environment variable name: %s", *a);
4931 STRV_FOREACH(b, environ) {
4934 eq = startswith(*b, *a);
4935 if (eq && *eq == '=') {
4937 r = sd_bus_message_append(m, "s", *b);
4939 return bus_log_create_error(r);
4946 r = sd_bus_message_close_container(m);
4949 return bus_log_create_error(r);
4951 r = sd_bus_call(bus, m, 0, &error, NULL);
4953 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4960 static int enable_sysv_units(const char *verb, char **args) {
4963 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4964 unsigned f = 1, t = 1;
4965 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4967 if (arg_scope != UNIT_FILE_SYSTEM)
4970 if (!streq(verb, "enable") &&
4971 !streq(verb, "disable") &&
4972 !streq(verb, "is-enabled"))
4975 /* Processes all SysV units, and reshuffles the array so that
4976 * afterwards only the native units remain */
4978 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
4983 for (f = 0; args[f]; f++) {
4985 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
4986 bool found_native = false, found_sysv;
4988 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4996 if (!endswith(name, ".service"))
4999 if (path_is_absolute(name))
5002 STRV_FOREACH(k, paths.unit_path) {
5003 _cleanup_free_ char *path = NULL;
5005 path = path_join(arg_root, *k, name);
5009 found_native = access(path, F_OK) >= 0;
5017 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5021 p[strlen(p) - strlen(".service")] = 0;
5022 found_sysv = access(p, F_OK) >= 0;
5026 /* Mark this entry, so that we don't try enabling it as native unit */
5027 args[f] = (char*) "";
5029 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5031 if (!isempty(arg_root))
5032 argv[c++] = q = strappend("--root=", arg_root);
5034 argv[c++] = basename(p);
5036 streq(verb, "enable") ? "on" :
5037 streq(verb, "disable") ? "off" : "--level=5";
5040 l = strv_join((char**)argv, " ");
5044 log_info("Executing %s", l);
5048 log_error("Failed to fork: %m");
5050 } else if (pid == 0) {
5053 execv(argv[0], (char**) argv);
5054 _exit(EXIT_FAILURE);
5057 j = wait_for_terminate(pid, &status);
5059 log_error("Failed to wait for child: %s", strerror(-r));
5063 if (status.si_code == CLD_EXITED) {
5064 if (streq(verb, "is-enabled")) {
5065 if (status.si_status == 0) {
5074 } else if (status.si_status != 0)
5080 /* Drop all SysV units */
5081 for (f = 0, t = 0; args[f]; f++) {
5083 if (isempty(args[f]))
5086 args[t++] = args[f];
5095 static int mangle_names(char **original_names, char ***mangled_names) {
5096 char **i, **l, **name;
5098 l = new(char*, strv_length(original_names) + 1);
5103 STRV_FOREACH(name, original_names) {
5105 /* When enabling units qualified path names are OK,
5106 * too, hence allow them explicitly. */
5111 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5127 static int enable_unit(sd_bus *bus, char **args) {
5128 _cleanup_strv_free_ char **names = NULL;
5129 const char *verb = args[0];
5130 UnitFileChange *changes = NULL;
5131 unsigned n_changes = 0;
5132 int carries_install_info = -1;
5138 r = mangle_names(args+1, &names);
5142 r = enable_sysv_units(verb, names);
5146 /* If the operation was fully executed by the SysV compat,
5147 * let's finish early */
5148 if (strv_isempty(names))
5151 if (!bus || avoid_bus()) {
5152 if (streq(verb, "enable")) {
5153 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5154 carries_install_info = r;
5155 } else if (streq(verb, "disable"))
5156 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5157 else if (streq(verb, "reenable")) {
5158 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5159 carries_install_info = r;
5160 } else if (streq(verb, "link"))
5161 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5162 else if (streq(verb, "preset")) {
5163 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5164 carries_install_info = r;
5165 } else if (streq(verb, "mask"))
5166 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5167 else if (streq(verb, "unmask"))
5168 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5170 assert_not_reached("Unknown verb");
5173 log_error("Operation failed: %s", strerror(-r));
5178 dump_unit_file_changes(changes, n_changes);
5182 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5183 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5184 int expect_carries_install_info = false;
5185 bool send_force = true, send_preset_mode = false;
5188 if (streq(verb, "enable")) {
5189 method = "EnableUnitFiles";
5190 expect_carries_install_info = true;
5191 } else if (streq(verb, "disable")) {
5192 method = "DisableUnitFiles";
5194 } else if (streq(verb, "reenable")) {
5195 method = "ReenableUnitFiles";
5196 expect_carries_install_info = true;
5197 } else if (streq(verb, "link"))
5198 method = "LinkUnitFiles";
5199 else if (streq(verb, "preset")) {
5201 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5202 method = "PresetUnitFilesWithMode";
5203 send_preset_mode = true;
5205 method = "PresetUnitFiles";
5207 expect_carries_install_info = true;
5208 } else if (streq(verb, "mask"))
5209 method = "MaskUnitFiles";
5210 else if (streq(verb, "unmask")) {
5211 method = "UnmaskUnitFiles";
5214 assert_not_reached("Unknown verb");
5216 r = sd_bus_message_new_method_call(
5219 "org.freedesktop.systemd1",
5220 "/org/freedesktop/systemd1",
5221 "org.freedesktop.systemd1.Manager",
5224 return bus_log_create_error(r);
5226 r = sd_bus_message_append_strv(m, names);
5228 return bus_log_create_error(r);
5230 if (send_preset_mode) {
5231 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5233 return bus_log_create_error(r);
5236 r = sd_bus_message_append(m, "b", arg_runtime);
5238 return bus_log_create_error(r);
5241 r = sd_bus_message_append(m, "b", arg_force);
5243 return bus_log_create_error(r);
5246 r = sd_bus_call(bus, m, 0, &error, &reply);
5248 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5252 if (expect_carries_install_info) {
5253 r = sd_bus_message_read(reply, "b", &carries_install_info);
5255 return bus_log_parse_error(r);
5258 r = deserialize_and_dump_unit_file_changes(reply);
5262 /* Try to reload if enabled */
5264 r = daemon_reload(bus, args);
5269 if (carries_install_info == 0)
5270 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5271 "using systemctl.\n"
5272 "Possible reasons for having this kind of units are:\n"
5273 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5274 " .wants/ or .requires/ directory.\n"
5275 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5276 " a requirement dependency on it.\n"
5277 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5278 " D-Bus, udev, scripted systemctl call, ...).\n");
5281 unit_file_changes_free(changes, n_changes);
5286 static int preset_all(sd_bus *bus, char **args) {
5287 UnitFileChange *changes = NULL;
5288 unsigned n_changes = 0;
5291 if (!bus || avoid_bus()) {
5293 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5295 log_error("Operation failed: %s", strerror(-r));
5300 dump_unit_file_changes(changes, n_changes);
5305 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5306 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5308 r = sd_bus_call_method(
5310 "org.freedesktop.systemd1",
5311 "/org/freedesktop/systemd1",
5312 "org.freedesktop.systemd1.Manager",
5313 "PresetAllUnitFiles",
5317 unit_file_preset_mode_to_string(arg_preset_mode),
5321 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5325 r = deserialize_and_dump_unit_file_changes(reply);
5330 r = daemon_reload(bus, args);
5336 unit_file_changes_free(changes, n_changes);
5341 static int unit_is_enabled(sd_bus *bus, char **args) {
5343 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5344 _cleanup_strv_free_ char **names = NULL;
5349 r = mangle_names(args+1, &names);
5353 r = enable_sysv_units(args[0], names);
5359 if (!bus || avoid_bus()) {
5361 STRV_FOREACH(name, names) {
5362 UnitFileState state;
5364 state = unit_file_get_state(arg_scope, arg_root, *name);
5366 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5370 if (state == UNIT_FILE_ENABLED ||
5371 state == UNIT_FILE_ENABLED_RUNTIME ||
5372 state == UNIT_FILE_STATIC)
5376 puts(unit_file_state_to_string(state));
5380 STRV_FOREACH(name, names) {
5381 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5384 r = sd_bus_call_method(
5386 "org.freedesktop.systemd1",
5387 "/org/freedesktop/systemd1",
5388 "org.freedesktop.systemd1.Manager",
5394 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5398 r = sd_bus_message_read(reply, "s", &s);
5400 return bus_log_parse_error(r);
5402 if (streq(s, "enabled") ||
5403 streq(s, "enabled-runtime") ||
5415 static int is_system_running(sd_bus *bus, char **args) {
5416 _cleanup_free_ char *state = NULL;
5419 r = sd_bus_get_property_string(
5421 "org.freedesktop.systemd1",
5422 "/org/freedesktop/systemd1",
5423 "org.freedesktop.systemd1.Manager",
5436 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5439 static void systemctl_help(void) {
5441 pager_open_if_enabled();
5443 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5444 "Query or send control commands to the systemd manager.\n\n"
5445 " -h --help Show this help\n"
5446 " --version Show package version\n"
5447 " --system Connect to system manager\n"
5448 " --user Connect to user service manager\n"
5449 " -H --host=[USER@]HOST\n"
5450 " Operate on remote host\n"
5451 " -M --machine=CONTAINER\n"
5452 " Operate on local container\n"
5453 " -t --type=TYPE List only units of a particular type\n"
5454 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5455 " -p --property=NAME Show only properties by this name\n"
5456 " -a --all Show all loaded units/properties, including dead/empty\n"
5457 " ones. To list all units installed on the system, use\n"
5458 " the 'list-unit-files' command instead.\n"
5459 " -l --full Don't ellipsize unit names on output\n"
5460 " -r --recursive Show unit list of host and local containers\n"
5461 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5462 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5463 " queueing a new job\n"
5464 " --show-types When showing sockets, explicitly show their type\n"
5465 " -i --ignore-inhibitors\n"
5466 " When shutting down or sleeping, ignore inhibitors\n"
5467 " --kill-who=WHO Who to send signal to\n"
5468 " -s --signal=SIGNAL Which signal to send\n"
5469 " -q --quiet Suppress output\n"
5470 " --no-block Do not wait until operation finished\n"
5471 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5472 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5474 " --no-legend Do not print a legend (column headers and hints)\n"
5475 " --no-pager Do not pipe output into a pager\n"
5476 " --no-ask-password\n"
5477 " Do not ask for system passwords\n"
5478 " --global Enable/disable unit files globally\n"
5479 " --runtime Enable unit files only temporarily until next reboot\n"
5480 " -f --force When enabling unit files, override existing symlinks\n"
5481 " When shutting down, execute action immediately\n"
5482 " --preset-mode= Specifies whether fully apply presets, or only enable,\n"
5483 " or only disable\n"
5484 " --root=PATH Enable unit files in the specified root directory\n"
5485 " -n --lines=INTEGER Number of journal entries to show\n"
5486 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5487 " verbose, export, json, json-pretty, json-sse, cat)\n"
5488 " --plain Print unit dependencies as a list instead of a tree\n\n"
5490 " list-units [PATTERN...] List loaded units\n"
5491 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5492 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5493 " start NAME... Start (activate) one or more units\n"
5494 " stop NAME... Stop (deactivate) one or more units\n"
5495 " reload NAME... Reload one or more units\n"
5496 " restart NAME... Start or restart one or more units\n"
5497 " try-restart NAME... Restart one or more units if active\n"
5498 " reload-or-restart NAME... Reload one or more units if possible,\n"
5499 " otherwise start or restart\n"
5500 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5501 " otherwise restart if active\n"
5502 " isolate NAME Start one unit and stop all others\n"
5503 " kill NAME... Send signal to processes of a unit\n"
5504 " is-active PATTERN... Check whether units are active\n"
5505 " is-failed PATTERN... Check whether units are failed\n"
5506 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
5507 " show [PATTERN...|JOB...] Show properties of one or more\n"
5508 " units/jobs or the manager\n"
5509 " cat PATTERN... Show files and drop-ins of one or more units\n"
5510 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5511 " help PATTERN...|PID... Show manual for one or more units\n"
5512 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
5514 " list-dependencies [NAME] Recursively show units which are required\n"
5515 " or wanted by this unit or by which this\n"
5516 " unit is required or wanted\n\n"
5517 "Unit File Commands:\n"
5518 " list-unit-files [PATTERN...] List installed unit files\n"
5519 " enable NAME... Enable one or more unit files\n"
5520 " disable NAME... Disable one or more unit files\n"
5521 " reenable NAME... Reenable one or more unit files\n"
5522 " preset NAME... Enable/disable one or more unit files\n"
5523 " based on preset configuration\n"
5524 " preset-all Enable/disable all unit files based on\n"
5525 " preset configuration\n"
5526 " is-enabled NAME... Check whether unit files are enabled\n\n"
5527 " mask NAME... Mask one or more units\n"
5528 " unmask NAME... Unmask one or more units\n"
5529 " link PATH... Link one or more units files into\n"
5530 " the search path\n"
5531 " get-default Get the name of the default target\n"
5532 " set-default NAME Set the default target\n\n"
5533 "Machine Commands:\n"
5534 " list-machines [PATTERN...] List local containers and host\n\n"
5536 " list-jobs [PATTERN...] List jobs\n"
5537 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5538 "Snapshot Commands:\n"
5539 " snapshot [NAME] Create a snapshot\n"
5540 " delete NAME... Remove one or more snapshots\n\n"
5541 "Environment Commands:\n"
5542 " show-environment Dump environment\n"
5543 " set-environment NAME=VALUE... Set one or more environment variables\n"
5544 " unset-environment NAME... Unset one or more environment variables\n"
5545 " import-environment NAME... Import all, one or more environment variables\n\n"
5546 "Manager Lifecycle Commands:\n"
5547 " daemon-reload Reload systemd manager configuration\n"
5548 " daemon-reexec Reexecute systemd manager\n\n"
5549 "System Commands:\n"
5550 " is-system-running Check whether system is fully running\n"
5551 " default Enter system default mode\n"
5552 " rescue Enter system rescue mode\n"
5553 " emergency Enter system emergency mode\n"
5554 " halt Shut down and halt the system\n"
5555 " poweroff Shut down and power-off the system\n"
5556 " reboot [ARG] Shut down and reboot the system\n"
5557 " kexec Shut down and reboot the system with kexec\n"
5558 " exit Request user instance exit\n"
5559 " switch-root ROOT [INIT] Change to a different root file system\n"
5560 " suspend Suspend the system\n"
5561 " hibernate Hibernate the system\n"
5562 " hybrid-sleep Hibernate and suspend the system\n",
5563 program_invocation_short_name);
5566 static void halt_help(void) {
5567 printf("%s [OPTIONS...]%s\n\n"
5568 "%s the system.\n\n"
5569 " --help Show this help\n"
5570 " --halt Halt the machine\n"
5571 " -p --poweroff Switch off the machine\n"
5572 " --reboot Reboot the machine\n"
5573 " -f --force Force immediate halt/power-off/reboot\n"
5574 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5575 " -d --no-wtmp Don't write wtmp record\n"
5576 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5577 program_invocation_short_name,
5578 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5579 arg_action == ACTION_REBOOT ? "Reboot" :
5580 arg_action == ACTION_POWEROFF ? "Power off" :
5584 static void shutdown_help(void) {
5585 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5586 "Shut down the system.\n\n"
5587 " --help Show this help\n"
5588 " -H --halt Halt the machine\n"
5589 " -P --poweroff Power-off the machine\n"
5590 " -r --reboot Reboot the machine\n"
5591 " -h Equivalent to --poweroff, overridden by --halt\n"
5592 " -k Don't halt/power-off/reboot, just send warnings\n"
5593 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5594 " -c Cancel a pending shutdown\n",
5595 program_invocation_short_name);
5598 static void telinit_help(void) {
5599 printf("%s [OPTIONS...] {COMMAND}\n\n"
5600 "Send control commands to the init daemon.\n\n"
5601 " --help Show this help\n"
5602 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5604 " 0 Power-off the machine\n"
5605 " 6 Reboot the machine\n"
5606 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5607 " 1, s, S Enter rescue mode\n"
5608 " q, Q Reload init daemon configuration\n"
5609 " u, U Reexecute init daemon\n",
5610 program_invocation_short_name);
5613 static void runlevel_help(void) {
5614 printf("%s [OPTIONS...]\n\n"
5615 "Prints the previous and current runlevel of the init system.\n\n"
5616 " --help Show this help\n",
5617 program_invocation_short_name);
5620 static void help_types(void) {
5625 puts("Available unit types:");
5626 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5627 t = unit_type_to_string(i);
5633 static int systemctl_parse_argv(int argc, char *argv[]) {
5642 ARG_IGNORE_DEPENDENCIES,
5654 ARG_NO_ASK_PASSWORD,
5664 static const struct option options[] = {
5665 { "help", no_argument, NULL, 'h' },
5666 { "version", no_argument, NULL, ARG_VERSION },
5667 { "type", required_argument, NULL, 't' },
5668 { "property", required_argument, NULL, 'p' },
5669 { "all", no_argument, NULL, 'a' },
5670 { "reverse", no_argument, NULL, ARG_REVERSE },
5671 { "after", no_argument, NULL, ARG_AFTER },
5672 { "before", no_argument, NULL, ARG_BEFORE },
5673 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5674 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5675 { "full", no_argument, NULL, 'l' },
5676 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5677 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5678 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5679 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5680 { "ignore-inhibitors", no_argument, NULL, 'i' },
5681 { "user", no_argument, NULL, ARG_USER },
5682 { "system", no_argument, NULL, ARG_SYSTEM },
5683 { "global", no_argument, NULL, ARG_GLOBAL },
5684 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5685 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5686 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5687 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5688 { "quiet", no_argument, NULL, 'q' },
5689 { "root", required_argument, NULL, ARG_ROOT },
5690 { "force", no_argument, NULL, ARG_FORCE },
5691 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5692 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5693 { "signal", required_argument, NULL, 's' },
5694 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5695 { "host", required_argument, NULL, 'H' },
5696 { "machine", required_argument, NULL, 'M' },
5697 { "runtime", no_argument, NULL, ARG_RUNTIME },
5698 { "lines", required_argument, NULL, 'n' },
5699 { "output", required_argument, NULL, 'o' },
5700 { "plain", no_argument, NULL, ARG_PLAIN },
5701 { "state", required_argument, NULL, ARG_STATE },
5702 { "recursive", no_argument, NULL, 'r' },
5703 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
5712 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
5721 puts(PACKAGE_STRING);
5722 puts(SYSTEMD_FEATURES);
5726 const char *word, *state;
5729 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5730 _cleanup_free_ char *type;
5732 type = strndup(word, size);
5736 if (streq(type, "help")) {
5741 if (unit_type_from_string(type) >= 0) {
5742 if (strv_push(&arg_types, type))
5748 /* It's much nicer to use --state= for
5749 * load states, but let's support this
5750 * in --types= too for compatibility
5751 * with old versions */
5752 if (unit_load_state_from_string(optarg) >= 0) {
5753 if (strv_push(&arg_states, type) < 0)
5759 log_error("Unknown unit type or load state '%s'.", type);
5760 log_info("Use -t help to see a list of allowed values.");
5768 /* Make sure that if the empty property list
5769 was specified, we won't show any properties. */
5770 if (isempty(optarg) && !arg_properties) {
5771 arg_properties = new0(char*, 1);
5772 if (!arg_properties)
5775 const char *word, *state;
5778 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5781 prop = strndup(word, size);
5785 if (strv_consume(&arg_properties, prop) < 0)
5790 /* If the user asked for a particular
5791 * property, show it to him, even if it is
5803 arg_dependency = DEPENDENCY_REVERSE;
5807 arg_dependency = DEPENDENCY_AFTER;
5811 arg_dependency = DEPENDENCY_BEFORE;
5814 case ARG_SHOW_TYPES:
5815 arg_show_types = true;
5819 arg_job_mode = optarg;
5823 arg_job_mode = "fail";
5826 case ARG_IRREVERSIBLE:
5827 arg_job_mode = "replace-irreversibly";
5830 case ARG_IGNORE_DEPENDENCIES:
5831 arg_job_mode = "ignore-dependencies";
5835 arg_scope = UNIT_FILE_USER;
5839 arg_scope = UNIT_FILE_SYSTEM;
5843 arg_scope = UNIT_FILE_GLOBAL;
5847 arg_no_block = true;
5851 arg_no_legend = true;
5855 arg_no_pager = true;
5871 if (strv_extend(&arg_states, "failed") < 0)
5889 arg_no_reload = true;
5893 arg_kill_who = optarg;
5897 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5898 log_error("Failed to parse signal string %s.", optarg);
5903 case ARG_NO_ASK_PASSWORD:
5904 arg_ask_password = false;
5908 arg_transport = BUS_TRANSPORT_REMOTE;
5913 arg_transport = BUS_TRANSPORT_CONTAINER;
5922 if (safe_atou(optarg, &arg_lines) < 0) {
5923 log_error("Failed to parse lines '%s'", optarg);
5929 arg_output = output_mode_from_string(optarg);
5930 if (arg_output < 0) {
5931 log_error("Unknown output '%s'.", optarg);
5937 arg_ignore_inhibitors = true;
5945 const char *word, *state;
5948 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5951 s = strndup(word, size);
5955 if (strv_consume(&arg_states, s) < 0)
5962 if (geteuid() != 0) {
5963 log_error("--recursive requires root privileges.");
5967 arg_recursive = true;
5970 case ARG_PRESET_MODE:
5972 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
5973 if (arg_preset_mode < 0) {
5974 log_error("Failed to parse preset mode: %s.", optarg);
5984 assert_not_reached("Unhandled option");
5987 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5988 log_error("Cannot access user instance remotely.");
5995 static int halt_parse_argv(int argc, char *argv[]) {
6004 static const struct option options[] = {
6005 { "help", no_argument, NULL, ARG_HELP },
6006 { "halt", no_argument, NULL, ARG_HALT },
6007 { "poweroff", no_argument, NULL, 'p' },
6008 { "reboot", no_argument, NULL, ARG_REBOOT },
6009 { "force", no_argument, NULL, 'f' },
6010 { "wtmp-only", no_argument, NULL, 'w' },
6011 { "no-wtmp", no_argument, NULL, 'd' },
6012 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6021 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6022 if (runlevel == '0' || runlevel == '6')
6025 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6033 arg_action = ACTION_HALT;
6037 if (arg_action != ACTION_REBOOT)
6038 arg_action = ACTION_POWEROFF;
6042 arg_action = ACTION_REBOOT;
6064 /* Compatibility nops */
6071 assert_not_reached("Unhandled option");
6074 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6075 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6078 } else if (optind < argc) {
6079 log_error("Too many arguments.");
6086 static int parse_time_spec(const char *t, usec_t *_u) {
6090 if (streq(t, "now"))
6092 else if (!strchr(t, ':')) {
6095 if (safe_atou64(t, &u) < 0)
6098 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6107 hour = strtol(t, &e, 10);
6108 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6111 minute = strtol(e+1, &e, 10);
6112 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6115 n = now(CLOCK_REALTIME);
6116 s = (time_t) (n / USEC_PER_SEC);
6118 assert_se(localtime_r(&s, &tm));
6120 tm.tm_hour = (int) hour;
6121 tm.tm_min = (int) minute;
6124 assert_se(s = mktime(&tm));
6126 *_u = (usec_t) s * USEC_PER_SEC;
6129 *_u += USEC_PER_DAY;
6135 static int shutdown_parse_argv(int argc, char *argv[]) {
6142 static const struct option options[] = {
6143 { "help", no_argument, NULL, ARG_HELP },
6144 { "halt", no_argument, NULL, 'H' },
6145 { "poweroff", no_argument, NULL, 'P' },
6146 { "reboot", no_argument, NULL, 'r' },
6147 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6148 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6157 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0)
6165 arg_action = ACTION_HALT;
6169 arg_action = ACTION_POWEROFF;
6174 arg_action = ACTION_KEXEC;
6176 arg_action = ACTION_REBOOT;
6180 arg_action = ACTION_KEXEC;
6184 if (arg_action != ACTION_HALT)
6185 arg_action = ACTION_POWEROFF;
6198 /* Compatibility nops */
6202 arg_action = ACTION_CANCEL_SHUTDOWN;
6209 assert_not_reached("Unhandled option");
6212 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6213 r = parse_time_spec(argv[optind], &arg_when);
6215 log_error("Failed to parse time specification: %s", argv[optind]);
6219 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6221 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6222 /* No time argument for shutdown cancel */
6223 arg_wall = argv + optind;
6224 else if (argc > optind + 1)
6225 /* We skip the time argument */
6226 arg_wall = argv + optind + 1;
6233 static int telinit_parse_argv(int argc, char *argv[]) {
6240 static const struct option options[] = {
6241 { "help", no_argument, NULL, ARG_HELP },
6242 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6246 static const struct {
6250 { '0', ACTION_POWEROFF },
6251 { '6', ACTION_REBOOT },
6252 { '1', ACTION_RESCUE },
6253 { '2', ACTION_RUNLEVEL2 },
6254 { '3', ACTION_RUNLEVEL3 },
6255 { '4', ACTION_RUNLEVEL4 },
6256 { '5', ACTION_RUNLEVEL5 },
6257 { 's', ACTION_RESCUE },
6258 { 'S', ACTION_RESCUE },
6259 { 'q', ACTION_RELOAD },
6260 { 'Q', ACTION_RELOAD },
6261 { 'u', ACTION_REEXEC },
6262 { 'U', ACTION_REEXEC }
6271 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6286 assert_not_reached("Unhandled option");
6289 if (optind >= argc) {
6290 log_error("%s: required argument missing.",
6291 program_invocation_short_name);
6295 if (optind + 1 < argc) {
6296 log_error("Too many arguments.");
6300 if (strlen(argv[optind]) != 1) {
6301 log_error("Expected single character argument.");
6305 for (i = 0; i < ELEMENTSOF(table); i++)
6306 if (table[i].from == argv[optind][0])
6309 if (i >= ELEMENTSOF(table)) {
6310 log_error("Unknown command '%s'.", argv[optind]);
6314 arg_action = table[i].to;
6321 static int runlevel_parse_argv(int argc, char *argv[]) {
6327 static const struct option options[] = {
6328 { "help", no_argument, NULL, ARG_HELP },
6337 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6348 assert_not_reached("Unhandled option");
6351 if (optind < argc) {
6352 log_error("Too many arguments.");
6359 static int parse_argv(int argc, char *argv[]) {
6363 if (program_invocation_short_name) {
6365 if (strstr(program_invocation_short_name, "halt")) {
6366 arg_action = ACTION_HALT;
6367 return halt_parse_argv(argc, argv);
6368 } else if (strstr(program_invocation_short_name, "poweroff")) {
6369 arg_action = ACTION_POWEROFF;
6370 return halt_parse_argv(argc, argv);
6371 } else if (strstr(program_invocation_short_name, "reboot")) {
6373 arg_action = ACTION_KEXEC;
6375 arg_action = ACTION_REBOOT;
6376 return halt_parse_argv(argc, argv);
6377 } else if (strstr(program_invocation_short_name, "shutdown")) {
6378 arg_action = ACTION_POWEROFF;
6379 return shutdown_parse_argv(argc, argv);
6380 } else if (strstr(program_invocation_short_name, "init")) {
6382 if (sd_booted() > 0) {
6383 arg_action = _ACTION_INVALID;
6384 return telinit_parse_argv(argc, argv);
6386 /* Hmm, so some other init system is
6387 * running, we need to forward this
6388 * request to it. For now we simply
6389 * guess that it is Upstart. */
6391 execv(TELINIT, argv);
6393 log_error("Couldn't find an alternative telinit implementation to spawn.");
6397 } else if (strstr(program_invocation_short_name, "runlevel")) {
6398 arg_action = ACTION_RUNLEVEL;
6399 return runlevel_parse_argv(argc, argv);
6403 arg_action = ACTION_SYSTEMCTL;
6404 return systemctl_parse_argv(argc, argv);
6407 _pure_ static int action_to_runlevel(void) {
6409 static const char table[_ACTION_MAX] = {
6410 [ACTION_HALT] = '0',
6411 [ACTION_POWEROFF] = '0',
6412 [ACTION_REBOOT] = '6',
6413 [ACTION_RUNLEVEL2] = '2',
6414 [ACTION_RUNLEVEL3] = '3',
6415 [ACTION_RUNLEVEL4] = '4',
6416 [ACTION_RUNLEVEL5] = '5',
6417 [ACTION_RESCUE] = '1'
6420 assert(arg_action < _ACTION_MAX);
6422 return table[arg_action];
6425 static int talk_initctl(void) {
6427 struct init_request request = {
6428 .magic = INIT_MAGIC,
6430 .cmd = INIT_CMD_RUNLVL
6433 _cleanup_close_ int fd = -1;
6437 rl = action_to_runlevel();
6441 request.runlevel = rl;
6443 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6445 if (errno == ENOENT)
6448 log_error("Failed to open "INIT_FIFO": %m");
6453 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6455 log_error("Failed to write to "INIT_FIFO": %m");
6456 return errno > 0 ? -errno : -EIO;
6462 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6464 static const struct {
6472 int (* const dispatch)(sd_bus *bus, char **args);
6478 { "list-units", MORE, 0, list_units },
6479 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6480 { "list-sockets", MORE, 1, list_sockets },
6481 { "list-timers", MORE, 1, list_timers },
6482 { "list-jobs", MORE, 1, list_jobs },
6483 { "list-machines", MORE, 1, list_machines },
6484 { "clear-jobs", EQUAL, 1, daemon_reload },
6485 { "cancel", MORE, 2, cancel_job },
6486 { "start", MORE, 2, start_unit },
6487 { "stop", MORE, 2, start_unit },
6488 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6489 { "reload", MORE, 2, start_unit },
6490 { "restart", MORE, 2, start_unit },
6491 { "try-restart", MORE, 2, start_unit },
6492 { "reload-or-restart", MORE, 2, start_unit },
6493 { "reload-or-try-restart", MORE, 2, start_unit },
6494 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6495 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6496 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6497 { "isolate", EQUAL, 2, start_unit },
6498 { "kill", MORE, 2, kill_unit },
6499 { "is-active", MORE, 2, check_unit_active },
6500 { "check", MORE, 2, check_unit_active },
6501 { "is-failed", MORE, 2, check_unit_failed },
6502 { "show", MORE, 1, show },
6503 { "cat", MORE, 2, cat },
6504 { "status", MORE, 1, show },
6505 { "help", MORE, 2, show },
6506 { "snapshot", LESS, 2, snapshot },
6507 { "delete", MORE, 2, delete_snapshot },
6508 { "daemon-reload", EQUAL, 1, daemon_reload },
6509 { "daemon-reexec", EQUAL, 1, daemon_reload },
6510 { "show-environment", EQUAL, 1, show_environment },
6511 { "set-environment", MORE, 2, set_environment },
6512 { "unset-environment", MORE, 2, set_environment },
6513 { "import-environment", MORE, 1, import_environment},
6514 { "halt", EQUAL, 1, start_special, FORCE },
6515 { "poweroff", EQUAL, 1, start_special, FORCE },
6516 { "reboot", EQUAL, 1, start_special, FORCE },
6517 { "kexec", EQUAL, 1, start_special },
6518 { "suspend", EQUAL, 1, start_special },
6519 { "hibernate", EQUAL, 1, start_special },
6520 { "hybrid-sleep", EQUAL, 1, start_special },
6521 { "default", EQUAL, 1, start_special },
6522 { "rescue", EQUAL, 1, start_special },
6523 { "emergency", EQUAL, 1, start_special },
6524 { "exit", EQUAL, 1, start_special },
6525 { "reset-failed", MORE, 1, reset_failed },
6526 { "enable", MORE, 2, enable_unit, NOBUS },
6527 { "disable", MORE, 2, enable_unit, NOBUS },
6528 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6529 { "reenable", MORE, 2, enable_unit, NOBUS },
6530 { "preset", MORE, 2, enable_unit, NOBUS },
6531 { "preset-all", EQUAL, 1, preset_all, NOBUS },
6532 { "mask", MORE, 2, enable_unit, NOBUS },
6533 { "unmask", MORE, 2, enable_unit, NOBUS },
6534 { "link", MORE, 2, enable_unit, NOBUS },
6535 { "switch-root", MORE, 2, switch_root },
6536 { "list-dependencies", LESS, 2, list_dependencies },
6537 { "set-default", EQUAL, 2, set_default, NOBUS },
6538 { "get-default", EQUAL, 1, get_default, NOBUS },
6539 { "set-property", MORE, 3, set_property },
6540 { "is-system-running", EQUAL, 1, is_system_running },
6549 left = argc - optind;
6551 /* Special rule: no arguments (left == 0) means "list-units" */
6553 if (streq(argv[optind], "help") && !argv[optind+1]) {
6554 log_error("This command expects one or more "
6555 "unit names. Did you mean --help?");
6559 for (; verb->verb; verb++)
6560 if (streq(argv[optind], verb->verb))
6563 log_error("Unknown operation '%s'.", argv[optind]);
6568 switch (verb->argc_cmp) {
6571 if (left != verb->argc) {
6572 log_error("Invalid number of arguments.");
6579 if (left < verb->argc) {
6580 log_error("Too few arguments.");
6587 if (left > verb->argc) {
6588 log_error("Too many arguments.");
6595 assert_not_reached("Unknown comparison operator.");
6598 /* Require a bus connection for all operations but
6600 if (verb->bus == NOBUS) {
6601 if (!bus && !avoid_bus()) {
6602 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6607 if (running_in_chroot() > 0) {
6608 log_info("Running in chroot, ignoring request.");
6612 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6613 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6618 return verb->dispatch(bus, argv + optind);
6621 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6623 struct sd_shutdown_command c = {
6630 union sockaddr_union sockaddr = {
6631 .un.sun_family = AF_UNIX,
6632 .un.sun_path = "/run/systemd/shutdownd",
6635 struct iovec iovec[2] = {{
6636 .iov_base = (char*) &c,
6637 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6640 struct msghdr msghdr = {
6641 .msg_name = &sockaddr,
6642 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6643 + strlen("/run/systemd/shutdownd"),
6648 _cleanup_close_ int fd;
6650 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6654 if (!isempty(message)) {
6655 iovec[1].iov_base = (char*) message;
6656 iovec[1].iov_len = strlen(message);
6657 msghdr.msg_iovlen++;
6660 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6666 static int reload_with_fallback(sd_bus *bus) {
6669 /* First, try systemd via D-Bus. */
6670 if (daemon_reload(bus, NULL) >= 0)
6674 /* Nothing else worked, so let's try signals */
6675 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6677 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6678 log_error("kill() failed: %m");
6685 static int start_with_fallback(sd_bus *bus) {
6688 /* First, try systemd via D-Bus. */
6689 if (start_unit(bus, NULL) >= 0)
6693 /* Nothing else worked, so let's try
6695 if (talk_initctl() > 0)
6698 log_error("Failed to talk to init daemon.");
6702 warn_wall(arg_action);
6706 static int halt_now(enum action a) {
6708 /* Make sure C-A-D is handled by the kernel from this
6710 reboot(RB_ENABLE_CAD);
6715 log_info("Halting.");
6716 reboot(RB_HALT_SYSTEM);
6719 case ACTION_POWEROFF:
6720 log_info("Powering off.");
6721 reboot(RB_POWER_OFF);
6724 case ACTION_REBOOT: {
6725 _cleanup_free_ char *param = NULL;
6727 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6728 log_info("Rebooting with argument '%s'.", param);
6729 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6730 LINUX_REBOOT_CMD_RESTART2, param);
6733 log_info("Rebooting.");
6734 reboot(RB_AUTOBOOT);
6739 assert_not_reached("Unknown action.");
6743 static int halt_main(sd_bus *bus) {
6746 r = check_inhibitors(bus, arg_action);
6750 if (geteuid() != 0) {
6751 /* Try logind if we are a normal user and no special
6752 * mode applies. Maybe PolicyKit allows us to shutdown
6755 if (arg_when <= 0 &&
6758 (arg_action == ACTION_POWEROFF ||
6759 arg_action == ACTION_REBOOT)) {
6760 r = reboot_with_logind(bus, arg_action);
6765 log_error("Must be root.");
6770 _cleanup_free_ char *m;
6772 m = strv_join(arg_wall, " ");
6776 r = send_shutdownd(arg_when,
6777 arg_action == ACTION_HALT ? 'H' :
6778 arg_action == ACTION_POWEROFF ? 'P' :
6779 arg_action == ACTION_KEXEC ? 'K' :
6786 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6788 char date[FORMAT_TIMESTAMP_MAX];
6790 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6791 format_timestamp(date, sizeof(date), arg_when));
6796 if (!arg_dry && !arg_force)
6797 return start_with_fallback(bus);
6800 if (sd_booted() > 0)
6801 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6803 r = utmp_put_shutdown();
6805 log_warning("Failed to write utmp record: %s", strerror(-r));
6812 r = halt_now(arg_action);
6813 log_error("Failed to reboot: %s", strerror(-r));
6818 static int runlevel_main(void) {
6819 int r, runlevel, previous;
6821 r = utmp_get_runlevel(&runlevel, &previous);
6828 previous <= 0 ? 'N' : previous,
6829 runlevel <= 0 ? 'N' : runlevel);
6834 int main(int argc, char*argv[]) {
6835 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
6838 setlocale(LC_ALL, "");
6839 log_parse_environment();
6842 /* Explicitly not on_tty() to avoid setting cached value.
6843 * This becomes relevant for piping output which might be
6845 original_stdout_is_tty = isatty(STDOUT_FILENO);
6847 r = parse_argv(argc, argv);
6851 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6852 * let's shortcut this */
6853 if (arg_action == ACTION_RUNLEVEL) {
6854 r = runlevel_main();
6858 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6859 log_info("Running in chroot, ignoring request.");
6865 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6867 /* systemctl_main() will print an error message for the bus
6868 * connection, but only if it needs to */
6870 switch (arg_action) {
6872 case ACTION_SYSTEMCTL:
6873 r = systemctl_main(bus, argc, argv, r);
6877 case ACTION_POWEROFF:
6883 case ACTION_RUNLEVEL2:
6884 case ACTION_RUNLEVEL3:
6885 case ACTION_RUNLEVEL4:
6886 case ACTION_RUNLEVEL5:
6888 case ACTION_EMERGENCY:
6889 case ACTION_DEFAULT:
6890 r = start_with_fallback(bus);
6895 r = reload_with_fallback(bus);
6898 case ACTION_CANCEL_SHUTDOWN: {
6899 _cleanup_free_ char *m = NULL;
6902 m = strv_join(arg_wall, " ");
6909 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6911 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6915 case ACTION_RUNLEVEL:
6916 case _ACTION_INVALID:
6918 assert_not_reached("Unknown action");
6923 ask_password_agent_close();
6924 polkit_agent_close();
6926 strv_free(arg_types);
6927 strv_free(arg_states);
6928 strv_free(arg_properties);
6930 return r < 0 ? EXIT_FAILURE : r;