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 bool original_stdout_is_tty;
81 static enum dependency {
87 } arg_dependency = DEPENDENCY_FORWARD;
88 static const char *arg_job_mode = "replace";
89 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
90 static bool arg_no_block = false;
91 static bool arg_no_legend = false;
92 static bool arg_no_pager = false;
93 static bool arg_no_wtmp = false;
94 static bool arg_no_wall = false;
95 static bool arg_no_reload = false;
96 static bool arg_show_types = false;
97 static bool arg_ignore_inhibitors = false;
98 static bool arg_dry = false;
99 static bool arg_quiet = false;
100 static bool arg_full = false;
101 static int arg_force = 0;
102 static bool arg_ask_password = true;
103 static bool arg_runtime = false;
104 static char **arg_wall = NULL;
105 static const char *arg_kill_who = NULL;
106 static int arg_signal = SIGTERM;
107 static const char *arg_root = NULL;
108 static usec_t arg_when = 0;
130 ACTION_CANCEL_SHUTDOWN,
132 } arg_action = ACTION_SYSTEMCTL;
133 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
134 static char *arg_host = NULL;
135 static unsigned arg_lines = 10;
136 static OutputMode arg_output = OUTPUT_SHORT;
137 static bool arg_plain = false;
138 static const struct {
142 { "start", "StartUnit" },
143 { "stop", "StopUnit" },
144 { "condstop", "StopUnit" },
145 { "reload", "ReloadUnit" },
146 { "restart", "RestartUnit" },
147 { "try-restart", "TryRestartUnit" },
148 { "condrestart", "TryRestartUnit" },
149 { "reload-or-restart", "ReloadOrRestartUnit" },
150 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
151 { "condreload", "ReloadOrTryRestartUnit" },
152 { "force-reload", "ReloadOrTryRestartUnit" }
155 static int daemon_reload(sd_bus *bus, char **args);
156 static int halt_now(enum action a);
158 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
160 static char** strv_skip_first(char **strv) {
161 if (strv_length(strv) > 0)
166 static void pager_open_if_enabled(void) {
174 static void ask_password_agent_open_if_enabled(void) {
176 /* Open the password agent as a child process if necessary */
178 if (!arg_ask_password)
181 if (arg_scope != UNIT_FILE_SYSTEM)
184 if (arg_transport != BUS_TRANSPORT_LOCAL)
187 ask_password_agent_open();
191 static void polkit_agent_open_if_enabled(void) {
193 /* Open the polkit agent as a child process if necessary */
195 if (!arg_ask_password)
198 if (arg_scope != UNIT_FILE_SYSTEM)
201 if (arg_transport != BUS_TRANSPORT_LOCAL)
208 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
211 if (!sd_bus_error_is_set(error))
214 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
215 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
216 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
217 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
218 return EXIT_NOPERMISSION;
220 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
221 return EXIT_NOTINSTALLED;
223 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
224 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
225 return EXIT_NOTIMPLEMENTED;
227 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
228 return EXIT_NOTCONFIGURED;
236 static void warn_wall(enum action a) {
237 static const char *table[_ACTION_MAX] = {
238 [ACTION_HALT] = "The system is going down for system halt NOW!",
239 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
240 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
241 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
242 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
243 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
244 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
251 _cleanup_free_ char *p;
253 p = strv_join(arg_wall, " ");
268 utmp_wall(table[a], NULL);
271 static bool avoid_bus(void) {
273 if (running_in_chroot() > 0)
276 if (sd_booted() <= 0)
279 if (!isempty(arg_root))
282 if (arg_scope == UNIT_FILE_GLOBAL)
288 static int compare_unit_info(const void *a, const void *b) {
289 const UnitInfo *u = a, *v = b;
292 d1 = strrchr(u->id, '.');
293 d2 = strrchr(v->id, '.');
298 r = strcasecmp(d1, d2);
303 return strcasecmp(u->id, v->id);
306 static bool output_show_unit(const UnitInfo *u, char **patterns) {
309 if (!strv_isempty(arg_states))
311 strv_contains(arg_states, u->load_state) ||
312 strv_contains(arg_states, u->sub_state) ||
313 strv_contains(arg_states, u->active_state);
315 if (!strv_isempty(patterns)) {
318 STRV_FOREACH(pattern, patterns)
319 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
324 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
325 strv_find(arg_types, dot+1))) &&
326 (arg_all || !(streq(u->active_state, "inactive")
327 || u->following[0]) || u->job_id > 0);
330 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
331 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
333 unsigned n_shown = 0;
336 max_id_len = sizeof("UNIT")-1;
337 load_len = sizeof("LOAD")-1;
338 active_len = sizeof("ACTIVE")-1;
339 sub_len = sizeof("SUB")-1;
340 job_len = sizeof("JOB")-1;
343 for (u = unit_infos; u < unit_infos + c; u++) {
344 max_id_len = MAX(max_id_len, strlen(u->id));
345 load_len = MAX(load_len, strlen(u->load_state));
346 active_len = MAX(active_len, strlen(u->active_state));
347 sub_len = MAX(sub_len, strlen(u->sub_state));
349 if (u->job_id != 0) {
350 job_len = MAX(job_len, strlen(u->job_type));
355 if (!arg_full && original_stdout_is_tty) {
358 id_len = MIN(max_id_len, 25u);
359 basic_len = 5 + id_len + 5 + active_len + sub_len;
362 basic_len += job_len + 1;
364 if (basic_len < (unsigned) columns()) {
365 unsigned extra_len, incr;
366 extra_len = columns() - basic_len;
368 /* Either UNIT already got 25, or is fully satisfied.
369 * Grant up to 25 to DESC now. */
370 incr = MIN(extra_len, 25u);
374 /* split the remaining space between UNIT and DESC,
375 * but do not give UNIT more than it needs. */
377 incr = MIN(extra_len / 2, max_id_len - id_len);
379 desc_len += extra_len - incr;
385 for (u = unit_infos; u < unit_infos + c; u++) {
386 _cleanup_free_ char *e = NULL;
387 const char *on_loaded, *off_loaded, *on = "";
388 const char *on_active, *off_active, *off = "";
390 if (!n_shown && !arg_no_legend) {
391 printf("%-*s %-*s %-*s %-*s ",
394 active_len, "ACTIVE",
398 printf("%-*s ", job_len, "JOB");
400 if (!arg_full && arg_no_pager)
401 printf("%.*s\n", desc_len, "DESCRIPTION");
403 printf("%s\n", "DESCRIPTION");
408 if (streq(u->load_state, "error") ||
409 streq(u->load_state, "not-found")) {
410 on_loaded = on = ansi_highlight_red();
411 off_loaded = off = ansi_highlight_off();
413 on_loaded = off_loaded = "";
415 if (streq(u->active_state, "failed")) {
416 on_active = on = ansi_highlight_red();
417 off_active = off = ansi_highlight_off();
419 on_active = off_active = "";
421 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
423 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
424 on, id_len, e ? e : u->id, off,
425 on_loaded, load_len, u->load_state, off_loaded,
426 on_active, active_len, u->active_state,
427 sub_len, u->sub_state, off_active,
428 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
431 printf("%.*s\n", desc_len, u->description);
433 printf("%s\n", u->description);
436 if (!arg_no_legend) {
437 const char *on, *off;
440 puts("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
441 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
442 "SUB = The low-level unit activation state, values depend on unit type.");
443 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
444 on = ansi_highlight();
445 off = ansi_highlight_off();
447 on = ansi_highlight_red();
448 off = ansi_highlight_off();
452 printf("%s%u loaded units listed.%s\n"
453 "To show all installed unit files use 'systemctl list-unit-files'.\n",
456 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
457 "To show all installed unit files use 'systemctl list-unit-files'.\n",
462 static int get_unit_list(
464 sd_bus_message **_reply,
465 UnitInfo **_unit_infos,
468 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
469 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
470 _cleanup_free_ UnitInfo *unit_infos = NULL;
479 r = sd_bus_call_method(
481 "org.freedesktop.systemd1",
482 "/org/freedesktop/systemd1",
483 "org.freedesktop.systemd1.Manager",
489 log_error("Failed to list units: %s", bus_error_message(&error, r));
493 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
495 return bus_log_parse_error(r);
497 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
498 if (!output_show_unit(&u, patterns))
501 if (!GREEDY_REALLOC(unit_infos, size, c+1))
507 return bus_log_parse_error(r);
509 r = sd_bus_message_exit_container(reply);
511 return bus_log_parse_error(r);
516 *_unit_infos = unit_infos;
522 static int list_units(sd_bus *bus, char **args) {
523 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
524 _cleanup_free_ UnitInfo *unit_infos = NULL;
527 pager_open_if_enabled();
529 r = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
533 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
534 output_units_list(unit_infos, r);
539 static int get_triggered_units(
544 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
547 r = sd_bus_get_property_strv(
549 "org.freedesktop.systemd1",
551 "org.freedesktop.systemd1.Unit",
557 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
562 static int get_listening(
564 const char* unit_path,
567 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
568 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
569 const char *type, *path;
572 r = sd_bus_get_property(
574 "org.freedesktop.systemd1",
576 "org.freedesktop.systemd1.Socket",
582 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
586 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
588 return bus_log_parse_error(r);
590 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
592 r = strv_extend(listening, type);
596 r = strv_extend(listening, path);
603 return bus_log_parse_error(r);
605 r = sd_bus_message_exit_container(reply);
607 return bus_log_parse_error(r);
618 /* Note: triggered is a list here, although it almost certainly
619 * will always be one unit. Nevertheless, dbus API allows for multiple
620 * values, so let's follow that.*/
623 /* The strv above is shared. free is set only in the first one. */
627 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
633 o = strcmp(a->path, b->path);
635 o = strcmp(a->type, b->type);
640 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
641 struct socket_info *s;
642 unsigned pathlen = sizeof("LISTEN") - 1,
643 typelen = (sizeof("TYPE") - 1) * arg_show_types,
644 socklen = sizeof("UNIT") - 1,
645 servlen = sizeof("ACTIVATES") - 1;
646 const char *on, *off;
648 for (s = socket_infos; s < socket_infos + cs; s++) {
652 socklen = MAX(socklen, strlen(s->id));
654 typelen = MAX(typelen, strlen(s->type));
655 pathlen = MAX(pathlen, strlen(s->path));
657 STRV_FOREACH(a, s->triggered)
658 tmp += strlen(*a) + 2*(a != s->triggered);
659 servlen = MAX(servlen, tmp);
664 printf("%-*s %-*.*s%-*s %s\n",
666 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
670 for (s = socket_infos; s < socket_infos + cs; s++) {
674 printf("%-*s %-*s %-*s",
675 pathlen, s->path, typelen, s->type, socklen, s->id);
678 pathlen, s->path, socklen, s->id);
679 STRV_FOREACH(a, s->triggered)
681 a == s->triggered ? "" : ",", *a);
685 on = ansi_highlight();
686 off = ansi_highlight_off();
690 on = ansi_highlight_red();
691 off = ansi_highlight_off();
694 if (!arg_no_legend) {
695 printf("%s%u sockets listed.%s\n", on, cs, off);
697 printf("Pass --all to see loaded but inactive sockets, too.\n");
703 static int list_sockets(sd_bus *bus, char **args) {
704 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
705 _cleanup_free_ UnitInfo *unit_infos = NULL;
706 _cleanup_free_ struct socket_info *socket_infos = NULL;
708 struct socket_info *s;
713 pager_open_if_enabled();
715 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
719 for (u = unit_infos; u < unit_infos + n; u++) {
720 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
723 if (!endswith(u->id, ".socket"))
726 r = get_triggered_units(bus, u->unit_path, &triggered);
730 c = get_listening(bus, u->unit_path, &listening);
736 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
741 for (i = 0; i < c; i++)
742 socket_infos[cs + i] = (struct socket_info) {
744 .type = listening[i*2],
745 .path = listening[i*2 + 1],
746 .triggered = triggered,
747 .own_triggered = i==0,
750 /* from this point on we will cleanup those socket_infos */
753 listening = triggered = NULL; /* avoid cleanup */
756 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
757 (__compar_fn_t) socket_info_compare);
759 output_sockets_list(socket_infos, cs);
762 assert(cs == 0 || socket_infos);
763 for (s = socket_infos; s < socket_infos + cs; s++) {
766 if (s->own_triggered)
767 strv_free(s->triggered);
773 static int get_next_elapse(
776 dual_timestamp *next) {
778 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
786 r = sd_bus_get_property_trivial(
788 "org.freedesktop.systemd1",
790 "org.freedesktop.systemd1.Timer",
791 "NextElapseUSecMonotonic",
796 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
800 r = sd_bus_get_property_trivial(
802 "org.freedesktop.systemd1",
804 "org.freedesktop.systemd1.Timer",
805 "NextElapseUSecRealtime",
810 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
824 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
828 if (a->next_elapse < b->next_elapse)
830 if (a->next_elapse > b->next_elapse)
833 return strcmp(a->id, b->id);
836 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
837 struct timer_info *t;
839 nextlen = sizeof("NEXT") - 1,
840 leftlen = sizeof("LEFT") - 1,
841 unitlen = sizeof("UNIT") - 1,
842 activatelen = sizeof("ACTIVATES") - 1;
844 const char *on, *off;
846 assert(timer_infos || n == 0);
848 for (t = timer_infos; t < timer_infos + n; t++) {
852 if (t->next_elapse > 0) {
853 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
855 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
856 nextlen = MAX(nextlen, strlen(tstamp) + 1);
858 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
859 leftlen = MAX(leftlen, strlen(trel));
862 unitlen = MAX(unitlen, strlen(t->id));
864 STRV_FOREACH(a, t->triggered)
865 ul += strlen(*a) + 2*(a != t->triggered);
866 activatelen = MAX(activatelen, ul);
871 printf("%-*s %-*s %-*s %s\n",
877 for (t = timer_infos; t < timer_infos + n; t++) {
878 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
881 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
882 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
884 printf("%-*s %-*s %-*s",
885 nextlen, tstamp, leftlen, trel, unitlen, t->id);
887 STRV_FOREACH(a, t->triggered)
889 a == t->triggered ? "" : ",", *a);
893 on = ansi_highlight();
894 off = ansi_highlight_off();
898 on = ansi_highlight_red();
899 off = ansi_highlight_off();
902 if (!arg_no_legend) {
903 printf("%s%u timers listed.%s\n", on, n, off);
905 printf("Pass --all to see loaded but inactive timers, too.\n");
911 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
917 if (next->monotonic != (usec_t) -1 && next->monotonic > 0) {
920 if (next->monotonic > nw->monotonic)
921 converted = nw->realtime + (next->monotonic - nw->monotonic);
923 converted = nw->realtime - (nw->monotonic - next->monotonic);
925 if (next->realtime != (usec_t) -1 && next->realtime > 0)
926 next_elapse = MIN(converted, next->realtime);
928 next_elapse = converted;
931 next_elapse = next->realtime;
936 static int list_timers(sd_bus *bus, char **args) {
938 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
939 _cleanup_free_ struct timer_info *timer_infos = NULL;
940 _cleanup_free_ UnitInfo *unit_infos = NULL;
941 struct timer_info *t;
948 pager_open_if_enabled();
950 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
954 dual_timestamp_get(&nw);
956 for (u = unit_infos; u < unit_infos + n; u++) {
957 _cleanup_strv_free_ char **triggered = NULL;
958 dual_timestamp next = {};
961 if (!endswith(u->id, ".timer"))
964 r = get_triggered_units(bus, u->unit_path, &triggered);
968 r = get_next_elapse(bus, u->unit_path, &next);
972 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
977 m = calc_next_elapse(&nw, &next);
979 timer_infos[c++] = (struct timer_info) {
982 .triggered = triggered,
985 triggered = NULL; /* avoid cleanup */
988 qsort_safe(timer_infos, c, sizeof(struct timer_info),
989 (__compar_fn_t) timer_info_compare);
991 output_timers_list(timer_infos, c);
994 for (t = timer_infos; t < timer_infos + c; t++)
995 strv_free(t->triggered);
1000 static int compare_unit_file_list(const void *a, const void *b) {
1001 const char *d1, *d2;
1002 const UnitFileList *u = a, *v = b;
1004 d1 = strrchr(u->path, '.');
1005 d2 = strrchr(v->path, '.');
1010 r = strcasecmp(d1, d2);
1015 return strcasecmp(basename(u->path), basename(v->path));
1018 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1021 if (!strv_isempty(patterns)) {
1024 STRV_FOREACH(pattern, patterns)
1025 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1030 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1033 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1034 unsigned max_id_len, id_cols, state_cols;
1035 const UnitFileList *u;
1037 max_id_len = sizeof("UNIT FILE")-1;
1038 state_cols = sizeof("STATE")-1;
1040 for (u = units; u < units + c; u++) {
1041 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1042 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1046 unsigned basic_cols;
1048 id_cols = MIN(max_id_len, 25u);
1049 basic_cols = 1 + id_cols + state_cols;
1050 if (basic_cols < (unsigned) columns())
1051 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1053 id_cols = max_id_len;
1056 printf("%-*s %-*s\n",
1057 id_cols, "UNIT FILE",
1058 state_cols, "STATE");
1060 for (u = units; u < units + c; u++) {
1061 _cleanup_free_ char *e = NULL;
1062 const char *on, *off;
1065 if (u->state == UNIT_FILE_MASKED ||
1066 u->state == UNIT_FILE_MASKED_RUNTIME ||
1067 u->state == UNIT_FILE_DISABLED ||
1068 u->state == UNIT_FILE_INVALID) {
1069 on = ansi_highlight_red();
1070 off = ansi_highlight_off();
1071 } else if (u->state == UNIT_FILE_ENABLED) {
1072 on = ansi_highlight_green();
1073 off = ansi_highlight_off();
1077 id = basename(u->path);
1079 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1081 printf("%-*s %s%-*s%s\n",
1082 id_cols, e ? e : id,
1083 on, state_cols, unit_file_state_to_string(u->state), off);
1087 printf("\n%u unit files listed.\n", c);
1090 static int list_unit_files(sd_bus *bus, char **args) {
1091 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1092 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1093 _cleanup_free_ UnitFileList *units = NULL;
1101 pager_open_if_enabled();
1109 h = hashmap_new(string_hash_func, string_compare_func);
1113 r = unit_file_get_list(arg_scope, arg_root, h);
1115 unit_file_list_free(h);
1116 log_error("Failed to get unit file list: %s", strerror(-r));
1120 n_units = hashmap_size(h);
1121 units = new(UnitFileList, n_units);
1123 unit_file_list_free(h);
1127 HASHMAP_FOREACH(u, h, i) {
1128 if (!output_show_unit_file(u, strv_skip_first(args)))
1135 assert(c <= n_units);
1138 r = sd_bus_call_method(
1140 "org.freedesktop.systemd1",
1141 "/org/freedesktop/systemd1",
1142 "org.freedesktop.systemd1.Manager",
1148 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1152 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1154 return bus_log_parse_error(r);
1156 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1158 if (!GREEDY_REALLOC(units, size, c + 1))
1161 units[c] = (struct UnitFileList) {
1163 unit_file_state_from_string(state)
1166 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1171 return bus_log_parse_error(r);
1173 r = sd_bus_message_exit_container(reply);
1175 return bus_log_parse_error(r);
1179 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1180 output_unit_file_list(units, c);
1184 for (unit = units; unit < units + c; unit++)
1190 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1191 _cleanup_free_ char *n = NULL;
1192 size_t max_len = MAX(columns(),20u);
1198 for (i = level - 1; i >= 0; i--) {
1200 if (len > max_len - 3 && !arg_full) {
1201 printf("%s...\n",max_len % 2 ? "" : " ");
1204 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1208 if (len > max_len - 3 && !arg_full) {
1209 printf("%s...\n",max_len % 2 ? "" : " ");
1213 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1217 printf("%s\n", name);
1221 n = ellipsize(name, max_len-len, 100);
1229 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1231 static const char *dependencies[_DEPENDENCY_MAX] = {
1232 [DEPENDENCY_FORWARD] = "Requires\0"
1233 "RequiresOverridable\0"
1235 "RequisiteOverridable\0"
1237 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1238 "RequiredByOverridable\0"
1241 [DEPENDENCY_AFTER] = "After\0",
1242 [DEPENDENCY_BEFORE] = "Before\0",
1245 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1246 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1247 _cleanup_strv_free_ char **ret = NULL;
1248 _cleanup_free_ char *path = NULL;
1254 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1256 path = unit_dbus_path_from_name(name);
1260 r = sd_bus_call_method(
1262 "org.freedesktop.systemd1",
1264 "org.freedesktop.DBus.Properties",
1268 "s", "org.freedesktop.systemd1.Unit");
1270 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1274 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1276 return bus_log_parse_error(r);
1278 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1281 r = sd_bus_message_read(reply, "s", &prop);
1283 return bus_log_parse_error(r);
1285 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1286 r = sd_bus_message_skip(reply, "v");
1288 return bus_log_parse_error(r);
1291 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1293 return bus_log_parse_error(r);
1295 r = bus_message_read_strv_extend(reply, &ret);
1297 return bus_log_parse_error(r);
1299 r = sd_bus_message_exit_container(reply);
1301 return bus_log_parse_error(r);
1304 r = sd_bus_message_exit_container(reply);
1306 return bus_log_parse_error(r);
1310 return bus_log_parse_error(r);
1312 r = sd_bus_message_exit_container(reply);
1314 return bus_log_parse_error(r);
1322 static int list_dependencies_compare(const void *_a, const void *_b) {
1323 const char **a = (const char**) _a, **b = (const char**) _b;
1325 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1327 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1330 return strcasecmp(*a, *b);
1333 static int list_dependencies_one(
1338 unsigned int branches) {
1340 _cleanup_strv_free_ char **deps = NULL;
1348 r = strv_extend(units, name);
1352 r = list_dependencies_get_dependencies(bus, name, &deps);
1356 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1358 STRV_FOREACH(c, deps) {
1361 if (strv_contains(*units, *c)) {
1363 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1370 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1372 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1374 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1376 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1380 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1381 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1388 strv_remove(*units, name);
1393 static int list_dependencies(sd_bus *bus, char **args) {
1394 _cleanup_strv_free_ char **units = NULL;
1395 _cleanup_free_ char *unit = NULL;
1401 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1406 u = SPECIAL_DEFAULT_TARGET;
1408 pager_open_if_enabled();
1412 return list_dependencies_one(bus, u, 0, &units, 0);
1415 struct machine_info {
1418 unsigned n_failed_units;
1423 static void free_machines_list(struct machine_info *machine_infos, int n) {
1429 for (i = 0; i < n; i++) {
1430 free(machine_infos[i].name);
1431 free(machine_infos[i].state);
1434 free(machine_infos);
1437 static int compare_machine_info(const void *a, const void *b) {
1438 const struct machine_info *u = a, *v = b;
1440 if (u->is_host != v->is_host)
1441 return u->is_host > v->is_host ? 1 : -1;
1443 return strcasecmp(u->name, v->name);
1446 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1447 static const struct bus_properties_map map[] = {
1448 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1449 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1450 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1454 _cleanup_bus_unref_ sd_bus *container = NULL;
1460 r = sd_bus_open_system_container(&container, mi->name);
1467 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", map, mi);
1474 static bool output_show_machine(const char *name, char **patterns) {
1479 if (strv_isempty(patterns))
1482 STRV_FOREACH(i, patterns)
1483 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1489 static int get_machine_list(
1491 struct machine_info **_machine_infos,
1494 struct machine_info *machine_infos = NULL;
1495 _cleanup_strv_free_ char **m = NULL;
1496 _cleanup_free_ char *hn = NULL;
1501 hn = gethostname_malloc();
1505 if (output_show_machine(hn, patterns)) {
1506 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1509 machine_infos[c].is_host = true;
1510 machine_infos[c].name = hn;
1513 get_machine_properties(bus, &machine_infos[c]);
1517 sd_get_machine_names(&m);
1518 STRV_FOREACH(i, m) {
1519 _cleanup_free_ char *class = NULL;
1521 if (!output_show_machine(*i, patterns))
1524 sd_machine_get_class(*i, &class);
1525 if (!streq_ptr(class, "container"))
1528 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1529 free_machines_list(machine_infos, c);
1533 machine_infos[c].is_host = false;
1534 machine_infos[c].name = strdup(*i);
1535 if (!machine_infos[c].name) {
1536 free_machines_list(machine_infos, c);
1540 get_machine_properties(NULL, &machine_infos[c]);
1544 *_machine_infos = machine_infos;
1548 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1549 struct machine_info *m;
1551 namelen = sizeof("NAME") - 1,
1552 statelen = sizeof("STATE") - 1,
1553 failedlen = sizeof("FAILED") - 1,
1554 jobslen = sizeof("JOBS") - 1;
1556 assert(machine_infos || n == 0);
1558 for (m = machine_infos; m < machine_infos + n; m++) {
1559 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1560 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1561 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1562 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1566 printf("%-*s %-*s %-*s %-*s\n",
1569 failedlen, "FAILED",
1572 for (m = machine_infos; m < machine_infos + n; m++) {
1573 const char *on_state, *off_state, *on_failed, *off_failed;
1575 if (streq_ptr(m->state, "degraded")) {
1576 on_state = ansi_highlight_red();
1577 off_state = ansi_highlight_off();
1578 } else if (!streq_ptr(m->state, "running")) {
1579 on_state = ansi_highlight_yellow();
1580 off_state = ansi_highlight_off();
1582 on_state = off_state = "";
1584 if (m->n_failed_units > 0) {
1585 on_failed = ansi_highlight_red();
1586 off_failed = ansi_highlight_off();
1588 on_failed = off_failed = "";
1591 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1592 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1593 on_state, statelen, strna(m->state), off_state,
1594 on_failed, failedlen, m->n_failed_units, off_failed,
1595 jobslen, m->n_jobs);
1597 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1598 namelen, strna(m->name),
1599 on_state, statelen, strna(m->state), off_state,
1600 on_failed, failedlen, m->n_failed_units, off_failed,
1601 jobslen, m->n_jobs);
1605 printf("\n%u machines listed.\n", n);
1608 static int list_machines(sd_bus *bus, char **args) {
1609 struct machine_info *machine_infos = NULL;
1614 if (geteuid() != 0) {
1615 log_error("Must be root.");
1619 pager_open_if_enabled();
1621 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1625 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1626 output_machines_list(machine_infos, r);
1627 free_machines_list(machine_infos, r);
1632 static int get_default(sd_bus *bus, char **args) {
1633 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1634 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1635 _cleanup_free_ char *_path = NULL;
1639 if (!bus || avoid_bus()) {
1640 r = unit_file_get_default(arg_scope, arg_root, &_path);
1642 log_error("Failed to get default target: %s", strerror(-r));
1648 r = sd_bus_call_method(
1650 "org.freedesktop.systemd1",
1651 "/org/freedesktop/systemd1",
1652 "org.freedesktop.systemd1.Manager",
1658 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1662 r = sd_bus_message_read(reply, "s", &path);
1664 return bus_log_parse_error(r);
1668 printf("%s\n", path);
1673 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1676 assert(changes || n_changes == 0);
1678 for (i = 0; i < n_changes; i++) {
1679 if (changes[i].type == UNIT_FILE_SYMLINK)
1680 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1682 log_info("rm '%s'", changes[i].path);
1686 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1687 const char *type, *path, *source;
1690 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1692 return bus_log_parse_error(r);
1694 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1696 if (streq(type, "symlink"))
1697 log_info("ln -s '%s' '%s'", source, path);
1699 log_info("rm '%s'", path);
1703 return bus_log_parse_error(r);
1705 r = sd_bus_message_exit_container(m);
1707 return bus_log_parse_error(r);
1712 static int set_default(sd_bus *bus, char **args) {
1713 _cleanup_free_ char *unit = NULL;
1714 UnitFileChange *changes = NULL;
1715 unsigned n_changes = 0;
1718 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1722 if (!bus || avoid_bus()) {
1723 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1725 log_error("Failed to set default target: %s", strerror(-r));
1730 dump_unit_file_changes(changes, n_changes);
1734 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1735 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1737 r = sd_bus_call_method(
1739 "org.freedesktop.systemd1",
1740 "/org/freedesktop/systemd1",
1741 "org.freedesktop.systemd1.Manager",
1745 "sb", unit, arg_force);
1747 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1751 r = deserialize_and_dump_unit_file_changes(reply);
1755 /* Try to reload if enabeld */
1757 r = daemon_reload(bus, args);
1762 unit_file_changes_free(changes, n_changes);
1769 const char *name, *type, *state;
1772 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1773 unsigned id_len, unit_len, type_len, state_len;
1774 const struct job_info *j;
1775 const char *on, *off;
1776 bool shorten = false;
1778 assert(n == 0 || jobs);
1781 on = ansi_highlight_green();
1782 off = ansi_highlight_off();
1784 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1788 pager_open_if_enabled();
1790 id_len = sizeof("JOB")-1;
1791 unit_len = sizeof("UNIT")-1;
1792 type_len = sizeof("TYPE")-1;
1793 state_len = sizeof("STATE")-1;
1795 for (j = jobs; j < jobs + n; j++) {
1796 uint32_t id = j->id;
1797 assert(j->name && j->type && j->state);
1799 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1800 unit_len = MAX(unit_len, strlen(j->name));
1801 type_len = MAX(type_len, strlen(j->type));
1802 state_len = MAX(state_len, strlen(j->state));
1805 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1806 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1811 printf("%*s %-*s %-*s %-*s\n",
1815 state_len, "STATE");
1817 for (j = jobs; j < jobs + n; j++) {
1818 _cleanup_free_ char *e = NULL;
1820 if (streq(j->state, "running")) {
1821 on = ansi_highlight();
1822 off = ansi_highlight_off();
1826 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1827 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1829 on, unit_len, e ? e : j->name, off,
1831 on, state_len, j->state, off);
1834 if (!arg_no_legend) {
1835 on = ansi_highlight();
1836 off = ansi_highlight_off();
1838 printf("\n%s%u jobs listed%s.\n", on, n, off);
1842 static bool output_show_job(struct job_info *job, char **patterns) {
1847 if (strv_isempty(patterns))
1850 STRV_FOREACH(pattern, patterns)
1851 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1856 static int list_jobs(sd_bus *bus, char **args) {
1857 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1858 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1859 const char *name, *type, *state, *job_path, *unit_path;
1860 _cleanup_free_ struct job_info *jobs = NULL;
1865 bool skipped = false;
1867 r = sd_bus_call_method(
1869 "org.freedesktop.systemd1",
1870 "/org/freedesktop/systemd1",
1871 "org.freedesktop.systemd1.Manager",
1877 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1881 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1883 return bus_log_parse_error(r);
1885 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1886 struct job_info job = { id, name, type, state };
1888 if (!output_show_job(&job, strv_skip_first(args))) {
1893 if (!GREEDY_REALLOC(jobs, size, c + 1))
1899 return bus_log_parse_error(r);
1901 r = sd_bus_message_exit_container(reply);
1903 return bus_log_parse_error(r);
1905 output_jobs_list(jobs, c, skipped);
1909 static int cancel_job(sd_bus *bus, char **args) {
1910 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1915 if (strv_length(args) <= 1)
1916 return daemon_reload(bus, args);
1918 STRV_FOREACH(name, args+1) {
1922 r = safe_atou32(*name, &id);
1924 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1928 r = sd_bus_call_method(
1930 "org.freedesktop.systemd1",
1931 "/org/freedesktop/systemd1",
1932 "org.freedesktop.systemd1.Manager",
1938 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1946 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1947 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1951 /* We ignore all errors here, since this is used to show a
1954 /* We don't use unit_dbus_path_from_name() directly since we
1955 * don't want to load the unit if it isn't loaded. */
1957 r = sd_bus_call_method(
1959 "org.freedesktop.systemd1",
1960 "/org/freedesktop/systemd1",
1961 "org.freedesktop.systemd1.Manager",
1969 r = sd_bus_message_read(reply, "o", &path);
1973 r = sd_bus_get_property_trivial(
1975 "org.freedesktop.systemd1",
1977 "org.freedesktop.systemd1.Unit",
1987 typedef struct WaitData {
1994 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2001 log_debug("Got D-Bus request: %s.%s() on %s",
2002 sd_bus_message_get_interface(m),
2003 sd_bus_message_get_member(m),
2004 sd_bus_message_get_path(m));
2006 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2007 log_error("Warning! D-Bus connection terminated.");
2009 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2011 const char *path, *result, *unit;
2015 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2017 ret = set_remove(d->set, (char*) path);
2023 if (!isempty(result))
2024 d->result = strdup(result);
2027 d->name = strdup(unit);
2032 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2034 ret = set_remove(d->set, (char*) path);
2041 d->result = strdup(result);
2047 bus_log_parse_error(r);
2053 static int enable_wait_for_jobs(sd_bus *bus) {
2058 r = sd_bus_add_match(
2061 "sender='org.freedesktop.systemd1',"
2062 "interface='org.freedesktop.systemd1.Manager',"
2063 "member='JobRemoved',"
2064 "path='/org/freedesktop/systemd1'",
2067 log_error("Failed to add match");
2071 /* This is slightly dirty, since we don't undo the match registrations. */
2075 static int bus_process_wait(sd_bus *bus) {
2079 r = sd_bus_process(bus, NULL);
2084 r = sd_bus_wait(bus, (uint64_t) -1);
2090 static int check_wait_response(WaitData *d) {
2096 if (streq(d->result, "timeout"))
2097 log_error("Job for %s timed out.", strna(d->name));
2098 else if (streq(d->result, "canceled"))
2099 log_error("Job for %s canceled.", strna(d->name));
2100 else if (streq(d->result, "dependency"))
2101 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2102 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2103 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2106 if (streq(d->result, "timeout"))
2108 else if (streq(d->result, "canceled"))
2110 else if (streq(d->result, "dependency"))
2112 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2118 static int wait_for_jobs(sd_bus *bus, Set *s) {
2119 WaitData d = { .set = s };
2125 q = sd_bus_add_filter(bus, wait_filter, &d);
2129 while (!set_isempty(s)) {
2130 q = bus_process_wait(bus);
2132 log_error("Failed to wait for response: %s", strerror(-r));
2137 q = check_wait_response(&d);
2138 /* Return the first error as it is most likely to be
2140 if (q < 0 && r == 0)
2142 log_debug("Got result %s/%s for job %s",
2143 strna(d.result), strerror(-q), strna(d.name));
2153 q = sd_bus_remove_filter(bus, wait_filter, &d);
2154 if (q < 0 && r == 0)
2160 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2161 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2162 _cleanup_free_ char *n = NULL, *state = NULL;
2168 n = unit_name_mangle(name, MANGLE_NOGLOB);
2172 /* We don't use unit_dbus_path_from_name() directly since we
2173 * don't want to load the unit if it isn't loaded. */
2175 r = sd_bus_call_method(
2177 "org.freedesktop.systemd1",
2178 "/org/freedesktop/systemd1",
2179 "org.freedesktop.systemd1.Manager",
2190 r = sd_bus_message_read(reply, "o", &path);
2192 return bus_log_parse_error(r);
2194 r = sd_bus_get_property_string(
2196 "org.freedesktop.systemd1",
2198 "org.freedesktop.systemd1.Unit",
2211 return nulstr_contains(good_states, state);
2214 static int check_triggering_units(
2218 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2219 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2220 _cleanup_strv_free_ char **triggered_by = NULL;
2221 bool print_warning_label = true;
2225 n = unit_name_mangle(name, MANGLE_NOGLOB);
2229 path = unit_dbus_path_from_name(n);
2233 r = sd_bus_get_property_string(
2235 "org.freedesktop.systemd1",
2237 "org.freedesktop.systemd1.Unit",
2242 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2246 if (streq(state, "masked"))
2249 r = sd_bus_get_property_strv(
2251 "org.freedesktop.systemd1",
2253 "org.freedesktop.systemd1.Unit",
2258 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2262 STRV_FOREACH(i, triggered_by) {
2263 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2265 log_error("Failed to check unit: %s", strerror(-r));
2272 if (print_warning_label) {
2273 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2274 print_warning_label = false;
2277 log_warning(" %s", *i);
2283 static const char *verb_to_method(const char *verb) {
2286 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2287 if (streq_ptr(unit_actions[i].verb, verb))
2288 return unit_actions[i].method;
2293 static const char *method_to_verb(const char *method) {
2296 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2297 if (streq_ptr(unit_actions[i].method, method))
2298 return unit_actions[i].verb;
2303 static int start_unit_one(
2308 sd_bus_error *error,
2311 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2320 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2321 r = sd_bus_call_method(
2323 "org.freedesktop.systemd1",
2324 "/org/freedesktop/systemd1",
2325 "org.freedesktop.systemd1.Manager",
2333 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2334 /* There's always a fallback possible for
2335 * legacy actions. */
2336 return -EADDRNOTAVAIL;
2338 verb = method_to_verb(method);
2340 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2344 r = sd_bus_message_read(reply, "o", &path);
2346 return bus_log_parse_error(r);
2348 if (need_daemon_reload(bus, name) > 0)
2349 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2350 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2359 log_debug("Adding %s to the set", p);
2360 r = set_consume(s, p);
2368 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2370 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2371 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2375 STRV_FOREACH(name, names) {
2379 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2381 t = unit_name_mangle(*name, MANGLE_GLOB);
2385 if (string_is_glob(t))
2386 r = strv_consume(&globs, t);
2388 r = strv_consume(&mangled, t);
2393 /* Query the manager only if any of the names are a glob, since
2394 * this is fairly expensive */
2395 if (!strv_isempty(globs)) {
2396 _cleanup_free_ UnitInfo *unit_infos = NULL;
2398 r = get_unit_list(bus, &reply, &unit_infos, globs);
2402 for (i = 0; i < r; i++)
2403 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2408 mangled = NULL; /* do not free */
2412 static const struct {
2416 } action_table[_ACTION_MAX] = {
2417 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2418 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2419 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2420 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2421 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2422 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2423 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2424 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2425 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2426 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2427 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2428 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2429 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2430 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2431 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2434 static enum action verb_to_action(const char *verb) {
2437 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2438 if (streq_ptr(action_table[i].verb, verb))
2441 return _ACTION_INVALID;
2444 static int start_unit(sd_bus *bus, char **args) {
2445 _cleanup_set_free_free_ Set *s = NULL;
2446 _cleanup_strv_free_ char **names = NULL;
2447 const char *method, *mode, *one_name;
2453 ask_password_agent_open_if_enabled();
2455 if (arg_action == ACTION_SYSTEMCTL) {
2457 method = verb_to_method(args[0]);
2458 action = verb_to_action(args[0]);
2460 mode = streq(args[0], "isolate") ? "isolate" :
2461 action_table[action].mode ?: arg_job_mode;
2463 one_name = action_table[action].target;
2465 assert(arg_action < ELEMENTSOF(action_table));
2466 assert(action_table[arg_action].target);
2468 method = "StartUnit";
2470 mode = action_table[arg_action].mode;
2471 one_name = action_table[arg_action].target;
2475 names = strv_new(one_name, NULL);
2477 r = expand_names(bus, args + 1, NULL, &names);
2479 log_error("Failed to expand names: %s", strerror(-r));
2482 if (!arg_no_block) {
2483 r = enable_wait_for_jobs(bus);
2485 log_error("Could not watch jobs: %s", strerror(-r));
2489 s = set_new(string_hash_func, string_compare_func);
2494 STRV_FOREACH(name, names) {
2495 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2498 q = start_unit_one(bus, method, *name, mode, &error, s);
2499 if (r >= 0 && q < 0)
2500 r = translate_bus_error_to_exit_status(q, &error);
2503 if (!arg_no_block) {
2506 q = wait_for_jobs(bus, s);
2510 /* When stopping units, warn if they can still be triggered by
2511 * another active unit (socket, path, timer) */
2512 if (!arg_quiet && streq(method, "StopUnit"))
2513 STRV_FOREACH(name, names)
2514 check_triggering_units(bus, *name);
2520 /* Ask systemd-logind, which might grant access to unprivileged users
2521 * through PolicyKit */
2522 static int reboot_with_logind(sd_bus *bus, enum action a) {
2524 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2531 polkit_agent_open_if_enabled();
2539 case ACTION_POWEROFF:
2540 method = "PowerOff";
2543 case ACTION_SUSPEND:
2547 case ACTION_HIBERNATE:
2548 method = "Hibernate";
2551 case ACTION_HYBRID_SLEEP:
2552 method = "HybridSleep";
2559 r = sd_bus_call_method(
2561 "org.freedesktop.login1",
2562 "/org/freedesktop/login1",
2563 "org.freedesktop.login1.Manager",
2569 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2577 static int check_inhibitors(sd_bus *bus, enum action a) {
2579 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2580 _cleanup_strv_free_ char **sessions = NULL;
2581 const char *what, *who, *why, *mode;
2590 if (arg_ignore_inhibitors || arg_force > 0)
2602 r = sd_bus_call_method(
2604 "org.freedesktop.login1",
2605 "/org/freedesktop/login1",
2606 "org.freedesktop.login1.Manager",
2612 /* If logind is not around, then there are no inhibitors... */
2615 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2617 return bus_log_parse_error(r);
2619 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2620 _cleanup_free_ char *comm = NULL, *user = NULL;
2621 _cleanup_strv_free_ char **sv = NULL;
2623 if (!streq(mode, "block"))
2626 sv = strv_split(what, ":");
2630 if (!strv_contains(sv,
2632 a == ACTION_POWEROFF ||
2633 a == ACTION_REBOOT ||
2634 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2637 get_process_comm(pid, &comm);
2638 user = uid_to_name(uid);
2640 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2641 who, (unsigned long) pid, strna(comm), strna(user), why);
2646 return bus_log_parse_error(r);
2648 r = sd_bus_message_exit_container(reply);
2650 return bus_log_parse_error(r);
2652 /* Check for current sessions */
2653 sd_get_sessions(&sessions);
2654 STRV_FOREACH(s, sessions) {
2655 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2657 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2660 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2663 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2666 sd_session_get_tty(*s, &tty);
2667 sd_session_get_seat(*s, &seat);
2668 sd_session_get_service(*s, &service);
2669 user = uid_to_name(uid);
2671 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2678 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2679 action_table[a].verb);
2687 static int start_special(sd_bus *bus, char **args) {
2693 a = verb_to_action(args[0]);
2695 r = check_inhibitors(bus, a);
2699 if (arg_force >= 2 && geteuid() != 0) {
2700 log_error("Must be root.");
2704 if (arg_force >= 2 &&
2705 (a == ACTION_HALT ||
2706 a == ACTION_POWEROFF ||
2707 a == ACTION_REBOOT))
2710 if (arg_force >= 1 &&
2711 (a == ACTION_HALT ||
2712 a == ACTION_POWEROFF ||
2713 a == ACTION_REBOOT ||
2714 a == ACTION_KEXEC ||
2716 return daemon_reload(bus, args);
2718 /* first try logind, to allow authentication with polkit */
2719 if (geteuid() != 0 &&
2720 (a == ACTION_POWEROFF ||
2721 a == ACTION_REBOOT ||
2722 a == ACTION_SUSPEND ||
2723 a == ACTION_HIBERNATE ||
2724 a == ACTION_HYBRID_SLEEP)) {
2725 r = reboot_with_logind(bus, a);
2730 r = start_unit(bus, args);
2731 if (r == EXIT_SUCCESS)
2737 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2738 _cleanup_strv_free_ char **names = NULL;
2745 r = expand_names(bus, args, NULL, &names);
2747 log_error("Failed to expand names: %s", strerror(-r));
2751 STRV_FOREACH(name, names) {
2754 state = check_one_unit(bus, *name, good_states, arg_quiet);
2764 static int check_unit_active(sd_bus *bus, char **args) {
2765 /* According to LSB: 3, "program is not running" */
2766 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2769 static int check_unit_failed(sd_bus *bus, char **args) {
2770 return check_unit_generic(bus, 1, "failed\0", args + 1);
2773 static int kill_unit(sd_bus *bus, char **args) {
2774 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2775 _cleanup_strv_free_ char **names = NULL;
2783 arg_kill_who = "all";
2785 r = expand_names(bus, args + 1, NULL, &names);
2787 log_error("Failed to expand names: %s", strerror(-r));
2789 STRV_FOREACH(name, names) {
2790 q = sd_bus_call_method(
2792 "org.freedesktop.systemd1",
2793 "/org/freedesktop/systemd1",
2794 "org.freedesktop.systemd1.Manager",
2798 "ssi", *names, arg_kill_who, arg_signal);
2800 log_error("Failed to kill unit %s: %s",
2801 *names, bus_error_message(&error, r));
2810 typedef struct ExecStatusInfo {
2818 usec_t start_timestamp;
2819 usec_t exit_timestamp;
2824 LIST_FIELDS(struct ExecStatusInfo, exec);
2827 static void exec_status_info_free(ExecStatusInfo *i) {
2836 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2837 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2840 int32_t code, status;
2846 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2848 return bus_log_parse_error(r);
2852 r = sd_bus_message_read(m, "s", &path);
2854 return bus_log_parse_error(r);
2856 i->path = strdup(path);
2860 r = sd_bus_message_read_strv(m, &i->argv);
2862 return bus_log_parse_error(r);
2864 r = sd_bus_message_read(m,
2867 &start_timestamp, &start_timestamp_monotonic,
2868 &exit_timestamp, &exit_timestamp_monotonic,
2872 return bus_log_parse_error(r);
2875 i->start_timestamp = (usec_t) start_timestamp;
2876 i->exit_timestamp = (usec_t) exit_timestamp;
2877 i->pid = (pid_t) pid;
2881 r = sd_bus_message_exit_container(m);
2883 return bus_log_parse_error(r);
2888 typedef struct UnitStatusInfo {
2890 const char *load_state;
2891 const char *active_state;
2892 const char *sub_state;
2893 const char *unit_file_state;
2895 const char *description;
2896 const char *following;
2898 char **documentation;
2900 const char *fragment_path;
2901 const char *source_path;
2902 const char *control_group;
2904 char **dropin_paths;
2906 const char *load_error;
2909 usec_t inactive_exit_timestamp;
2910 usec_t inactive_exit_timestamp_monotonic;
2911 usec_t active_enter_timestamp;
2912 usec_t active_exit_timestamp;
2913 usec_t inactive_enter_timestamp;
2915 bool need_daemon_reload;
2920 const char *status_text;
2921 const char *pid_file;
2924 usec_t start_timestamp;
2925 usec_t exit_timestamp;
2927 int exit_code, exit_status;
2929 usec_t condition_timestamp;
2930 bool condition_result;
2931 bool failed_condition_trigger;
2932 bool failed_condition_negate;
2933 const char *failed_condition;
2934 const char *failed_condition_param;
2937 unsigned n_accepted;
2938 unsigned n_connections;
2941 /* Pairs of type, path */
2945 const char *sysfs_path;
2947 /* Mount, Automount */
2953 LIST_HEAD(ExecStatusInfo, exec);
2956 static void print_status_info(
2961 const char *on, *off, *ss;
2963 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2964 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2967 arg_all * OUTPUT_SHOW_ALL |
2968 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2969 on_tty() * OUTPUT_COLOR |
2970 !arg_quiet * OUTPUT_WARN_CUTOFF |
2971 arg_full * OUTPUT_FULL_WIDTH;
2976 /* This shows pretty information about a unit. See
2977 * print_property() for a low-level property printer */
2979 printf("%s", strna(i->id));
2981 if (i->description && !streq_ptr(i->id, i->description))
2982 printf(" - %s", i->description);
2987 printf(" Follow: unit currently follows state of %s\n", i->following);
2989 if (streq_ptr(i->load_state, "error")) {
2990 on = ansi_highlight_red();
2991 off = ansi_highlight_off();
2995 path = i->source_path ? i->source_path : i->fragment_path;
2998 printf(" Loaded: %s%s%s (Reason: %s)\n",
2999 on, strna(i->load_state), off, i->load_error);
3000 else if (path && i->unit_file_state)
3001 printf(" Loaded: %s%s%s (%s; %s)\n",
3002 on, strna(i->load_state), off, path, i->unit_file_state);
3004 printf(" Loaded: %s%s%s (%s)\n",
3005 on, strna(i->load_state), off, path);
3007 printf(" Loaded: %s%s%s\n",
3008 on, strna(i->load_state), off);
3010 if (!strv_isempty(i->dropin_paths)) {
3011 _cleanup_free_ char *dir = NULL;
3015 STRV_FOREACH(dropin, i->dropin_paths) {
3016 if (! dir || last) {
3017 printf(dir ? " " : " Drop-In: ");
3022 if (path_get_parent(*dropin, &dir) < 0) {
3027 printf("%s\n %s", dir,
3028 draw_special_char(DRAW_TREE_RIGHT));
3031 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3033 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3037 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3039 if (streq_ptr(i->active_state, "failed")) {
3040 on = ansi_highlight_red();
3041 off = ansi_highlight_off();
3042 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3043 on = ansi_highlight_green();
3044 off = ansi_highlight_off();
3049 printf(" Active: %s%s (%s)%s",
3050 on, strna(i->active_state), ss, off);
3052 printf(" Active: %s%s%s",
3053 on, strna(i->active_state), off);
3055 if (!isempty(i->result) && !streq(i->result, "success"))
3056 printf(" (Result: %s)", i->result);
3058 timestamp = (streq_ptr(i->active_state, "active") ||
3059 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3060 (streq_ptr(i->active_state, "inactive") ||
3061 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3062 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3063 i->active_exit_timestamp;
3065 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3066 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3069 printf(" since %s; %s\n", s2, s1);
3071 printf(" since %s\n", s2);
3075 if (!i->condition_result && i->condition_timestamp > 0) {
3076 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3077 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3079 printf(" start condition failed at %s%s%s\n",
3080 s2, s1 ? "; " : "", s1 ? s1 : "");
3081 if (i->failed_condition_trigger)
3082 printf(" none of the trigger conditions were met\n");
3083 else if (i->failed_condition)
3084 printf(" %s=%s%s was not met\n",
3085 i->failed_condition,
3086 i->failed_condition_negate ? "!" : "",
3087 i->failed_condition_param);
3091 printf(" Device: %s\n", i->sysfs_path);
3093 printf(" Where: %s\n", i->where);
3095 printf(" What: %s\n", i->what);
3097 STRV_FOREACH(t, i->documentation)
3098 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3100 STRV_FOREACH_PAIR(t, t2, i->listen)
3101 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3104 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3106 LIST_FOREACH(exec, p, i->exec) {
3107 _cleanup_free_ char *argv = NULL;
3110 /* Only show exited processes here */
3114 argv = strv_join(p->argv, " ");
3115 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3117 good = is_clean_exit_lsb(p->code, p->status, NULL);
3119 on = ansi_highlight_red();
3120 off = ansi_highlight_off();
3124 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3126 if (p->code == CLD_EXITED) {
3129 printf("status=%i", p->status);
3131 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3136 printf("signal=%s", signal_to_string(p->status));
3138 printf(")%s\n", off);
3140 if (i->main_pid == p->pid &&
3141 i->start_timestamp == p->start_timestamp &&
3142 i->exit_timestamp == p->start_timestamp)
3143 /* Let's not show this twice */
3146 if (p->pid == i->control_pid)
3150 if (i->main_pid > 0 || i->control_pid > 0) {
3151 if (i->main_pid > 0) {
3152 printf(" Main PID: %u", (unsigned) i->main_pid);
3155 _cleanup_free_ char *comm = NULL;
3156 get_process_comm(i->main_pid, &comm);
3158 printf(" (%s)", comm);
3159 } else if (i->exit_code > 0) {
3160 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3162 if (i->exit_code == CLD_EXITED) {
3165 printf("status=%i", i->exit_status);
3167 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3172 printf("signal=%s", signal_to_string(i->exit_status));
3176 if (i->control_pid > 0)
3180 if (i->control_pid > 0) {
3181 _cleanup_free_ char *c = NULL;
3183 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3185 get_process_comm(i->control_pid, &c);
3194 printf(" Status: \"%s\"\n", i->status_text);
3196 if (i->control_group &&
3197 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
3200 printf(" CGroup: %s\n", i->control_group);
3202 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3205 char prefix[] = " ";
3208 if (c > sizeof(prefix) - 1)
3209 c -= sizeof(prefix) - 1;
3213 if (i->main_pid > 0)
3214 extra[k++] = i->main_pid;
3216 if (i->control_pid > 0)
3217 extra[k++] = i->control_pid;
3219 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
3220 c, false, extra, k, flags);
3224 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3226 show_journal_by_unit(stdout,
3230 i->inactive_exit_timestamp_monotonic,
3234 arg_scope == UNIT_FILE_SYSTEM,
3238 if (i->need_daemon_reload)
3239 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3240 ansi_highlight_red(),
3241 ansi_highlight_off(),
3242 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3245 static void show_unit_help(UnitStatusInfo *i) {
3250 if (!i->documentation) {
3251 log_info("Documentation for %s not known.", i->id);
3255 STRV_FOREACH(p, i->documentation) {
3257 if (startswith(*p, "man:")) {
3258 const char *args[4] = { "man", NULL, NULL, NULL };
3259 _cleanup_free_ char *page = NULL, *section = NULL;
3266 if ((*p)[k-1] == ')')
3267 e = strrchr(*p, '(');
3270 page = strndup((*p) + 4, e - *p - 4);
3271 section = strndup(e + 1, *p + k - e - 2);
3272 if (!page || !section) {
3284 log_error("Failed to fork: %m");
3290 execvp(args[0], (char**) args);
3291 log_error("Failed to execute man: %m");
3292 _exit(EXIT_FAILURE);
3295 wait_for_terminate(pid, NULL);
3297 log_info("Can't show: %s", *p);
3301 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3308 switch (contents[0]) {
3310 case SD_BUS_TYPE_STRING: {
3313 r = sd_bus_message_read(m, "s", &s);
3315 return bus_log_parse_error(r);
3318 if (streq(name, "Id"))
3320 else if (streq(name, "LoadState"))
3322 else if (streq(name, "ActiveState"))
3323 i->active_state = s;
3324 else if (streq(name, "SubState"))
3326 else if (streq(name, "Description"))
3328 else if (streq(name, "FragmentPath"))
3329 i->fragment_path = s;
3330 else if (streq(name, "SourcePath"))
3333 else if (streq(name, "DefaultControlGroup")) {
3335 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3337 i->control_group = e;
3340 else if (streq(name, "ControlGroup"))
3341 i->control_group = s;
3342 else if (streq(name, "StatusText"))
3344 else if (streq(name, "PIDFile"))
3346 else if (streq(name, "SysFSPath"))
3348 else if (streq(name, "Where"))
3350 else if (streq(name, "What"))
3352 else if (streq(name, "Following"))
3354 else if (streq(name, "UnitFileState"))
3355 i->unit_file_state = s;
3356 else if (streq(name, "Result"))
3363 case SD_BUS_TYPE_BOOLEAN: {
3366 r = sd_bus_message_read(m, "b", &b);
3368 return bus_log_parse_error(r);
3370 if (streq(name, "Accept"))
3372 else if (streq(name, "NeedDaemonReload"))
3373 i->need_daemon_reload = b;
3374 else if (streq(name, "ConditionResult"))
3375 i->condition_result = b;
3380 case SD_BUS_TYPE_UINT32: {
3383 r = sd_bus_message_read(m, "u", &u);
3385 return bus_log_parse_error(r);
3387 if (streq(name, "MainPID")) {
3389 i->main_pid = (pid_t) u;
3392 } else if (streq(name, "ControlPID"))
3393 i->control_pid = (pid_t) u;
3394 else if (streq(name, "ExecMainPID")) {
3396 i->main_pid = (pid_t) u;
3397 } else if (streq(name, "NAccepted"))
3399 else if (streq(name, "NConnections"))
3400 i->n_connections = u;
3405 case SD_BUS_TYPE_INT32: {
3408 r = sd_bus_message_read(m, "i", &j);
3410 return bus_log_parse_error(r);
3412 if (streq(name, "ExecMainCode"))
3413 i->exit_code = (int) j;
3414 else if (streq(name, "ExecMainStatus"))
3415 i->exit_status = (int) j;
3420 case SD_BUS_TYPE_UINT64: {
3423 r = sd_bus_message_read(m, "t", &u);
3425 return bus_log_parse_error(r);
3427 if (streq(name, "ExecMainStartTimestamp"))
3428 i->start_timestamp = (usec_t) u;
3429 else if (streq(name, "ExecMainExitTimestamp"))
3430 i->exit_timestamp = (usec_t) u;
3431 else if (streq(name, "ActiveEnterTimestamp"))
3432 i->active_enter_timestamp = (usec_t) u;
3433 else if (streq(name, "InactiveEnterTimestamp"))
3434 i->inactive_enter_timestamp = (usec_t) u;
3435 else if (streq(name, "InactiveExitTimestamp"))
3436 i->inactive_exit_timestamp = (usec_t) u;
3437 else if (streq(name, "InactiveExitTimestampMonotonic"))
3438 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3439 else if (streq(name, "ActiveExitTimestamp"))
3440 i->active_exit_timestamp = (usec_t) u;
3441 else if (streq(name, "ConditionTimestamp"))
3442 i->condition_timestamp = (usec_t) u;
3447 case SD_BUS_TYPE_ARRAY:
3449 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3450 _cleanup_free_ ExecStatusInfo *info = NULL;
3452 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3454 return bus_log_parse_error(r);
3456 info = new0(ExecStatusInfo, 1);
3460 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3462 info->name = strdup(name);
3466 LIST_PREPEND(exec, i->exec, info);
3468 info = new0(ExecStatusInfo, 1);
3474 return bus_log_parse_error(r);
3476 r = sd_bus_message_exit_container(m);
3478 return bus_log_parse_error(r);
3482 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3483 const char *type, *path;
3485 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3487 return bus_log_parse_error(r);
3489 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3491 r = strv_extend(&i->listen, type);
3495 r = strv_extend(&i->listen, path);
3500 return bus_log_parse_error(r);
3502 r = sd_bus_message_exit_container(m);
3504 return bus_log_parse_error(r);
3508 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3510 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3512 return bus_log_parse_error(r);
3514 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3516 r = sd_bus_message_read_strv(m, &i->documentation);
3518 return bus_log_parse_error(r);
3520 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3521 const char *cond, *param;
3522 int trigger, negate;
3525 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3527 return bus_log_parse_error(r);
3529 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3530 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3531 if (state < 0 && (!trigger || !i->failed_condition)) {
3532 i->failed_condition = cond;
3533 i->failed_condition_trigger = trigger;
3534 i->failed_condition_negate = negate;
3535 i->failed_condition_param = param;
3539 return bus_log_parse_error(r);
3541 r = sd_bus_message_exit_container(m);
3543 return bus_log_parse_error(r);
3550 case SD_BUS_TYPE_STRUCT_BEGIN:
3552 if (streq(name, "LoadError")) {
3553 const char *n, *message;
3555 r = sd_bus_message_read(m, "(ss)", &n, &message);
3557 return bus_log_parse_error(r);
3559 if (!isempty(message))
3560 i->load_error = message;
3573 r = sd_bus_message_skip(m, contents);
3575 return bus_log_parse_error(r);
3580 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3586 /* This is a low-level property printer, see
3587 * print_status_info() for the nicer output */
3589 if (arg_properties && !strv_find(arg_properties, name)) {
3590 /* skip what we didn't read */
3591 r = sd_bus_message_skip(m, contents);
3595 switch (contents[0]) {
3597 case SD_BUS_TYPE_STRUCT_BEGIN:
3599 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3602 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3604 return bus_log_parse_error(r);
3607 printf("%s=%u\n", name, (unsigned) u);
3609 printf("%s=\n", name);
3613 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3616 r = sd_bus_message_read(m, "(so)", &s, NULL);
3618 return bus_log_parse_error(r);
3620 if (arg_all || !isempty(s))
3621 printf("%s=%s\n", name, s);
3625 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3626 const char *a = NULL, *b = NULL;
3628 r = sd_bus_message_read(m, "(ss)", &a, &b);
3630 return bus_log_parse_error(r);
3632 if (arg_all || !isempty(a) || !isempty(b))
3633 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3636 } else if (streq_ptr(name, "SystemCallFilter")) {
3637 _cleanup_strv_free_ char **l = NULL;
3640 r = sd_bus_message_enter_container(m, 'r', "bas");
3642 return bus_log_parse_error(r);
3644 r = sd_bus_message_read(m, "b", &whitelist);
3646 return bus_log_parse_error(r);
3648 r = sd_bus_message_read_strv(m, &l);
3650 return bus_log_parse_error(r);
3652 r = sd_bus_message_exit_container(m);
3654 return bus_log_parse_error(r);
3656 if (arg_all || whitelist || !strv_isempty(l)) {
3660 fputs(name, stdout);
3666 STRV_FOREACH(i, l) {
3674 fputc('\n', stdout);
3682 case SD_BUS_TYPE_ARRAY:
3684 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3688 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3690 return bus_log_parse_error(r);
3692 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3693 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3696 return bus_log_parse_error(r);
3698 r = sd_bus_message_exit_container(m);
3700 return bus_log_parse_error(r);
3704 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3705 const char *type, *path;
3707 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3709 return bus_log_parse_error(r);
3711 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3712 printf("%s=%s\n", type, path);
3714 return bus_log_parse_error(r);
3716 r = sd_bus_message_exit_container(m);
3718 return bus_log_parse_error(r);
3722 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3723 const char *type, *path;
3725 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3727 return bus_log_parse_error(r);
3729 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3730 printf("Listen%s=%s\n", type, path);
3732 return bus_log_parse_error(r);
3734 r = sd_bus_message_exit_container(m);
3736 return bus_log_parse_error(r);
3740 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3742 uint64_t value, next_elapse;
3744 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3746 return bus_log_parse_error(r);
3748 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3749 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3751 printf("%s={ value=%s ; next_elapse=%s }\n",
3753 format_timespan(timespan1, sizeof(timespan1), value, 0),
3754 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3757 return bus_log_parse_error(r);
3759 r = sd_bus_message_exit_container(m);
3761 return bus_log_parse_error(r);
3765 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3766 ExecStatusInfo info = {};
3768 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3770 return bus_log_parse_error(r);
3772 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3773 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3774 _cleanup_free_ char *tt;
3776 tt = strv_join(info.argv, " ");
3778 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3782 yes_no(info.ignore),
3783 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3784 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3785 (unsigned) info. pid,
3786 sigchld_code_to_string(info.code),
3788 info.code == CLD_EXITED ? "" : "/",
3789 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3792 strv_free(info.argv);
3796 r = sd_bus_message_exit_container(m);
3798 return bus_log_parse_error(r);
3802 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3803 const char *path, *rwm;
3805 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3807 return bus_log_parse_error(r);
3809 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3810 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3812 return bus_log_parse_error(r);
3814 r = sd_bus_message_exit_container(m);
3816 return bus_log_parse_error(r);
3820 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3824 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3826 return bus_log_parse_error(r);
3828 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3829 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3831 return bus_log_parse_error(r);
3833 r = sd_bus_message_exit_container(m);
3835 return bus_log_parse_error(r);
3839 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3843 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3845 return bus_log_parse_error(r);
3847 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3848 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3850 return bus_log_parse_error(r);
3852 r = sd_bus_message_exit_container(m);
3854 return bus_log_parse_error(r);
3862 r = bus_print_property(name, m, arg_all);
3864 return bus_log_parse_error(r);
3867 r = sd_bus_message_skip(m, contents);
3869 return bus_log_parse_error(r);
3872 printf("%s=[unprintable]\n", name);
3878 static int show_one(
3882 bool show_properties,
3886 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3887 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3888 UnitStatusInfo info = {};
3895 log_debug("Showing one %s", path);
3897 r = sd_bus_call_method(
3899 "org.freedesktop.systemd1",
3901 "org.freedesktop.DBus.Properties",
3907 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3911 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3913 return bus_log_parse_error(r);
3920 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3921 const char *name, *contents;
3923 r = sd_bus_message_read(reply, "s", &name);
3925 return bus_log_parse_error(r);
3927 r = sd_bus_message_peek_type(reply, NULL, &contents);
3929 return bus_log_parse_error(r);
3931 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3933 return bus_log_parse_error(r);
3935 if (show_properties)
3936 r = print_property(name, reply, contents);
3938 r = status_property(name, reply, &info, contents);
3942 r = sd_bus_message_exit_container(reply);
3944 return bus_log_parse_error(r);
3946 r = sd_bus_message_exit_container(reply);
3948 return bus_log_parse_error(r);
3951 return bus_log_parse_error(r);
3953 r = sd_bus_message_exit_container(reply);
3955 return bus_log_parse_error(r);
3959 if (!show_properties) {
3960 if (streq(verb, "help"))
3961 show_unit_help(&info);
3963 print_status_info(&info, ellipsized);
3966 strv_free(info.documentation);
3967 strv_free(info.dropin_paths);
3968 strv_free(info.listen);
3970 if (!streq_ptr(info.active_state, "active") &&
3971 !streq_ptr(info.active_state, "reloading") &&
3972 streq(verb, "status")) {
3973 /* According to LSB: "program not running" */
3974 /* 0: program is running or service is OK
3975 * 1: program is dead and /run PID file exists
3976 * 2: program is dead and /run/lock lock file exists
3977 * 3: program is not running
3978 * 4: program or service status is unknown
3980 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3986 while ((p = info.exec)) {
3987 LIST_REMOVE(exec, info.exec, p);
3988 exec_status_info_free(p);
3994 static int get_unit_dbus_path_by_pid(
3999 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4000 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4004 r = sd_bus_call_method(
4006 "org.freedesktop.systemd1",
4007 "/org/freedesktop/systemd1",
4008 "org.freedesktop.systemd1.Manager",
4014 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
4018 r = sd_bus_message_read(reply, "o", &u);
4020 return bus_log_parse_error(r);
4030 static int show_all(
4033 bool show_properties,
4037 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4038 _cleanup_free_ UnitInfo *unit_infos = NULL;
4043 r = get_unit_list(bus, &reply, &unit_infos, NULL);
4047 pager_open_if_enabled();
4051 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4053 for (u = unit_infos; u < unit_infos + c; u++) {
4054 _cleanup_free_ char *p = NULL;
4056 p = unit_dbus_path_from_name(u->id);
4060 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4068 static int cat(sd_bus *bus, char **args) {
4069 _cleanup_free_ char *unit = NULL;
4070 _cleanup_strv_free_ char **names = NULL;
4078 r = expand_names(bus, args + 1, NULL, &names);
4080 log_error("Failed to expand names: %s", strerror(-r));
4082 pager_open_if_enabled();
4084 STRV_FOREACH(name, names) {
4085 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4086 _cleanup_strv_free_ char **dropin_paths = NULL;
4087 _cleanup_free_ char *fragment_path = NULL;
4090 unit = unit_dbus_path_from_name(*name);
4094 if (need_daemon_reload(bus, *name) > 0)
4095 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4096 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4098 r = sd_bus_get_property_string(
4100 "org.freedesktop.systemd1",
4102 "org.freedesktop.systemd1.Unit",
4107 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4111 r = sd_bus_get_property_strv(
4113 "org.freedesktop.systemd1",
4115 "org.freedesktop.systemd1.Unit",
4120 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4129 if (!isempty(fragment_path)) {
4130 printf("%s# %s%s\n",
4131 ansi_highlight_blue(),
4133 ansi_highlight_off());
4136 r = sendfile_full(STDOUT_FILENO, fragment_path);
4138 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4143 STRV_FOREACH(path, dropin_paths) {
4144 printf("%s%s# %s%s\n",
4145 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4146 ansi_highlight_blue(),
4148 ansi_highlight_off());
4151 r = sendfile_full(STDOUT_FILENO, *path);
4153 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4159 return r < 0 ? r : 0;
4162 static int show(sd_bus *bus, char **args) {
4163 bool show_properties, show_status, new_line = false;
4164 bool ellipsized = false;
4170 show_properties = streq(args[0], "show");
4171 show_status = streq(args[0], "status");
4173 if (show_properties)
4174 pager_open_if_enabled();
4176 /* If no argument is specified inspect the manager itself */
4178 if (show_properties && strv_length(args) <= 1)
4179 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4181 if (show_status && strv_length(args) <= 1)
4182 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4184 _cleanup_free_ char **patterns = NULL;
4187 STRV_FOREACH(name, args + 1) {
4188 _cleanup_free_ char *unit = NULL;
4191 if (safe_atou32(*name, &id) < 0) {
4192 if (strv_push(&patterns, *name) < 0)
4196 } else if (show_properties) {
4197 /* Interpret as job id */
4198 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4202 /* Interpret as PID */
4203 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4210 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4213 if (!strv_isempty(patterns)) {
4214 _cleanup_strv_free_ char **names = NULL;
4216 r = expand_names(bus, patterns, NULL, &names);
4218 log_error("Failed to expand names: %s", strerror(-r));
4220 STRV_FOREACH(name, names) {
4221 _cleanup_free_ char *unit;
4223 unit = unit_dbus_path_from_name(*name);
4227 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4232 if (ellipsized && !arg_quiet)
4233 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4238 static int set_property(sd_bus *bus, char **args) {
4239 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4240 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4241 _cleanup_free_ char *n = NULL;
4245 r = sd_bus_message_new_method_call(
4248 "org.freedesktop.systemd1",
4249 "/org/freedesktop/systemd1",
4250 "org.freedesktop.systemd1.Manager",
4251 "SetUnitProperties");
4253 return bus_log_create_error(r);
4255 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4259 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4261 return bus_log_create_error(r);
4263 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4265 return bus_log_create_error(r);
4267 STRV_FOREACH(i, args + 2) {
4268 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4270 return bus_log_create_error(r);
4272 r = bus_append_unit_property_assignment(m, *i);
4276 r = sd_bus_message_close_container(m);
4278 return bus_log_create_error(r);
4281 r = sd_bus_message_close_container(m);
4283 return bus_log_create_error(r);
4285 r = sd_bus_call(bus, m, 0, &error, NULL);
4287 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4294 static int snapshot(sd_bus *bus, char **args) {
4295 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4296 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4297 _cleanup_free_ char *n = NULL, *id = NULL;
4301 if (strv_length(args) > 1)
4302 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4308 r = sd_bus_call_method(
4310 "org.freedesktop.systemd1",
4311 "/org/freedesktop/systemd1",
4312 "org.freedesktop.systemd1.Manager",
4318 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4322 r = sd_bus_message_read(reply, "o", &path);
4324 return bus_log_parse_error(r);
4326 r = sd_bus_get_property_string(
4328 "org.freedesktop.systemd1",
4330 "org.freedesktop.systemd1.Unit",
4335 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4345 static int delete_snapshot(sd_bus *bus, char **args) {
4346 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4347 _cleanup_strv_free_ char **names = NULL;
4353 r = expand_names(bus, args + 1, ".snapshot", &names);
4355 log_error("Failed to expand names: %s", strerror(-r));
4357 STRV_FOREACH(name, names) {
4358 q = sd_bus_call_method(
4360 "org.freedesktop.systemd1",
4361 "/org/freedesktop/systemd1",
4362 "org.freedesktop.systemd1.Manager",
4368 log_error("Failed to remove snapshot %s: %s",
4369 *name, bus_error_message(&error, r));
4378 static int daemon_reload(sd_bus *bus, char **args) {
4379 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4383 if (arg_action == ACTION_RELOAD)
4385 else if (arg_action == ACTION_REEXEC)
4386 method = "Reexecute";
4388 assert(arg_action == ACTION_SYSTEMCTL);
4391 streq(args[0], "clear-jobs") ||
4392 streq(args[0], "cancel") ? "ClearJobs" :
4393 streq(args[0], "daemon-reexec") ? "Reexecute" :
4394 streq(args[0], "reset-failed") ? "ResetFailed" :
4395 streq(args[0], "halt") ? "Halt" :
4396 streq(args[0], "poweroff") ? "PowerOff" :
4397 streq(args[0], "reboot") ? "Reboot" :
4398 streq(args[0], "kexec") ? "KExec" :
4399 streq(args[0], "exit") ? "Exit" :
4400 /* "daemon-reload" */ "Reload";
4403 r = sd_bus_call_method(
4405 "org.freedesktop.systemd1",
4406 "/org/freedesktop/systemd1",
4407 "org.freedesktop.systemd1.Manager",
4413 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4414 /* There's always a fallback possible for
4415 * legacy actions. */
4417 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4418 /* On reexecution, we expect a disconnect, not a
4422 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4424 return r < 0 ? r : 0;
4427 static int reset_failed(sd_bus *bus, char **args) {
4428 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4429 _cleanup_strv_free_ char **names = NULL;
4433 if (strv_length(args) <= 1)
4434 return daemon_reload(bus, args);
4436 r = expand_names(bus, args + 1, NULL, &names);
4438 log_error("Failed to expand names: %s", strerror(-r));
4440 STRV_FOREACH(name, names) {
4441 q = sd_bus_call_method(
4443 "org.freedesktop.systemd1",
4444 "/org/freedesktop/systemd1",
4445 "org.freedesktop.systemd1.Manager",
4451 log_error("Failed to reset failed state of unit %s: %s",
4452 *name, bus_error_message(&error, r));
4461 static int show_environment(sd_bus *bus, char **args) {
4462 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4463 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4467 pager_open_if_enabled();
4469 r = sd_bus_get_property(
4471 "org.freedesktop.systemd1",
4472 "/org/freedesktop/systemd1",
4473 "org.freedesktop.systemd1.Manager",
4479 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4483 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4485 return bus_log_parse_error(r);
4487 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4490 return bus_log_parse_error(r);
4492 r = sd_bus_message_exit_container(reply);
4494 return bus_log_parse_error(r);
4499 static int switch_root(sd_bus *bus, char **args) {
4500 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4501 _cleanup_free_ char *cmdline_init = NULL;
4502 const char *root, *init;
4506 l = strv_length(args);
4507 if (l < 2 || l > 3) {
4508 log_error("Wrong number of arguments.");
4517 r = parse_env_file("/proc/cmdline", WHITESPACE,
4518 "init", &cmdline_init,
4521 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4523 init = cmdline_init;
4530 const char *root_systemd_path = NULL, *root_init_path = NULL;
4532 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4533 root_init_path = strappenda3(root, "/", init);
4535 /* If the passed init is actually the same as the
4536 * systemd binary, then let's suppress it. */
4537 if (files_same(root_init_path, root_systemd_path) > 0)
4541 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4543 r = sd_bus_call_method(
4545 "org.freedesktop.systemd1",
4546 "/org/freedesktop/systemd1",
4547 "org.freedesktop.systemd1.Manager",
4553 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4560 static int set_environment(sd_bus *bus, char **args) {
4561 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4562 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4569 method = streq(args[0], "set-environment")
4571 : "UnsetEnvironment";
4573 r = sd_bus_message_new_method_call(
4576 "org.freedesktop.systemd1",
4577 "/org/freedesktop/systemd1",
4578 "org.freedesktop.systemd1.Manager",
4581 return bus_log_create_error(r);
4583 r = sd_bus_message_append_strv(m, args + 1);
4585 return bus_log_create_error(r);
4587 r = sd_bus_call(bus, m, 0, &error, NULL);
4589 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4596 static int import_environment(sd_bus *bus, char **args) {
4597 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4598 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4604 r = sd_bus_message_new_method_call(
4607 "org.freedesktop.systemd1",
4608 "/org/freedesktop/systemd1",
4609 "org.freedesktop.systemd1.Manager",
4612 return bus_log_create_error(r);
4614 if (strv_isempty(args + 1))
4615 r = sd_bus_message_append_strv(m, environ);
4619 r = sd_bus_message_open_container(m, 'a', "s");
4621 return bus_log_create_error(r);
4623 STRV_FOREACH(a, args + 1) {
4625 if (!env_name_is_valid(*a)) {
4626 log_error("Not a valid environment variable name: %s", *a);
4630 STRV_FOREACH(b, environ) {
4633 eq = startswith(*b, *a);
4634 if (eq && *eq == '=') {
4636 r = sd_bus_message_append(m, "s", *b);
4638 return bus_log_create_error(r);
4645 r = sd_bus_message_close_container(m);
4648 return bus_log_create_error(r);
4650 r = sd_bus_call(bus, m, 0, &error, NULL);
4652 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4659 static int enable_sysv_units(const char *verb, char **args) {
4662 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4663 unsigned f = 1, t = 1;
4664 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4666 if (arg_scope != UNIT_FILE_SYSTEM)
4669 if (!streq(verb, "enable") &&
4670 !streq(verb, "disable") &&
4671 !streq(verb, "is-enabled"))
4674 /* Processes all SysV units, and reshuffles the array so that
4675 * afterwards only the native units remain */
4677 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4682 for (f = 0; args[f]; f++) {
4684 _cleanup_free_ char *p = NULL, *q = NULL;
4685 bool found_native = false, found_sysv;
4687 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4695 if (!endswith(name, ".service"))
4698 if (path_is_absolute(name))
4701 STRV_FOREACH(k, paths.unit_path) {
4702 if (!isempty(arg_root))
4703 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4705 asprintf(&p, "%s/%s", *k, name);
4712 found_native = access(p, F_OK) >= 0;
4723 if (!isempty(arg_root))
4724 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4726 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4732 p[strlen(p) - sizeof(".service") + 1] = 0;
4733 found_sysv = access(p, F_OK) >= 0;
4738 /* Mark this entry, so that we don't try enabling it as native unit */
4739 args[f] = (char*) "";
4741 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4743 if (!isempty(arg_root))
4744 argv[c++] = q = strappend("--root=", arg_root);
4746 argv[c++] = basename(p);
4748 streq(verb, "enable") ? "on" :
4749 streq(verb, "disable") ? "off" : "--level=5";
4752 l = strv_join((char**)argv, " ");
4758 log_info("Executing %s", l);
4763 log_error("Failed to fork: %m");
4766 } else if (pid == 0) {
4769 execv(argv[0], (char**) argv);
4770 _exit(EXIT_FAILURE);
4773 j = wait_for_terminate(pid, &status);
4775 log_error("Failed to wait for child: %s", strerror(-r));
4780 if (status.si_code == CLD_EXITED) {
4781 if (streq(verb, "is-enabled")) {
4782 if (status.si_status == 0) {
4791 } else if (status.si_status != 0) {
4802 /* Drop all SysV units */
4803 for (f = 0, t = 0; args[f]; f++) {
4805 if (isempty(args[f]))
4808 args[t++] = args[f];
4817 static int mangle_names(char **original_names, char ***mangled_names) {
4818 char **i, **l, **name;
4820 l = new(char*, strv_length(original_names) + 1);
4825 STRV_FOREACH(name, original_names) {
4827 /* When enabling units qualified path names are OK,
4828 * too, hence allow them explicitly. */
4833 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4849 static int enable_unit(sd_bus *bus, char **args) {
4850 _cleanup_strv_free_ char **names = NULL;
4851 const char *verb = args[0];
4852 UnitFileChange *changes = NULL;
4853 unsigned n_changes = 0;
4854 int carries_install_info = -1;
4860 r = mangle_names(args+1, &names);
4864 r = enable_sysv_units(verb, names);
4868 /* If the operation was fully executed by the SysV compat,
4869 * let's finish early */
4870 if (strv_isempty(names))
4873 if (!bus || avoid_bus()) {
4874 if (streq(verb, "enable")) {
4875 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4876 carries_install_info = r;
4877 } else if (streq(verb, "disable"))
4878 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4879 else if (streq(verb, "reenable")) {
4880 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4881 carries_install_info = r;
4882 } else if (streq(verb, "link"))
4883 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4884 else if (streq(verb, "preset")) {
4885 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4886 carries_install_info = r;
4887 } else if (streq(verb, "mask"))
4888 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4889 else if (streq(verb, "unmask"))
4890 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4892 assert_not_reached("Unknown verb");
4895 log_error("Operation failed: %s", strerror(-r));
4900 dump_unit_file_changes(changes, n_changes);
4904 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4905 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4906 int expect_carries_install_info = false;
4907 bool send_force = true;
4910 if (streq(verb, "enable")) {
4911 method = "EnableUnitFiles";
4912 expect_carries_install_info = true;
4913 } else if (streq(verb, "disable")) {
4914 method = "DisableUnitFiles";
4916 } else if (streq(verb, "reenable")) {
4917 method = "ReenableUnitFiles";
4918 expect_carries_install_info = true;
4919 } else if (streq(verb, "link"))
4920 method = "LinkUnitFiles";
4921 else if (streq(verb, "preset")) {
4922 method = "PresetUnitFiles";
4923 expect_carries_install_info = true;
4924 } else if (streq(verb, "mask"))
4925 method = "MaskUnitFiles";
4926 else if (streq(verb, "unmask")) {
4927 method = "UnmaskUnitFiles";
4930 assert_not_reached("Unknown verb");
4932 r = sd_bus_message_new_method_call(
4935 "org.freedesktop.systemd1",
4936 "/org/freedesktop/systemd1",
4937 "org.freedesktop.systemd1.Manager",
4940 return bus_log_create_error(r);
4942 r = sd_bus_message_append_strv(m, names);
4944 return bus_log_create_error(r);
4946 r = sd_bus_message_append(m, "b", arg_runtime);
4948 return bus_log_create_error(r);
4951 r = sd_bus_message_append(m, "b", arg_force);
4953 return bus_log_create_error(r);
4956 r = sd_bus_call(bus, m, 0, &error, &reply);
4958 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4962 if (expect_carries_install_info) {
4963 r = sd_bus_message_read(reply, "b", &carries_install_info);
4965 return bus_log_parse_error(r);
4968 r = deserialize_and_dump_unit_file_changes(reply);
4972 /* Try to reload if enabeld */
4974 r = daemon_reload(bus, args);
4979 if (carries_install_info == 0)
4980 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4981 "using systemctl.\n"
4982 "Possible reasons for having this kind of units are:\n"
4983 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4984 " .wants/ or .requires/ directory.\n"
4985 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4986 " a requirement dependency on it.\n"
4987 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4988 " D-Bus, udev, scripted systemctl call, ...).\n");
4991 unit_file_changes_free(changes, n_changes);
4996 static int unit_is_enabled(sd_bus *bus, char **args) {
4998 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4999 _cleanup_strv_free_ char **names = NULL;
5004 r = mangle_names(args+1, &names);
5008 r = enable_sysv_units(args[0], names);
5014 if (!bus || avoid_bus()) {
5016 STRV_FOREACH(name, names) {
5017 UnitFileState state;
5019 state = unit_file_get_state(arg_scope, arg_root, *name);
5021 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5025 if (state == UNIT_FILE_ENABLED ||
5026 state == UNIT_FILE_ENABLED_RUNTIME ||
5027 state == UNIT_FILE_STATIC)
5031 puts(unit_file_state_to_string(state));
5035 STRV_FOREACH(name, names) {
5036 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5039 r = sd_bus_call_method(
5041 "org.freedesktop.systemd1",
5042 "/org/freedesktop/systemd1",
5043 "org.freedesktop.systemd1.Manager",
5049 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5053 r = sd_bus_message_read(reply, "s", &s);
5055 return bus_log_parse_error(r);
5057 if (streq(s, "enabled") ||
5058 streq(s, "enabled-runtime") ||
5070 static int systemctl_help(void) {
5072 pager_open_if_enabled();
5074 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5075 "Query or send control commands to the systemd manager.\n\n"
5076 " -h --help Show this help\n"
5077 " --version Show package version\n"
5078 " --system Connect to system manager\n"
5079 " --user Connect to user service manager\n"
5080 " -H --host=[USER@]HOST\n"
5081 " Operate on remote host\n"
5082 " -M --machine=CONTAINER\n"
5083 " Operate on local container\n"
5084 " -t --type=TYPE List only units of a particular type\n"
5085 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5086 " -p --property=NAME Show only properties by this name\n"
5087 " -a --all Show all loaded units/properties, including dead/empty\n"
5088 " ones. To list all units installed on the system, use\n"
5089 " the 'list-unit-files' command instead.\n"
5090 " -l --full Don't ellipsize unit names on output\n"
5091 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5092 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5093 " queueing a new job\n"
5094 " --show-types When showing sockets, explicitly show their type\n"
5095 " -i --ignore-inhibitors\n"
5096 " When shutting down or sleeping, ignore inhibitors\n"
5097 " --kill-who=WHO Who to send signal to\n"
5098 " -s --signal=SIGNAL Which signal to send\n"
5099 " -q --quiet Suppress output\n"
5100 " --no-block Do not wait until operation finished\n"
5101 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5102 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5104 " --no-legend Do not print a legend (column headers and hints)\n"
5105 " --no-pager Do not pipe output into a pager\n"
5106 " --no-ask-password\n"
5107 " Do not ask for system passwords\n"
5108 " --global Enable/disable unit files globally\n"
5109 " --runtime Enable unit files only temporarily until next reboot\n"
5110 " -f --force When enabling unit files, override existing symlinks\n"
5111 " When shutting down, execute action immediately\n"
5112 " --root=PATH Enable unit files in the specified root directory\n"
5113 " -n --lines=INTEGER Number of journal entries to show\n"
5114 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5115 " verbose, export, json, json-pretty, json-sse, cat)\n"
5116 " --plain Print unit dependencies as a list instead of a tree\n\n"
5118 " list-units [PATTERN...] List loaded units\n"
5119 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5120 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5121 " start NAME... Start (activate) one or more units\n"
5122 " stop NAME... Stop (deactivate) one or more units\n"
5123 " reload NAME... Reload one or more units\n"
5124 " restart NAME... Start or restart one or more units\n"
5125 " try-restart NAME... Restart one or more units if active\n"
5126 " reload-or-restart NAME... Reload one or more units if possible,\n"
5127 " otherwise start or restart\n"
5128 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5129 " otherwise restart if active\n"
5130 " isolate NAME Start one unit and stop all others\n"
5131 " kill NAME... Send signal to processes of a unit\n"
5132 " is-active NAME... Check whether units are active\n"
5133 " is-failed NAME... Check whether units are failed\n"
5134 " status [NAME...|PID...] Show runtime status of one or more units\n"
5135 " show [NAME...|JOB...] Show properties of one or more\n"
5136 " units/jobs or the manager\n"
5137 " cat NAME... Show files and drop-ins of one or more units\n"
5138 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5139 " help NAME...|PID... Show manual for one or more units\n"
5140 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
5142 " list-dependencies [NAME] Recursively show units which are required\n"
5143 " or wanted by this unit or by which this\n"
5144 " unit is required or wanted\n\n"
5145 "Unit File Commands:\n"
5146 " list-unit-files [PATTERN...] List installed unit files\n"
5147 " enable NAME... Enable one or more unit files\n"
5148 " disable NAME... Disable one or more unit files\n"
5149 " reenable NAME... Reenable one or more unit files\n"
5150 " preset NAME... Enable/disable one or more unit files\n"
5151 " based on preset configuration\n"
5152 " is-enabled NAME... Check whether unit files are enabled\n\n"
5153 " mask NAME... Mask one or more units\n"
5154 " unmask NAME... Unmask one or more units\n"
5155 " link PATH... Link one or more units files into\n"
5156 " the search path\n"
5157 " get-default Get the name of the default target\n"
5158 " set-default NAME Set the default target\n\n"
5159 "Machine Commands:\n"
5160 " list-machines [PATTERN...] List local containers and host\n\n"
5162 " list-jobs [PATTERN...] List jobs\n"
5163 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5164 "Snapshot Commands:\n"
5165 " snapshot [NAME] Create a snapshot\n"
5166 " delete NAME... Remove one or more snapshots\n\n"
5167 "Environment Commands:\n"
5168 " show-environment Dump environment\n"
5169 " set-environment NAME=VALUE... Set one or more environment variables\n"
5170 " unset-environment NAME... Unset one or more environment variables\n"
5171 " import-environment NAME... Import all, one or more environment variables\n\n"
5172 "Manager Lifecycle Commands:\n"
5173 " daemon-reload Reload systemd manager configuration\n"
5174 " daemon-reexec Reexecute systemd manager\n\n"
5175 "System Commands:\n"
5176 " default Enter system default mode\n"
5177 " rescue Enter system rescue mode\n"
5178 " emergency Enter system emergency mode\n"
5179 " halt Shut down and halt the system\n"
5180 " poweroff Shut down and power-off the system\n"
5181 " reboot [ARG] Shut down and reboot the system\n"
5182 " kexec Shut down and reboot the system with kexec\n"
5183 " exit Request user instance exit\n"
5184 " switch-root ROOT [INIT] Change to a different root file system\n"
5185 " suspend Suspend the system\n"
5186 " hibernate Hibernate the system\n"
5187 " hybrid-sleep Hibernate and suspend the system\n",
5188 program_invocation_short_name);
5193 static int halt_help(void) {
5195 printf("%s [OPTIONS...]%s\n\n"
5196 "%s the system.\n\n"
5197 " --help Show this help\n"
5198 " --halt Halt the machine\n"
5199 " -p --poweroff Switch off the machine\n"
5200 " --reboot Reboot the machine\n"
5201 " -f --force Force immediate halt/power-off/reboot\n"
5202 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5203 " -d --no-wtmp Don't write wtmp record\n"
5204 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5205 program_invocation_short_name,
5206 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5207 arg_action == ACTION_REBOOT ? "Reboot" :
5208 arg_action == ACTION_POWEROFF ? "Power off" :
5214 static int shutdown_help(void) {
5216 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5217 "Shut down the system.\n\n"
5218 " --help Show this help\n"
5219 " -H --halt Halt the machine\n"
5220 " -P --poweroff Power-off the machine\n"
5221 " -r --reboot Reboot the machine\n"
5222 " -h Equivalent to --poweroff, overridden by --halt\n"
5223 " -k Don't halt/power-off/reboot, just send warnings\n"
5224 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5225 " -c Cancel a pending shutdown\n",
5226 program_invocation_short_name);
5231 static int telinit_help(void) {
5233 printf("%s [OPTIONS...] {COMMAND}\n\n"
5234 "Send control commands to the init daemon.\n\n"
5235 " --help Show this help\n"
5236 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5238 " 0 Power-off the machine\n"
5239 " 6 Reboot the machine\n"
5240 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5241 " 1, s, S Enter rescue mode\n"
5242 " q, Q Reload init daemon configuration\n"
5243 " u, U Reexecute init daemon\n",
5244 program_invocation_short_name);
5249 static int runlevel_help(void) {
5251 printf("%s [OPTIONS...]\n\n"
5252 "Prints the previous and current runlevel of the init system.\n\n"
5253 " --help Show this help\n",
5254 program_invocation_short_name);
5259 static int help_types(void) {
5263 puts("Available unit types:");
5264 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5265 t = unit_type_to_string(i);
5273 static int systemctl_parse_argv(int argc, char *argv[]) {
5282 ARG_IGNORE_DEPENDENCIES,
5294 ARG_NO_ASK_PASSWORD,
5303 static const struct option options[] = {
5304 { "help", no_argument, NULL, 'h' },
5305 { "version", no_argument, NULL, ARG_VERSION },
5306 { "type", required_argument, NULL, 't' },
5307 { "property", required_argument, NULL, 'p' },
5308 { "all", no_argument, NULL, 'a' },
5309 { "reverse", no_argument, NULL, ARG_REVERSE },
5310 { "after", no_argument, NULL, ARG_AFTER },
5311 { "before", no_argument, NULL, ARG_BEFORE },
5312 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5313 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5314 { "full", no_argument, NULL, 'l' },
5315 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5316 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5317 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5318 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5319 { "ignore-inhibitors", no_argument, NULL, 'i' },
5320 { "user", no_argument, NULL, ARG_USER },
5321 { "system", no_argument, NULL, ARG_SYSTEM },
5322 { "global", no_argument, NULL, ARG_GLOBAL },
5323 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5324 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5325 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5326 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5327 { "quiet", no_argument, NULL, 'q' },
5328 { "root", required_argument, NULL, ARG_ROOT },
5329 { "force", no_argument, NULL, ARG_FORCE },
5330 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5331 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5332 { "signal", required_argument, NULL, 's' },
5333 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5334 { "host", required_argument, NULL, 'H' },
5335 { "machine", required_argument, NULL, 'M' },
5336 { "runtime", no_argument, NULL, ARG_RUNTIME },
5337 { "lines", required_argument, NULL, 'n' },
5338 { "output", required_argument, NULL, 'o' },
5339 { "plain", no_argument, NULL, ARG_PLAIN },
5340 { "state", required_argument, NULL, ARG_STATE },
5349 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5354 return systemctl_help();
5357 puts(PACKAGE_STRING);
5358 puts(SYSTEMD_FEATURES);
5365 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5366 _cleanup_free_ char *type;
5368 type = strndup(word, size);
5372 if (streq(type, "help")) {
5377 if (unit_type_from_string(type) >= 0) {
5378 if (strv_push(&arg_types, type))
5384 /* It's much nicer to use --state= for
5385 * load states, but let's support this
5386 * in --types= too for compatibility
5387 * with old versions */
5388 if (unit_load_state_from_string(optarg) >= 0) {
5389 if (strv_push(&arg_states, type) < 0)
5395 log_error("Unknown unit type or load state '%s'.", type);
5396 log_info("Use -t help to see a list of allowed values.");
5404 /* Make sure that if the empty property list
5405 was specified, we won't show any properties. */
5406 if (isempty(optarg) && !arg_properties) {
5407 arg_properties = new0(char*, 1);
5408 if (!arg_properties)
5414 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5417 prop = strndup(word, size);
5421 if (strv_consume(&arg_properties, prop) < 0)
5426 /* If the user asked for a particular
5427 * property, show it to him, even if it is
5439 arg_dependency = DEPENDENCY_REVERSE;
5443 arg_dependency = DEPENDENCY_AFTER;
5447 arg_dependency = DEPENDENCY_BEFORE;
5450 case ARG_SHOW_TYPES:
5451 arg_show_types = true;
5455 arg_job_mode = optarg;
5459 arg_job_mode = "fail";
5462 case ARG_IRREVERSIBLE:
5463 arg_job_mode = "replace-irreversibly";
5466 case ARG_IGNORE_DEPENDENCIES:
5467 arg_job_mode = "ignore-dependencies";
5471 arg_scope = UNIT_FILE_USER;
5475 arg_scope = UNIT_FILE_SYSTEM;
5479 arg_scope = UNIT_FILE_GLOBAL;
5483 arg_no_block = true;
5487 arg_no_legend = true;
5491 arg_no_pager = true;
5507 if (strv_extend(&arg_states, "failed") < 0)
5525 arg_no_reload = true;
5529 arg_kill_who = optarg;
5533 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5534 log_error("Failed to parse signal string %s.", optarg);
5539 case ARG_NO_ASK_PASSWORD:
5540 arg_ask_password = false;
5544 arg_transport = BUS_TRANSPORT_REMOTE;
5549 arg_transport = BUS_TRANSPORT_CONTAINER;
5558 if (safe_atou(optarg, &arg_lines) < 0) {
5559 log_error("Failed to parse lines '%s'", optarg);
5565 arg_output = output_mode_from_string(optarg);
5566 if (arg_output < 0) {
5567 log_error("Unknown output '%s'.", optarg);
5573 arg_ignore_inhibitors = true;
5584 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5587 s = strndup(word, size);
5591 if (strv_consume(&arg_states, s) < 0)
5601 assert_not_reached("Unhandled option");
5605 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5606 log_error("Cannot access user instance remotely.");
5613 static int halt_parse_argv(int argc, char *argv[]) {
5622 static const struct option options[] = {
5623 { "help", no_argument, NULL, ARG_HELP },
5624 { "halt", no_argument, NULL, ARG_HALT },
5625 { "poweroff", no_argument, NULL, 'p' },
5626 { "reboot", no_argument, NULL, ARG_REBOOT },
5627 { "force", no_argument, NULL, 'f' },
5628 { "wtmp-only", no_argument, NULL, 'w' },
5629 { "no-wtmp", no_argument, NULL, 'd' },
5630 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5639 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5640 if (runlevel == '0' || runlevel == '6')
5643 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5650 arg_action = ACTION_HALT;
5654 if (arg_action != ACTION_REBOOT)
5655 arg_action = ACTION_POWEROFF;
5659 arg_action = ACTION_REBOOT;
5681 /* Compatibility nops */
5688 assert_not_reached("Unhandled option");
5692 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5693 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5695 log_error("Failed to write reboot param to "
5696 REBOOT_PARAM_FILE": %s", strerror(-r));
5699 } else if (optind < argc) {
5700 log_error("Too many arguments.");
5707 static int parse_time_spec(const char *t, usec_t *_u) {
5711 if (streq(t, "now"))
5713 else if (!strchr(t, ':')) {
5716 if (safe_atou64(t, &u) < 0)
5719 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5728 hour = strtol(t, &e, 10);
5729 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5732 minute = strtol(e+1, &e, 10);
5733 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5736 n = now(CLOCK_REALTIME);
5737 s = (time_t) (n / USEC_PER_SEC);
5739 assert_se(localtime_r(&s, &tm));
5741 tm.tm_hour = (int) hour;
5742 tm.tm_min = (int) minute;
5745 assert_se(s = mktime(&tm));
5747 *_u = (usec_t) s * USEC_PER_SEC;
5750 *_u += USEC_PER_DAY;
5756 static int shutdown_parse_argv(int argc, char *argv[]) {
5763 static const struct option options[] = {
5764 { "help", no_argument, NULL, ARG_HELP },
5765 { "halt", no_argument, NULL, 'H' },
5766 { "poweroff", no_argument, NULL, 'P' },
5767 { "reboot", no_argument, NULL, 'r' },
5768 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5769 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5778 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5782 return shutdown_help();
5785 arg_action = ACTION_HALT;
5789 arg_action = ACTION_POWEROFF;
5794 arg_action = ACTION_KEXEC;
5796 arg_action = ACTION_REBOOT;
5800 arg_action = ACTION_KEXEC;
5804 if (arg_action != ACTION_HALT)
5805 arg_action = ACTION_POWEROFF;
5818 /* Compatibility nops */
5822 arg_action = ACTION_CANCEL_SHUTDOWN;
5829 assert_not_reached("Unhandled option");
5833 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5834 r = parse_time_spec(argv[optind], &arg_when);
5836 log_error("Failed to parse time specification: %s", argv[optind]);
5840 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5842 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5843 /* No time argument for shutdown cancel */
5844 arg_wall = argv + optind;
5845 else if (argc > optind + 1)
5846 /* We skip the time argument */
5847 arg_wall = argv + optind + 1;
5854 static int telinit_parse_argv(int argc, char *argv[]) {
5861 static const struct option options[] = {
5862 { "help", no_argument, NULL, ARG_HELP },
5863 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5867 static const struct {
5871 { '0', ACTION_POWEROFF },
5872 { '6', ACTION_REBOOT },
5873 { '1', ACTION_RESCUE },
5874 { '2', ACTION_RUNLEVEL2 },
5875 { '3', ACTION_RUNLEVEL3 },
5876 { '4', ACTION_RUNLEVEL4 },
5877 { '5', ACTION_RUNLEVEL5 },
5878 { 's', ACTION_RESCUE },
5879 { 'S', ACTION_RESCUE },
5880 { 'q', ACTION_RELOAD },
5881 { 'Q', ACTION_RELOAD },
5882 { 'u', ACTION_REEXEC },
5883 { 'U', ACTION_REEXEC }
5892 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5896 return telinit_help();
5906 assert_not_reached("Unhandled option");
5910 if (optind >= argc) {
5915 if (optind + 1 < argc) {
5916 log_error("Too many arguments.");
5920 if (strlen(argv[optind]) != 1) {
5921 log_error("Expected single character argument.");
5925 for (i = 0; i < ELEMENTSOF(table); i++)
5926 if (table[i].from == argv[optind][0])
5929 if (i >= ELEMENTSOF(table)) {
5930 log_error("Unknown command '%s'.", argv[optind]);
5934 arg_action = table[i].to;
5941 static int runlevel_parse_argv(int argc, char *argv[]) {
5947 static const struct option options[] = {
5948 { "help", no_argument, NULL, ARG_HELP },
5957 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5961 return runlevel_help();
5967 assert_not_reached("Unhandled option");
5971 if (optind < argc) {
5972 log_error("Too many arguments.");
5979 static int parse_argv(int argc, char *argv[]) {
5983 if (program_invocation_short_name) {
5985 if (strstr(program_invocation_short_name, "halt")) {
5986 arg_action = ACTION_HALT;
5987 return halt_parse_argv(argc, argv);
5988 } else if (strstr(program_invocation_short_name, "poweroff")) {
5989 arg_action = ACTION_POWEROFF;
5990 return halt_parse_argv(argc, argv);
5991 } else if (strstr(program_invocation_short_name, "reboot")) {
5993 arg_action = ACTION_KEXEC;
5995 arg_action = ACTION_REBOOT;
5996 return halt_parse_argv(argc, argv);
5997 } else if (strstr(program_invocation_short_name, "shutdown")) {
5998 arg_action = ACTION_POWEROFF;
5999 return shutdown_parse_argv(argc, argv);
6000 } else if (strstr(program_invocation_short_name, "init")) {
6002 if (sd_booted() > 0) {
6003 arg_action = _ACTION_INVALID;
6004 return telinit_parse_argv(argc, argv);
6006 /* Hmm, so some other init system is
6007 * running, we need to forward this
6008 * request to it. For now we simply
6009 * guess that it is Upstart. */
6011 execv(TELINIT, argv);
6013 log_error("Couldn't find an alternative telinit implementation to spawn.");
6017 } else if (strstr(program_invocation_short_name, "runlevel")) {
6018 arg_action = ACTION_RUNLEVEL;
6019 return runlevel_parse_argv(argc, argv);
6023 arg_action = ACTION_SYSTEMCTL;
6024 return systemctl_parse_argv(argc, argv);
6027 _pure_ static int action_to_runlevel(void) {
6029 static const char table[_ACTION_MAX] = {
6030 [ACTION_HALT] = '0',
6031 [ACTION_POWEROFF] = '0',
6032 [ACTION_REBOOT] = '6',
6033 [ACTION_RUNLEVEL2] = '2',
6034 [ACTION_RUNLEVEL3] = '3',
6035 [ACTION_RUNLEVEL4] = '4',
6036 [ACTION_RUNLEVEL5] = '5',
6037 [ACTION_RESCUE] = '1'
6040 assert(arg_action < _ACTION_MAX);
6042 return table[arg_action];
6045 static int talk_initctl(void) {
6047 struct init_request request = {
6048 .magic = INIT_MAGIC,
6050 .cmd = INIT_CMD_RUNLVL
6053 _cleanup_close_ int fd = -1;
6057 rl = action_to_runlevel();
6061 request.runlevel = rl;
6063 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6065 if (errno == ENOENT)
6068 log_error("Failed to open "INIT_FIFO": %m");
6073 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6075 log_error("Failed to write to "INIT_FIFO": %m");
6076 return errno > 0 ? -errno : -EIO;
6082 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6084 static const struct {
6092 int (* const dispatch)(sd_bus *bus, char **args);
6098 { "list-units", MORE, 0, list_units },
6099 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6100 { "list-sockets", MORE, 1, list_sockets },
6101 { "list-timers", MORE, 1, list_timers },
6102 { "list-jobs", MORE, 1, list_jobs },
6103 { "list-machines", MORE, 1, list_machines },
6104 { "clear-jobs", EQUAL, 1, daemon_reload },
6105 { "cancel", MORE, 2, cancel_job },
6106 { "start", MORE, 2, start_unit },
6107 { "stop", MORE, 2, start_unit },
6108 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6109 { "reload", MORE, 2, start_unit },
6110 { "restart", MORE, 2, start_unit },
6111 { "try-restart", MORE, 2, start_unit },
6112 { "reload-or-restart", MORE, 2, start_unit },
6113 { "reload-or-try-restart", MORE, 2, start_unit },
6114 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6115 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6116 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6117 { "isolate", EQUAL, 2, start_unit },
6118 { "kill", MORE, 2, kill_unit },
6119 { "is-active", MORE, 2, check_unit_active },
6120 { "check", MORE, 2, check_unit_active },
6121 { "is-failed", MORE, 2, check_unit_failed },
6122 { "show", MORE, 1, show },
6123 { "cat", MORE, 2, cat },
6124 { "status", MORE, 1, show },
6125 { "help", MORE, 2, show },
6126 { "snapshot", LESS, 2, snapshot },
6127 { "delete", MORE, 2, delete_snapshot },
6128 { "daemon-reload", EQUAL, 1, daemon_reload },
6129 { "daemon-reexec", EQUAL, 1, daemon_reload },
6130 { "show-environment", EQUAL, 1, show_environment },
6131 { "set-environment", MORE, 2, set_environment },
6132 { "unset-environment", MORE, 2, set_environment },
6133 { "import-environment", MORE, 1, import_environment},
6134 { "halt", EQUAL, 1, start_special, FORCE },
6135 { "poweroff", EQUAL, 1, start_special, FORCE },
6136 { "reboot", EQUAL, 1, start_special, FORCE },
6137 { "kexec", EQUAL, 1, start_special },
6138 { "suspend", EQUAL, 1, start_special },
6139 { "hibernate", EQUAL, 1, start_special },
6140 { "hybrid-sleep", EQUAL, 1, start_special },
6141 { "default", EQUAL, 1, start_special },
6142 { "rescue", EQUAL, 1, start_special },
6143 { "emergency", EQUAL, 1, start_special },
6144 { "exit", EQUAL, 1, start_special },
6145 { "reset-failed", MORE, 1, reset_failed },
6146 { "enable", MORE, 2, enable_unit, NOBUS },
6147 { "disable", MORE, 2, enable_unit, NOBUS },
6148 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6149 { "reenable", MORE, 2, enable_unit, NOBUS },
6150 { "preset", MORE, 2, enable_unit, NOBUS },
6151 { "mask", MORE, 2, enable_unit, NOBUS },
6152 { "unmask", MORE, 2, enable_unit, NOBUS },
6153 { "link", MORE, 2, enable_unit, NOBUS },
6154 { "switch-root", MORE, 2, switch_root },
6155 { "list-dependencies", LESS, 2, list_dependencies },
6156 { "set-default", EQUAL, 2, set_default, NOBUS },
6157 { "get-default", EQUAL, 1, get_default, NOBUS },
6158 { "set-property", MORE, 3, set_property },
6167 left = argc - optind;
6169 /* Special rule: no arguments (left == 0) means "list-units" */
6171 if (streq(argv[optind], "help") && !argv[optind+1]) {
6172 log_error("This command expects one or more "
6173 "unit names. Did you mean --help?");
6177 for (; verb->verb; verb++)
6178 if (streq(argv[optind], verb->verb))
6181 log_error("Unknown operation '%s'.", argv[optind]);
6186 switch (verb->argc_cmp) {
6189 if (left != verb->argc) {
6190 log_error("Invalid number of arguments.");
6197 if (left < verb->argc) {
6198 log_error("Too few arguments.");
6205 if (left > verb->argc) {
6206 log_error("Too many arguments.");
6213 assert_not_reached("Unknown comparison operator.");
6216 /* Require a bus connection for all operations but
6218 if (verb->bus == NOBUS) {
6219 if (!bus && !avoid_bus()) {
6220 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6225 if (running_in_chroot() > 0) {
6226 log_info("Running in chroot, ignoring request.");
6230 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6231 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6236 return verb->dispatch(bus, argv + optind);
6239 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6241 struct sd_shutdown_command c = {
6248 union sockaddr_union sockaddr = {
6249 .un.sun_family = AF_UNIX,
6250 .un.sun_path = "/run/systemd/shutdownd",
6253 struct iovec iovec[2] = {{
6254 .iov_base = (char*) &c,
6255 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6258 struct msghdr msghdr = {
6259 .msg_name = &sockaddr,
6260 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6261 + sizeof("/run/systemd/shutdownd") - 1,
6266 _cleanup_close_ int fd;
6268 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6272 if (!isempty(message)) {
6273 iovec[1].iov_base = (char*) message;
6274 iovec[1].iov_len = strlen(message);
6275 msghdr.msg_iovlen++;
6278 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6284 static int reload_with_fallback(sd_bus *bus) {
6287 /* First, try systemd via D-Bus. */
6288 if (daemon_reload(bus, NULL) >= 0)
6292 /* Nothing else worked, so let's try signals */
6293 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6295 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6296 log_error("kill() failed: %m");
6303 static int start_with_fallback(sd_bus *bus) {
6306 /* First, try systemd via D-Bus. */
6307 if (start_unit(bus, NULL) >= 0)
6311 /* Nothing else worked, so let's try
6313 if (talk_initctl() > 0)
6316 log_error("Failed to talk to init daemon.");
6320 warn_wall(arg_action);
6324 static int halt_now(enum action a) {
6326 /* Make sure C-A-D is handled by the kernel from this
6328 reboot(RB_ENABLE_CAD);
6333 log_info("Halting.");
6334 reboot(RB_HALT_SYSTEM);
6337 case ACTION_POWEROFF:
6338 log_info("Powering off.");
6339 reboot(RB_POWER_OFF);
6342 case ACTION_REBOOT: {
6343 _cleanup_free_ char *param = NULL;
6345 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6346 log_info("Rebooting with argument '%s'.", param);
6347 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6348 LINUX_REBOOT_CMD_RESTART2, param);
6351 log_info("Rebooting.");
6352 reboot(RB_AUTOBOOT);
6357 assert_not_reached("Unknown action.");
6361 static int halt_main(sd_bus *bus) {
6364 r = check_inhibitors(bus, arg_action);
6368 if (geteuid() != 0) {
6369 /* Try logind if we are a normal user and no special
6370 * mode applies. Maybe PolicyKit allows us to shutdown
6373 if (arg_when <= 0 &&
6376 (arg_action == ACTION_POWEROFF ||
6377 arg_action == ACTION_REBOOT)) {
6378 r = reboot_with_logind(bus, arg_action);
6383 log_error("Must be root.");
6388 _cleanup_free_ char *m;
6390 m = strv_join(arg_wall, " ");
6394 r = send_shutdownd(arg_when,
6395 arg_action == ACTION_HALT ? 'H' :
6396 arg_action == ACTION_POWEROFF ? 'P' :
6397 arg_action == ACTION_KEXEC ? 'K' :
6404 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6406 char date[FORMAT_TIMESTAMP_MAX];
6408 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6409 format_timestamp(date, sizeof(date), arg_when));
6414 if (!arg_dry && !arg_force)
6415 return start_with_fallback(bus);
6418 if (sd_booted() > 0)
6419 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6421 r = utmp_put_shutdown();
6423 log_warning("Failed to write utmp record: %s", strerror(-r));
6430 r = halt_now(arg_action);
6431 log_error("Failed to reboot: %s", strerror(-r));
6436 static int runlevel_main(void) {
6437 int r, runlevel, previous;
6439 r = utmp_get_runlevel(&runlevel, &previous);
6446 previous <= 0 ? 'N' : previous,
6447 runlevel <= 0 ? 'N' : runlevel);
6452 int main(int argc, char*argv[]) {
6453 _cleanup_bus_unref_ sd_bus *bus = NULL;
6456 setlocale(LC_ALL, "");
6457 log_parse_environment();
6460 /* Explicitly not on_tty() to avoid setting cached value.
6461 * This becomes relevant for piping output which might be
6463 original_stdout_is_tty = isatty(STDOUT_FILENO);
6465 r = parse_argv(argc, argv);
6469 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6470 * let's shortcut this */
6471 if (arg_action == ACTION_RUNLEVEL) {
6472 r = runlevel_main();
6476 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6477 log_info("Running in chroot, ignoring request.");
6483 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6485 /* systemctl_main() will print an error message for the bus
6486 * connection, but only if it needs to */
6488 switch (arg_action) {
6490 case ACTION_SYSTEMCTL:
6491 r = systemctl_main(bus, argc, argv, r);
6495 case ACTION_POWEROFF:
6501 case ACTION_RUNLEVEL2:
6502 case ACTION_RUNLEVEL3:
6503 case ACTION_RUNLEVEL4:
6504 case ACTION_RUNLEVEL5:
6506 case ACTION_EMERGENCY:
6507 case ACTION_DEFAULT:
6508 r = start_with_fallback(bus);
6513 r = reload_with_fallback(bus);
6516 case ACTION_CANCEL_SHUTDOWN: {
6517 _cleanup_free_ char *m = NULL;
6520 m = strv_join(arg_wall, " ");
6527 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6529 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6533 case ACTION_RUNLEVEL:
6534 case _ACTION_INVALID:
6536 assert_not_reached("Unknown action");
6541 ask_password_agent_close();
6542 polkit_agent_close();
6544 strv_free(arg_types);
6545 strv_free(arg_states);
6546 strv_free(arg_properties);
6548 return r < 0 ? EXIT_FAILURE : r;