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 {
1419 char *control_group;
1420 uint32_t n_failed_units;
1425 static const struct bus_properties_map machine_info_property_map[] = {
1426 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1427 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1428 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1429 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1430 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1434 static void free_machines_list(struct machine_info *machine_infos, int n) {
1440 for (i = 0; i < n; i++) {
1441 free(machine_infos[i].name);
1442 free(machine_infos[i].state);
1443 free(machine_infos[i].control_group);
1446 free(machine_infos);
1449 static int compare_machine_info(const void *a, const void *b) {
1450 const struct machine_info *u = a, *v = b;
1452 if (u->is_host != v->is_host)
1453 return u->is_host > v->is_host ? 1 : -1;
1455 return strcasecmp(u->name, v->name);
1458 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1459 _cleanup_bus_unref_ sd_bus *container = NULL;
1465 r = sd_bus_open_system_container(&container, mi->name);
1472 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1479 static bool output_show_machine(const char *name, char **patterns) {
1484 if (strv_isempty(patterns))
1487 STRV_FOREACH(i, patterns)
1488 if (fnmatch(*i, name, FNM_NOESCAPE) == 0)
1494 static int get_machine_list(
1496 struct machine_info **_machine_infos,
1499 struct machine_info *machine_infos = NULL;
1500 _cleanup_strv_free_ char **m = NULL;
1501 _cleanup_free_ char *hn = NULL;
1506 hn = gethostname_malloc();
1510 if (output_show_machine(hn, patterns)) {
1511 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1514 machine_infos[c].is_host = true;
1515 machine_infos[c].name = hn;
1518 get_machine_properties(bus, &machine_infos[c]);
1522 sd_get_machine_names(&m);
1523 STRV_FOREACH(i, m) {
1524 _cleanup_free_ char *class = NULL;
1526 if (!output_show_machine(*i, patterns))
1529 sd_machine_get_class(*i, &class);
1530 if (!streq_ptr(class, "container"))
1533 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1534 free_machines_list(machine_infos, c);
1538 machine_infos[c].is_host = false;
1539 machine_infos[c].name = strdup(*i);
1540 if (!machine_infos[c].name) {
1541 free_machines_list(machine_infos, c);
1545 get_machine_properties(NULL, &machine_infos[c]);
1549 *_machine_infos = machine_infos;
1553 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1554 struct machine_info *m;
1556 namelen = sizeof("NAME") - 1,
1557 statelen = sizeof("STATE") - 1,
1558 failedlen = sizeof("FAILED") - 1,
1559 jobslen = sizeof("JOBS") - 1;
1561 assert(machine_infos || n == 0);
1563 for (m = machine_infos; m < machine_infos + n; m++) {
1564 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1565 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1566 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1567 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1571 printf("%-*s %-*s %-*s %-*s\n",
1574 failedlen, "FAILED",
1577 for (m = machine_infos; m < machine_infos + n; m++) {
1578 const char *on_state, *off_state, *on_failed, *off_failed;
1580 if (streq_ptr(m->state, "degraded")) {
1581 on_state = ansi_highlight_red();
1582 off_state = ansi_highlight_off();
1583 } else if (!streq_ptr(m->state, "running")) {
1584 on_state = ansi_highlight_yellow();
1585 off_state = ansi_highlight_off();
1587 on_state = off_state = "";
1589 if (m->n_failed_units > 0) {
1590 on_failed = ansi_highlight_red();
1591 off_failed = ansi_highlight_off();
1593 on_failed = off_failed = "";
1596 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1597 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1598 on_state, statelen, strna(m->state), off_state,
1599 on_failed, failedlen, m->n_failed_units, off_failed,
1600 jobslen, m->n_jobs);
1602 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1603 namelen, strna(m->name),
1604 on_state, statelen, strna(m->state), off_state,
1605 on_failed, failedlen, m->n_failed_units, off_failed,
1606 jobslen, m->n_jobs);
1610 printf("\n%u machines listed.\n", n);
1613 static int list_machines(sd_bus *bus, char **args) {
1614 struct machine_info *machine_infos = NULL;
1619 if (geteuid() != 0) {
1620 log_error("Must be root.");
1624 pager_open_if_enabled();
1626 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1630 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1631 output_machines_list(machine_infos, r);
1632 free_machines_list(machine_infos, r);
1637 static int get_default(sd_bus *bus, char **args) {
1638 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1639 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1640 _cleanup_free_ char *_path = NULL;
1644 if (!bus || avoid_bus()) {
1645 r = unit_file_get_default(arg_scope, arg_root, &_path);
1647 log_error("Failed to get default target: %s", strerror(-r));
1653 r = sd_bus_call_method(
1655 "org.freedesktop.systemd1",
1656 "/org/freedesktop/systemd1",
1657 "org.freedesktop.systemd1.Manager",
1663 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1667 r = sd_bus_message_read(reply, "s", &path);
1669 return bus_log_parse_error(r);
1673 printf("%s\n", path);
1678 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1681 assert(changes || n_changes == 0);
1683 for (i = 0; i < n_changes; i++) {
1684 if (changes[i].type == UNIT_FILE_SYMLINK)
1685 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1687 log_info("rm '%s'", changes[i].path);
1691 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1692 const char *type, *path, *source;
1695 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1697 return bus_log_parse_error(r);
1699 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1701 if (streq(type, "symlink"))
1702 log_info("ln -s '%s' '%s'", source, path);
1704 log_info("rm '%s'", path);
1708 return bus_log_parse_error(r);
1710 r = sd_bus_message_exit_container(m);
1712 return bus_log_parse_error(r);
1717 static int set_default(sd_bus *bus, char **args) {
1718 _cleanup_free_ char *unit = NULL;
1719 UnitFileChange *changes = NULL;
1720 unsigned n_changes = 0;
1723 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1727 if (!bus || avoid_bus()) {
1728 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1730 log_error("Failed to set default target: %s", strerror(-r));
1735 dump_unit_file_changes(changes, n_changes);
1739 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1740 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1742 r = sd_bus_call_method(
1744 "org.freedesktop.systemd1",
1745 "/org/freedesktop/systemd1",
1746 "org.freedesktop.systemd1.Manager",
1750 "sb", unit, arg_force);
1752 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1756 r = deserialize_and_dump_unit_file_changes(reply);
1760 /* Try to reload if enabeld */
1762 r = daemon_reload(bus, args);
1767 unit_file_changes_free(changes, n_changes);
1774 const char *name, *type, *state;
1777 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1778 unsigned id_len, unit_len, type_len, state_len;
1779 const struct job_info *j;
1780 const char *on, *off;
1781 bool shorten = false;
1783 assert(n == 0 || jobs);
1786 on = ansi_highlight_green();
1787 off = ansi_highlight_off();
1789 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1793 pager_open_if_enabled();
1795 id_len = sizeof("JOB")-1;
1796 unit_len = sizeof("UNIT")-1;
1797 type_len = sizeof("TYPE")-1;
1798 state_len = sizeof("STATE")-1;
1800 for (j = jobs; j < jobs + n; j++) {
1801 uint32_t id = j->id;
1802 assert(j->name && j->type && j->state);
1804 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1805 unit_len = MAX(unit_len, strlen(j->name));
1806 type_len = MAX(type_len, strlen(j->type));
1807 state_len = MAX(state_len, strlen(j->state));
1810 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1811 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1816 printf("%*s %-*s %-*s %-*s\n",
1820 state_len, "STATE");
1822 for (j = jobs; j < jobs + n; j++) {
1823 _cleanup_free_ char *e = NULL;
1825 if (streq(j->state, "running")) {
1826 on = ansi_highlight();
1827 off = ansi_highlight_off();
1831 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1832 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1834 on, unit_len, e ? e : j->name, off,
1836 on, state_len, j->state, off);
1839 if (!arg_no_legend) {
1840 on = ansi_highlight();
1841 off = ansi_highlight_off();
1843 printf("\n%s%u jobs listed%s.\n", on, n, off);
1847 static bool output_show_job(struct job_info *job, char **patterns) {
1852 if (strv_isempty(patterns))
1855 STRV_FOREACH(pattern, patterns)
1856 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1861 static int list_jobs(sd_bus *bus, char **args) {
1862 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1863 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1864 const char *name, *type, *state, *job_path, *unit_path;
1865 _cleanup_free_ struct job_info *jobs = NULL;
1870 bool skipped = false;
1872 r = sd_bus_call_method(
1874 "org.freedesktop.systemd1",
1875 "/org/freedesktop/systemd1",
1876 "org.freedesktop.systemd1.Manager",
1882 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1886 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1888 return bus_log_parse_error(r);
1890 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1891 struct job_info job = { id, name, type, state };
1893 if (!output_show_job(&job, strv_skip_first(args))) {
1898 if (!GREEDY_REALLOC(jobs, size, c + 1))
1904 return bus_log_parse_error(r);
1906 r = sd_bus_message_exit_container(reply);
1908 return bus_log_parse_error(r);
1910 output_jobs_list(jobs, c, skipped);
1914 static int cancel_job(sd_bus *bus, char **args) {
1915 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1920 if (strv_length(args) <= 1)
1921 return daemon_reload(bus, args);
1923 STRV_FOREACH(name, args+1) {
1927 r = safe_atou32(*name, &id);
1929 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1933 r = sd_bus_call_method(
1935 "org.freedesktop.systemd1",
1936 "/org/freedesktop/systemd1",
1937 "org.freedesktop.systemd1.Manager",
1943 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1951 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1952 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1956 /* We ignore all errors here, since this is used to show a
1959 /* We don't use unit_dbus_path_from_name() directly since we
1960 * don't want to load the unit if it isn't loaded. */
1962 r = sd_bus_call_method(
1964 "org.freedesktop.systemd1",
1965 "/org/freedesktop/systemd1",
1966 "org.freedesktop.systemd1.Manager",
1974 r = sd_bus_message_read(reply, "o", &path);
1978 r = sd_bus_get_property_trivial(
1980 "org.freedesktop.systemd1",
1982 "org.freedesktop.systemd1.Unit",
1992 typedef struct WaitData {
1999 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
2006 log_debug("Got D-Bus request: %s.%s() on %s",
2007 sd_bus_message_get_interface(m),
2008 sd_bus_message_get_member(m),
2009 sd_bus_message_get_path(m));
2011 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
2012 log_error("Warning! D-Bus connection terminated.");
2014 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
2016 const char *path, *result, *unit;
2020 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
2022 ret = set_remove(d->set, (char*) path);
2028 if (!isempty(result))
2029 d->result = strdup(result);
2032 d->name = strdup(unit);
2037 r = sd_bus_message_read(m, "uos", &id, &path, &result);
2039 ret = set_remove(d->set, (char*) path);
2046 d->result = strdup(result);
2052 bus_log_parse_error(r);
2058 static int enable_wait_for_jobs(sd_bus *bus) {
2063 r = sd_bus_add_match(
2066 "sender='org.freedesktop.systemd1',"
2067 "interface='org.freedesktop.systemd1.Manager',"
2068 "member='JobRemoved',"
2069 "path='/org/freedesktop/systemd1'",
2072 log_error("Failed to add match");
2076 /* This is slightly dirty, since we don't undo the match registrations. */
2080 static int bus_process_wait(sd_bus *bus) {
2084 r = sd_bus_process(bus, NULL);
2089 r = sd_bus_wait(bus, (uint64_t) -1);
2095 static int check_wait_response(WaitData *d) {
2101 if (streq(d->result, "timeout"))
2102 log_error("Job for %s timed out.", strna(d->name));
2103 else if (streq(d->result, "canceled"))
2104 log_error("Job for %s canceled.", strna(d->name));
2105 else if (streq(d->result, "dependency"))
2106 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
2107 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2108 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
2111 if (streq(d->result, "timeout"))
2113 else if (streq(d->result, "canceled"))
2115 else if (streq(d->result, "dependency"))
2117 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
2123 static int wait_for_jobs(sd_bus *bus, Set *s) {
2124 WaitData d = { .set = s };
2130 q = sd_bus_add_filter(bus, wait_filter, &d);
2134 while (!set_isempty(s)) {
2135 q = bus_process_wait(bus);
2137 log_error("Failed to wait for response: %s", strerror(-r));
2142 q = check_wait_response(&d);
2143 /* Return the first error as it is most likely to be
2145 if (q < 0 && r == 0)
2147 log_debug("Got result %s/%s for job %s",
2148 strna(d.result), strerror(-q), strna(d.name));
2158 q = sd_bus_remove_filter(bus, wait_filter, &d);
2159 if (q < 0 && r == 0)
2165 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2166 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2167 _cleanup_free_ char *n = NULL, *state = NULL;
2173 n = unit_name_mangle(name, MANGLE_NOGLOB);
2177 /* We don't use unit_dbus_path_from_name() directly since we
2178 * don't want to load the unit if it isn't loaded. */
2180 r = sd_bus_call_method(
2182 "org.freedesktop.systemd1",
2183 "/org/freedesktop/systemd1",
2184 "org.freedesktop.systemd1.Manager",
2195 r = sd_bus_message_read(reply, "o", &path);
2197 return bus_log_parse_error(r);
2199 r = sd_bus_get_property_string(
2201 "org.freedesktop.systemd1",
2203 "org.freedesktop.systemd1.Unit",
2216 return nulstr_contains(good_states, state);
2219 static int check_triggering_units(
2223 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2224 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2225 _cleanup_strv_free_ char **triggered_by = NULL;
2226 bool print_warning_label = true;
2230 n = unit_name_mangle(name, MANGLE_NOGLOB);
2234 path = unit_dbus_path_from_name(n);
2238 r = sd_bus_get_property_string(
2240 "org.freedesktop.systemd1",
2242 "org.freedesktop.systemd1.Unit",
2247 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2251 if (streq(state, "masked"))
2254 r = sd_bus_get_property_strv(
2256 "org.freedesktop.systemd1",
2258 "org.freedesktop.systemd1.Unit",
2263 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2267 STRV_FOREACH(i, triggered_by) {
2268 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2270 log_error("Failed to check unit: %s", strerror(-r));
2277 if (print_warning_label) {
2278 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2279 print_warning_label = false;
2282 log_warning(" %s", *i);
2288 static const char *verb_to_method(const char *verb) {
2291 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2292 if (streq_ptr(unit_actions[i].verb, verb))
2293 return unit_actions[i].method;
2298 static const char *method_to_verb(const char *method) {
2301 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2302 if (streq_ptr(unit_actions[i].method, method))
2303 return unit_actions[i].verb;
2308 static int start_unit_one(
2313 sd_bus_error *error,
2316 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2325 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2326 r = sd_bus_call_method(
2328 "org.freedesktop.systemd1",
2329 "/org/freedesktop/systemd1",
2330 "org.freedesktop.systemd1.Manager",
2338 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2339 /* There's always a fallback possible for
2340 * legacy actions. */
2341 return -EADDRNOTAVAIL;
2343 verb = method_to_verb(method);
2345 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2349 r = sd_bus_message_read(reply, "o", &path);
2351 return bus_log_parse_error(r);
2353 if (need_daemon_reload(bus, name) > 0)
2354 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2355 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2364 log_debug("Adding %s to the set", p);
2365 r = set_consume(s, p);
2373 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2375 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2376 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2380 STRV_FOREACH(name, names) {
2384 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2386 t = unit_name_mangle(*name, MANGLE_GLOB);
2390 if (string_is_glob(t))
2391 r = strv_consume(&globs, t);
2393 r = strv_consume(&mangled, t);
2398 /* Query the manager only if any of the names are a glob, since
2399 * this is fairly expensive */
2400 if (!strv_isempty(globs)) {
2401 _cleanup_free_ UnitInfo *unit_infos = NULL;
2403 r = get_unit_list(bus, &reply, &unit_infos, globs);
2407 for (i = 0; i < r; i++)
2408 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2413 mangled = NULL; /* do not free */
2417 static const struct {
2421 } action_table[_ACTION_MAX] = {
2422 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2423 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2424 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2425 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2426 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2427 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2428 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2429 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2430 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2431 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2432 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2433 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2434 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2435 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2436 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2439 static enum action verb_to_action(const char *verb) {
2442 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2443 if (streq_ptr(action_table[i].verb, verb))
2446 return _ACTION_INVALID;
2449 static int start_unit(sd_bus *bus, char **args) {
2450 _cleanup_set_free_free_ Set *s = NULL;
2451 _cleanup_strv_free_ char **names = NULL;
2452 const char *method, *mode, *one_name;
2458 ask_password_agent_open_if_enabled();
2460 if (arg_action == ACTION_SYSTEMCTL) {
2462 method = verb_to_method(args[0]);
2463 action = verb_to_action(args[0]);
2465 mode = streq(args[0], "isolate") ? "isolate" :
2466 action_table[action].mode ?: arg_job_mode;
2468 one_name = action_table[action].target;
2470 assert(arg_action < ELEMENTSOF(action_table));
2471 assert(action_table[arg_action].target);
2473 method = "StartUnit";
2475 mode = action_table[arg_action].mode;
2476 one_name = action_table[arg_action].target;
2480 names = strv_new(one_name, NULL);
2482 r = expand_names(bus, args + 1, NULL, &names);
2484 log_error("Failed to expand names: %s", strerror(-r));
2487 if (!arg_no_block) {
2488 r = enable_wait_for_jobs(bus);
2490 log_error("Could not watch jobs: %s", strerror(-r));
2494 s = set_new(string_hash_func, string_compare_func);
2499 STRV_FOREACH(name, names) {
2500 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2503 q = start_unit_one(bus, method, *name, mode, &error, s);
2504 if (r >= 0 && q < 0)
2505 r = translate_bus_error_to_exit_status(q, &error);
2508 if (!arg_no_block) {
2511 q = wait_for_jobs(bus, s);
2515 /* When stopping units, warn if they can still be triggered by
2516 * another active unit (socket, path, timer) */
2517 if (!arg_quiet && streq(method, "StopUnit"))
2518 STRV_FOREACH(name, names)
2519 check_triggering_units(bus, *name);
2525 /* Ask systemd-logind, which might grant access to unprivileged users
2526 * through PolicyKit */
2527 static int reboot_with_logind(sd_bus *bus, enum action a) {
2529 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2536 polkit_agent_open_if_enabled();
2544 case ACTION_POWEROFF:
2545 method = "PowerOff";
2548 case ACTION_SUSPEND:
2552 case ACTION_HIBERNATE:
2553 method = "Hibernate";
2556 case ACTION_HYBRID_SLEEP:
2557 method = "HybridSleep";
2564 r = sd_bus_call_method(
2566 "org.freedesktop.login1",
2567 "/org/freedesktop/login1",
2568 "org.freedesktop.login1.Manager",
2574 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2582 static int check_inhibitors(sd_bus *bus, enum action a) {
2584 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2585 _cleanup_strv_free_ char **sessions = NULL;
2586 const char *what, *who, *why, *mode;
2595 if (arg_ignore_inhibitors || arg_force > 0)
2607 r = sd_bus_call_method(
2609 "org.freedesktop.login1",
2610 "/org/freedesktop/login1",
2611 "org.freedesktop.login1.Manager",
2617 /* If logind is not around, then there are no inhibitors... */
2620 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2622 return bus_log_parse_error(r);
2624 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2625 _cleanup_free_ char *comm = NULL, *user = NULL;
2626 _cleanup_strv_free_ char **sv = NULL;
2628 if (!streq(mode, "block"))
2631 sv = strv_split(what, ":");
2635 if (!strv_contains(sv,
2637 a == ACTION_POWEROFF ||
2638 a == ACTION_REBOOT ||
2639 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2642 get_process_comm(pid, &comm);
2643 user = uid_to_name(uid);
2645 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2646 who, (unsigned long) pid, strna(comm), strna(user), why);
2651 return bus_log_parse_error(r);
2653 r = sd_bus_message_exit_container(reply);
2655 return bus_log_parse_error(r);
2657 /* Check for current sessions */
2658 sd_get_sessions(&sessions);
2659 STRV_FOREACH(s, sessions) {
2660 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2662 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2665 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2668 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2671 sd_session_get_tty(*s, &tty);
2672 sd_session_get_seat(*s, &seat);
2673 sd_session_get_service(*s, &service);
2674 user = uid_to_name(uid);
2676 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2683 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2684 action_table[a].verb);
2692 static int start_special(sd_bus *bus, char **args) {
2698 a = verb_to_action(args[0]);
2700 r = check_inhibitors(bus, a);
2704 if (arg_force >= 2 && geteuid() != 0) {
2705 log_error("Must be root.");
2709 if (arg_force >= 2 &&
2710 (a == ACTION_HALT ||
2711 a == ACTION_POWEROFF ||
2712 a == ACTION_REBOOT))
2715 if (arg_force >= 1 &&
2716 (a == ACTION_HALT ||
2717 a == ACTION_POWEROFF ||
2718 a == ACTION_REBOOT ||
2719 a == ACTION_KEXEC ||
2721 return daemon_reload(bus, args);
2723 /* first try logind, to allow authentication with polkit */
2724 if (geteuid() != 0 &&
2725 (a == ACTION_POWEROFF ||
2726 a == ACTION_REBOOT ||
2727 a == ACTION_SUSPEND ||
2728 a == ACTION_HIBERNATE ||
2729 a == ACTION_HYBRID_SLEEP)) {
2730 r = reboot_with_logind(bus, a);
2735 r = start_unit(bus, args);
2736 if (r == EXIT_SUCCESS)
2742 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2743 _cleanup_strv_free_ char **names = NULL;
2750 r = expand_names(bus, args, NULL, &names);
2752 log_error("Failed to expand names: %s", strerror(-r));
2756 STRV_FOREACH(name, names) {
2759 state = check_one_unit(bus, *name, good_states, arg_quiet);
2769 static int check_unit_active(sd_bus *bus, char **args) {
2770 /* According to LSB: 3, "program is not running" */
2771 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2774 static int check_unit_failed(sd_bus *bus, char **args) {
2775 return check_unit_generic(bus, 1, "failed\0", args + 1);
2778 static int kill_unit(sd_bus *bus, char **args) {
2779 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2780 _cleanup_strv_free_ char **names = NULL;
2788 arg_kill_who = "all";
2790 r = expand_names(bus, args + 1, NULL, &names);
2792 log_error("Failed to expand names: %s", strerror(-r));
2794 STRV_FOREACH(name, names) {
2795 q = sd_bus_call_method(
2797 "org.freedesktop.systemd1",
2798 "/org/freedesktop/systemd1",
2799 "org.freedesktop.systemd1.Manager",
2803 "ssi", *names, arg_kill_who, arg_signal);
2805 log_error("Failed to kill unit %s: %s",
2806 *names, bus_error_message(&error, r));
2815 typedef struct ExecStatusInfo {
2823 usec_t start_timestamp;
2824 usec_t exit_timestamp;
2829 LIST_FIELDS(struct ExecStatusInfo, exec);
2832 static void exec_status_info_free(ExecStatusInfo *i) {
2841 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2842 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2845 int32_t code, status;
2851 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2853 return bus_log_parse_error(r);
2857 r = sd_bus_message_read(m, "s", &path);
2859 return bus_log_parse_error(r);
2861 i->path = strdup(path);
2865 r = sd_bus_message_read_strv(m, &i->argv);
2867 return bus_log_parse_error(r);
2869 r = sd_bus_message_read(m,
2872 &start_timestamp, &start_timestamp_monotonic,
2873 &exit_timestamp, &exit_timestamp_monotonic,
2877 return bus_log_parse_error(r);
2880 i->start_timestamp = (usec_t) start_timestamp;
2881 i->exit_timestamp = (usec_t) exit_timestamp;
2882 i->pid = (pid_t) pid;
2886 r = sd_bus_message_exit_container(m);
2888 return bus_log_parse_error(r);
2893 typedef struct UnitStatusInfo {
2895 const char *load_state;
2896 const char *active_state;
2897 const char *sub_state;
2898 const char *unit_file_state;
2900 const char *description;
2901 const char *following;
2903 char **documentation;
2905 const char *fragment_path;
2906 const char *source_path;
2907 const char *control_group;
2909 char **dropin_paths;
2911 const char *load_error;
2914 usec_t inactive_exit_timestamp;
2915 usec_t inactive_exit_timestamp_monotonic;
2916 usec_t active_enter_timestamp;
2917 usec_t active_exit_timestamp;
2918 usec_t inactive_enter_timestamp;
2920 bool need_daemon_reload;
2925 const char *status_text;
2926 const char *pid_file;
2929 usec_t start_timestamp;
2930 usec_t exit_timestamp;
2932 int exit_code, exit_status;
2934 usec_t condition_timestamp;
2935 bool condition_result;
2936 bool failed_condition_trigger;
2937 bool failed_condition_negate;
2938 const char *failed_condition;
2939 const char *failed_condition_param;
2942 unsigned n_accepted;
2943 unsigned n_connections;
2946 /* Pairs of type, path */
2950 const char *sysfs_path;
2952 /* Mount, Automount */
2958 LIST_HEAD(ExecStatusInfo, exec);
2961 static void print_status_info(
2966 const char *active_on, *active_off, *on, *off, *ss;
2968 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2969 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2972 arg_all * OUTPUT_SHOW_ALL |
2973 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2974 on_tty() * OUTPUT_COLOR |
2975 !arg_quiet * OUTPUT_WARN_CUTOFF |
2976 arg_full * OUTPUT_FULL_WIDTH;
2981 /* This shows pretty information about a unit. See
2982 * print_property() for a low-level property printer */
2984 if (streq_ptr(i->active_state, "failed")) {
2985 active_on = ansi_highlight_red();
2986 active_off = ansi_highlight_off();
2987 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2988 active_on = ansi_highlight_green();
2989 active_off = ansi_highlight_off();
2991 active_on = active_off = "";
2993 printf("%s%s%s%s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
2995 if (i->description && !streq_ptr(i->id, i->description))
2996 printf(" - %s", i->description);
3001 printf(" Follow: unit currently follows state of %s\n", i->following);
3003 if (streq_ptr(i->load_state, "error")) {
3004 on = ansi_highlight_red();
3005 off = ansi_highlight_off();
3009 path = i->source_path ? i->source_path : i->fragment_path;
3012 printf(" Loaded: %s%s%s (Reason: %s)\n",
3013 on, strna(i->load_state), off, i->load_error);
3014 else if (path && i->unit_file_state)
3015 printf(" Loaded: %s%s%s (%s; %s)\n",
3016 on, strna(i->load_state), off, path, i->unit_file_state);
3018 printf(" Loaded: %s%s%s (%s)\n",
3019 on, strna(i->load_state), off, path);
3021 printf(" Loaded: %s%s%s\n",
3022 on, strna(i->load_state), off);
3024 if (!strv_isempty(i->dropin_paths)) {
3025 _cleanup_free_ char *dir = NULL;
3029 STRV_FOREACH(dropin, i->dropin_paths) {
3030 if (! dir || last) {
3031 printf(dir ? " " : " Drop-In: ");
3036 if (path_get_parent(*dropin, &dir) < 0) {
3041 printf("%s\n %s", dir,
3042 draw_special_char(DRAW_TREE_RIGHT));
3045 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3047 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3051 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3053 printf(" Active: %s%s (%s)%s",
3054 active_on, strna(i->active_state), ss, active_off);
3056 printf(" Active: %s%s%s",
3057 active_on, strna(i->active_state), active_off);
3059 if (!isempty(i->result) && !streq(i->result, "success"))
3060 printf(" (Result: %s)", i->result);
3062 timestamp = (streq_ptr(i->active_state, "active") ||
3063 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3064 (streq_ptr(i->active_state, "inactive") ||
3065 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3066 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3067 i->active_exit_timestamp;
3069 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3070 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3073 printf(" since %s; %s\n", s2, s1);
3075 printf(" since %s\n", s2);
3079 if (!i->condition_result && i->condition_timestamp > 0) {
3080 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3081 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3083 printf(" start condition failed at %s%s%s\n",
3084 s2, s1 ? "; " : "", s1 ? s1 : "");
3085 if (i->failed_condition_trigger)
3086 printf(" none of the trigger conditions were met\n");
3087 else if (i->failed_condition)
3088 printf(" %s=%s%s was not met\n",
3089 i->failed_condition,
3090 i->failed_condition_negate ? "!" : "",
3091 i->failed_condition_param);
3095 printf(" Device: %s\n", i->sysfs_path);
3097 printf(" Where: %s\n", i->where);
3099 printf(" What: %s\n", i->what);
3101 STRV_FOREACH(t, i->documentation)
3102 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3104 STRV_FOREACH_PAIR(t, t2, i->listen)
3105 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3108 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3110 LIST_FOREACH(exec, p, i->exec) {
3111 _cleanup_free_ char *argv = NULL;
3114 /* Only show exited processes here */
3118 argv = strv_join(p->argv, " ");
3119 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
3121 good = is_clean_exit_lsb(p->code, p->status, NULL);
3123 on = ansi_highlight_red();
3124 off = ansi_highlight_off();
3128 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3130 if (p->code == CLD_EXITED) {
3133 printf("status=%i", p->status);
3135 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3140 printf("signal=%s", signal_to_string(p->status));
3142 printf(")%s\n", off);
3144 if (i->main_pid == p->pid &&
3145 i->start_timestamp == p->start_timestamp &&
3146 i->exit_timestamp == p->start_timestamp)
3147 /* Let's not show this twice */
3150 if (p->pid == i->control_pid)
3154 if (i->main_pid > 0 || i->control_pid > 0) {
3155 if (i->main_pid > 0) {
3156 printf(" Main PID: %u", (unsigned) i->main_pid);
3159 _cleanup_free_ char *comm = NULL;
3160 get_process_comm(i->main_pid, &comm);
3162 printf(" (%s)", comm);
3163 } else if (i->exit_code > 0) {
3164 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3166 if (i->exit_code == CLD_EXITED) {
3169 printf("status=%i", i->exit_status);
3171 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3176 printf("signal=%s", signal_to_string(i->exit_status));
3180 if (i->control_pid > 0)
3184 if (i->control_pid > 0) {
3185 _cleanup_free_ char *c = NULL;
3187 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
3189 get_process_comm(i->control_pid, &c);
3198 printf(" Status: \"%s\"\n", i->status_text);
3200 if (i->control_group &&
3201 (i->main_pid > 0 || i->control_pid > 0 ||
3202 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_CONTAINER) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3205 printf(" CGroup: %s\n", i->control_group);
3207 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
3210 static const char prefix[] = " ";
3213 if (c > sizeof(prefix) - 1)
3214 c -= sizeof(prefix) - 1;
3218 if (i->main_pid > 0)
3219 extra[k++] = i->main_pid;
3221 if (i->control_pid > 0)
3222 extra[k++] = i->control_pid;
3224 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, flags);
3228 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3229 show_journal_by_unit(stdout,
3233 i->inactive_exit_timestamp_monotonic,
3236 flags | OUTPUT_BEGIN_NEWLINE,
3237 arg_scope == UNIT_FILE_SYSTEM,
3241 if (i->need_daemon_reload)
3242 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3243 ansi_highlight_red(),
3244 ansi_highlight_off(),
3245 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3248 static void show_unit_help(UnitStatusInfo *i) {
3253 if (!i->documentation) {
3254 log_info("Documentation for %s not known.", i->id);
3258 STRV_FOREACH(p, i->documentation) {
3260 if (startswith(*p, "man:")) {
3261 const char *args[4] = { "man", NULL, NULL, NULL };
3262 _cleanup_free_ char *page = NULL, *section = NULL;
3269 if ((*p)[k-1] == ')')
3270 e = strrchr(*p, '(');
3273 page = strndup((*p) + 4, e - *p - 4);
3274 section = strndup(e + 1, *p + k - e - 2);
3275 if (!page || !section) {
3287 log_error("Failed to fork: %m");
3293 execvp(args[0], (char**) args);
3294 log_error("Failed to execute man: %m");
3295 _exit(EXIT_FAILURE);
3298 wait_for_terminate(pid, NULL);
3300 log_info("Can't show: %s", *p);
3304 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3311 switch (contents[0]) {
3313 case SD_BUS_TYPE_STRING: {
3316 r = sd_bus_message_read(m, "s", &s);
3318 return bus_log_parse_error(r);
3321 if (streq(name, "Id"))
3323 else if (streq(name, "LoadState"))
3325 else if (streq(name, "ActiveState"))
3326 i->active_state = s;
3327 else if (streq(name, "SubState"))
3329 else if (streq(name, "Description"))
3331 else if (streq(name, "FragmentPath"))
3332 i->fragment_path = s;
3333 else if (streq(name, "SourcePath"))
3336 else if (streq(name, "DefaultControlGroup")) {
3338 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3340 i->control_group = e;
3343 else if (streq(name, "ControlGroup"))
3344 i->control_group = s;
3345 else if (streq(name, "StatusText"))
3347 else if (streq(name, "PIDFile"))
3349 else if (streq(name, "SysFSPath"))
3351 else if (streq(name, "Where"))
3353 else if (streq(name, "What"))
3355 else if (streq(name, "Following"))
3357 else if (streq(name, "UnitFileState"))
3358 i->unit_file_state = s;
3359 else if (streq(name, "Result"))
3366 case SD_BUS_TYPE_BOOLEAN: {
3369 r = sd_bus_message_read(m, "b", &b);
3371 return bus_log_parse_error(r);
3373 if (streq(name, "Accept"))
3375 else if (streq(name, "NeedDaemonReload"))
3376 i->need_daemon_reload = b;
3377 else if (streq(name, "ConditionResult"))
3378 i->condition_result = b;
3383 case SD_BUS_TYPE_UINT32: {
3386 r = sd_bus_message_read(m, "u", &u);
3388 return bus_log_parse_error(r);
3390 if (streq(name, "MainPID")) {
3392 i->main_pid = (pid_t) u;
3395 } else if (streq(name, "ControlPID"))
3396 i->control_pid = (pid_t) u;
3397 else if (streq(name, "ExecMainPID")) {
3399 i->main_pid = (pid_t) u;
3400 } else if (streq(name, "NAccepted"))
3402 else if (streq(name, "NConnections"))
3403 i->n_connections = u;
3408 case SD_BUS_TYPE_INT32: {
3411 r = sd_bus_message_read(m, "i", &j);
3413 return bus_log_parse_error(r);
3415 if (streq(name, "ExecMainCode"))
3416 i->exit_code = (int) j;
3417 else if (streq(name, "ExecMainStatus"))
3418 i->exit_status = (int) j;
3423 case SD_BUS_TYPE_UINT64: {
3426 r = sd_bus_message_read(m, "t", &u);
3428 return bus_log_parse_error(r);
3430 if (streq(name, "ExecMainStartTimestamp"))
3431 i->start_timestamp = (usec_t) u;
3432 else if (streq(name, "ExecMainExitTimestamp"))
3433 i->exit_timestamp = (usec_t) u;
3434 else if (streq(name, "ActiveEnterTimestamp"))
3435 i->active_enter_timestamp = (usec_t) u;
3436 else if (streq(name, "InactiveEnterTimestamp"))
3437 i->inactive_enter_timestamp = (usec_t) u;
3438 else if (streq(name, "InactiveExitTimestamp"))
3439 i->inactive_exit_timestamp = (usec_t) u;
3440 else if (streq(name, "InactiveExitTimestampMonotonic"))
3441 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3442 else if (streq(name, "ActiveExitTimestamp"))
3443 i->active_exit_timestamp = (usec_t) u;
3444 else if (streq(name, "ConditionTimestamp"))
3445 i->condition_timestamp = (usec_t) u;
3450 case SD_BUS_TYPE_ARRAY:
3452 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3453 _cleanup_free_ ExecStatusInfo *info = NULL;
3455 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3457 return bus_log_parse_error(r);
3459 info = new0(ExecStatusInfo, 1);
3463 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3465 info->name = strdup(name);
3469 LIST_PREPEND(exec, i->exec, info);
3471 info = new0(ExecStatusInfo, 1);
3477 return bus_log_parse_error(r);
3479 r = sd_bus_message_exit_container(m);
3481 return bus_log_parse_error(r);
3485 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3486 const char *type, *path;
3488 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3490 return bus_log_parse_error(r);
3492 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3494 r = strv_extend(&i->listen, type);
3498 r = strv_extend(&i->listen, path);
3503 return bus_log_parse_error(r);
3505 r = sd_bus_message_exit_container(m);
3507 return bus_log_parse_error(r);
3511 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3513 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3515 return bus_log_parse_error(r);
3517 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3519 r = sd_bus_message_read_strv(m, &i->documentation);
3521 return bus_log_parse_error(r);
3523 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3524 const char *cond, *param;
3525 int trigger, negate;
3528 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3530 return bus_log_parse_error(r);
3532 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3533 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3534 if (state < 0 && (!trigger || !i->failed_condition)) {
3535 i->failed_condition = cond;
3536 i->failed_condition_trigger = trigger;
3537 i->failed_condition_negate = negate;
3538 i->failed_condition_param = param;
3542 return bus_log_parse_error(r);
3544 r = sd_bus_message_exit_container(m);
3546 return bus_log_parse_error(r);
3553 case SD_BUS_TYPE_STRUCT_BEGIN:
3555 if (streq(name, "LoadError")) {
3556 const char *n, *message;
3558 r = sd_bus_message_read(m, "(ss)", &n, &message);
3560 return bus_log_parse_error(r);
3562 if (!isempty(message))
3563 i->load_error = message;
3576 r = sd_bus_message_skip(m, contents);
3578 return bus_log_parse_error(r);
3583 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3589 /* This is a low-level property printer, see
3590 * print_status_info() for the nicer output */
3592 if (arg_properties && !strv_find(arg_properties, name)) {
3593 /* skip what we didn't read */
3594 r = sd_bus_message_skip(m, contents);
3598 switch (contents[0]) {
3600 case SD_BUS_TYPE_STRUCT_BEGIN:
3602 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3605 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3607 return bus_log_parse_error(r);
3610 printf("%s=%u\n", name, (unsigned) u);
3612 printf("%s=\n", name);
3616 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3619 r = sd_bus_message_read(m, "(so)", &s, NULL);
3621 return bus_log_parse_error(r);
3623 if (arg_all || !isempty(s))
3624 printf("%s=%s\n", name, s);
3628 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3629 const char *a = NULL, *b = NULL;
3631 r = sd_bus_message_read(m, "(ss)", &a, &b);
3633 return bus_log_parse_error(r);
3635 if (arg_all || !isempty(a) || !isempty(b))
3636 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3639 } else if (streq_ptr(name, "SystemCallFilter")) {
3640 _cleanup_strv_free_ char **l = NULL;
3643 r = sd_bus_message_enter_container(m, 'r', "bas");
3645 return bus_log_parse_error(r);
3647 r = sd_bus_message_read(m, "b", &whitelist);
3649 return bus_log_parse_error(r);
3651 r = sd_bus_message_read_strv(m, &l);
3653 return bus_log_parse_error(r);
3655 r = sd_bus_message_exit_container(m);
3657 return bus_log_parse_error(r);
3659 if (arg_all || whitelist || !strv_isempty(l)) {
3663 fputs(name, stdout);
3669 STRV_FOREACH(i, l) {
3677 fputc('\n', stdout);
3685 case SD_BUS_TYPE_ARRAY:
3687 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3691 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3693 return bus_log_parse_error(r);
3695 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3696 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3699 return bus_log_parse_error(r);
3701 r = sd_bus_message_exit_container(m);
3703 return bus_log_parse_error(r);
3707 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3708 const char *type, *path;
3710 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3712 return bus_log_parse_error(r);
3714 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3715 printf("%s=%s\n", type, path);
3717 return bus_log_parse_error(r);
3719 r = sd_bus_message_exit_container(m);
3721 return bus_log_parse_error(r);
3725 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3726 const char *type, *path;
3728 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3730 return bus_log_parse_error(r);
3732 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3733 printf("Listen%s=%s\n", type, path);
3735 return bus_log_parse_error(r);
3737 r = sd_bus_message_exit_container(m);
3739 return bus_log_parse_error(r);
3743 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3745 uint64_t value, next_elapse;
3747 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3749 return bus_log_parse_error(r);
3751 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3752 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3754 printf("%s={ value=%s ; next_elapse=%s }\n",
3756 format_timespan(timespan1, sizeof(timespan1), value, 0),
3757 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3760 return bus_log_parse_error(r);
3762 r = sd_bus_message_exit_container(m);
3764 return bus_log_parse_error(r);
3768 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3769 ExecStatusInfo info = {};
3771 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3773 return bus_log_parse_error(r);
3775 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3776 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3777 _cleanup_free_ char *tt;
3779 tt = strv_join(info.argv, " ");
3781 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3785 yes_no(info.ignore),
3786 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3787 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3788 (unsigned) info. pid,
3789 sigchld_code_to_string(info.code),
3791 info.code == CLD_EXITED ? "" : "/",
3792 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3795 strv_free(info.argv);
3799 r = sd_bus_message_exit_container(m);
3801 return bus_log_parse_error(r);
3805 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3806 const char *path, *rwm;
3808 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3810 return bus_log_parse_error(r);
3812 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3813 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3815 return bus_log_parse_error(r);
3817 r = sd_bus_message_exit_container(m);
3819 return bus_log_parse_error(r);
3823 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3827 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3829 return bus_log_parse_error(r);
3831 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3832 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3834 return bus_log_parse_error(r);
3836 r = sd_bus_message_exit_container(m);
3838 return bus_log_parse_error(r);
3842 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3846 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3848 return bus_log_parse_error(r);
3850 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3851 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3853 return bus_log_parse_error(r);
3855 r = sd_bus_message_exit_container(m);
3857 return bus_log_parse_error(r);
3865 r = bus_print_property(name, m, arg_all);
3867 return bus_log_parse_error(r);
3870 r = sd_bus_message_skip(m, contents);
3872 return bus_log_parse_error(r);
3875 printf("%s=[unprintable]\n", name);
3881 static int show_one(
3885 bool show_properties,
3889 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3890 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3891 UnitStatusInfo info = {};
3898 log_debug("Showing one %s", path);
3900 r = sd_bus_call_method(
3902 "org.freedesktop.systemd1",
3904 "org.freedesktop.DBus.Properties",
3910 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3914 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3916 return bus_log_parse_error(r);
3923 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3924 const char *name, *contents;
3926 r = sd_bus_message_read(reply, "s", &name);
3928 return bus_log_parse_error(r);
3930 r = sd_bus_message_peek_type(reply, NULL, &contents);
3932 return bus_log_parse_error(r);
3934 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3936 return bus_log_parse_error(r);
3938 if (show_properties)
3939 r = print_property(name, reply, contents);
3941 r = status_property(name, reply, &info, contents);
3945 r = sd_bus_message_exit_container(reply);
3947 return bus_log_parse_error(r);
3949 r = sd_bus_message_exit_container(reply);
3951 return bus_log_parse_error(r);
3954 return bus_log_parse_error(r);
3956 r = sd_bus_message_exit_container(reply);
3958 return bus_log_parse_error(r);
3962 if (!show_properties) {
3963 if (streq(verb, "help"))
3964 show_unit_help(&info);
3966 print_status_info(&info, ellipsized);
3969 strv_free(info.documentation);
3970 strv_free(info.dropin_paths);
3971 strv_free(info.listen);
3973 if (!streq_ptr(info.active_state, "active") &&
3974 !streq_ptr(info.active_state, "reloading") &&
3975 streq(verb, "status")) {
3976 /* According to LSB: "program not running" */
3977 /* 0: program is running or service is OK
3978 * 1: program is dead and /run PID file exists
3979 * 2: program is dead and /run/lock lock file exists
3980 * 3: program is not running
3981 * 4: program or service status is unknown
3983 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3989 while ((p = info.exec)) {
3990 LIST_REMOVE(exec, info.exec, p);
3991 exec_status_info_free(p);
3997 static int get_unit_dbus_path_by_pid(
4002 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4003 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4007 r = sd_bus_call_method(
4009 "org.freedesktop.systemd1",
4010 "/org/freedesktop/systemd1",
4011 "org.freedesktop.systemd1.Manager",
4017 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
4021 r = sd_bus_message_read(reply, "o", &u);
4023 return bus_log_parse_error(r);
4033 static int show_all(
4036 bool show_properties,
4040 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4041 _cleanup_free_ UnitInfo *unit_infos = NULL;
4046 r = get_unit_list(bus, &reply, &unit_infos, NULL);
4050 pager_open_if_enabled();
4054 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4056 for (u = unit_infos; u < unit_infos + c; u++) {
4057 _cleanup_free_ char *p = NULL;
4059 p = unit_dbus_path_from_name(u->id);
4063 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4071 static int show_system_status(sd_bus *bus) {
4072 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4073 _cleanup_free_ char *hn = NULL;
4074 struct machine_info mi = {};
4075 const char *on, *off;
4078 hn = gethostname_malloc();
4082 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4084 log_error("Failed to read server status: %s", strerror(-r));
4088 if (streq_ptr(mi.state, "degraded")) {
4089 on = ansi_highlight_red();
4090 off = ansi_highlight_off();
4091 } else if (!streq_ptr(mi.state, "running")) {
4092 on = ansi_highlight_yellow();
4093 off = ansi_highlight_off();
4097 printf("%s%s%s%s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4099 printf(" State: %s%s%s\n",
4100 on, strna(mi.state), off);
4102 printf(" Jobs: %u queued\n", mi.n_jobs);
4103 printf(" Failed: %u units\n", mi.n_failed_units);
4105 printf(" Since: %s; %s\n",
4106 format_timestamp(since2, sizeof(since2), mi.timestamp),
4107 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4109 printf(" CGroup: %s\n", mi.control_group ?: "/");
4110 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
4112 arg_all * OUTPUT_SHOW_ALL |
4113 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
4114 on_tty() * OUTPUT_COLOR |
4115 !arg_quiet * OUTPUT_WARN_CUTOFF |
4116 arg_full * OUTPUT_FULL_WIDTH;
4118 static const char prefix[] = " ";
4122 if (c > sizeof(prefix) - 1)
4123 c -= sizeof(prefix) - 1;
4127 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, flags);
4131 free(mi.control_group);
4136 static int show(sd_bus *bus, char **args) {
4137 bool show_properties, show_status, new_line = false;
4138 bool ellipsized = false;
4144 show_properties = streq(args[0], "show");
4145 show_status = streq(args[0], "status");
4147 if (show_properties)
4148 pager_open_if_enabled();
4150 /* If no argument is specified inspect the manager itself */
4152 if (show_properties && strv_length(args) <= 1)
4153 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4155 if (show_status && strv_length(args) <= 1) {
4158 pager_open_if_enabled();
4160 show_system_status(bus);
4164 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4166 _cleanup_free_ char **patterns = NULL;
4169 STRV_FOREACH(name, args + 1) {
4170 _cleanup_free_ char *unit = NULL;
4173 if (safe_atou32(*name, &id) < 0) {
4174 if (strv_push(&patterns, *name) < 0)
4178 } else if (show_properties) {
4179 /* Interpret as job id */
4180 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4184 /* Interpret as PID */
4185 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4192 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4195 if (!strv_isempty(patterns)) {
4196 _cleanup_strv_free_ char **names = NULL;
4198 r = expand_names(bus, patterns, NULL, &names);
4200 log_error("Failed to expand names: %s", strerror(-r));
4202 STRV_FOREACH(name, names) {
4203 _cleanup_free_ char *unit;
4205 unit = unit_dbus_path_from_name(*name);
4209 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
4214 if (ellipsized && !arg_quiet)
4215 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4220 static int cat(sd_bus *bus, char **args) {
4221 _cleanup_free_ char *unit = NULL;
4222 _cleanup_strv_free_ char **names = NULL;
4230 r = expand_names(bus, args + 1, NULL, &names);
4232 log_error("Failed to expand names: %s", strerror(-r));
4234 pager_open_if_enabled();
4236 STRV_FOREACH(name, names) {
4237 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4238 _cleanup_strv_free_ char **dropin_paths = NULL;
4239 _cleanup_free_ char *fragment_path = NULL;
4242 unit = unit_dbus_path_from_name(*name);
4246 if (need_daemon_reload(bus, *name) > 0)
4247 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
4248 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
4250 r = sd_bus_get_property_string(
4252 "org.freedesktop.systemd1",
4254 "org.freedesktop.systemd1.Unit",
4259 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
4263 r = sd_bus_get_property_strv(
4265 "org.freedesktop.systemd1",
4267 "org.freedesktop.systemd1.Unit",
4272 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
4281 if (!isempty(fragment_path)) {
4282 printf("%s# %s%s\n",
4283 ansi_highlight_blue(),
4285 ansi_highlight_off());
4288 r = sendfile_full(STDOUT_FILENO, fragment_path);
4290 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
4295 STRV_FOREACH(path, dropin_paths) {
4296 printf("%s%s# %s%s\n",
4297 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4298 ansi_highlight_blue(),
4300 ansi_highlight_off());
4303 r = sendfile_full(STDOUT_FILENO, *path);
4305 log_warning("Failed to cat %s: %s", *path, strerror(-r));
4311 return r < 0 ? r : 0;
4314 static int set_property(sd_bus *bus, char **args) {
4315 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4316 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4317 _cleanup_free_ char *n = NULL;
4321 r = sd_bus_message_new_method_call(
4324 "org.freedesktop.systemd1",
4325 "/org/freedesktop/systemd1",
4326 "org.freedesktop.systemd1.Manager",
4327 "SetUnitProperties");
4329 return bus_log_create_error(r);
4331 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4335 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4337 return bus_log_create_error(r);
4339 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4341 return bus_log_create_error(r);
4343 STRV_FOREACH(i, args + 2) {
4344 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4346 return bus_log_create_error(r);
4348 r = bus_append_unit_property_assignment(m, *i);
4352 r = sd_bus_message_close_container(m);
4354 return bus_log_create_error(r);
4357 r = sd_bus_message_close_container(m);
4359 return bus_log_create_error(r);
4361 r = sd_bus_call(bus, m, 0, &error, NULL);
4363 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4370 static int snapshot(sd_bus *bus, char **args) {
4371 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4372 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4373 _cleanup_free_ char *n = NULL, *id = NULL;
4377 if (strv_length(args) > 1)
4378 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4384 r = sd_bus_call_method(
4386 "org.freedesktop.systemd1",
4387 "/org/freedesktop/systemd1",
4388 "org.freedesktop.systemd1.Manager",
4394 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4398 r = sd_bus_message_read(reply, "o", &path);
4400 return bus_log_parse_error(r);
4402 r = sd_bus_get_property_string(
4404 "org.freedesktop.systemd1",
4406 "org.freedesktop.systemd1.Unit",
4411 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4421 static int delete_snapshot(sd_bus *bus, char **args) {
4422 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4423 _cleanup_strv_free_ char **names = NULL;
4429 r = expand_names(bus, args + 1, ".snapshot", &names);
4431 log_error("Failed to expand names: %s", strerror(-r));
4433 STRV_FOREACH(name, names) {
4434 q = sd_bus_call_method(
4436 "org.freedesktop.systemd1",
4437 "/org/freedesktop/systemd1",
4438 "org.freedesktop.systemd1.Manager",
4444 log_error("Failed to remove snapshot %s: %s",
4445 *name, bus_error_message(&error, r));
4454 static int daemon_reload(sd_bus *bus, char **args) {
4455 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4459 if (arg_action == ACTION_RELOAD)
4461 else if (arg_action == ACTION_REEXEC)
4462 method = "Reexecute";
4464 assert(arg_action == ACTION_SYSTEMCTL);
4467 streq(args[0], "clear-jobs") ||
4468 streq(args[0], "cancel") ? "ClearJobs" :
4469 streq(args[0], "daemon-reexec") ? "Reexecute" :
4470 streq(args[0], "reset-failed") ? "ResetFailed" :
4471 streq(args[0], "halt") ? "Halt" :
4472 streq(args[0], "poweroff") ? "PowerOff" :
4473 streq(args[0], "reboot") ? "Reboot" :
4474 streq(args[0], "kexec") ? "KExec" :
4475 streq(args[0], "exit") ? "Exit" :
4476 /* "daemon-reload" */ "Reload";
4479 r = sd_bus_call_method(
4481 "org.freedesktop.systemd1",
4482 "/org/freedesktop/systemd1",
4483 "org.freedesktop.systemd1.Manager",
4489 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4490 /* There's always a fallback possible for
4491 * legacy actions. */
4493 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4494 /* On reexecution, we expect a disconnect, not a
4498 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4500 return r < 0 ? r : 0;
4503 static int reset_failed(sd_bus *bus, char **args) {
4504 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4505 _cleanup_strv_free_ char **names = NULL;
4509 if (strv_length(args) <= 1)
4510 return daemon_reload(bus, args);
4512 r = expand_names(bus, args + 1, NULL, &names);
4514 log_error("Failed to expand names: %s", strerror(-r));
4516 STRV_FOREACH(name, names) {
4517 q = sd_bus_call_method(
4519 "org.freedesktop.systemd1",
4520 "/org/freedesktop/systemd1",
4521 "org.freedesktop.systemd1.Manager",
4527 log_error("Failed to reset failed state of unit %s: %s",
4528 *name, bus_error_message(&error, r));
4537 static int show_environment(sd_bus *bus, char **args) {
4538 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4539 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4543 pager_open_if_enabled();
4545 r = sd_bus_get_property(
4547 "org.freedesktop.systemd1",
4548 "/org/freedesktop/systemd1",
4549 "org.freedesktop.systemd1.Manager",
4555 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4559 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4561 return bus_log_parse_error(r);
4563 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4566 return bus_log_parse_error(r);
4568 r = sd_bus_message_exit_container(reply);
4570 return bus_log_parse_error(r);
4575 static int switch_root(sd_bus *bus, char **args) {
4576 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4577 _cleanup_free_ char *cmdline_init = NULL;
4578 const char *root, *init;
4582 l = strv_length(args);
4583 if (l < 2 || l > 3) {
4584 log_error("Wrong number of arguments.");
4593 r = parse_env_file("/proc/cmdline", WHITESPACE,
4594 "init", &cmdline_init,
4597 log_debug("Failed to parse /proc/cmdline: %s", strerror(-r));
4599 init = cmdline_init;
4606 const char *root_systemd_path = NULL, *root_init_path = NULL;
4608 root_systemd_path = strappenda(root, "/" SYSTEMD_BINARY_PATH);
4609 root_init_path = strappenda3(root, "/", init);
4611 /* If the passed init is actually the same as the
4612 * systemd binary, then let's suppress it. */
4613 if (files_same(root_init_path, root_systemd_path) > 0)
4617 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4619 r = sd_bus_call_method(
4621 "org.freedesktop.systemd1",
4622 "/org/freedesktop/systemd1",
4623 "org.freedesktop.systemd1.Manager",
4629 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4636 static int set_environment(sd_bus *bus, char **args) {
4637 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4638 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4645 method = streq(args[0], "set-environment")
4647 : "UnsetEnvironment";
4649 r = sd_bus_message_new_method_call(
4652 "org.freedesktop.systemd1",
4653 "/org/freedesktop/systemd1",
4654 "org.freedesktop.systemd1.Manager",
4657 return bus_log_create_error(r);
4659 r = sd_bus_message_append_strv(m, args + 1);
4661 return bus_log_create_error(r);
4663 r = sd_bus_call(bus, m, 0, &error, NULL);
4665 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4672 static int import_environment(sd_bus *bus, char **args) {
4673 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4674 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4680 r = sd_bus_message_new_method_call(
4683 "org.freedesktop.systemd1",
4684 "/org/freedesktop/systemd1",
4685 "org.freedesktop.systemd1.Manager",
4688 return bus_log_create_error(r);
4690 if (strv_isempty(args + 1))
4691 r = sd_bus_message_append_strv(m, environ);
4695 r = sd_bus_message_open_container(m, 'a', "s");
4697 return bus_log_create_error(r);
4699 STRV_FOREACH(a, args + 1) {
4701 if (!env_name_is_valid(*a)) {
4702 log_error("Not a valid environment variable name: %s", *a);
4706 STRV_FOREACH(b, environ) {
4709 eq = startswith(*b, *a);
4710 if (eq && *eq == '=') {
4712 r = sd_bus_message_append(m, "s", *b);
4714 return bus_log_create_error(r);
4721 r = sd_bus_message_close_container(m);
4724 return bus_log_create_error(r);
4726 r = sd_bus_call(bus, m, 0, &error, NULL);
4728 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4735 static int enable_sysv_units(const char *verb, char **args) {
4738 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4739 unsigned f = 1, t = 1;
4740 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4742 if (arg_scope != UNIT_FILE_SYSTEM)
4745 if (!streq(verb, "enable") &&
4746 !streq(verb, "disable") &&
4747 !streq(verb, "is-enabled"))
4750 /* Processes all SysV units, and reshuffles the array so that
4751 * afterwards only the native units remain */
4753 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4758 for (f = 0; args[f]; f++) {
4760 _cleanup_free_ char *p = NULL, *q = NULL;
4761 bool found_native = false, found_sysv;
4763 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4771 if (!endswith(name, ".service"))
4774 if (path_is_absolute(name))
4777 STRV_FOREACH(k, paths.unit_path) {
4778 if (!isempty(arg_root))
4779 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4781 asprintf(&p, "%s/%s", *k, name);
4788 found_native = access(p, F_OK) >= 0;
4799 if (!isempty(arg_root))
4800 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4802 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4808 p[strlen(p) - sizeof(".service") + 1] = 0;
4809 found_sysv = access(p, F_OK) >= 0;
4814 /* Mark this entry, so that we don't try enabling it as native unit */
4815 args[f] = (char*) "";
4817 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4819 if (!isempty(arg_root))
4820 argv[c++] = q = strappend("--root=", arg_root);
4822 argv[c++] = basename(p);
4824 streq(verb, "enable") ? "on" :
4825 streq(verb, "disable") ? "off" : "--level=5";
4828 l = strv_join((char**)argv, " ");
4834 log_info("Executing %s", l);
4839 log_error("Failed to fork: %m");
4842 } else if (pid == 0) {
4845 execv(argv[0], (char**) argv);
4846 _exit(EXIT_FAILURE);
4849 j = wait_for_terminate(pid, &status);
4851 log_error("Failed to wait for child: %s", strerror(-r));
4856 if (status.si_code == CLD_EXITED) {
4857 if (streq(verb, "is-enabled")) {
4858 if (status.si_status == 0) {
4867 } else if (status.si_status != 0) {
4878 /* Drop all SysV units */
4879 for (f = 0, t = 0; args[f]; f++) {
4881 if (isempty(args[f]))
4884 args[t++] = args[f];
4893 static int mangle_names(char **original_names, char ***mangled_names) {
4894 char **i, **l, **name;
4896 l = new(char*, strv_length(original_names) + 1);
4901 STRV_FOREACH(name, original_names) {
4903 /* When enabling units qualified path names are OK,
4904 * too, hence allow them explicitly. */
4909 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4925 static int enable_unit(sd_bus *bus, char **args) {
4926 _cleanup_strv_free_ char **names = NULL;
4927 const char *verb = args[0];
4928 UnitFileChange *changes = NULL;
4929 unsigned n_changes = 0;
4930 int carries_install_info = -1;
4936 r = mangle_names(args+1, &names);
4940 r = enable_sysv_units(verb, names);
4944 /* If the operation was fully executed by the SysV compat,
4945 * let's finish early */
4946 if (strv_isempty(names))
4949 if (!bus || avoid_bus()) {
4950 if (streq(verb, "enable")) {
4951 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4952 carries_install_info = r;
4953 } else if (streq(verb, "disable"))
4954 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4955 else if (streq(verb, "reenable")) {
4956 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4957 carries_install_info = r;
4958 } else if (streq(verb, "link"))
4959 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4960 else if (streq(verb, "preset")) {
4961 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4962 carries_install_info = r;
4963 } else if (streq(verb, "mask"))
4964 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4965 else if (streq(verb, "unmask"))
4966 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4968 assert_not_reached("Unknown verb");
4971 log_error("Operation failed: %s", strerror(-r));
4976 dump_unit_file_changes(changes, n_changes);
4980 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4981 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4982 int expect_carries_install_info = false;
4983 bool send_force = true;
4986 if (streq(verb, "enable")) {
4987 method = "EnableUnitFiles";
4988 expect_carries_install_info = true;
4989 } else if (streq(verb, "disable")) {
4990 method = "DisableUnitFiles";
4992 } else if (streq(verb, "reenable")) {
4993 method = "ReenableUnitFiles";
4994 expect_carries_install_info = true;
4995 } else if (streq(verb, "link"))
4996 method = "LinkUnitFiles";
4997 else if (streq(verb, "preset")) {
4998 method = "PresetUnitFiles";
4999 expect_carries_install_info = true;
5000 } else if (streq(verb, "mask"))
5001 method = "MaskUnitFiles";
5002 else if (streq(verb, "unmask")) {
5003 method = "UnmaskUnitFiles";
5006 assert_not_reached("Unknown verb");
5008 r = sd_bus_message_new_method_call(
5011 "org.freedesktop.systemd1",
5012 "/org/freedesktop/systemd1",
5013 "org.freedesktop.systemd1.Manager",
5016 return bus_log_create_error(r);
5018 r = sd_bus_message_append_strv(m, names);
5020 return bus_log_create_error(r);
5022 r = sd_bus_message_append(m, "b", arg_runtime);
5024 return bus_log_create_error(r);
5027 r = sd_bus_message_append(m, "b", arg_force);
5029 return bus_log_create_error(r);
5032 r = sd_bus_call(bus, m, 0, &error, &reply);
5034 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5038 if (expect_carries_install_info) {
5039 r = sd_bus_message_read(reply, "b", &carries_install_info);
5041 return bus_log_parse_error(r);
5044 r = deserialize_and_dump_unit_file_changes(reply);
5048 /* Try to reload if enabeld */
5050 r = daemon_reload(bus, args);
5055 if (carries_install_info == 0)
5056 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5057 "using systemctl.\n"
5058 "Possible reasons for having this kind of units are:\n"
5059 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5060 " .wants/ or .requires/ directory.\n"
5061 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5062 " a requirement dependency on it.\n"
5063 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5064 " D-Bus, udev, scripted systemctl call, ...).\n");
5067 unit_file_changes_free(changes, n_changes);
5072 static int unit_is_enabled(sd_bus *bus, char **args) {
5074 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5075 _cleanup_strv_free_ char **names = NULL;
5080 r = mangle_names(args+1, &names);
5084 r = enable_sysv_units(args[0], names);
5090 if (!bus || avoid_bus()) {
5092 STRV_FOREACH(name, names) {
5093 UnitFileState state;
5095 state = unit_file_get_state(arg_scope, arg_root, *name);
5097 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
5101 if (state == UNIT_FILE_ENABLED ||
5102 state == UNIT_FILE_ENABLED_RUNTIME ||
5103 state == UNIT_FILE_STATIC)
5107 puts(unit_file_state_to_string(state));
5111 STRV_FOREACH(name, names) {
5112 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5115 r = sd_bus_call_method(
5117 "org.freedesktop.systemd1",
5118 "/org/freedesktop/systemd1",
5119 "org.freedesktop.systemd1.Manager",
5125 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5129 r = sd_bus_message_read(reply, "s", &s);
5131 return bus_log_parse_error(r);
5133 if (streq(s, "enabled") ||
5134 streq(s, "enabled-runtime") ||
5146 static int systemctl_help(void) {
5148 pager_open_if_enabled();
5150 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
5151 "Query or send control commands to the systemd manager.\n\n"
5152 " -h --help Show this help\n"
5153 " --version Show package version\n"
5154 " --system Connect to system manager\n"
5155 " --user Connect to user service manager\n"
5156 " -H --host=[USER@]HOST\n"
5157 " Operate on remote host\n"
5158 " -M --machine=CONTAINER\n"
5159 " Operate on local container\n"
5160 " -t --type=TYPE List only units of a particular type\n"
5161 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
5162 " -p --property=NAME Show only properties by this name\n"
5163 " -a --all Show all loaded units/properties, including dead/empty\n"
5164 " ones. To list all units installed on the system, use\n"
5165 " the 'list-unit-files' command instead.\n"
5166 " -l --full Don't ellipsize unit names on output\n"
5167 " --reverse Show reverse dependencies with 'list-dependencies'\n"
5168 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
5169 " queueing a new job\n"
5170 " --show-types When showing sockets, explicitly show their type\n"
5171 " -i --ignore-inhibitors\n"
5172 " When shutting down or sleeping, ignore inhibitors\n"
5173 " --kill-who=WHO Who to send signal to\n"
5174 " -s --signal=SIGNAL Which signal to send\n"
5175 " -q --quiet Suppress output\n"
5176 " --no-block Do not wait until operation finished\n"
5177 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5178 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
5180 " --no-legend Do not print a legend (column headers and hints)\n"
5181 " --no-pager Do not pipe output into a pager\n"
5182 " --no-ask-password\n"
5183 " Do not ask for system passwords\n"
5184 " --global Enable/disable unit files globally\n"
5185 " --runtime Enable unit files only temporarily until next reboot\n"
5186 " -f --force When enabling unit files, override existing symlinks\n"
5187 " When shutting down, execute action immediately\n"
5188 " --root=PATH Enable unit files in the specified root directory\n"
5189 " -n --lines=INTEGER Number of journal entries to show\n"
5190 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
5191 " verbose, export, json, json-pretty, json-sse, cat)\n"
5192 " --plain Print unit dependencies as a list instead of a tree\n\n"
5194 " list-units [PATTERN...] List loaded units\n"
5195 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
5196 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
5197 " start NAME... Start (activate) one or more units\n"
5198 " stop NAME... Stop (deactivate) one or more units\n"
5199 " reload NAME... Reload one or more units\n"
5200 " restart NAME... Start or restart one or more units\n"
5201 " try-restart NAME... Restart one or more units if active\n"
5202 " reload-or-restart NAME... Reload one or more units if possible,\n"
5203 " otherwise start or restart\n"
5204 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5205 " otherwise restart if active\n"
5206 " isolate NAME Start one unit and stop all others\n"
5207 " kill NAME... Send signal to processes of a unit\n"
5208 " is-active NAME... Check whether units are active\n"
5209 " is-failed NAME... Check whether units are failed\n"
5210 " status [NAME...|PID...] Show runtime status of one or more units\n"
5211 " show [NAME...|JOB...] Show properties of one or more\n"
5212 " units/jobs or the manager\n"
5213 " cat NAME... Show files and drop-ins of one or more units\n"
5214 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5215 " help NAME...|PID... Show manual for one or more units\n"
5216 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
5218 " list-dependencies [NAME] Recursively show units which are required\n"
5219 " or wanted by this unit or by which this\n"
5220 " unit is required or wanted\n\n"
5221 "Unit File Commands:\n"
5222 " list-unit-files [PATTERN...] List installed unit files\n"
5223 " enable NAME... Enable one or more unit files\n"
5224 " disable NAME... Disable one or more unit files\n"
5225 " reenable NAME... Reenable one or more unit files\n"
5226 " preset NAME... Enable/disable one or more unit files\n"
5227 " based on preset configuration\n"
5228 " is-enabled NAME... Check whether unit files are enabled\n\n"
5229 " mask NAME... Mask one or more units\n"
5230 " unmask NAME... Unmask one or more units\n"
5231 " link PATH... Link one or more units files into\n"
5232 " the search path\n"
5233 " get-default Get the name of the default target\n"
5234 " set-default NAME Set the default target\n\n"
5235 "Machine Commands:\n"
5236 " list-machines [PATTERN...] List local containers and host\n\n"
5238 " list-jobs [PATTERN...] List jobs\n"
5239 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5240 "Snapshot Commands:\n"
5241 " snapshot [NAME] Create a snapshot\n"
5242 " delete NAME... Remove one or more snapshots\n\n"
5243 "Environment Commands:\n"
5244 " show-environment Dump environment\n"
5245 " set-environment NAME=VALUE... Set one or more environment variables\n"
5246 " unset-environment NAME... Unset one or more environment variables\n"
5247 " import-environment NAME... Import all, one or more environment variables\n\n"
5248 "Manager Lifecycle Commands:\n"
5249 " daemon-reload Reload systemd manager configuration\n"
5250 " daemon-reexec Reexecute systemd manager\n\n"
5251 "System Commands:\n"
5252 " default Enter system default mode\n"
5253 " rescue Enter system rescue mode\n"
5254 " emergency Enter system emergency mode\n"
5255 " halt Shut down and halt the system\n"
5256 " poweroff Shut down and power-off the system\n"
5257 " reboot [ARG] Shut down and reboot the system\n"
5258 " kexec Shut down and reboot the system with kexec\n"
5259 " exit Request user instance exit\n"
5260 " switch-root ROOT [INIT] Change to a different root file system\n"
5261 " suspend Suspend the system\n"
5262 " hibernate Hibernate the system\n"
5263 " hybrid-sleep Hibernate and suspend the system\n",
5264 program_invocation_short_name);
5269 static int halt_help(void) {
5271 printf("%s [OPTIONS...]%s\n\n"
5272 "%s the system.\n\n"
5273 " --help Show this help\n"
5274 " --halt Halt the machine\n"
5275 " -p --poweroff Switch off the machine\n"
5276 " --reboot Reboot the machine\n"
5277 " -f --force Force immediate halt/power-off/reboot\n"
5278 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5279 " -d --no-wtmp Don't write wtmp record\n"
5280 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5281 program_invocation_short_name,
5282 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5283 arg_action == ACTION_REBOOT ? "Reboot" :
5284 arg_action == ACTION_POWEROFF ? "Power off" :
5290 static int shutdown_help(void) {
5292 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5293 "Shut down the system.\n\n"
5294 " --help Show this help\n"
5295 " -H --halt Halt the machine\n"
5296 " -P --poweroff Power-off the machine\n"
5297 " -r --reboot Reboot the machine\n"
5298 " -h Equivalent to --poweroff, overridden by --halt\n"
5299 " -k Don't halt/power-off/reboot, just send warnings\n"
5300 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5301 " -c Cancel a pending shutdown\n",
5302 program_invocation_short_name);
5307 static int telinit_help(void) {
5309 printf("%s [OPTIONS...] {COMMAND}\n\n"
5310 "Send control commands to the init daemon.\n\n"
5311 " --help Show this help\n"
5312 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5314 " 0 Power-off the machine\n"
5315 " 6 Reboot the machine\n"
5316 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5317 " 1, s, S Enter rescue mode\n"
5318 " q, Q Reload init daemon configuration\n"
5319 " u, U Reexecute init daemon\n",
5320 program_invocation_short_name);
5325 static int runlevel_help(void) {
5327 printf("%s [OPTIONS...]\n\n"
5328 "Prints the previous and current runlevel of the init system.\n\n"
5329 " --help Show this help\n",
5330 program_invocation_short_name);
5335 static int help_types(void) {
5339 puts("Available unit types:");
5340 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5341 t = unit_type_to_string(i);
5349 static int systemctl_parse_argv(int argc, char *argv[]) {
5358 ARG_IGNORE_DEPENDENCIES,
5370 ARG_NO_ASK_PASSWORD,
5379 static const struct option options[] = {
5380 { "help", no_argument, NULL, 'h' },
5381 { "version", no_argument, NULL, ARG_VERSION },
5382 { "type", required_argument, NULL, 't' },
5383 { "property", required_argument, NULL, 'p' },
5384 { "all", no_argument, NULL, 'a' },
5385 { "reverse", no_argument, NULL, ARG_REVERSE },
5386 { "after", no_argument, NULL, ARG_AFTER },
5387 { "before", no_argument, NULL, ARG_BEFORE },
5388 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5389 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5390 { "full", no_argument, NULL, 'l' },
5391 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5392 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5393 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5394 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5395 { "ignore-inhibitors", no_argument, NULL, 'i' },
5396 { "user", no_argument, NULL, ARG_USER },
5397 { "system", no_argument, NULL, ARG_SYSTEM },
5398 { "global", no_argument, NULL, ARG_GLOBAL },
5399 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5400 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5401 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5402 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5403 { "quiet", no_argument, NULL, 'q' },
5404 { "root", required_argument, NULL, ARG_ROOT },
5405 { "force", no_argument, NULL, ARG_FORCE },
5406 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5407 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5408 { "signal", required_argument, NULL, 's' },
5409 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5410 { "host", required_argument, NULL, 'H' },
5411 { "machine", required_argument, NULL, 'M' },
5412 { "runtime", no_argument, NULL, ARG_RUNTIME },
5413 { "lines", required_argument, NULL, 'n' },
5414 { "output", required_argument, NULL, 'o' },
5415 { "plain", no_argument, NULL, ARG_PLAIN },
5416 { "state", required_argument, NULL, ARG_STATE },
5425 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5430 return systemctl_help();
5433 puts(PACKAGE_STRING);
5434 puts(SYSTEMD_FEATURES);
5441 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5442 _cleanup_free_ char *type;
5444 type = strndup(word, size);
5448 if (streq(type, "help")) {
5453 if (unit_type_from_string(type) >= 0) {
5454 if (strv_push(&arg_types, type))
5460 /* It's much nicer to use --state= for
5461 * load states, but let's support this
5462 * in --types= too for compatibility
5463 * with old versions */
5464 if (unit_load_state_from_string(optarg) >= 0) {
5465 if (strv_push(&arg_states, type) < 0)
5471 log_error("Unknown unit type or load state '%s'.", type);
5472 log_info("Use -t help to see a list of allowed values.");
5480 /* Make sure that if the empty property list
5481 was specified, we won't show any properties. */
5482 if (isempty(optarg) && !arg_properties) {
5483 arg_properties = new0(char*, 1);
5484 if (!arg_properties)
5490 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5493 prop = strndup(word, size);
5497 if (strv_consume(&arg_properties, prop) < 0)
5502 /* If the user asked for a particular
5503 * property, show it to him, even if it is
5515 arg_dependency = DEPENDENCY_REVERSE;
5519 arg_dependency = DEPENDENCY_AFTER;
5523 arg_dependency = DEPENDENCY_BEFORE;
5526 case ARG_SHOW_TYPES:
5527 arg_show_types = true;
5531 arg_job_mode = optarg;
5535 arg_job_mode = "fail";
5538 case ARG_IRREVERSIBLE:
5539 arg_job_mode = "replace-irreversibly";
5542 case ARG_IGNORE_DEPENDENCIES:
5543 arg_job_mode = "ignore-dependencies";
5547 arg_scope = UNIT_FILE_USER;
5551 arg_scope = UNIT_FILE_SYSTEM;
5555 arg_scope = UNIT_FILE_GLOBAL;
5559 arg_no_block = true;
5563 arg_no_legend = true;
5567 arg_no_pager = true;
5583 if (strv_extend(&arg_states, "failed") < 0)
5601 arg_no_reload = true;
5605 arg_kill_who = optarg;
5609 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5610 log_error("Failed to parse signal string %s.", optarg);
5615 case ARG_NO_ASK_PASSWORD:
5616 arg_ask_password = false;
5620 arg_transport = BUS_TRANSPORT_REMOTE;
5625 arg_transport = BUS_TRANSPORT_CONTAINER;
5634 if (safe_atou(optarg, &arg_lines) < 0) {
5635 log_error("Failed to parse lines '%s'", optarg);
5641 arg_output = output_mode_from_string(optarg);
5642 if (arg_output < 0) {
5643 log_error("Unknown output '%s'.", optarg);
5649 arg_ignore_inhibitors = true;
5660 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5663 s = strndup(word, size);
5667 if (strv_consume(&arg_states, s) < 0)
5677 assert_not_reached("Unhandled option");
5681 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5682 log_error("Cannot access user instance remotely.");
5689 static int halt_parse_argv(int argc, char *argv[]) {
5698 static const struct option options[] = {
5699 { "help", no_argument, NULL, ARG_HELP },
5700 { "halt", no_argument, NULL, ARG_HALT },
5701 { "poweroff", no_argument, NULL, 'p' },
5702 { "reboot", no_argument, NULL, ARG_REBOOT },
5703 { "force", no_argument, NULL, 'f' },
5704 { "wtmp-only", no_argument, NULL, 'w' },
5705 { "no-wtmp", no_argument, NULL, 'd' },
5706 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5715 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5716 if (runlevel == '0' || runlevel == '6')
5719 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5726 arg_action = ACTION_HALT;
5730 if (arg_action != ACTION_REBOOT)
5731 arg_action = ACTION_POWEROFF;
5735 arg_action = ACTION_REBOOT;
5757 /* Compatibility nops */
5764 assert_not_reached("Unhandled option");
5768 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5769 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5771 log_error("Failed to write reboot param to "
5772 REBOOT_PARAM_FILE": %s", strerror(-r));
5775 } else if (optind < argc) {
5776 log_error("Too many arguments.");
5783 static int parse_time_spec(const char *t, usec_t *_u) {
5787 if (streq(t, "now"))
5789 else if (!strchr(t, ':')) {
5792 if (safe_atou64(t, &u) < 0)
5795 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5804 hour = strtol(t, &e, 10);
5805 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5808 minute = strtol(e+1, &e, 10);
5809 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5812 n = now(CLOCK_REALTIME);
5813 s = (time_t) (n / USEC_PER_SEC);
5815 assert_se(localtime_r(&s, &tm));
5817 tm.tm_hour = (int) hour;
5818 tm.tm_min = (int) minute;
5821 assert_se(s = mktime(&tm));
5823 *_u = (usec_t) s * USEC_PER_SEC;
5826 *_u += USEC_PER_DAY;
5832 static int shutdown_parse_argv(int argc, char *argv[]) {
5839 static const struct option options[] = {
5840 { "help", no_argument, NULL, ARG_HELP },
5841 { "halt", no_argument, NULL, 'H' },
5842 { "poweroff", no_argument, NULL, 'P' },
5843 { "reboot", no_argument, NULL, 'r' },
5844 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5845 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5854 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5858 return shutdown_help();
5861 arg_action = ACTION_HALT;
5865 arg_action = ACTION_POWEROFF;
5870 arg_action = ACTION_KEXEC;
5872 arg_action = ACTION_REBOOT;
5876 arg_action = ACTION_KEXEC;
5880 if (arg_action != ACTION_HALT)
5881 arg_action = ACTION_POWEROFF;
5894 /* Compatibility nops */
5898 arg_action = ACTION_CANCEL_SHUTDOWN;
5905 assert_not_reached("Unhandled option");
5909 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5910 r = parse_time_spec(argv[optind], &arg_when);
5912 log_error("Failed to parse time specification: %s", argv[optind]);
5916 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5918 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5919 /* No time argument for shutdown cancel */
5920 arg_wall = argv + optind;
5921 else if (argc > optind + 1)
5922 /* We skip the time argument */
5923 arg_wall = argv + optind + 1;
5930 static int telinit_parse_argv(int argc, char *argv[]) {
5937 static const struct option options[] = {
5938 { "help", no_argument, NULL, ARG_HELP },
5939 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5943 static const struct {
5947 { '0', ACTION_POWEROFF },
5948 { '6', ACTION_REBOOT },
5949 { '1', ACTION_RESCUE },
5950 { '2', ACTION_RUNLEVEL2 },
5951 { '3', ACTION_RUNLEVEL3 },
5952 { '4', ACTION_RUNLEVEL4 },
5953 { '5', ACTION_RUNLEVEL5 },
5954 { 's', ACTION_RESCUE },
5955 { 'S', ACTION_RESCUE },
5956 { 'q', ACTION_RELOAD },
5957 { 'Q', ACTION_RELOAD },
5958 { 'u', ACTION_REEXEC },
5959 { 'U', ACTION_REEXEC }
5968 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5972 return telinit_help();
5982 assert_not_reached("Unhandled option");
5986 if (optind >= argc) {
5991 if (optind + 1 < argc) {
5992 log_error("Too many arguments.");
5996 if (strlen(argv[optind]) != 1) {
5997 log_error("Expected single character argument.");
6001 for (i = 0; i < ELEMENTSOF(table); i++)
6002 if (table[i].from == argv[optind][0])
6005 if (i >= ELEMENTSOF(table)) {
6006 log_error("Unknown command '%s'.", argv[optind]);
6010 arg_action = table[i].to;
6017 static int runlevel_parse_argv(int argc, char *argv[]) {
6023 static const struct option options[] = {
6024 { "help", no_argument, NULL, ARG_HELP },
6033 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
6037 return runlevel_help();
6043 assert_not_reached("Unhandled option");
6047 if (optind < argc) {
6048 log_error("Too many arguments.");
6055 static int parse_argv(int argc, char *argv[]) {
6059 if (program_invocation_short_name) {
6061 if (strstr(program_invocation_short_name, "halt")) {
6062 arg_action = ACTION_HALT;
6063 return halt_parse_argv(argc, argv);
6064 } else if (strstr(program_invocation_short_name, "poweroff")) {
6065 arg_action = ACTION_POWEROFF;
6066 return halt_parse_argv(argc, argv);
6067 } else if (strstr(program_invocation_short_name, "reboot")) {
6069 arg_action = ACTION_KEXEC;
6071 arg_action = ACTION_REBOOT;
6072 return halt_parse_argv(argc, argv);
6073 } else if (strstr(program_invocation_short_name, "shutdown")) {
6074 arg_action = ACTION_POWEROFF;
6075 return shutdown_parse_argv(argc, argv);
6076 } else if (strstr(program_invocation_short_name, "init")) {
6078 if (sd_booted() > 0) {
6079 arg_action = _ACTION_INVALID;
6080 return telinit_parse_argv(argc, argv);
6082 /* Hmm, so some other init system is
6083 * running, we need to forward this
6084 * request to it. For now we simply
6085 * guess that it is Upstart. */
6087 execv(TELINIT, argv);
6089 log_error("Couldn't find an alternative telinit implementation to spawn.");
6093 } else if (strstr(program_invocation_short_name, "runlevel")) {
6094 arg_action = ACTION_RUNLEVEL;
6095 return runlevel_parse_argv(argc, argv);
6099 arg_action = ACTION_SYSTEMCTL;
6100 return systemctl_parse_argv(argc, argv);
6103 _pure_ static int action_to_runlevel(void) {
6105 static const char table[_ACTION_MAX] = {
6106 [ACTION_HALT] = '0',
6107 [ACTION_POWEROFF] = '0',
6108 [ACTION_REBOOT] = '6',
6109 [ACTION_RUNLEVEL2] = '2',
6110 [ACTION_RUNLEVEL3] = '3',
6111 [ACTION_RUNLEVEL4] = '4',
6112 [ACTION_RUNLEVEL5] = '5',
6113 [ACTION_RESCUE] = '1'
6116 assert(arg_action < _ACTION_MAX);
6118 return table[arg_action];
6121 static int talk_initctl(void) {
6123 struct init_request request = {
6124 .magic = INIT_MAGIC,
6126 .cmd = INIT_CMD_RUNLVL
6129 _cleanup_close_ int fd = -1;
6133 rl = action_to_runlevel();
6137 request.runlevel = rl;
6139 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
6141 if (errno == ENOENT)
6144 log_error("Failed to open "INIT_FIFO": %m");
6149 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
6151 log_error("Failed to write to "INIT_FIFO": %m");
6152 return errno > 0 ? -errno : -EIO;
6158 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
6160 static const struct {
6168 int (* const dispatch)(sd_bus *bus, char **args);
6174 { "list-units", MORE, 0, list_units },
6175 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
6176 { "list-sockets", MORE, 1, list_sockets },
6177 { "list-timers", MORE, 1, list_timers },
6178 { "list-jobs", MORE, 1, list_jobs },
6179 { "list-machines", MORE, 1, list_machines },
6180 { "clear-jobs", EQUAL, 1, daemon_reload },
6181 { "cancel", MORE, 2, cancel_job },
6182 { "start", MORE, 2, start_unit },
6183 { "stop", MORE, 2, start_unit },
6184 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6185 { "reload", MORE, 2, start_unit },
6186 { "restart", MORE, 2, start_unit },
6187 { "try-restart", MORE, 2, start_unit },
6188 { "reload-or-restart", MORE, 2, start_unit },
6189 { "reload-or-try-restart", MORE, 2, start_unit },
6190 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
6191 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
6192 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
6193 { "isolate", EQUAL, 2, start_unit },
6194 { "kill", MORE, 2, kill_unit },
6195 { "is-active", MORE, 2, check_unit_active },
6196 { "check", MORE, 2, check_unit_active },
6197 { "is-failed", MORE, 2, check_unit_failed },
6198 { "show", MORE, 1, show },
6199 { "cat", MORE, 2, cat },
6200 { "status", MORE, 1, show },
6201 { "help", MORE, 2, show },
6202 { "snapshot", LESS, 2, snapshot },
6203 { "delete", MORE, 2, delete_snapshot },
6204 { "daemon-reload", EQUAL, 1, daemon_reload },
6205 { "daemon-reexec", EQUAL, 1, daemon_reload },
6206 { "show-environment", EQUAL, 1, show_environment },
6207 { "set-environment", MORE, 2, set_environment },
6208 { "unset-environment", MORE, 2, set_environment },
6209 { "import-environment", MORE, 1, import_environment},
6210 { "halt", EQUAL, 1, start_special, FORCE },
6211 { "poweroff", EQUAL, 1, start_special, FORCE },
6212 { "reboot", EQUAL, 1, start_special, FORCE },
6213 { "kexec", EQUAL, 1, start_special },
6214 { "suspend", EQUAL, 1, start_special },
6215 { "hibernate", EQUAL, 1, start_special },
6216 { "hybrid-sleep", EQUAL, 1, start_special },
6217 { "default", EQUAL, 1, start_special },
6218 { "rescue", EQUAL, 1, start_special },
6219 { "emergency", EQUAL, 1, start_special },
6220 { "exit", EQUAL, 1, start_special },
6221 { "reset-failed", MORE, 1, reset_failed },
6222 { "enable", MORE, 2, enable_unit, NOBUS },
6223 { "disable", MORE, 2, enable_unit, NOBUS },
6224 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6225 { "reenable", MORE, 2, enable_unit, NOBUS },
6226 { "preset", MORE, 2, enable_unit, NOBUS },
6227 { "mask", MORE, 2, enable_unit, NOBUS },
6228 { "unmask", MORE, 2, enable_unit, NOBUS },
6229 { "link", MORE, 2, enable_unit, NOBUS },
6230 { "switch-root", MORE, 2, switch_root },
6231 { "list-dependencies", LESS, 2, list_dependencies },
6232 { "set-default", EQUAL, 2, set_default, NOBUS },
6233 { "get-default", EQUAL, 1, get_default, NOBUS },
6234 { "set-property", MORE, 3, set_property },
6243 left = argc - optind;
6245 /* Special rule: no arguments (left == 0) means "list-units" */
6247 if (streq(argv[optind], "help") && !argv[optind+1]) {
6248 log_error("This command expects one or more "
6249 "unit names. Did you mean --help?");
6253 for (; verb->verb; verb++)
6254 if (streq(argv[optind], verb->verb))
6257 log_error("Unknown operation '%s'.", argv[optind]);
6262 switch (verb->argc_cmp) {
6265 if (left != verb->argc) {
6266 log_error("Invalid number of arguments.");
6273 if (left < verb->argc) {
6274 log_error("Too few arguments.");
6281 if (left > verb->argc) {
6282 log_error("Too many arguments.");
6289 assert_not_reached("Unknown comparison operator.");
6292 /* Require a bus connection for all operations but
6294 if (verb->bus == NOBUS) {
6295 if (!bus && !avoid_bus()) {
6296 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6301 if (running_in_chroot() > 0) {
6302 log_info("Running in chroot, ignoring request.");
6306 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6307 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6312 return verb->dispatch(bus, argv + optind);
6315 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6317 struct sd_shutdown_command c = {
6324 union sockaddr_union sockaddr = {
6325 .un.sun_family = AF_UNIX,
6326 .un.sun_path = "/run/systemd/shutdownd",
6329 struct iovec iovec[2] = {{
6330 .iov_base = (char*) &c,
6331 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6334 struct msghdr msghdr = {
6335 .msg_name = &sockaddr,
6336 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6337 + sizeof("/run/systemd/shutdownd") - 1,
6342 _cleanup_close_ int fd;
6344 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6348 if (!isempty(message)) {
6349 iovec[1].iov_base = (char*) message;
6350 iovec[1].iov_len = strlen(message);
6351 msghdr.msg_iovlen++;
6354 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6360 static int reload_with_fallback(sd_bus *bus) {
6363 /* First, try systemd via D-Bus. */
6364 if (daemon_reload(bus, NULL) >= 0)
6368 /* Nothing else worked, so let's try signals */
6369 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6371 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6372 log_error("kill() failed: %m");
6379 static int start_with_fallback(sd_bus *bus) {
6382 /* First, try systemd via D-Bus. */
6383 if (start_unit(bus, NULL) >= 0)
6387 /* Nothing else worked, so let's try
6389 if (talk_initctl() > 0)
6392 log_error("Failed to talk to init daemon.");
6396 warn_wall(arg_action);
6400 static int halt_now(enum action a) {
6402 /* Make sure C-A-D is handled by the kernel from this
6404 reboot(RB_ENABLE_CAD);
6409 log_info("Halting.");
6410 reboot(RB_HALT_SYSTEM);
6413 case ACTION_POWEROFF:
6414 log_info("Powering off.");
6415 reboot(RB_POWER_OFF);
6418 case ACTION_REBOOT: {
6419 _cleanup_free_ char *param = NULL;
6421 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6422 log_info("Rebooting with argument '%s'.", param);
6423 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6424 LINUX_REBOOT_CMD_RESTART2, param);
6427 log_info("Rebooting.");
6428 reboot(RB_AUTOBOOT);
6433 assert_not_reached("Unknown action.");
6437 static int halt_main(sd_bus *bus) {
6440 r = check_inhibitors(bus, arg_action);
6444 if (geteuid() != 0) {
6445 /* Try logind if we are a normal user and no special
6446 * mode applies. Maybe PolicyKit allows us to shutdown
6449 if (arg_when <= 0 &&
6452 (arg_action == ACTION_POWEROFF ||
6453 arg_action == ACTION_REBOOT)) {
6454 r = reboot_with_logind(bus, arg_action);
6459 log_error("Must be root.");
6464 _cleanup_free_ char *m;
6466 m = strv_join(arg_wall, " ");
6470 r = send_shutdownd(arg_when,
6471 arg_action == ACTION_HALT ? 'H' :
6472 arg_action == ACTION_POWEROFF ? 'P' :
6473 arg_action == ACTION_KEXEC ? 'K' :
6480 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6482 char date[FORMAT_TIMESTAMP_MAX];
6484 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6485 format_timestamp(date, sizeof(date), arg_when));
6490 if (!arg_dry && !arg_force)
6491 return start_with_fallback(bus);
6494 if (sd_booted() > 0)
6495 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6497 r = utmp_put_shutdown();
6499 log_warning("Failed to write utmp record: %s", strerror(-r));
6506 r = halt_now(arg_action);
6507 log_error("Failed to reboot: %s", strerror(-r));
6512 static int runlevel_main(void) {
6513 int r, runlevel, previous;
6515 r = utmp_get_runlevel(&runlevel, &previous);
6522 previous <= 0 ? 'N' : previous,
6523 runlevel <= 0 ? 'N' : runlevel);
6528 int main(int argc, char*argv[]) {
6529 _cleanup_bus_unref_ sd_bus *bus = NULL;
6532 setlocale(LC_ALL, "");
6533 log_parse_environment();
6536 /* Explicitly not on_tty() to avoid setting cached value.
6537 * This becomes relevant for piping output which might be
6539 original_stdout_is_tty = isatty(STDOUT_FILENO);
6541 r = parse_argv(argc, argv);
6545 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6546 * let's shortcut this */
6547 if (arg_action == ACTION_RUNLEVEL) {
6548 r = runlevel_main();
6552 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6553 log_info("Running in chroot, ignoring request.");
6559 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6561 /* systemctl_main() will print an error message for the bus
6562 * connection, but only if it needs to */
6564 switch (arg_action) {
6566 case ACTION_SYSTEMCTL:
6567 r = systemctl_main(bus, argc, argv, r);
6571 case ACTION_POWEROFF:
6577 case ACTION_RUNLEVEL2:
6578 case ACTION_RUNLEVEL3:
6579 case ACTION_RUNLEVEL4:
6580 case ACTION_RUNLEVEL5:
6582 case ACTION_EMERGENCY:
6583 case ACTION_DEFAULT:
6584 r = start_with_fallback(bus);
6589 r = reload_with_fallback(bus);
6592 case ACTION_CANCEL_SHUTDOWN: {
6593 _cleanup_free_ char *m = NULL;
6596 m = strv_join(arg_wall, " ");
6603 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6605 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6609 case ACTION_RUNLEVEL:
6610 case _ACTION_INVALID:
6612 assert_not_reached("Unknown action");
6617 ask_password_agent_close();
6618 polkit_agent_close();
6620 strv_free(arg_types);
6621 strv_free(arg_states);
6622 strv_free(arg_properties);
6624 return r < 0 ? EXIT_FAILURE : r;