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"
61 #include "bus-errors.h"
63 #include "unit-name.h"
65 #include "spawn-ask-password-agent.h"
66 #include "spawn-polkit-agent.h"
68 #include "logs-show.h"
69 #include "socket-util.h"
73 #include "bus-message.h"
74 #include "bus-error.h"
75 #include "bus-errors.h"
77 static char **arg_types = NULL;
78 static char **arg_states = NULL;
79 static char **arg_properties = NULL;
80 static bool arg_all = false;
81 static bool original_stdout_is_tty;
82 static enum dependency {
88 } arg_dependency = DEPENDENCY_FORWARD;
89 static const char *arg_job_mode = "replace";
90 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
91 static bool arg_no_block = false;
92 static bool arg_no_legend = false;
93 static bool arg_no_pager = false;
94 static bool arg_no_wtmp = false;
95 static bool arg_no_wall = false;
96 static bool arg_no_reload = false;
97 static bool arg_show_types = false;
98 static bool arg_ignore_inhibitors = false;
99 static bool arg_dry = false;
100 static bool arg_quiet = false;
101 static bool arg_full = false;
102 static int arg_force = 0;
103 static bool arg_ask_password = true;
104 static bool arg_runtime = false;
105 static char **arg_wall = NULL;
106 static const char *arg_kill_who = NULL;
107 static int arg_signal = SIGTERM;
108 static const char *arg_root = NULL;
109 static usec_t arg_when = 0;
131 ACTION_CANCEL_SHUTDOWN,
133 } arg_action = ACTION_SYSTEMCTL;
134 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
135 static char *arg_host = NULL;
136 static unsigned arg_lines = 10;
137 static OutputMode arg_output = OUTPUT_SHORT;
138 static bool arg_plain = false;
139 static const struct {
143 { "start", "StartUnit" },
144 { "stop", "StopUnit" },
145 { "condstop", "StopUnit" },
146 { "reload", "ReloadUnit" },
147 { "restart", "RestartUnit" },
148 { "try-restart", "TryRestartUnit" },
149 { "condrestart", "TryRestartUnit" },
150 { "reload-or-restart", "ReloadOrRestartUnit" },
151 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
152 { "condreload", "ReloadOrTryRestartUnit" },
153 { "force-reload", "ReloadOrTryRestartUnit" }
156 static int daemon_reload(sd_bus *bus, char **args);
157 static int halt_now(enum action a);
159 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
161 static char** strv_skip_first(char **strv) {
162 if (strv_length(strv) > 0)
167 static void pager_open_if_enabled(void) {
175 static void ask_password_agent_open_if_enabled(void) {
177 /* Open the password agent as a child process if necessary */
179 if (!arg_ask_password)
182 if (arg_scope != UNIT_FILE_SYSTEM)
185 if (arg_transport != BUS_TRANSPORT_LOCAL)
188 ask_password_agent_open();
192 static void polkit_agent_open_if_enabled(void) {
194 /* Open the polkit agent as a child process if necessary */
196 if (!arg_ask_password)
199 if (arg_scope != UNIT_FILE_SYSTEM)
202 if (arg_transport != BUS_TRANSPORT_LOCAL)
209 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
212 if (!sd_bus_error_is_set(error))
215 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
216 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
217 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
218 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
219 return EXIT_NOPERMISSION;
221 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
222 return EXIT_NOTINSTALLED;
224 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
225 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
226 return EXIT_NOTIMPLEMENTED;
228 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
229 return EXIT_NOTCONFIGURED;
237 static void warn_wall(enum action a) {
238 static const char *table[_ACTION_MAX] = {
239 [ACTION_HALT] = "The system is going down for system halt NOW!",
240 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
241 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
242 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
243 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
244 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
245 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
252 _cleanup_free_ char *p;
254 p = strv_join(arg_wall, " ");
269 utmp_wall(table[a], NULL);
272 static bool avoid_bus(void) {
274 if (running_in_chroot() > 0)
277 if (sd_booted() <= 0)
280 if (!isempty(arg_root))
283 if (arg_scope == UNIT_FILE_GLOBAL)
289 static int compare_unit_info(const void *a, const void *b) {
290 const UnitInfo *u = a, *v = b;
293 d1 = strrchr(u->id, '.');
294 d2 = strrchr(v->id, '.');
299 r = strcasecmp(d1, d2);
304 return strcasecmp(u->id, v->id);
307 static bool output_show_unit(const UnitInfo *u, char **patterns) {
310 if (!strv_isempty(arg_states))
312 strv_contains(arg_states, u->load_state) ||
313 strv_contains(arg_states, u->sub_state) ||
314 strv_contains(arg_states, u->active_state);
316 if (!strv_isempty(patterns)) {
319 STRV_FOREACH(pattern, patterns)
320 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
325 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
326 strv_find(arg_types, dot+1))) &&
327 (arg_all || !(streq(u->active_state, "inactive")
328 || u->following[0]) || u->job_id > 0);
331 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
332 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
334 unsigned n_shown = 0;
337 max_id_len = sizeof("UNIT")-1;
338 load_len = sizeof("LOAD")-1;
339 active_len = sizeof("ACTIVE")-1;
340 sub_len = sizeof("SUB")-1;
341 job_len = sizeof("JOB")-1;
344 for (u = unit_infos; u < unit_infos + c; u++) {
345 max_id_len = MAX(max_id_len, strlen(u->id));
346 load_len = MAX(load_len, strlen(u->load_state));
347 active_len = MAX(active_len, strlen(u->active_state));
348 sub_len = MAX(sub_len, strlen(u->sub_state));
350 if (u->job_id != 0) {
351 job_len = MAX(job_len, strlen(u->job_type));
356 if (!arg_full && original_stdout_is_tty) {
359 id_len = MIN(max_id_len, 25u);
360 basic_len = 5 + id_len + 5 + active_len + sub_len;
363 basic_len += job_len + 1;
365 if (basic_len < (unsigned) columns()) {
366 unsigned extra_len, incr;
367 extra_len = columns() - basic_len;
369 /* Either UNIT already got 25, or is fully satisfied.
370 * Grant up to 25 to DESC now. */
371 incr = MIN(extra_len, 25u);
375 /* split the remaining space between UNIT and DESC,
376 * but do not give UNIT more than it needs. */
378 incr = MIN(extra_len / 2, max_id_len - id_len);
380 desc_len += extra_len - incr;
386 for (u = unit_infos; u < unit_infos + c; u++) {
387 _cleanup_free_ char *e = NULL;
388 const char *on_loaded, *off_loaded, *on = "";
389 const char *on_active, *off_active, *off = "";
391 if (!n_shown && !arg_no_legend) {
392 printf("%-*s %-*s %-*s %-*s ",
395 active_len, "ACTIVE",
399 printf("%-*s ", job_len, "JOB");
401 if (!arg_full && arg_no_pager)
402 printf("%.*s\n", desc_len, "DESCRIPTION");
404 printf("%s\n", "DESCRIPTION");
409 if (streq(u->load_state, "error") ||
410 streq(u->load_state, "not-found")) {
411 on_loaded = on = ansi_highlight_red();
412 off_loaded = off = ansi_highlight_off();
414 on_loaded = off_loaded = "";
416 if (streq(u->active_state, "failed")) {
417 on_active = on = ansi_highlight_red();
418 off_active = off = ansi_highlight_off();
420 on_active = off_active = "";
422 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
424 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
425 on, id_len, e ? e : u->id, off,
426 on_loaded, load_len, u->load_state, off_loaded,
427 on_active, active_len, u->active_state,
428 sub_len, u->sub_state, off_active,
429 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
432 printf("%.*s\n", desc_len, u->description);
434 printf("%s\n", u->description);
437 if (!arg_no_legend) {
438 const char *on, *off;
441 puts("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
442 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
443 "SUB = The low-level unit activation state, values depend on unit type.");
444 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
445 on = ansi_highlight();
446 off = ansi_highlight_off();
448 on = ansi_highlight_red();
449 off = ansi_highlight_off();
453 printf("%s%u loaded units listed.%s\n"
454 "To show all installed unit files use 'systemctl list-unit-files'.\n",
457 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
458 "To show all installed unit files use 'systemctl list-unit-files'.\n",
463 static int get_unit_list(
465 sd_bus_message **_reply,
466 UnitInfo **_unit_infos,
469 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
470 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
471 _cleanup_free_ UnitInfo *unit_infos = NULL;
480 r = sd_bus_call_method(
482 "org.freedesktop.systemd1",
483 "/org/freedesktop/systemd1",
484 "org.freedesktop.systemd1.Manager",
490 log_error("Failed to list units: %s", bus_error_message(&error, r));
494 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
496 return bus_log_parse_error(r);
498 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
499 if (!output_show_unit(&u, patterns))
502 if (!GREEDY_REALLOC(unit_infos, size, c+1))
508 return bus_log_parse_error(r);
510 r = sd_bus_message_exit_container(reply);
512 return bus_log_parse_error(r);
517 *_unit_infos = unit_infos;
523 static int list_units(sd_bus *bus, char **args) {
524 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
525 _cleanup_free_ UnitInfo *unit_infos = NULL;
528 pager_open_if_enabled();
530 r = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
534 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
535 output_units_list(unit_infos, r);
540 static int get_triggered_units(
545 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
548 r = sd_bus_get_property_strv(
550 "org.freedesktop.systemd1",
552 "org.freedesktop.systemd1.Unit",
558 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
563 static int get_listening(
565 const char* unit_path,
568 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
569 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
570 const char *type, *path;
573 r = sd_bus_get_property(
575 "org.freedesktop.systemd1",
577 "org.freedesktop.systemd1.Socket",
583 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
587 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
589 return bus_log_parse_error(r);
591 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
593 r = strv_extend(listening, type);
597 r = strv_extend(listening, path);
604 return bus_log_parse_error(r);
606 r = sd_bus_message_exit_container(reply);
608 return bus_log_parse_error(r);
619 /* Note: triggered is a list here, although it almost certainly
620 * will always be one unit. Nevertheless, dbus API allows for multiple
621 * values, so let's follow that.*/
624 /* The strv above is shared. free is set only in the first one. */
628 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
634 o = strcmp(a->path, b->path);
636 o = strcmp(a->type, b->type);
641 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
642 struct socket_info *s;
643 unsigned pathlen = sizeof("LISTEN") - 1,
644 typelen = (sizeof("TYPE") - 1) * arg_show_types,
645 socklen = sizeof("UNIT") - 1,
646 servlen = sizeof("ACTIVATES") - 1;
647 const char *on, *off;
649 for (s = socket_infos; s < socket_infos + cs; s++) {
653 socklen = MAX(socklen, strlen(s->id));
655 typelen = MAX(typelen, strlen(s->type));
656 pathlen = MAX(pathlen, strlen(s->path));
658 STRV_FOREACH(a, s->triggered)
659 tmp += strlen(*a) + 2*(a != s->triggered);
660 servlen = MAX(servlen, tmp);
665 printf("%-*s %-*.*s%-*s %s\n",
667 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
671 for (s = socket_infos; s < socket_infos + cs; s++) {
675 printf("%-*s %-*s %-*s",
676 pathlen, s->path, typelen, s->type, socklen, s->id);
679 pathlen, s->path, socklen, s->id);
680 STRV_FOREACH(a, s->triggered)
682 a == s->triggered ? "" : ",", *a);
686 on = ansi_highlight();
687 off = ansi_highlight_off();
691 on = ansi_highlight_red();
692 off = ansi_highlight_off();
695 if (!arg_no_legend) {
696 printf("%s%u sockets listed.%s\n", on, cs, off);
698 printf("Pass --all to see loaded but inactive sockets, too.\n");
704 static int list_sockets(sd_bus *bus, char **args) {
705 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
706 _cleanup_free_ UnitInfo *unit_infos = NULL;
707 _cleanup_free_ struct socket_info *socket_infos = NULL;
709 struct socket_info *s;
714 pager_open_if_enabled();
716 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
720 for (u = unit_infos; u < unit_infos + n; u++) {
721 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
724 if (!endswith(u->id, ".socket"))
727 r = get_triggered_units(bus, u->unit_path, &triggered);
731 c = get_listening(bus, u->unit_path, &listening);
737 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
742 for (i = 0; i < c; i++)
743 socket_infos[cs + i] = (struct socket_info) {
745 .type = listening[i*2],
746 .path = listening[i*2 + 1],
747 .triggered = triggered,
748 .own_triggered = i==0,
751 /* from this point on we will cleanup those socket_infos */
754 listening = triggered = NULL; /* avoid cleanup */
757 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
758 (__compar_fn_t) socket_info_compare);
760 output_sockets_list(socket_infos, cs);
763 assert(cs == 0 || socket_infos);
764 for (s = socket_infos; s < socket_infos + cs; s++) {
767 if (s->own_triggered)
768 strv_free(s->triggered);
774 static int get_next_elapse(
777 dual_timestamp *next) {
779 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
787 r = sd_bus_get_property_trivial(
789 "org.freedesktop.systemd1",
791 "org.freedesktop.systemd1.Timer",
792 "NextElapseUSecMonotonic",
797 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
801 r = sd_bus_get_property_trivial(
803 "org.freedesktop.systemd1",
805 "org.freedesktop.systemd1.Timer",
806 "NextElapseUSecRealtime",
811 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
825 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
829 if (a->next_elapse < b->next_elapse)
831 if (a->next_elapse > b->next_elapse)
834 return strcmp(a->id, b->id);
837 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
838 struct timer_info *t;
840 nextlen = sizeof("NEXT") - 1,
841 leftlen = sizeof("LEFT") - 1,
842 unitlen = sizeof("UNIT") - 1,
843 activatelen = sizeof("ACTIVATES") - 1;
845 const char *on, *off;
847 assert(timer_infos || n == 0);
849 for (t = timer_infos; t < timer_infos + n; t++) {
853 if (t->next_elapse > 0) {
854 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
856 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
857 nextlen = MAX(nextlen, strlen(tstamp) + 1);
859 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
860 leftlen = MAX(leftlen, strlen(trel));
863 unitlen = MAX(unitlen, strlen(t->id));
865 STRV_FOREACH(a, t->triggered)
866 ul += strlen(*a) + 2*(a != t->triggered);
867 activatelen = MAX(activatelen, ul);
872 printf("%-*s %-*s %-*s %s\n",
878 for (t = timer_infos; t < timer_infos + n; t++) {
879 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
882 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
883 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
885 printf("%-*s %-*s %-*s",
886 nextlen, tstamp, leftlen, trel, unitlen, t->id);
888 STRV_FOREACH(a, t->triggered)
890 a == t->triggered ? "" : ",", *a);
894 on = ansi_highlight();
895 off = ansi_highlight_off();
899 on = ansi_highlight_red();
900 off = ansi_highlight_off();
903 if (!arg_no_legend) {
904 printf("%s%u timers listed.%s\n", on, n, off);
906 printf("Pass --all to see loaded but inactive timers, too.\n");
912 static int list_timers(sd_bus *bus, char **args) {
914 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
915 _cleanup_free_ struct timer_info *timer_infos = NULL;
916 _cleanup_free_ UnitInfo *unit_infos = NULL;
917 struct timer_info *t;
924 pager_open_if_enabled();
926 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
930 dual_timestamp_get(&nw);
932 for (u = unit_infos; u < unit_infos + n; u++) {
933 _cleanup_strv_free_ char **triggered = NULL;
937 if (!endswith(u->id, ".timer"))
940 r = get_triggered_units(bus, u->unit_path, &triggered);
944 r = get_next_elapse(bus, u->unit_path, &next);
948 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
951 if (next.monotonic > nw.monotonic)
952 converted = nw.realtime + (next.monotonic - nw.monotonic);
954 converted = nw.realtime - (nw.monotonic - next.monotonic);
956 if (next.realtime != (usec_t) -1 && next.realtime > 0)
957 m = MIN(converted, next.realtime);
963 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
968 timer_infos[c++] = (struct timer_info) {
971 .triggered = triggered,
974 triggered = NULL; /* avoid cleanup */
977 qsort_safe(timer_infos, c, sizeof(struct timer_info),
978 (__compar_fn_t) timer_info_compare);
980 output_timers_list(timer_infos, c);
983 for (t = timer_infos; t < timer_infos + c; t++)
984 strv_free(t->triggered);
989 static int compare_unit_file_list(const void *a, const void *b) {
991 const UnitFileList *u = a, *v = b;
993 d1 = strrchr(u->path, '.');
994 d2 = strrchr(v->path, '.');
999 r = strcasecmp(d1, d2);
1004 return strcasecmp(basename(u->path), basename(v->path));
1007 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1010 if (!strv_isempty(patterns)) {
1013 STRV_FOREACH(pattern, patterns)
1014 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1019 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1022 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1023 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
1024 const UnitFileList *u;
1026 max_id_len = sizeof("UNIT FILE")-1;
1027 state_cols = sizeof("STATE")-1;
1029 for (u = units; u < units + c; u++) {
1030 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1031 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1035 unsigned basic_cols;
1037 id_cols = MIN(max_id_len, 25u);
1038 basic_cols = 1 + id_cols + state_cols;
1039 if (basic_cols < (unsigned) columns())
1040 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1042 id_cols = max_id_len;
1045 printf("%-*s %-*s\n",
1046 id_cols, "UNIT FILE",
1047 state_cols, "STATE");
1049 for (u = units; u < units + c; u++) {
1050 _cleanup_free_ char *e = NULL;
1051 const char *on, *off;
1056 if (u->state == UNIT_FILE_MASKED ||
1057 u->state == UNIT_FILE_MASKED_RUNTIME ||
1058 u->state == UNIT_FILE_DISABLED ||
1059 u->state == UNIT_FILE_INVALID) {
1060 on = ansi_highlight_red();
1061 off = ansi_highlight_off();
1062 } else if (u->state == UNIT_FILE_ENABLED) {
1063 on = ansi_highlight_green();
1064 off = ansi_highlight_off();
1068 id = basename(u->path);
1070 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1072 printf("%-*s %s%-*s%s\n",
1073 id_cols, e ? e : id,
1074 on, state_cols, unit_file_state_to_string(u->state), off);
1078 printf("\n%u unit files listed.\n", n_shown);
1081 static int list_unit_files(sd_bus *bus, char **args) {
1082 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1083 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1084 _cleanup_free_ UnitFileList *units = NULL;
1092 pager_open_if_enabled();
1100 h = hashmap_new(string_hash_func, string_compare_func);
1104 r = unit_file_get_list(arg_scope, arg_root, h);
1106 unit_file_list_free(h);
1107 log_error("Failed to get unit file list: %s", strerror(-r));
1111 n_units = hashmap_size(h);
1112 units = new(UnitFileList, n_units);
1114 unit_file_list_free(h);
1118 HASHMAP_FOREACH(u, h, i) {
1119 if (!output_show_unit_file(u, strv_skip_first(args)))
1126 assert(c <= n_units);
1129 r = sd_bus_call_method(
1131 "org.freedesktop.systemd1",
1132 "/org/freedesktop/systemd1",
1133 "org.freedesktop.systemd1.Manager",
1139 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1143 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1145 return bus_log_parse_error(r);
1147 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1149 if (!GREEDY_REALLOC(units, size, c + 1))
1152 units[c] = (struct UnitFileList) {
1154 unit_file_state_from_string(state)
1157 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1162 return bus_log_parse_error(r);
1164 r = sd_bus_message_exit_container(reply);
1166 return bus_log_parse_error(r);
1170 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1171 output_unit_file_list(units, c);
1175 for (unit = units; unit < units + c; unit++)
1181 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1182 _cleanup_free_ char *n = NULL;
1183 size_t max_len = MAX(columns(),20u);
1189 for (i = level - 1; i >= 0; i--) {
1191 if (len > max_len - 3 && !arg_full) {
1192 printf("%s...\n",max_len % 2 ? "" : " ");
1195 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1199 if (len > max_len - 3 && !arg_full) {
1200 printf("%s...\n",max_len % 2 ? "" : " ");
1204 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1208 printf("%s\n", name);
1212 n = ellipsize(name, max_len-len, 100);
1220 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1222 static const char *dependencies[_DEPENDENCY_MAX] = {
1223 [DEPENDENCY_FORWARD] = "Requires\0"
1224 "RequiresOverridable\0"
1226 "RequisiteOverridable\0"
1228 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1229 "RequiredByOverridable\0"
1232 [DEPENDENCY_AFTER] = "After\0",
1233 [DEPENDENCY_BEFORE] = "Before\0",
1236 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1237 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1238 _cleanup_strv_free_ char **ret = NULL;
1239 _cleanup_free_ char *path = NULL;
1245 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1247 path = unit_dbus_path_from_name(name);
1251 r = sd_bus_call_method(
1253 "org.freedesktop.systemd1",
1255 "org.freedesktop.DBus.Properties",
1259 "s", "org.freedesktop.systemd1.Unit");
1261 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1265 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1267 return bus_log_parse_error(r);
1269 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1272 r = sd_bus_message_read(reply, "s", &prop);
1274 return bus_log_parse_error(r);
1276 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1277 r = sd_bus_message_skip(reply, "v");
1279 return bus_log_parse_error(r);
1282 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1284 return bus_log_parse_error(r);
1286 r = bus_message_read_strv_extend(reply, &ret);
1288 return bus_log_parse_error(r);
1290 r = sd_bus_message_exit_container(reply);
1292 return bus_log_parse_error(r);
1295 r = sd_bus_message_exit_container(reply);
1297 return bus_log_parse_error(r);
1301 return bus_log_parse_error(r);
1303 r = sd_bus_message_exit_container(reply);
1305 return bus_log_parse_error(r);
1313 static int list_dependencies_compare(const void *_a, const void *_b) {
1314 const char **a = (const char**) _a, **b = (const char**) _b;
1316 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1318 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1321 return strcasecmp(*a, *b);
1324 static int list_dependencies_one(
1329 unsigned int branches) {
1331 _cleanup_strv_free_ char **deps = NULL;
1339 r = strv_extend(units, name);
1343 r = list_dependencies_get_dependencies(bus, name, &deps);
1347 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1349 STRV_FOREACH(c, deps) {
1352 if (strv_contains(*units, *c)) {
1354 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1361 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1363 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1365 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1367 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1371 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1372 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1379 strv_remove(*units, name);
1384 static int list_dependencies(sd_bus *bus, char **args) {
1385 _cleanup_strv_free_ char **units = NULL;
1386 _cleanup_free_ char *unit = NULL;
1392 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1397 u = SPECIAL_DEFAULT_TARGET;
1399 pager_open_if_enabled();
1403 return list_dependencies_one(bus, u, 0, &units, 0);
1406 static int get_default(sd_bus *bus, char **args) {
1407 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1408 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1409 _cleanup_free_ char *_path = NULL;
1413 if (!bus || avoid_bus()) {
1414 r = unit_file_get_default(arg_scope, arg_root, &_path);
1416 log_error("Failed to get default target: %s", strerror(-r));
1422 r = sd_bus_call_method(
1424 "org.freedesktop.systemd1",
1425 "/org/freedesktop/systemd1",
1426 "org.freedesktop.systemd1.Manager",
1432 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1436 r = sd_bus_message_read(reply, "s", &path);
1438 return bus_log_parse_error(r);
1442 printf("%s\n", path);
1447 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1450 assert(changes || n_changes == 0);
1452 for (i = 0; i < n_changes; i++) {
1453 if (changes[i].type == UNIT_FILE_SYMLINK)
1454 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1456 log_info("rm '%s'", changes[i].path);
1460 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1461 const char *type, *path, *source;
1464 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1466 return bus_log_parse_error(r);
1468 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1470 if (streq(type, "symlink"))
1471 log_info("ln -s '%s' '%s'", source, path);
1473 log_info("rm '%s'", path);
1477 return bus_log_parse_error(r);
1479 r = sd_bus_message_exit_container(m);
1481 return bus_log_parse_error(r);
1486 static int set_default(sd_bus *bus, char **args) {
1487 _cleanup_free_ char *unit = NULL;
1488 UnitFileChange *changes = NULL;
1489 unsigned n_changes = 0;
1492 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1496 if (!bus || avoid_bus()) {
1497 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1499 log_error("Failed to set default target: %s", strerror(-r));
1504 dump_unit_file_changes(changes, n_changes);
1508 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1509 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1511 r = sd_bus_call_method(
1513 "org.freedesktop.systemd1",
1514 "/org/freedesktop/systemd1",
1515 "org.freedesktop.systemd1.Manager",
1519 "sb", unit, arg_force);
1521 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1525 r = deserialize_and_dump_unit_file_changes(reply);
1529 /* Try to reload if enabeld */
1531 r = daemon_reload(bus, args);
1536 unit_file_changes_free(changes, n_changes);
1543 const char *name, *type, *state;
1546 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1547 unsigned id_len, unit_len, type_len, state_len;
1548 const struct job_info *j;
1549 const char *on, *off;
1550 bool shorten = false;
1552 assert(n == 0 || jobs);
1555 on = ansi_highlight_green();
1556 off = ansi_highlight_off();
1558 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1562 pager_open_if_enabled();
1564 id_len = sizeof("JOB")-1;
1565 unit_len = sizeof("UNIT")-1;
1566 type_len = sizeof("TYPE")-1;
1567 state_len = sizeof("STATE")-1;
1569 for (j = jobs; j < jobs + n; j++) {
1570 uint32_t id = j->id;
1571 assert(j->name && j->type && j->state);
1573 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1574 unit_len = MAX(unit_len, strlen(j->name));
1575 type_len = MAX(type_len, strlen(j->type));
1576 state_len = MAX(state_len, strlen(j->state));
1579 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1580 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1585 printf("%*s %-*s %-*s %-*s\n",
1589 state_len, "STATE");
1591 for (j = jobs; j < jobs + n; j++) {
1592 _cleanup_free_ char *e = NULL;
1594 if (streq(j->state, "running")) {
1595 on = ansi_highlight();
1596 off = ansi_highlight_off();
1600 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1601 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1603 on, unit_len, e ? e : j->name, off,
1605 on, state_len, j->state, off);
1608 if (!arg_no_legend) {
1609 on = ansi_highlight();
1610 off = ansi_highlight_off();
1612 printf("\n%s%u jobs listed%s.\n", on, n, off);
1616 static bool output_show_job(struct job_info *job, char **patterns) {
1617 if (!strv_isempty(patterns)) {
1620 STRV_FOREACH(pattern, patterns)
1621 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1629 static int list_jobs(sd_bus *bus, char **args) {
1630 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1631 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1632 const char *name, *type, *state, *job_path, *unit_path;
1633 _cleanup_free_ struct job_info *jobs = NULL;
1638 bool skipped = false;
1640 r = sd_bus_call_method(
1642 "org.freedesktop.systemd1",
1643 "/org/freedesktop/systemd1",
1644 "org.freedesktop.systemd1.Manager",
1650 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1654 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1656 return bus_log_parse_error(r);
1658 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1659 struct job_info job = { id, name, type, state };
1661 if (!output_show_job(&job, strv_skip_first(args))) {
1666 if (!GREEDY_REALLOC(jobs, size, c + 1))
1672 return bus_log_parse_error(r);
1674 r = sd_bus_message_exit_container(reply);
1676 return bus_log_parse_error(r);
1678 output_jobs_list(jobs, c, skipped);
1682 static int cancel_job(sd_bus *bus, char **args) {
1683 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1688 if (strv_length(args) <= 1)
1689 return daemon_reload(bus, args);
1691 STRV_FOREACH(name, args+1) {
1695 r = safe_atou32(*name, &id);
1697 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1701 r = sd_bus_call_method(
1703 "org.freedesktop.systemd1",
1704 "/org/freedesktop/systemd1",
1705 "org.freedesktop.systemd1.Manager",
1711 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1719 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1720 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1724 /* We ignore all errors here, since this is used to show a
1727 /* We don't use unit_dbus_path_from_name() directly since we
1728 * don't want to load the unit if it isn't loaded. */
1730 r = sd_bus_call_method(
1732 "org.freedesktop.systemd1",
1733 "/org/freedesktop/systemd1",
1734 "org.freedesktop.systemd1.Manager",
1742 r = sd_bus_message_read(reply, "o", &path);
1746 r = sd_bus_get_property_trivial(
1748 "org.freedesktop.systemd1",
1750 "org.freedesktop.systemd1.Unit",
1760 typedef struct WaitData {
1767 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1774 log_debug("Got D-Bus request: %s.%s() on %s",
1775 sd_bus_message_get_interface(m),
1776 sd_bus_message_get_member(m),
1777 sd_bus_message_get_path(m));
1779 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1780 log_error("Warning! D-Bus connection terminated.");
1782 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1784 const char *path, *result, *unit;
1788 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1790 ret = set_remove(d->set, (char*) path);
1796 if (!isempty(result))
1797 d->result = strdup(result);
1800 d->name = strdup(unit);
1805 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1807 ret = set_remove(d->set, (char*) path);
1814 d->result = strdup(result);
1820 bus_log_parse_error(r);
1826 static int enable_wait_for_jobs(sd_bus *bus) {
1831 r = sd_bus_add_match(
1834 "sender='org.freedesktop.systemd1',"
1835 "interface='org.freedesktop.systemd1.Manager',"
1836 "member='JobRemoved',"
1837 "path='/org/freedesktop/systemd1'",
1840 log_error("Failed to add match");
1844 /* This is slightly dirty, since we don't undo the match registrations. */
1848 static int bus_process_wait(sd_bus *bus) {
1852 r = sd_bus_process(bus, NULL);
1857 r = sd_bus_wait(bus, (uint64_t) -1);
1863 static int check_wait_response(WaitData *d) {
1869 if (streq(d->result, "timeout"))
1870 log_error("Job for %s timed out.", strna(d->name));
1871 else if (streq(d->result, "canceled"))
1872 log_error("Job for %s canceled.", strna(d->name));
1873 else if (streq(d->result, "dependency"))
1874 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1875 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1876 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1879 if (streq(d->result, "timeout"))
1881 else if (streq(d->result, "canceled"))
1883 else if (streq(d->result, "dependency"))
1885 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1891 static int wait_for_jobs(sd_bus *bus, Set *s) {
1892 WaitData d = { .set = s };
1898 q = sd_bus_add_filter(bus, wait_filter, &d);
1902 while (!set_isempty(s)) {
1903 q = bus_process_wait(bus);
1905 log_error("Failed to wait for response: %s", strerror(-r));
1910 q = check_wait_response(&d);
1911 /* Return the first error as it is most likely to be
1913 if (q < 0 && r == 0)
1915 log_debug("Got result %s/%s for job %s",
1916 strna(d.result), strerror(-q), strna(d.name));
1926 q = sd_bus_remove_filter(bus, wait_filter, &d);
1927 if (q < 0 && r == 0)
1933 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1934 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1935 _cleanup_free_ char *n = NULL, *state = NULL;
1941 n = unit_name_mangle(name, MANGLE_NOGLOB);
1945 /* We don't use unit_dbus_path_from_name() directly since we
1946 * don't want to load the unit if it isn't loaded. */
1948 r = sd_bus_call_method(
1950 "org.freedesktop.systemd1",
1951 "/org/freedesktop/systemd1",
1952 "org.freedesktop.systemd1.Manager",
1963 r = sd_bus_message_read(reply, "o", &path);
1965 return bus_log_parse_error(r);
1967 r = sd_bus_get_property_string(
1969 "org.freedesktop.systemd1",
1971 "org.freedesktop.systemd1.Unit",
1984 return nulstr_contains(good_states, state);
1987 static int check_triggering_units(
1991 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1992 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1993 _cleanup_strv_free_ char **triggered_by = NULL;
1994 bool print_warning_label = true;
1998 n = unit_name_mangle(name, MANGLE_NOGLOB);
2002 path = unit_dbus_path_from_name(n);
2006 r = sd_bus_get_property_string(
2008 "org.freedesktop.systemd1",
2010 "org.freedesktop.systemd1.Unit",
2015 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2019 if (streq(state, "masked"))
2022 r = sd_bus_get_property_strv(
2024 "org.freedesktop.systemd1",
2026 "org.freedesktop.systemd1.Unit",
2031 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2035 STRV_FOREACH(i, triggered_by) {
2036 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2038 log_error("Failed to check unit: %s", strerror(-r));
2045 if (print_warning_label) {
2046 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2047 print_warning_label = false;
2050 log_warning(" %s", *i);
2056 static const char *verb_to_method(const char *verb) {
2059 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2060 if (streq_ptr(unit_actions[i].verb, verb))
2061 return unit_actions[i].method;
2066 static const char *method_to_verb(const char *method) {
2069 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2070 if (streq_ptr(unit_actions[i].method, method))
2071 return unit_actions[i].verb;
2076 static int start_unit_one(
2081 sd_bus_error *error,
2084 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2093 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2094 r = sd_bus_call_method(
2096 "org.freedesktop.systemd1",
2097 "/org/freedesktop/systemd1",
2098 "org.freedesktop.systemd1.Manager",
2106 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2107 /* There's always a fallback possible for
2108 * legacy actions. */
2109 return -EADDRNOTAVAIL;
2111 verb = method_to_verb(method);
2113 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2117 r = sd_bus_message_read(reply, "o", &path);
2119 return bus_log_parse_error(r);
2121 if (need_daemon_reload(bus, name) > 0)
2122 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2123 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2132 log_debug("Adding %s to the set", p);
2133 r = set_consume(s, p);
2141 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2143 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2144 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2148 STRV_FOREACH(name, names) {
2152 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2154 t = unit_name_mangle(*name, MANGLE_GLOB);
2158 if (string_is_glob(t))
2159 r = strv_push(&globs, t);
2161 r = strv_push(&mangled, t);
2168 /* Query the manager only if any of the names are a glob, since
2169 * this is fairly expensive */
2170 if (!strv_isempty(globs)) {
2171 _cleanup_free_ UnitInfo *unit_infos = NULL;
2173 r = get_unit_list(bus, &reply, &unit_infos, globs);
2177 for (i = 0; i < r; i++)
2178 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2183 mangled = NULL; /* do not free */
2187 static const struct {
2191 } action_table[_ACTION_MAX] = {
2192 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2193 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2194 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2195 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2196 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2197 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2198 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2199 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2200 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2201 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2202 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2203 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2204 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2205 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2206 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2209 static enum action verb_to_action(const char *verb) {
2212 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2213 if (streq_ptr(action_table[i].verb, verb))
2216 return _ACTION_INVALID;
2219 static int start_unit(sd_bus *bus, char **args) {
2220 _cleanup_set_free_free_ Set *s = NULL;
2221 _cleanup_strv_free_ char **names = NULL;
2222 const char *method, *mode, *one_name;
2228 ask_password_agent_open_if_enabled();
2230 if (arg_action == ACTION_SYSTEMCTL) {
2232 method = verb_to_method(args[0]);
2233 action = verb_to_action(args[0]);
2235 mode = streq(args[0], "isolate") ? "isolate" :
2236 action_table[action].mode ?: arg_job_mode;
2238 one_name = action_table[action].target;
2240 assert(arg_action < ELEMENTSOF(action_table));
2241 assert(action_table[arg_action].target);
2243 method = "StartUnit";
2245 mode = action_table[arg_action].mode;
2246 one_name = action_table[arg_action].target;
2250 names = strv_new(one_name, NULL);
2252 r = expand_names(bus, args + 1, NULL, &names);
2254 log_error("Failed to expand names: %s", strerror(-r));
2257 if (!arg_no_block) {
2258 r = enable_wait_for_jobs(bus);
2260 log_error("Could not watch jobs: %s", strerror(-r));
2264 s = set_new(string_hash_func, string_compare_func);
2269 STRV_FOREACH(name, names) {
2270 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2273 q = start_unit_one(bus, method, *name, mode, &error, s);
2274 if (r >= 0 && q < 0)
2275 r = translate_bus_error_to_exit_status(q, &error);
2278 if (!arg_no_block) {
2281 q = wait_for_jobs(bus, s);
2285 /* When stopping units, warn if they can still be triggered by
2286 * another active unit (socket, path, timer) */
2287 if (!arg_quiet && streq(method, "StopUnit"))
2288 STRV_FOREACH(name, names)
2289 check_triggering_units(bus, *name);
2295 /* Ask systemd-logind, which might grant access to unprivileged users
2296 * through PolicyKit */
2297 static int reboot_with_logind(sd_bus *bus, enum action a) {
2299 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2306 polkit_agent_open_if_enabled();
2314 case ACTION_POWEROFF:
2315 method = "PowerOff";
2318 case ACTION_SUSPEND:
2322 case ACTION_HIBERNATE:
2323 method = "Hibernate";
2326 case ACTION_HYBRID_SLEEP:
2327 method = "HybridSleep";
2334 r = sd_bus_call_method(
2336 "org.freedesktop.login1",
2337 "/org/freedesktop/login1",
2338 "org.freedesktop.login1.Manager",
2344 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2352 static int check_inhibitors(sd_bus *bus, enum action a) {
2354 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2355 _cleanup_strv_free_ char **sessions = NULL;
2356 const char *what, *who, *why, *mode;
2365 if (arg_ignore_inhibitors || arg_force > 0)
2377 r = sd_bus_call_method(
2379 "org.freedesktop.login1",
2380 "/org/freedesktop/login1",
2381 "org.freedesktop.login1.Manager",
2387 /* If logind is not around, then there are no inhibitors... */
2390 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2392 return bus_log_parse_error(r);
2394 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2395 _cleanup_free_ char *comm = NULL, *user = NULL;
2396 _cleanup_strv_free_ char **sv = NULL;
2398 if (!streq(mode, "block"))
2401 sv = strv_split(what, ":");
2405 if (!strv_contains(sv,
2407 a == ACTION_POWEROFF ||
2408 a == ACTION_REBOOT ||
2409 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2412 get_process_comm(pid, &comm);
2413 user = uid_to_name(uid);
2415 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2416 who, (unsigned long) pid, strna(comm), strna(user), why);
2421 return bus_log_parse_error(r);
2423 r = sd_bus_message_exit_container(reply);
2425 return bus_log_parse_error(r);
2427 /* Check for current sessions */
2428 sd_get_sessions(&sessions);
2429 STRV_FOREACH(s, sessions) {
2430 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2432 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2435 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2438 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2441 sd_session_get_tty(*s, &tty);
2442 sd_session_get_seat(*s, &seat);
2443 sd_session_get_service(*s, &service);
2444 user = uid_to_name(uid);
2446 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2453 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2454 action_table[a].verb);
2462 static int start_special(sd_bus *bus, char **args) {
2468 a = verb_to_action(args[0]);
2470 r = check_inhibitors(bus, a);
2474 if (arg_force >= 2 && geteuid() != 0) {
2475 log_error("Must be root.");
2479 if (arg_force >= 2 &&
2480 (a == ACTION_HALT ||
2481 a == ACTION_POWEROFF ||
2482 a == ACTION_REBOOT))
2485 if (arg_force >= 1 &&
2486 (a == ACTION_HALT ||
2487 a == ACTION_POWEROFF ||
2488 a == ACTION_REBOOT ||
2489 a == ACTION_KEXEC ||
2491 return daemon_reload(bus, args);
2493 /* first try logind, to allow authentication with polkit */
2494 if (geteuid() != 0 &&
2495 (a == ACTION_POWEROFF ||
2496 a == ACTION_REBOOT ||
2497 a == ACTION_SUSPEND ||
2498 a == ACTION_HIBERNATE ||
2499 a == ACTION_HYBRID_SLEEP)) {
2500 r = reboot_with_logind(bus, a);
2505 r = start_unit(bus, args);
2506 if (r == EXIT_SUCCESS)
2512 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2513 _cleanup_strv_free_ char **names = NULL;
2520 r = expand_names(bus, args, NULL, &names);
2522 log_error("Failed to expand names: %s", strerror(-r));
2524 STRV_FOREACH(name, names) {
2527 state = check_one_unit(bus, *name, good_states, arg_quiet);
2537 static int check_unit_active(sd_bus *bus, char **args) {
2538 /* According to LSB: 3, "program is not running" */
2539 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2542 static int check_unit_failed(sd_bus *bus, char **args) {
2543 return check_unit_generic(bus, 1, "failed\0", args + 1);
2546 static int kill_unit(sd_bus *bus, char **args) {
2547 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2548 _cleanup_strv_free_ char **names = NULL;
2556 arg_kill_who = "all";
2558 r = expand_names(bus, args + 1, NULL, &names);
2560 log_error("Failed to expand names: %s", strerror(-r));
2562 STRV_FOREACH(name, names) {
2563 q = sd_bus_call_method(
2565 "org.freedesktop.systemd1",
2566 "/org/freedesktop/systemd1",
2567 "org.freedesktop.systemd1.Manager",
2571 "ssi", *names, arg_kill_who, arg_signal);
2573 log_error("Failed to kill unit %s: %s",
2574 *names, bus_error_message(&error, r));
2583 typedef struct ExecStatusInfo {
2591 usec_t start_timestamp;
2592 usec_t exit_timestamp;
2597 LIST_FIELDS(struct ExecStatusInfo, exec);
2600 static void exec_status_info_free(ExecStatusInfo *i) {
2609 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2610 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2613 int32_t code, status;
2619 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2621 return bus_log_parse_error(r);
2625 r = sd_bus_message_read(m, "s", &path);
2627 return bus_log_parse_error(r);
2629 i->path = strdup(path);
2633 r = sd_bus_message_read_strv(m, &i->argv);
2635 return bus_log_parse_error(r);
2637 r = sd_bus_message_read(m,
2640 &start_timestamp, &start_timestamp_monotonic,
2641 &exit_timestamp, &exit_timestamp_monotonic,
2645 return bus_log_parse_error(r);
2648 i->start_timestamp = (usec_t) start_timestamp;
2649 i->exit_timestamp = (usec_t) exit_timestamp;
2650 i->pid = (pid_t) pid;
2654 r = sd_bus_message_exit_container(m);
2656 return bus_log_parse_error(r);
2661 typedef struct UnitStatusInfo {
2663 const char *load_state;
2664 const char *active_state;
2665 const char *sub_state;
2666 const char *unit_file_state;
2668 const char *description;
2669 const char *following;
2671 char **documentation;
2673 const char *fragment_path;
2674 const char *source_path;
2675 const char *control_group;
2677 char **dropin_paths;
2679 const char *load_error;
2682 usec_t inactive_exit_timestamp;
2683 usec_t inactive_exit_timestamp_monotonic;
2684 usec_t active_enter_timestamp;
2685 usec_t active_exit_timestamp;
2686 usec_t inactive_enter_timestamp;
2688 bool need_daemon_reload;
2693 const char *status_text;
2694 const char *pid_file;
2697 usec_t start_timestamp;
2698 usec_t exit_timestamp;
2700 int exit_code, exit_status;
2702 usec_t condition_timestamp;
2703 bool condition_result;
2704 bool failed_condition_trigger;
2705 bool failed_condition_negate;
2706 const char *failed_condition;
2707 const char *failed_condition_param;
2710 unsigned n_accepted;
2711 unsigned n_connections;
2714 /* Pairs of type, path */
2718 const char *sysfs_path;
2720 /* Mount, Automount */
2726 LIST_HEAD(ExecStatusInfo, exec);
2729 static void print_status_info(
2734 const char *on, *off, *ss;
2736 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2737 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2740 arg_all * OUTPUT_SHOW_ALL |
2741 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2742 on_tty() * OUTPUT_COLOR |
2743 !arg_quiet * OUTPUT_WARN_CUTOFF |
2744 arg_full * OUTPUT_FULL_WIDTH;
2749 /* This shows pretty information about a unit. See
2750 * print_property() for a low-level property printer */
2752 printf("%s", strna(i->id));
2754 if (i->description && !streq_ptr(i->id, i->description))
2755 printf(" - %s", i->description);
2760 printf(" Follow: unit currently follows state of %s\n", i->following);
2762 if (streq_ptr(i->load_state, "error")) {
2763 on = ansi_highlight_red();
2764 off = ansi_highlight_off();
2768 path = i->source_path ? i->source_path : i->fragment_path;
2771 printf(" Loaded: %s%s%s (Reason: %s)\n",
2772 on, strna(i->load_state), off, i->load_error);
2773 else if (path && i->unit_file_state)
2774 printf(" Loaded: %s%s%s (%s; %s)\n",
2775 on, strna(i->load_state), off, path, i->unit_file_state);
2777 printf(" Loaded: %s%s%s (%s)\n",
2778 on, strna(i->load_state), off, path);
2780 printf(" Loaded: %s%s%s\n",
2781 on, strna(i->load_state), off);
2783 if (!strv_isempty(i->dropin_paths)) {
2784 _cleanup_free_ char *dir = NULL;
2788 STRV_FOREACH(dropin, i->dropin_paths) {
2789 if (! dir || last) {
2790 printf(dir ? " " : " Drop-In: ");
2795 if (path_get_parent(*dropin, &dir) < 0) {
2800 printf("%s\n %s", dir,
2801 draw_special_char(DRAW_TREE_RIGHT));
2804 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2806 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2810 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2812 if (streq_ptr(i->active_state, "failed")) {
2813 on = ansi_highlight_red();
2814 off = ansi_highlight_off();
2815 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2816 on = ansi_highlight_green();
2817 off = ansi_highlight_off();
2822 printf(" Active: %s%s (%s)%s",
2823 on, strna(i->active_state), ss, off);
2825 printf(" Active: %s%s%s",
2826 on, strna(i->active_state), off);
2828 if (!isempty(i->result) && !streq(i->result, "success"))
2829 printf(" (Result: %s)", i->result);
2831 timestamp = (streq_ptr(i->active_state, "active") ||
2832 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2833 (streq_ptr(i->active_state, "inactive") ||
2834 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2835 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2836 i->active_exit_timestamp;
2838 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2839 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2842 printf(" since %s; %s\n", s2, s1);
2844 printf(" since %s\n", s2);
2848 if (!i->condition_result && i->condition_timestamp > 0) {
2849 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2850 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2852 printf(" start condition failed at %s%s%s\n",
2853 s2, s1 ? "; " : "", s1 ? s1 : "");
2854 if (i->failed_condition_trigger)
2855 printf(" none of the trigger conditions were met\n");
2856 else if (i->failed_condition)
2857 printf(" %s=%s%s was not met\n",
2858 i->failed_condition,
2859 i->failed_condition_negate ? "!" : "",
2860 i->failed_condition_param);
2864 printf(" Device: %s\n", i->sysfs_path);
2866 printf(" Where: %s\n", i->where);
2868 printf(" What: %s\n", i->what);
2870 STRV_FOREACH(t, i->documentation)
2871 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2873 STRV_FOREACH_PAIR(t, t2, i->listen)
2874 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2877 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2879 LIST_FOREACH(exec, p, i->exec) {
2880 _cleanup_free_ char *argv = NULL;
2883 /* Only show exited processes here */
2887 argv = strv_join(p->argv, " ");
2888 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2890 good = is_clean_exit_lsb(p->code, p->status, NULL);
2892 on = ansi_highlight_red();
2893 off = ansi_highlight_off();
2897 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2899 if (p->code == CLD_EXITED) {
2902 printf("status=%i", p->status);
2904 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2909 printf("signal=%s", signal_to_string(p->status));
2911 printf(")%s\n", off);
2913 if (i->main_pid == p->pid &&
2914 i->start_timestamp == p->start_timestamp &&
2915 i->exit_timestamp == p->start_timestamp)
2916 /* Let's not show this twice */
2919 if (p->pid == i->control_pid)
2923 if (i->main_pid > 0 || i->control_pid > 0) {
2924 if (i->main_pid > 0) {
2925 printf(" Main PID: %u", (unsigned) i->main_pid);
2928 _cleanup_free_ char *comm = NULL;
2929 get_process_comm(i->main_pid, &comm);
2931 printf(" (%s)", comm);
2932 } else if (i->exit_code > 0) {
2933 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2935 if (i->exit_code == CLD_EXITED) {
2938 printf("status=%i", i->exit_status);
2940 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2945 printf("signal=%s", signal_to_string(i->exit_status));
2949 if (i->control_pid > 0)
2953 if (i->control_pid > 0) {
2954 _cleanup_free_ char *c = NULL;
2956 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2958 get_process_comm(i->control_pid, &c);
2967 printf(" Status: \"%s\"\n", i->status_text);
2969 if (i->control_group &&
2970 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2973 printf(" CGroup: %s\n", i->control_group);
2975 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2978 char prefix[] = " ";
2981 if (c > sizeof(prefix) - 1)
2982 c -= sizeof(prefix) - 1;
2986 if (i->main_pid > 0)
2987 extra[k++] = i->main_pid;
2989 if (i->control_pid > 0)
2990 extra[k++] = i->control_pid;
2992 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2993 c, false, extra, k, flags);
2997 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2999 show_journal_by_unit(stdout,
3003 i->inactive_exit_timestamp_monotonic,
3007 arg_scope == UNIT_FILE_SYSTEM,
3011 if (i->need_daemon_reload)
3012 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
3013 ansi_highlight_red(),
3014 ansi_highlight_off(),
3015 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
3018 static void show_unit_help(UnitStatusInfo *i) {
3023 if (!i->documentation) {
3024 log_info("Documentation for %s not known.", i->id);
3028 STRV_FOREACH(p, i->documentation) {
3030 if (startswith(*p, "man:")) {
3031 const char *args[4] = { "man", NULL, NULL, NULL };
3032 _cleanup_free_ char *page = NULL, *section = NULL;
3039 if ((*p)[k-1] == ')')
3040 e = strrchr(*p, '(');
3043 page = strndup((*p) + 4, e - *p - 4);
3044 section = strndup(e + 1, *p + k - e - 2);
3045 if (!page || !section) {
3057 log_error("Failed to fork: %m");
3063 execvp(args[0], (char**) args);
3064 log_error("Failed to execute man: %m");
3065 _exit(EXIT_FAILURE);
3068 wait_for_terminate(pid, NULL);
3070 log_info("Can't show: %s", *p);
3074 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3081 switch (contents[0]) {
3083 case SD_BUS_TYPE_STRING: {
3086 r = sd_bus_message_read(m, "s", &s);
3088 return bus_log_parse_error(r);
3091 if (streq(name, "Id"))
3093 else if (streq(name, "LoadState"))
3095 else if (streq(name, "ActiveState"))
3096 i->active_state = s;
3097 else if (streq(name, "SubState"))
3099 else if (streq(name, "Description"))
3101 else if (streq(name, "FragmentPath"))
3102 i->fragment_path = s;
3103 else if (streq(name, "SourcePath"))
3106 else if (streq(name, "DefaultControlGroup")) {
3108 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3110 i->control_group = e;
3113 else if (streq(name, "ControlGroup"))
3114 i->control_group = s;
3115 else if (streq(name, "StatusText"))
3117 else if (streq(name, "PIDFile"))
3119 else if (streq(name, "SysFSPath"))
3121 else if (streq(name, "Where"))
3123 else if (streq(name, "What"))
3125 else if (streq(name, "Following"))
3127 else if (streq(name, "UnitFileState"))
3128 i->unit_file_state = s;
3129 else if (streq(name, "Result"))
3136 case SD_BUS_TYPE_BOOLEAN: {
3139 r = sd_bus_message_read(m, "b", &b);
3141 return bus_log_parse_error(r);
3143 if (streq(name, "Accept"))
3145 else if (streq(name, "NeedDaemonReload"))
3146 i->need_daemon_reload = b;
3147 else if (streq(name, "ConditionResult"))
3148 i->condition_result = b;
3153 case SD_BUS_TYPE_UINT32: {
3156 r = sd_bus_message_read(m, "u", &u);
3158 return bus_log_parse_error(r);
3160 if (streq(name, "MainPID")) {
3162 i->main_pid = (pid_t) u;
3165 } else if (streq(name, "ControlPID"))
3166 i->control_pid = (pid_t) u;
3167 else if (streq(name, "ExecMainPID")) {
3169 i->main_pid = (pid_t) u;
3170 } else if (streq(name, "NAccepted"))
3172 else if (streq(name, "NConnections"))
3173 i->n_connections = u;
3178 case SD_BUS_TYPE_INT32: {
3181 r = sd_bus_message_read(m, "i", &j);
3183 return bus_log_parse_error(r);
3185 if (streq(name, "ExecMainCode"))
3186 i->exit_code = (int) j;
3187 else if (streq(name, "ExecMainStatus"))
3188 i->exit_status = (int) j;
3193 case SD_BUS_TYPE_UINT64: {
3196 r = sd_bus_message_read(m, "t", &u);
3198 return bus_log_parse_error(r);
3200 if (streq(name, "ExecMainStartTimestamp"))
3201 i->start_timestamp = (usec_t) u;
3202 else if (streq(name, "ExecMainExitTimestamp"))
3203 i->exit_timestamp = (usec_t) u;
3204 else if (streq(name, "ActiveEnterTimestamp"))
3205 i->active_enter_timestamp = (usec_t) u;
3206 else if (streq(name, "InactiveEnterTimestamp"))
3207 i->inactive_enter_timestamp = (usec_t) u;
3208 else if (streq(name, "InactiveExitTimestamp"))
3209 i->inactive_exit_timestamp = (usec_t) u;
3210 else if (streq(name, "InactiveExitTimestampMonotonic"))
3211 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3212 else if (streq(name, "ActiveExitTimestamp"))
3213 i->active_exit_timestamp = (usec_t) u;
3214 else if (streq(name, "ConditionTimestamp"))
3215 i->condition_timestamp = (usec_t) u;
3220 case SD_BUS_TYPE_ARRAY:
3222 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3223 _cleanup_free_ ExecStatusInfo *info = NULL;
3225 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3227 return bus_log_parse_error(r);
3229 info = new0(ExecStatusInfo, 1);
3233 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3235 info->name = strdup(name);
3239 LIST_PREPEND(exec, i->exec, info);
3241 info = new0(ExecStatusInfo, 1);
3247 return bus_log_parse_error(r);
3249 r = sd_bus_message_exit_container(m);
3251 return bus_log_parse_error(r);
3255 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3256 const char *type, *path;
3258 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3260 return bus_log_parse_error(r);
3262 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3264 r = strv_extend(&i->listen, type);
3268 r = strv_extend(&i->listen, path);
3273 return bus_log_parse_error(r);
3275 r = sd_bus_message_exit_container(m);
3277 return bus_log_parse_error(r);
3281 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3283 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3285 return bus_log_parse_error(r);
3287 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3289 r = sd_bus_message_read_strv(m, &i->documentation);
3291 return bus_log_parse_error(r);
3293 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3294 const char *cond, *param;
3295 int trigger, negate;
3298 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3300 return bus_log_parse_error(r);
3302 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3303 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3304 if (state < 0 && (!trigger || !i->failed_condition)) {
3305 i->failed_condition = cond;
3306 i->failed_condition_trigger = trigger;
3307 i->failed_condition_negate = negate;
3308 i->failed_condition_param = param;
3312 return bus_log_parse_error(r);
3314 r = sd_bus_message_exit_container(m);
3316 return bus_log_parse_error(r);
3323 case SD_BUS_TYPE_STRUCT_BEGIN:
3325 if (streq(name, "LoadError")) {
3326 const char *n, *message;
3328 r = sd_bus_message_read(m, "(ss)", &n, &message);
3330 return bus_log_parse_error(r);
3332 if (!isempty(message))
3333 i->load_error = message;
3346 r = sd_bus_message_skip(m, contents);
3348 return bus_log_parse_error(r);
3353 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3359 /* This is a low-level property printer, see
3360 * print_status_info() for the nicer output */
3362 if (arg_properties && !strv_find(arg_properties, name)) {
3363 /* skip what we didn't read */
3364 r = sd_bus_message_skip(m, contents);
3368 switch (contents[0]) {
3370 case SD_BUS_TYPE_STRUCT_BEGIN:
3372 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3375 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3377 return bus_log_parse_error(r);
3380 printf("%s=%u\n", name, (unsigned) u);
3382 printf("%s=\n", name);
3386 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3389 r = sd_bus_message_read(m, "(so)", &s, NULL);
3391 return bus_log_parse_error(r);
3393 if (arg_all || !isempty(s))
3394 printf("%s=%s\n", name, s);
3398 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3399 const char *a = NULL, *b = NULL;
3401 r = sd_bus_message_read(m, "(ss)", &a, &b);
3403 return bus_log_parse_error(r);
3405 if (arg_all || !isempty(a) || !isempty(b))
3406 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3413 case SD_BUS_TYPE_ARRAY:
3415 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3419 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3421 return bus_log_parse_error(r);
3423 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3424 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3427 return bus_log_parse_error(r);
3429 r = sd_bus_message_exit_container(m);
3431 return bus_log_parse_error(r);
3435 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3436 const char *type, *path;
3438 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3440 return bus_log_parse_error(r);
3442 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3443 printf("%s=%s\n", type, path);
3445 return bus_log_parse_error(r);
3447 r = sd_bus_message_exit_container(m);
3449 return bus_log_parse_error(r);
3453 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3454 const char *type, *path;
3456 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3458 return bus_log_parse_error(r);
3460 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3461 printf("Listen%s=%s\n", type, path);
3463 return bus_log_parse_error(r);
3465 r = sd_bus_message_exit_container(m);
3467 return bus_log_parse_error(r);
3471 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3473 uint64_t value, next_elapse;
3475 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3477 return bus_log_parse_error(r);
3479 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3480 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3482 printf("%s={ value=%s ; next_elapse=%s }\n",
3484 format_timespan(timespan1, sizeof(timespan1), value, 0),
3485 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3488 return bus_log_parse_error(r);
3490 r = sd_bus_message_exit_container(m);
3492 return bus_log_parse_error(r);
3496 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3497 ExecStatusInfo info = {};
3499 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3501 return bus_log_parse_error(r);
3503 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3504 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3505 _cleanup_free_ char *tt;
3507 tt = strv_join(info.argv, " ");
3509 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3513 yes_no(info.ignore),
3514 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3515 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3516 (unsigned) info. pid,
3517 sigchld_code_to_string(info.code),
3519 info.code == CLD_EXITED ? "" : "/",
3520 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3523 strv_free(info.argv);
3527 r = sd_bus_message_exit_container(m);
3529 return bus_log_parse_error(r);
3533 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3534 const char *path, *rwm;
3536 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3538 return bus_log_parse_error(r);
3540 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3541 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3543 return bus_log_parse_error(r);
3545 r = sd_bus_message_exit_container(m);
3547 return bus_log_parse_error(r);
3551 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3555 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3557 return bus_log_parse_error(r);
3559 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3560 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3562 return bus_log_parse_error(r);
3564 r = sd_bus_message_exit_container(m);
3566 return bus_log_parse_error(r);
3570 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3574 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3576 return bus_log_parse_error(r);
3578 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3579 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3581 return bus_log_parse_error(r);
3583 r = sd_bus_message_exit_container(m);
3585 return bus_log_parse_error(r);
3593 r = bus_print_property(name, m, arg_all);
3595 return bus_log_parse_error(r);
3598 r = sd_bus_message_skip(m, contents);
3600 return bus_log_parse_error(r);
3603 printf("%s=[unprintable]\n", name);
3609 static int show_one(
3613 bool show_properties,
3617 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3618 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3619 UnitStatusInfo info = {};
3626 log_debug("Showing one %s", path);
3628 r = sd_bus_call_method(
3630 "org.freedesktop.systemd1",
3632 "org.freedesktop.DBus.Properties",
3638 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3642 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3644 return bus_log_parse_error(r);
3651 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3652 const char *name, *contents;
3654 r = sd_bus_message_read(reply, "s", &name);
3656 return bus_log_parse_error(r);
3658 r = sd_bus_message_peek_type(reply, NULL, &contents);
3660 return bus_log_parse_error(r);
3662 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3664 return bus_log_parse_error(r);
3666 if (show_properties)
3667 r = print_property(name, reply, contents);
3669 r = status_property(name, reply, &info, contents);
3673 r = sd_bus_message_exit_container(reply);
3675 return bus_log_parse_error(r);
3677 r = sd_bus_message_exit_container(reply);
3679 return bus_log_parse_error(r);
3682 return bus_log_parse_error(r);
3684 r = sd_bus_message_exit_container(reply);
3686 return bus_log_parse_error(r);
3690 if (!show_properties) {
3691 if (streq(verb, "help"))
3692 show_unit_help(&info);
3694 print_status_info(&info, ellipsized);
3697 strv_free(info.documentation);
3698 strv_free(info.dropin_paths);
3699 strv_free(info.listen);
3701 if (!streq_ptr(info.active_state, "active") &&
3702 !streq_ptr(info.active_state, "reloading") &&
3703 streq(verb, "status")) {
3704 /* According to LSB: "program not running" */
3705 /* 0: program is running or service is OK
3706 * 1: program is dead and /var/run pid file exists
3707 * 2: program is dead and /var/lock lock file exists
3708 * 3: program is not running
3709 * 4: program or service status is unknown
3711 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3717 while ((p = info.exec)) {
3718 LIST_REMOVE(exec, info.exec, p);
3719 exec_status_info_free(p);
3725 static int get_unit_dbus_path_by_pid(
3730 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3731 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3735 r = sd_bus_call_method(
3737 "org.freedesktop.systemd1",
3738 "/org/freedesktop/systemd1",
3739 "org.freedesktop.systemd1.Manager",
3745 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3749 r = sd_bus_message_read(reply, "o", &u);
3751 return bus_log_parse_error(r);
3761 static int show_all(
3764 bool show_properties,
3768 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3769 _cleanup_free_ UnitInfo *unit_infos = NULL;
3774 r = get_unit_list(bus, &reply, &unit_infos, NULL);
3778 pager_open_if_enabled();
3782 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3784 for (u = unit_infos; u < unit_infos + c; u++) {
3785 _cleanup_free_ char *p = NULL;
3787 p = unit_dbus_path_from_name(u->id);
3791 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3799 static int cat(sd_bus *bus, char **args) {
3800 _cleanup_free_ char *unit = NULL;
3801 _cleanup_strv_free_ char **names = NULL;
3809 r = expand_names(bus, args + 1, NULL, &names);
3811 log_error("Failed to expand names: %s", strerror(-r));
3813 pager_open_if_enabled();
3815 STRV_FOREACH(name, names) {
3816 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3817 _cleanup_strv_free_ char **dropin_paths = NULL;
3818 _cleanup_free_ char *fragment_path = NULL;
3821 unit = unit_dbus_path_from_name(*name);
3825 if (need_daemon_reload(bus, *name) > 0)
3826 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3827 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3829 r = sd_bus_get_property_string(
3831 "org.freedesktop.systemd1",
3833 "org.freedesktop.systemd1.Unit",
3838 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3842 r = sd_bus_get_property_strv(
3844 "org.freedesktop.systemd1",
3846 "org.freedesktop.systemd1.Unit",
3851 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3860 if (!isempty(fragment_path)) {
3861 printf("%s# %s%s\n",
3862 ansi_highlight_blue(),
3864 ansi_highlight_off());
3867 r = sendfile_full(STDOUT_FILENO, fragment_path);
3869 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3874 STRV_FOREACH(path, dropin_paths) {
3875 printf("%s%s# %s%s\n",
3876 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3877 ansi_highlight_blue(),
3879 ansi_highlight_off());
3882 r = sendfile_full(STDOUT_FILENO, *path);
3884 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3890 return r < 0 ? r : 0;
3893 static int show(sd_bus *bus, char **args) {
3894 bool show_properties, show_status, new_line = false;
3895 bool ellipsized = false;
3901 show_properties = streq(args[0], "show");
3902 show_status = streq(args[0], "status");
3904 if (show_properties)
3905 pager_open_if_enabled();
3907 /* If no argument is specified inspect the manager itself */
3909 if (show_properties && strv_length(args) <= 1)
3910 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3912 if (show_status && strv_length(args) <= 1)
3913 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3915 _cleanup_free_ char **patterns = NULL;
3918 STRV_FOREACH(name, args + 1) {
3919 _cleanup_free_ char *unit = NULL;
3922 if (safe_atou32(*name, &id) < 0) {
3923 if (strv_push(&patterns, *name) < 0)
3927 } else if (show_properties) {
3928 /* Interpret as job id */
3929 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3933 /* Interpret as PID */
3934 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3941 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3944 if (!strv_isempty(patterns)) {
3945 _cleanup_strv_free_ char **names = NULL;
3947 r = expand_names(bus, patterns, NULL, &names);
3949 log_error("Failed to expand names: %s", strerror(-r));
3951 STRV_FOREACH(name, names) {
3952 _cleanup_free_ char *unit;
3954 unit = unit_dbus_path_from_name(*name);
3958 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3963 if (ellipsized && !arg_quiet)
3964 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3969 static int append_assignment(sd_bus_message *m, const char *assignment) {
3977 eq = strchr(assignment, '=');
3979 log_error("Not an assignment: %s", assignment);
3983 field = strndupa(assignment, eq - assignment);
3986 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3988 return bus_log_create_error(r);
3990 if (streq(field, "CPUAccounting") ||
3991 streq(field, "MemoryAccounting") ||
3992 streq(field, "BlockIOAccounting")) {
3994 r = parse_boolean(eq);
3996 log_error("Failed to parse boolean assignment %s.", assignment);
4000 r = sd_bus_message_append(m, "v", "b", r);
4002 } else if (streq(field, "MemoryLimit")) {
4005 r = parse_bytes(eq, &bytes);
4007 log_error("Failed to parse bytes specification %s", assignment);
4011 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
4013 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
4016 r = safe_atou64(eq, &u);
4018 log_error("Failed to parse %s value %s.", field, eq);
4022 r = sd_bus_message_append(m, "v", "t", u);
4024 } else if (streq(field, "DevicePolicy"))
4025 r = sd_bus_message_append(m, "v", "s", eq);
4027 else if (streq(field, "DeviceAllow")) {
4030 r = sd_bus_message_append(m, "v", "a(ss)", 0);
4032 const char *path, *rwm;
4035 e = strchr(eq, ' ');
4037 path = strndupa(eq, e - eq);
4044 if (!path_startswith(path, "/dev")) {
4045 log_error("%s is not a device file in /dev.", path);
4049 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
4052 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
4055 r = sd_bus_message_append(m, "v", "a(st)", 0);
4057 const char *path, *bandwidth;
4061 e = strchr(eq, ' ');
4063 path = strndupa(eq, e - eq);
4066 log_error("Failed to parse %s value %s.", field, eq);
4070 if (!path_startswith(path, "/dev")) {
4071 log_error("%s is not a device file in /dev.", path);
4075 r = parse_bytes(bandwidth, &bytes);
4077 log_error("Failed to parse byte value %s.", bandwidth);
4081 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4084 } else if (streq(field, "BlockIODeviceWeight")) {
4087 r = sd_bus_message_append(m, "v", "a(st)", 0);
4089 const char *path, *weight;
4093 e = strchr(eq, ' ');
4095 path = strndupa(eq, e - eq);
4098 log_error("Failed to parse %s value %s.", field, eq);
4102 if (!path_startswith(path, "/dev")) {
4103 log_error("%s is not a device file in /dev.", path);
4107 r = safe_atou64(weight, &u);
4109 log_error("Failed to parse %s value %s.", field, weight);
4112 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4116 log_error("Unknown assignment %s.", assignment);
4121 return bus_log_create_error(r);
4126 static int set_property(sd_bus *bus, char **args) {
4127 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4128 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4129 _cleanup_free_ char *n = NULL;
4133 r = sd_bus_message_new_method_call(
4135 "org.freedesktop.systemd1",
4136 "/org/freedesktop/systemd1",
4137 "org.freedesktop.systemd1.Manager",
4138 "SetUnitProperties",
4141 return bus_log_create_error(r);
4143 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4147 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4149 return bus_log_create_error(r);
4151 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4153 return bus_log_create_error(r);
4155 STRV_FOREACH(i, args + 2) {
4156 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4158 return bus_log_create_error(r);
4160 r = append_assignment(m, *i);
4164 r = sd_bus_message_close_container(m);
4166 return bus_log_create_error(r);
4169 r = sd_bus_message_close_container(m);
4171 return bus_log_create_error(r);
4173 r = sd_bus_call(bus, m, 0, &error, NULL);
4175 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4182 static int snapshot(sd_bus *bus, char **args) {
4183 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4184 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4185 _cleanup_free_ char *n = NULL, *id = NULL;
4189 if (strv_length(args) > 1)
4190 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4196 r = sd_bus_call_method(
4198 "org.freedesktop.systemd1",
4199 "/org/freedesktop/systemd1",
4200 "org.freedesktop.systemd1.Manager",
4206 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4210 r = sd_bus_message_read(reply, "o", &path);
4212 return bus_log_parse_error(r);
4214 r = sd_bus_get_property_string(
4216 "org.freedesktop.systemd1",
4218 "org.freedesktop.systemd1.Unit",
4223 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4233 static int delete_snapshot(sd_bus *bus, char **args) {
4234 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4235 _cleanup_strv_free_ char **names = NULL;
4241 r = expand_names(bus, args + 1, ".snapshot", &names);
4243 log_error("Failed to expand names: %s", strerror(-r));
4245 STRV_FOREACH(name, names) {
4246 q = sd_bus_call_method(
4248 "org.freedesktop.systemd1",
4249 "/org/freedesktop/systemd1",
4250 "org.freedesktop.systemd1.Manager",
4256 log_error("Failed to remove snapshot %s: %s",
4257 *name, bus_error_message(&error, r));
4266 static int daemon_reload(sd_bus *bus, char **args) {
4267 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4271 if (arg_action == ACTION_RELOAD)
4273 else if (arg_action == ACTION_REEXEC)
4274 method = "Reexecute";
4276 assert(arg_action == ACTION_SYSTEMCTL);
4279 streq(args[0], "clear-jobs") ||
4280 streq(args[0], "cancel") ? "ClearJobs" :
4281 streq(args[0], "daemon-reexec") ? "Reexecute" :
4282 streq(args[0], "reset-failed") ? "ResetFailed" :
4283 streq(args[0], "halt") ? "Halt" :
4284 streq(args[0], "poweroff") ? "PowerOff" :
4285 streq(args[0], "reboot") ? "Reboot" :
4286 streq(args[0], "kexec") ? "KExec" :
4287 streq(args[0], "exit") ? "Exit" :
4288 /* "daemon-reload" */ "Reload";
4291 r = sd_bus_call_method(
4293 "org.freedesktop.systemd1",
4294 "/org/freedesktop/systemd1",
4295 "org.freedesktop.systemd1.Manager",
4301 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4302 /* There's always a fallback possible for
4303 * legacy actions. */
4305 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4306 /* On reexecution, we expect a disconnect, not a
4310 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4312 return r < 0 ? r : 0;
4315 static int reset_failed(sd_bus *bus, char **args) {
4316 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4317 _cleanup_strv_free_ char **names = NULL;
4321 if (strv_length(args) <= 1)
4322 return daemon_reload(bus, args);
4324 r = expand_names(bus, args + 1, NULL, &names);
4326 log_error("Failed to expand names: %s", strerror(-r));
4328 STRV_FOREACH(name, names) {
4329 q = sd_bus_call_method(
4331 "org.freedesktop.systemd1",
4332 "/org/freedesktop/systemd1",
4333 "org.freedesktop.systemd1.Manager",
4339 log_error("Failed to reset failed state of unit %s: %s",
4340 *name, bus_error_message(&error, r));
4349 static int show_environment(sd_bus *bus, char **args) {
4350 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4351 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4355 pager_open_if_enabled();
4357 r = sd_bus_get_property(
4359 "org.freedesktop.systemd1",
4360 "/org/freedesktop/systemd1",
4361 "org.freedesktop.systemd1.Manager",
4367 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4371 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4373 return bus_log_parse_error(r);
4375 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4378 return bus_log_parse_error(r);
4380 r = sd_bus_message_exit_container(reply);
4382 return bus_log_parse_error(r);
4387 static int switch_root(sd_bus *bus, char **args) {
4388 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4389 _cleanup_free_ char *init = NULL;
4394 l = strv_length(args);
4395 if (l < 2 || l > 3) {
4396 log_error("Wrong number of arguments.");
4403 init = strdup(args[2]);
4405 parse_env_file("/proc/cmdline", WHITESPACE,
4416 log_debug("switching root - root: %s; init: %s", root, init);
4418 r = sd_bus_call_method(
4420 "org.freedesktop.systemd1",
4421 "/org/freedesktop/systemd1",
4422 "org.freedesktop.systemd1.Manager",
4428 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4435 static int set_environment(sd_bus *bus, char **args) {
4436 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4437 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4444 method = streq(args[0], "set-environment")
4446 : "UnsetEnvironment";
4448 r = sd_bus_message_new_method_call(
4450 "org.freedesktop.systemd1",
4451 "/org/freedesktop/systemd1",
4452 "org.freedesktop.systemd1.Manager",
4456 return bus_log_create_error(r);
4458 r = sd_bus_message_append_strv(m, args + 1);
4460 return bus_log_create_error(r);
4462 r = sd_bus_call(bus, m, 0, &error, NULL);
4464 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4471 static int import_environment(sd_bus *bus, char **args) {
4472 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4473 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4479 r = sd_bus_message_new_method_call(
4481 "org.freedesktop.systemd1",
4482 "/org/freedesktop/systemd1",
4483 "org.freedesktop.systemd1.Manager",
4487 return bus_log_create_error(r);
4489 if (strv_isempty(args + 1))
4490 r = sd_bus_message_append_strv(m, environ);
4494 r = sd_bus_message_open_container(m, 'a', "s");
4496 return bus_log_create_error(r);
4498 STRV_FOREACH(a, args + 1) {
4500 if (!env_name_is_valid(*a)) {
4501 log_error("Not a valid environment variable name: %s", *a);
4505 STRV_FOREACH(b, environ) {
4508 eq = startswith(*b, *a);
4509 if (eq && *eq == '=') {
4511 r = sd_bus_message_append(m, "s", *b);
4513 return bus_log_create_error(r);
4520 r = sd_bus_message_close_container(m);
4523 return bus_log_create_error(r);
4525 r = sd_bus_call(bus, m, 0, &error, NULL);
4527 log_error("Failed to import environment: %s", bus_error_message(&error, r));
4534 static int enable_sysv_units(const char *verb, char **args) {
4537 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4538 unsigned f = 1, t = 1;
4539 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4541 if (arg_scope != UNIT_FILE_SYSTEM)
4544 if (!streq(verb, "enable") &&
4545 !streq(verb, "disable") &&
4546 !streq(verb, "is-enabled"))
4549 /* Processes all SysV units, and reshuffles the array so that
4550 * afterwards only the native units remain */
4552 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4557 for (f = 0; args[f]; f++) {
4559 _cleanup_free_ char *p = NULL, *q = NULL;
4560 bool found_native = false, found_sysv;
4562 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4570 if (!endswith(name, ".service"))
4573 if (path_is_absolute(name))
4576 STRV_FOREACH(k, paths.unit_path) {
4577 if (!isempty(arg_root))
4578 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4580 asprintf(&p, "%s/%s", *k, name);
4587 found_native = access(p, F_OK) >= 0;
4598 if (!isempty(arg_root))
4599 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4601 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4607 p[strlen(p) - sizeof(".service") + 1] = 0;
4608 found_sysv = access(p, F_OK) >= 0;
4613 /* Mark this entry, so that we don't try enabling it as native unit */
4614 args[f] = (char*) "";
4616 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4618 if (!isempty(arg_root))
4619 argv[c++] = q = strappend("--root=", arg_root);
4621 argv[c++] = basename(p);
4623 streq(verb, "enable") ? "on" :
4624 streq(verb, "disable") ? "off" : "--level=5";
4627 l = strv_join((char**)argv, " ");
4633 log_info("Executing %s", l);
4638 log_error("Failed to fork: %m");
4641 } else if (pid == 0) {
4644 execv(argv[0], (char**) argv);
4645 _exit(EXIT_FAILURE);
4648 j = wait_for_terminate(pid, &status);
4650 log_error("Failed to wait for child: %s", strerror(-r));
4655 if (status.si_code == CLD_EXITED) {
4656 if (streq(verb, "is-enabled")) {
4657 if (status.si_status == 0) {
4666 } else if (status.si_status != 0) {
4677 /* Drop all SysV units */
4678 for (f = 0, t = 0; args[f]; f++) {
4680 if (isempty(args[f]))
4683 args[t++] = args[f];
4692 static int mangle_names(char **original_names, char ***mangled_names) {
4693 char **i, **l, **name;
4695 l = new(char*, strv_length(original_names) + 1);
4700 STRV_FOREACH(name, original_names) {
4702 /* When enabling units qualified path names are OK,
4703 * too, hence allow them explicitly. */
4708 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4724 static int enable_unit(sd_bus *bus, char **args) {
4725 _cleanup_strv_free_ char **names = NULL;
4726 const char *verb = args[0];
4727 UnitFileChange *changes = NULL;
4728 unsigned n_changes = 0;
4729 int carries_install_info = -1;
4735 r = mangle_names(args+1, &names);
4739 r = enable_sysv_units(verb, names);
4743 /* If the operation was fully executed by the SysV compat,
4744 * let's finish early */
4745 if (strv_isempty(names))
4748 if (!bus || avoid_bus()) {
4749 if (streq(verb, "enable")) {
4750 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4751 carries_install_info = r;
4752 } else if (streq(verb, "disable"))
4753 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4754 else if (streq(verb, "reenable")) {
4755 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4756 carries_install_info = r;
4757 } else if (streq(verb, "link"))
4758 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4759 else if (streq(verb, "preset")) {
4760 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4761 carries_install_info = r;
4762 } else if (streq(verb, "mask"))
4763 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4764 else if (streq(verb, "unmask"))
4765 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4767 assert_not_reached("Unknown verb");
4770 log_error("Operation failed: %s", strerror(-r));
4775 dump_unit_file_changes(changes, n_changes);
4779 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4780 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4781 int expect_carries_install_info = false;
4782 bool send_force = true;
4785 if (streq(verb, "enable")) {
4786 method = "EnableUnitFiles";
4787 expect_carries_install_info = true;
4788 } else if (streq(verb, "disable")) {
4789 method = "DisableUnitFiles";
4791 } else if (streq(verb, "reenable")) {
4792 method = "ReenableUnitFiles";
4793 expect_carries_install_info = true;
4794 } else if (streq(verb, "link"))
4795 method = "LinkUnitFiles";
4796 else if (streq(verb, "preset")) {
4797 method = "PresetUnitFiles";
4798 expect_carries_install_info = true;
4799 } else if (streq(verb, "mask"))
4800 method = "MaskUnitFiles";
4801 else if (streq(verb, "unmask")) {
4802 method = "UnmaskUnitFiles";
4805 assert_not_reached("Unknown verb");
4807 r = sd_bus_message_new_method_call(
4809 "org.freedesktop.systemd1",
4810 "/org/freedesktop/systemd1",
4811 "org.freedesktop.systemd1.Manager",
4815 return bus_log_create_error(r);
4817 r = sd_bus_message_append_strv(m, names);
4819 return bus_log_create_error(r);
4821 r = sd_bus_message_append(m, "b", arg_runtime);
4823 return bus_log_create_error(r);
4826 r = sd_bus_message_append(m, "b", arg_force);
4828 return bus_log_create_error(r);
4831 r = sd_bus_call(bus, m, 0, &error, &reply);
4833 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4837 if (expect_carries_install_info) {
4838 r = sd_bus_message_read(reply, "b", &carries_install_info);
4840 return bus_log_parse_error(r);
4843 r = deserialize_and_dump_unit_file_changes(reply);
4847 /* Try to reload if enabeld */
4849 r = daemon_reload(bus, args);
4854 if (carries_install_info == 0)
4855 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4856 "using systemctl.\n"
4857 "Possible reasons for having this kind of units are:\n"
4858 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4859 " .wants/ or .requires/ directory.\n"
4860 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4861 " a requirement dependency on it.\n"
4862 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4863 " D-Bus, udev, scripted systemctl call, ...).\n");
4866 unit_file_changes_free(changes, n_changes);
4871 static int unit_is_enabled(sd_bus *bus, char **args) {
4873 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4874 _cleanup_strv_free_ char **names = NULL;
4879 r = mangle_names(args+1, &names);
4883 r = enable_sysv_units(args[0], names);
4889 if (!bus || avoid_bus()) {
4891 STRV_FOREACH(name, names) {
4892 UnitFileState state;
4894 state = unit_file_get_state(arg_scope, arg_root, *name);
4896 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4900 if (state == UNIT_FILE_ENABLED ||
4901 state == UNIT_FILE_ENABLED_RUNTIME ||
4902 state == UNIT_FILE_STATIC)
4906 puts(unit_file_state_to_string(state));
4910 STRV_FOREACH(name, names) {
4911 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4914 r = sd_bus_call_method(
4916 "org.freedesktop.systemd1",
4917 "/org/freedesktop/systemd1",
4918 "org.freedesktop.systemd1.Manager",
4924 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4928 r = sd_bus_message_read(reply, "s", &s);
4930 return bus_log_parse_error(r);
4932 if (streq(s, "enabled") ||
4933 streq(s, "enabled-runtime") ||
4945 static int systemctl_help(void) {
4947 pager_open_if_enabled();
4949 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4950 "Query or send control commands to the systemd manager.\n\n"
4951 " -h --help Show this help\n"
4952 " --version Show package version\n"
4953 " --system Connect to system manager\n"
4954 " --user Connect to user service manager\n"
4955 " -H --host=[USER@]HOST\n"
4956 " Operate on remote host\n"
4957 " -M --machine=CONTAINER\n"
4958 " Operate on local container\n"
4959 " -t --type=TYPE List only units of a particular type\n"
4960 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4961 " -p --property=NAME Show only properties by this name\n"
4962 " -a --all Show all loaded units/properties, including dead/empty\n"
4963 " ones. To list all units installed on the system, use\n"
4964 " the 'list-unit-files' command instead.\n"
4965 " -l --full Don't ellipsize unit names on output\n"
4966 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4967 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4968 " queueing a new job\n"
4969 " --show-types When showing sockets, explicitly show their type\n"
4970 " -i --ignore-inhibitors\n"
4971 " When shutting down or sleeping, ignore inhibitors\n"
4972 " --kill-who=WHO Who to send signal to\n"
4973 " -s --signal=SIGNAL Which signal to send\n"
4974 " -q --quiet Suppress output\n"
4975 " --no-block Do not wait until operation finished\n"
4976 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4977 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4979 " --no-legend Do not print a legend (column headers and hints)\n"
4980 " --no-pager Do not pipe output into a pager\n"
4981 " --no-ask-password\n"
4982 " Do not ask for system passwords\n"
4983 " --global Enable/disable unit files globally\n"
4984 " --runtime Enable unit files only temporarily until next reboot\n"
4985 " -f --force When enabling unit files, override existing symlinks\n"
4986 " When shutting down, execute action immediately\n"
4987 " --root=PATH Enable unit files in the specified root directory\n"
4988 " -n --lines=INTEGER Number of journal entries to show\n"
4989 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4990 " verbose, export, json, json-pretty, json-sse, cat)\n"
4991 " --plain Print unit dependencies as a list instead of a tree\n\n"
4993 " list-units [PATTERN...] List loaded units\n"
4994 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4995 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4996 " start NAME... Start (activate) one or more units\n"
4997 " stop NAME... Stop (deactivate) one or more units\n"
4998 " reload NAME... Reload one or more units\n"
4999 " restart NAME... Start or restart one or more units\n"
5000 " try-restart NAME... Restart one or more units if active\n"
5001 " reload-or-restart NAME... Reload one or more units if possible,\n"
5002 " otherwise start or restart\n"
5003 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
5004 " otherwise restart if active\n"
5005 " isolate NAME Start one unit and stop all others\n"
5006 " kill NAME... Send signal to processes of a unit\n"
5007 " is-active NAME... Check whether units are active\n"
5008 " is-failed NAME... Check whether units are failed\n"
5009 " status [NAME...|PID...] Show runtime status of one or more units\n"
5010 " show [NAME...|JOB...] Show properties of one or more\n"
5011 " units/jobs or the manager\n"
5012 " cat NAME... Show files and drop-ins of one or more units\n"
5013 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
5014 " help NAME...|PID... Show manual for one or more units\n"
5015 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
5017 " list-dependencies [NAME] Recursively show units which are required\n"
5018 " or wanted by this unit or by which this\n"
5019 " unit is required or wanted\n\n"
5020 "Unit File Commands:\n"
5021 " list-unit-files [PATTERN...] List installed unit files\n"
5022 " enable NAME... Enable one or more unit files\n"
5023 " disable NAME... Disable one or more unit files\n"
5024 " reenable NAME... Reenable one or more unit files\n"
5025 " preset NAME... Enable/disable one or more unit files\n"
5026 " based on preset configuration\n"
5027 " is-enabled NAME... Check whether unit files are enabled\n\n"
5028 " mask NAME... Mask one or more units\n"
5029 " unmask NAME... Unmask one or more units\n"
5030 " link PATH... Link one or more units files into\n"
5031 " the search path\n"
5032 " get-default Get the name of the default target\n"
5033 " set-default NAME Set the default target\n\n"
5035 " list-jobs [PATTERN...] List jobs\n"
5036 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
5037 "Snapshot Commands:\n"
5038 " snapshot [NAME] Create a snapshot\n"
5039 " delete NAME... Remove one or more snapshots\n\n"
5040 "Environment Commands:\n"
5041 " show-environment Dump environment\n"
5042 " set-environment NAME=VALUE... Set one or more environment variables\n"
5043 " unset-environment NAME... Unset one or more environment variables\n"
5044 " import-environment NAME... Import all, one or more environment variables\n\n"
5045 "Manager Lifecycle Commands:\n"
5046 " daemon-reload Reload systemd manager configuration\n"
5047 " daemon-reexec Reexecute systemd manager\n\n"
5048 "System Commands:\n"
5049 " default Enter system default mode\n"
5050 " rescue Enter system rescue mode\n"
5051 " emergency Enter system emergency mode\n"
5052 " halt Shut down and halt the system\n"
5053 " poweroff Shut down and power-off the system\n"
5054 " reboot [ARG] Shut down and reboot the system\n"
5055 " kexec Shut down and reboot the system with kexec\n"
5056 " exit Request user instance exit\n"
5057 " switch-root ROOT [INIT] Change to a different root file system\n"
5058 " suspend Suspend the system\n"
5059 " hibernate Hibernate the system\n"
5060 " hybrid-sleep Hibernate and suspend the system\n",
5061 program_invocation_short_name);
5066 static int halt_help(void) {
5068 printf("%s [OPTIONS...]%s\n\n"
5069 "%s the system.\n\n"
5070 " --help Show this help\n"
5071 " --halt Halt the machine\n"
5072 " -p --poweroff Switch off the machine\n"
5073 " --reboot Reboot the machine\n"
5074 " -f --force Force immediate halt/power-off/reboot\n"
5075 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
5076 " -d --no-wtmp Don't write wtmp record\n"
5077 " --no-wall Don't send wall message before halt/power-off/reboot\n",
5078 program_invocation_short_name,
5079 arg_action == ACTION_REBOOT ? " [ARG]" : "",
5080 arg_action == ACTION_REBOOT ? "Reboot" :
5081 arg_action == ACTION_POWEROFF ? "Power off" :
5087 static int shutdown_help(void) {
5089 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
5090 "Shut down the system.\n\n"
5091 " --help Show this help\n"
5092 " -H --halt Halt the machine\n"
5093 " -P --poweroff Power-off the machine\n"
5094 " -r --reboot Reboot the machine\n"
5095 " -h Equivalent to --poweroff, overridden by --halt\n"
5096 " -k Don't halt/power-off/reboot, just send warnings\n"
5097 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5098 " -c Cancel a pending shutdown\n",
5099 program_invocation_short_name);
5104 static int telinit_help(void) {
5106 printf("%s [OPTIONS...] {COMMAND}\n\n"
5107 "Send control commands to the init daemon.\n\n"
5108 " --help Show this help\n"
5109 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5111 " 0 Power-off the machine\n"
5112 " 6 Reboot the machine\n"
5113 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5114 " 1, s, S Enter rescue mode\n"
5115 " q, Q Reload init daemon configuration\n"
5116 " u, U Reexecute init daemon\n",
5117 program_invocation_short_name);
5122 static int runlevel_help(void) {
5124 printf("%s [OPTIONS...]\n\n"
5125 "Prints the previous and current runlevel of the init system.\n\n"
5126 " --help Show this help\n",
5127 program_invocation_short_name);
5132 static int help_types(void) {
5136 puts("Available unit types:");
5137 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5138 t = unit_type_to_string(i);
5146 static int systemctl_parse_argv(int argc, char *argv[]) {
5155 ARG_IGNORE_DEPENDENCIES,
5167 ARG_NO_ASK_PASSWORD,
5176 static const struct option options[] = {
5177 { "help", no_argument, NULL, 'h' },
5178 { "version", no_argument, NULL, ARG_VERSION },
5179 { "type", required_argument, NULL, 't' },
5180 { "property", required_argument, NULL, 'p' },
5181 { "all", no_argument, NULL, 'a' },
5182 { "reverse", no_argument, NULL, ARG_REVERSE },
5183 { "after", no_argument, NULL, ARG_AFTER },
5184 { "before", no_argument, NULL, ARG_BEFORE },
5185 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5186 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5187 { "full", no_argument, NULL, 'l' },
5188 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5189 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5190 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5191 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5192 { "ignore-inhibitors", no_argument, NULL, 'i' },
5193 { "user", no_argument, NULL, ARG_USER },
5194 { "system", no_argument, NULL, ARG_SYSTEM },
5195 { "global", no_argument, NULL, ARG_GLOBAL },
5196 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5197 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5198 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5199 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5200 { "quiet", no_argument, NULL, 'q' },
5201 { "root", required_argument, NULL, ARG_ROOT },
5202 { "force", no_argument, NULL, ARG_FORCE },
5203 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5204 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5205 { "signal", required_argument, NULL, 's' },
5206 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5207 { "host", required_argument, NULL, 'H' },
5208 { "machine", required_argument, NULL, 'M' },
5209 { "runtime", no_argument, NULL, ARG_RUNTIME },
5210 { "lines", required_argument, NULL, 'n' },
5211 { "output", required_argument, NULL, 'o' },
5212 { "plain", no_argument, NULL, ARG_PLAIN },
5213 { "state", required_argument, NULL, ARG_STATE },
5222 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5227 return systemctl_help();
5230 puts(PACKAGE_STRING);
5231 puts(SYSTEMD_FEATURES);
5238 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5239 _cleanup_free_ char *type;
5241 type = strndup(word, size);
5245 if (streq(type, "help")) {
5250 if (unit_type_from_string(type) >= 0) {
5251 if (strv_push(&arg_types, type))
5257 /* It's much nicer to use --state= for
5258 * load states, but let's support this
5259 * in --types= too for compatibility
5260 * with old versions */
5261 if (unit_load_state_from_string(optarg) >= 0) {
5262 if (strv_push(&arg_states, type) < 0)
5268 log_error("Unknown unit type or load state '%s'.", type);
5269 log_info("Use -t help to see a list of allowed values.");
5277 /* Make sure that if the empty property list
5278 was specified, we won't show any properties. */
5279 if (isempty(optarg) && !arg_properties) {
5280 arg_properties = new0(char*, 1);
5281 if (!arg_properties)
5287 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5290 prop = strndup(word, size);
5294 if (strv_push(&arg_properties, prop) < 0) {
5301 /* If the user asked for a particular
5302 * property, show it to him, even if it is
5314 arg_dependency = DEPENDENCY_REVERSE;
5318 arg_dependency = DEPENDENCY_AFTER;
5322 arg_dependency = DEPENDENCY_BEFORE;
5325 case ARG_SHOW_TYPES:
5326 arg_show_types = true;
5330 arg_job_mode = optarg;
5334 arg_job_mode = "fail";
5337 case ARG_IRREVERSIBLE:
5338 arg_job_mode = "replace-irreversibly";
5341 case ARG_IGNORE_DEPENDENCIES:
5342 arg_job_mode = "ignore-dependencies";
5346 arg_scope = UNIT_FILE_USER;
5350 arg_scope = UNIT_FILE_SYSTEM;
5354 arg_scope = UNIT_FILE_GLOBAL;
5358 arg_no_block = true;
5362 arg_no_legend = true;
5366 arg_no_pager = true;
5382 if (strv_extend(&arg_states, "failed") < 0)
5400 arg_no_reload = true;
5404 arg_kill_who = optarg;
5408 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5409 log_error("Failed to parse signal string %s.", optarg);
5414 case ARG_NO_ASK_PASSWORD:
5415 arg_ask_password = false;
5419 arg_transport = BUS_TRANSPORT_REMOTE;
5424 arg_transport = BUS_TRANSPORT_CONTAINER;
5433 if (safe_atou(optarg, &arg_lines) < 0) {
5434 log_error("Failed to parse lines '%s'", optarg);
5440 arg_output = output_mode_from_string(optarg);
5441 if (arg_output < 0) {
5442 log_error("Unknown output '%s'.", optarg);
5448 arg_ignore_inhibitors = true;
5459 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5462 s = strndup(word, size);
5466 if (strv_push(&arg_states, s) < 0) {
5478 assert_not_reached("Unhandled option");
5482 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5483 log_error("Cannot access user instance remotely.");
5490 static int halt_parse_argv(int argc, char *argv[]) {
5499 static const struct option options[] = {
5500 { "help", no_argument, NULL, ARG_HELP },
5501 { "halt", no_argument, NULL, ARG_HALT },
5502 { "poweroff", no_argument, NULL, 'p' },
5503 { "reboot", no_argument, NULL, ARG_REBOOT },
5504 { "force", no_argument, NULL, 'f' },
5505 { "wtmp-only", no_argument, NULL, 'w' },
5506 { "no-wtmp", no_argument, NULL, 'd' },
5507 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5516 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5517 if (runlevel == '0' || runlevel == '6')
5520 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5527 arg_action = ACTION_HALT;
5531 if (arg_action != ACTION_REBOOT)
5532 arg_action = ACTION_POWEROFF;
5536 arg_action = ACTION_REBOOT;
5558 /* Compatibility nops */
5565 assert_not_reached("Unhandled option");
5569 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5570 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5572 log_error("Failed to write reboot param to "
5573 REBOOT_PARAM_FILE": %s", strerror(-r));
5576 } else if (optind < argc) {
5577 log_error("Too many arguments.");
5584 static int parse_time_spec(const char *t, usec_t *_u) {
5588 if (streq(t, "now"))
5590 else if (!strchr(t, ':')) {
5593 if (safe_atou64(t, &u) < 0)
5596 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5605 hour = strtol(t, &e, 10);
5606 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5609 minute = strtol(e+1, &e, 10);
5610 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5613 n = now(CLOCK_REALTIME);
5614 s = (time_t) (n / USEC_PER_SEC);
5616 assert_se(localtime_r(&s, &tm));
5618 tm.tm_hour = (int) hour;
5619 tm.tm_min = (int) minute;
5622 assert_se(s = mktime(&tm));
5624 *_u = (usec_t) s * USEC_PER_SEC;
5627 *_u += USEC_PER_DAY;
5633 static int shutdown_parse_argv(int argc, char *argv[]) {
5640 static const struct option options[] = {
5641 { "help", no_argument, NULL, ARG_HELP },
5642 { "halt", no_argument, NULL, 'H' },
5643 { "poweroff", no_argument, NULL, 'P' },
5644 { "reboot", no_argument, NULL, 'r' },
5645 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5646 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5655 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5659 return shutdown_help();
5662 arg_action = ACTION_HALT;
5666 arg_action = ACTION_POWEROFF;
5671 arg_action = ACTION_KEXEC;
5673 arg_action = ACTION_REBOOT;
5677 arg_action = ACTION_KEXEC;
5681 if (arg_action != ACTION_HALT)
5682 arg_action = ACTION_POWEROFF;
5695 /* Compatibility nops */
5699 arg_action = ACTION_CANCEL_SHUTDOWN;
5706 assert_not_reached("Unhandled option");
5710 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5711 r = parse_time_spec(argv[optind], &arg_when);
5713 log_error("Failed to parse time specification: %s", argv[optind]);
5717 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5719 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5720 /* No time argument for shutdown cancel */
5721 arg_wall = argv + optind;
5722 else if (argc > optind + 1)
5723 /* We skip the time argument */
5724 arg_wall = argv + optind + 1;
5731 static int telinit_parse_argv(int argc, char *argv[]) {
5738 static const struct option options[] = {
5739 { "help", no_argument, NULL, ARG_HELP },
5740 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5744 static const struct {
5748 { '0', ACTION_POWEROFF },
5749 { '6', ACTION_REBOOT },
5750 { '1', ACTION_RESCUE },
5751 { '2', ACTION_RUNLEVEL2 },
5752 { '3', ACTION_RUNLEVEL3 },
5753 { '4', ACTION_RUNLEVEL4 },
5754 { '5', ACTION_RUNLEVEL5 },
5755 { 's', ACTION_RESCUE },
5756 { 'S', ACTION_RESCUE },
5757 { 'q', ACTION_RELOAD },
5758 { 'Q', ACTION_RELOAD },
5759 { 'u', ACTION_REEXEC },
5760 { 'U', ACTION_REEXEC }
5769 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5773 return telinit_help();
5783 assert_not_reached("Unhandled option");
5787 if (optind >= argc) {
5792 if (optind + 1 < argc) {
5793 log_error("Too many arguments.");
5797 if (strlen(argv[optind]) != 1) {
5798 log_error("Expected single character argument.");
5802 for (i = 0; i < ELEMENTSOF(table); i++)
5803 if (table[i].from == argv[optind][0])
5806 if (i >= ELEMENTSOF(table)) {
5807 log_error("Unknown command '%s'.", argv[optind]);
5811 arg_action = table[i].to;
5818 static int runlevel_parse_argv(int argc, char *argv[]) {
5824 static const struct option options[] = {
5825 { "help", no_argument, NULL, ARG_HELP },
5834 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5838 return runlevel_help();
5845 assert_not_reached("Unhandled option");
5849 if (optind < argc) {
5850 log_error("Too many arguments.");
5857 static int parse_argv(int argc, char *argv[]) {
5861 if (program_invocation_short_name) {
5863 if (strstr(program_invocation_short_name, "halt")) {
5864 arg_action = ACTION_HALT;
5865 return halt_parse_argv(argc, argv);
5866 } else if (strstr(program_invocation_short_name, "poweroff")) {
5867 arg_action = ACTION_POWEROFF;
5868 return halt_parse_argv(argc, argv);
5869 } else if (strstr(program_invocation_short_name, "reboot")) {
5871 arg_action = ACTION_KEXEC;
5873 arg_action = ACTION_REBOOT;
5874 return halt_parse_argv(argc, argv);
5875 } else if (strstr(program_invocation_short_name, "shutdown")) {
5876 arg_action = ACTION_POWEROFF;
5877 return shutdown_parse_argv(argc, argv);
5878 } else if (strstr(program_invocation_short_name, "init")) {
5880 if (sd_booted() > 0) {
5881 arg_action = _ACTION_INVALID;
5882 return telinit_parse_argv(argc, argv);
5884 /* Hmm, so some other init system is
5885 * running, we need to forward this
5886 * request to it. For now we simply
5887 * guess that it is Upstart. */
5889 execv(TELINIT, argv);
5891 log_error("Couldn't find an alternative telinit implementation to spawn.");
5895 } else if (strstr(program_invocation_short_name, "runlevel")) {
5896 arg_action = ACTION_RUNLEVEL;
5897 return runlevel_parse_argv(argc, argv);
5901 arg_action = ACTION_SYSTEMCTL;
5902 return systemctl_parse_argv(argc, argv);
5905 _pure_ static int action_to_runlevel(void) {
5907 static const char table[_ACTION_MAX] = {
5908 [ACTION_HALT] = '0',
5909 [ACTION_POWEROFF] = '0',
5910 [ACTION_REBOOT] = '6',
5911 [ACTION_RUNLEVEL2] = '2',
5912 [ACTION_RUNLEVEL3] = '3',
5913 [ACTION_RUNLEVEL4] = '4',
5914 [ACTION_RUNLEVEL5] = '5',
5915 [ACTION_RESCUE] = '1'
5918 assert(arg_action < _ACTION_MAX);
5920 return table[arg_action];
5923 static int talk_initctl(void) {
5925 struct init_request request = {
5926 .magic = INIT_MAGIC,
5928 .cmd = INIT_CMD_RUNLVL
5931 _cleanup_close_ int fd = -1;
5935 rl = action_to_runlevel();
5939 request.runlevel = rl;
5941 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5943 if (errno == ENOENT)
5946 log_error("Failed to open "INIT_FIFO": %m");
5951 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5953 log_error("Failed to write to "INIT_FIFO": %m");
5954 return errno > 0 ? -errno : -EIO;
5960 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5962 static const struct {
5970 int (* const dispatch)(sd_bus *bus, char **args);
5976 { "list-units", MORE, 0, list_units },
5977 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
5978 { "list-sockets", MORE, 1, list_sockets },
5979 { "list-timers", MORE, 1, list_timers },
5980 { "list-jobs", MORE, 1, list_jobs },
5981 { "clear-jobs", EQUAL, 1, daemon_reload },
5982 { "cancel", MORE, 2, cancel_job },
5983 { "start", MORE, 2, start_unit },
5984 { "stop", MORE, 2, start_unit },
5985 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5986 { "reload", MORE, 2, start_unit },
5987 { "restart", MORE, 2, start_unit },
5988 { "try-restart", MORE, 2, start_unit },
5989 { "reload-or-restart", MORE, 2, start_unit },
5990 { "reload-or-try-restart", MORE, 2, start_unit },
5991 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5992 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5993 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5994 { "isolate", EQUAL, 2, start_unit },
5995 { "kill", MORE, 2, kill_unit },
5996 { "is-active", MORE, 2, check_unit_active },
5997 { "check", MORE, 2, check_unit_active },
5998 { "is-failed", MORE, 2, check_unit_failed },
5999 { "show", MORE, 1, show },
6000 { "cat", MORE, 2, cat },
6001 { "status", MORE, 1, show },
6002 { "help", MORE, 2, show },
6003 { "snapshot", LESS, 2, snapshot },
6004 { "delete", MORE, 2, delete_snapshot },
6005 { "daemon-reload", EQUAL, 1, daemon_reload },
6006 { "daemon-reexec", EQUAL, 1, daemon_reload },
6007 { "show-environment", EQUAL, 1, show_environment },
6008 { "set-environment", MORE, 2, set_environment },
6009 { "unset-environment", MORE, 2, set_environment },
6010 { "import-environment", MORE, 1, import_environment},
6011 { "halt", EQUAL, 1, start_special, FORCE },
6012 { "poweroff", EQUAL, 1, start_special, FORCE },
6013 { "reboot", EQUAL, 1, start_special, FORCE },
6014 { "kexec", EQUAL, 1, start_special },
6015 { "suspend", EQUAL, 1, start_special },
6016 { "hibernate", EQUAL, 1, start_special },
6017 { "hybrid-sleep", EQUAL, 1, start_special },
6018 { "default", EQUAL, 1, start_special },
6019 { "rescue", EQUAL, 1, start_special },
6020 { "emergency", EQUAL, 1, start_special },
6021 { "exit", EQUAL, 1, start_special },
6022 { "reset-failed", MORE, 1, reset_failed },
6023 { "enable", MORE, 2, enable_unit, NOBUS },
6024 { "disable", MORE, 2, enable_unit, NOBUS },
6025 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
6026 { "reenable", MORE, 2, enable_unit, NOBUS },
6027 { "preset", MORE, 2, enable_unit, NOBUS },
6028 { "mask", MORE, 2, enable_unit, NOBUS },
6029 { "unmask", MORE, 2, enable_unit, NOBUS },
6030 { "link", MORE, 2, enable_unit, NOBUS },
6031 { "switch-root", MORE, 2, switch_root },
6032 { "list-dependencies", LESS, 2, list_dependencies },
6033 { "set-default", EQUAL, 2, set_default, NOBUS },
6034 { "get-default", EQUAL, 1, get_default, NOBUS },
6035 { "set-property", MORE, 3, set_property },
6044 left = argc - optind;
6046 /* Special rule: no arguments (left == 0) means "list-units" */
6048 if (streq(argv[optind], "help") && !argv[optind+1]) {
6049 log_error("This command expects one or more "
6050 "unit names. Did you mean --help?");
6054 for (; verb->verb; verb++)
6055 if (streq(argv[optind], verb->verb))
6058 log_error("Unknown operation '%s'.", argv[optind]);
6063 switch (verb->argc_cmp) {
6066 if (left != verb->argc) {
6067 log_error("Invalid number of arguments.");
6074 if (left < verb->argc) {
6075 log_error("Too few arguments.");
6082 if (left > verb->argc) {
6083 log_error("Too many arguments.");
6090 assert_not_reached("Unknown comparison operator.");
6093 /* Require a bus connection for all operations but
6095 if (verb->bus == NOBUS) {
6096 if (!bus && !avoid_bus()) {
6097 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6102 if (running_in_chroot() > 0) {
6103 log_info("Running in chroot, ignoring request.");
6107 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6108 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6113 return verb->dispatch(bus, argv + optind);
6116 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6118 struct sd_shutdown_command c = {
6125 union sockaddr_union sockaddr = {
6126 .un.sun_family = AF_UNIX,
6127 .un.sun_path = "/run/systemd/shutdownd",
6130 struct iovec iovec[2] = {{
6131 .iov_base = (char*) &c,
6132 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6135 struct msghdr msghdr = {
6136 .msg_name = &sockaddr,
6137 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6138 + sizeof("/run/systemd/shutdownd") - 1,
6143 _cleanup_close_ int fd;
6145 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6149 if (!isempty(message)) {
6150 iovec[1].iov_base = (char*) message;
6151 iovec[1].iov_len = strlen(message);
6152 msghdr.msg_iovlen++;
6155 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6161 static int reload_with_fallback(sd_bus *bus) {
6164 /* First, try systemd via D-Bus. */
6165 if (daemon_reload(bus, NULL) >= 0)
6169 /* Nothing else worked, so let's try signals */
6170 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6172 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6173 log_error("kill() failed: %m");
6180 static int start_with_fallback(sd_bus *bus) {
6183 /* First, try systemd via D-Bus. */
6184 if (start_unit(bus, NULL) >= 0)
6188 /* Nothing else worked, so let's try
6190 if (talk_initctl() > 0)
6193 log_error("Failed to talk to init daemon.");
6197 warn_wall(arg_action);
6201 static int halt_now(enum action a) {
6203 /* Make sure C-A-D is handled by the kernel from this
6205 reboot(RB_ENABLE_CAD);
6210 log_info("Halting.");
6211 reboot(RB_HALT_SYSTEM);
6214 case ACTION_POWEROFF:
6215 log_info("Powering off.");
6216 reboot(RB_POWER_OFF);
6219 case ACTION_REBOOT: {
6220 _cleanup_free_ char *param = NULL;
6222 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6223 log_info("Rebooting with argument '%s'.", param);
6224 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6225 LINUX_REBOOT_CMD_RESTART2, param);
6228 log_info("Rebooting.");
6229 reboot(RB_AUTOBOOT);
6234 assert_not_reached("Unknown action.");
6238 static int halt_main(sd_bus *bus) {
6241 r = check_inhibitors(bus, arg_action);
6245 if (geteuid() != 0) {
6246 /* Try logind if we are a normal user and no special
6247 * mode applies. Maybe PolicyKit allows us to shutdown
6250 if (arg_when <= 0 &&
6253 (arg_action == ACTION_POWEROFF ||
6254 arg_action == ACTION_REBOOT)) {
6255 r = reboot_with_logind(bus, arg_action);
6260 log_error("Must be root.");
6265 _cleanup_free_ char *m;
6267 m = strv_join(arg_wall, " ");
6271 r = send_shutdownd(arg_when,
6272 arg_action == ACTION_HALT ? 'H' :
6273 arg_action == ACTION_POWEROFF ? 'P' :
6274 arg_action == ACTION_KEXEC ? 'K' :
6281 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6283 char date[FORMAT_TIMESTAMP_MAX];
6285 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6286 format_timestamp(date, sizeof(date), arg_when));
6291 if (!arg_dry && !arg_force)
6292 return start_with_fallback(bus);
6295 if (sd_booted() > 0)
6296 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6298 r = utmp_put_shutdown();
6300 log_warning("Failed to write utmp record: %s", strerror(-r));
6307 r = halt_now(arg_action);
6308 log_error("Failed to reboot: %s", strerror(-r));
6313 static int runlevel_main(void) {
6314 int r, runlevel, previous;
6316 r = utmp_get_runlevel(&runlevel, &previous);
6323 previous <= 0 ? 'N' : previous,
6324 runlevel <= 0 ? 'N' : runlevel);
6329 int main(int argc, char*argv[]) {
6330 _cleanup_bus_unref_ sd_bus *bus = NULL;
6333 setlocale(LC_ALL, "");
6334 log_parse_environment();
6337 /* Explicitly not on_tty() to avoid setting cached value.
6338 * This becomes relevant for piping output which might be
6340 original_stdout_is_tty = isatty(STDOUT_FILENO);
6342 r = parse_argv(argc, argv);
6346 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6347 * let's shortcut this */
6348 if (arg_action == ACTION_RUNLEVEL) {
6349 r = runlevel_main();
6353 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6354 log_info("Running in chroot, ignoring request.");
6360 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6362 /* systemctl_main() will print an error message for the bus
6363 * connection, but only if it needs to */
6365 switch (arg_action) {
6367 case ACTION_SYSTEMCTL:
6368 r = systemctl_main(bus, argc, argv, r);
6372 case ACTION_POWEROFF:
6378 case ACTION_RUNLEVEL2:
6379 case ACTION_RUNLEVEL3:
6380 case ACTION_RUNLEVEL4:
6381 case ACTION_RUNLEVEL5:
6383 case ACTION_EMERGENCY:
6384 case ACTION_DEFAULT:
6385 r = start_with_fallback(bus);
6390 r = reload_with_fallback(bus);
6393 case ACTION_CANCEL_SHUTDOWN: {
6394 _cleanup_free_ char *m = NULL;
6397 m = strv_join(arg_wall, " ");
6404 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6406 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6410 case ACTION_RUNLEVEL:
6411 case _ACTION_INVALID:
6413 assert_not_reached("Unknown action");
6418 ask_password_agent_close();
6419 polkit_agent_close();
6421 strv_free(arg_types);
6422 strv_free(arg_states);
6423 strv_free(arg_properties);
6425 return r < 0 ? EXIT_FAILURE : r;