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"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
76 static char **arg_types = NULL;
77 static char **arg_states = NULL;
78 static char **arg_properties = NULL;
79 static bool arg_all = false;
80 static bool original_stdout_is_tty;
81 static enum dependency {
87 } arg_dependency = DEPENDENCY_FORWARD;
88 static const char *arg_job_mode = "replace";
89 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
90 static bool arg_no_block = false;
91 static bool arg_no_legend = false;
92 static bool arg_no_pager = false;
93 static bool arg_no_wtmp = false;
94 static bool arg_no_wall = false;
95 static bool arg_no_reload = false;
96 static bool arg_show_types = false;
97 static bool arg_ignore_inhibitors = false;
98 static bool arg_dry = false;
99 static bool arg_quiet = false;
100 static bool arg_full = false;
101 static int arg_force = 0;
102 static bool arg_ask_password = true;
103 static bool arg_runtime = false;
104 static char **arg_wall = NULL;
105 static const char *arg_kill_who = NULL;
106 static int arg_signal = SIGTERM;
107 static const char *arg_root = NULL;
108 static usec_t arg_when = 0;
130 ACTION_CANCEL_SHUTDOWN,
132 } arg_action = ACTION_SYSTEMCTL;
133 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
134 static char *arg_host = NULL;
135 static unsigned arg_lines = 10;
136 static OutputMode arg_output = OUTPUT_SHORT;
137 static bool arg_plain = false;
139 static int daemon_reload(sd_bus *bus, char **args);
140 static int halt_now(enum action a);
142 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
144 static char** strv_skip_first(char **strv) {
145 if (strv_length(strv) > 0)
150 static void pager_open_if_enabled(void) {
158 static void ask_password_agent_open_if_enabled(void) {
160 /* Open the password agent as a child process if necessary */
162 if (!arg_ask_password)
165 if (arg_scope != UNIT_FILE_SYSTEM)
168 if (arg_transport != BUS_TRANSPORT_LOCAL)
171 ask_password_agent_open();
175 static void polkit_agent_open_if_enabled(void) {
177 /* Open the polkit 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)
192 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
195 if (!sd_bus_error_is_set(error))
198 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
199 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
200 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
201 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
202 return EXIT_NOPERMISSION;
204 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
205 return EXIT_NOTINSTALLED;
207 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
208 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
209 return EXIT_NOTIMPLEMENTED;
211 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
212 return EXIT_NOTCONFIGURED;
220 static void warn_wall(enum action a) {
221 static const char *table[_ACTION_MAX] = {
222 [ACTION_HALT] = "The system is going down for system halt NOW!",
223 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
224 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
225 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
226 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
227 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
228 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
235 _cleanup_free_ char *p;
237 p = strv_join(arg_wall, " ");
252 utmp_wall(table[a], NULL);
255 static bool avoid_bus(void) {
257 if (running_in_chroot() > 0)
260 if (sd_booted() <= 0)
263 if (!isempty(arg_root))
266 if (arg_scope == UNIT_FILE_GLOBAL)
272 static int compare_unit_info(const void *a, const void *b) {
273 const UnitInfo *u = a, *v = b;
276 d1 = strrchr(u->id, '.');
277 d2 = strrchr(v->id, '.');
282 r = strcasecmp(d1, d2);
287 return strcasecmp(u->id, v->id);
290 static bool output_show_unit(const UnitInfo *u, char **patterns) {
293 if (!strv_isempty(arg_states))
295 strv_contains(arg_states, u->load_state) ||
296 strv_contains(arg_states, u->sub_state) ||
297 strv_contains(arg_states, u->active_state);
299 if (!strv_isempty(patterns)) {
302 STRV_FOREACH(pattern, patterns)
303 if (fnmatch(*pattern, u->id, FNM_NOESCAPE) == 0)
308 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
309 strv_find(arg_types, dot+1))) &&
310 (arg_all || !(streq(u->active_state, "inactive")
311 || u->following[0]) || u->job_id > 0);
314 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
315 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
317 unsigned n_shown = 0;
320 max_id_len = sizeof("UNIT")-1;
321 load_len = sizeof("LOAD")-1;
322 active_len = sizeof("ACTIVE")-1;
323 sub_len = sizeof("SUB")-1;
324 job_len = sizeof("JOB")-1;
327 for (u = unit_infos; u < unit_infos + c; u++) {
328 max_id_len = MAX(max_id_len, strlen(u->id));
329 load_len = MAX(load_len, strlen(u->load_state));
330 active_len = MAX(active_len, strlen(u->active_state));
331 sub_len = MAX(sub_len, strlen(u->sub_state));
333 if (u->job_id != 0) {
334 job_len = MAX(job_len, strlen(u->job_type));
339 if (!arg_full && original_stdout_is_tty) {
342 id_len = MIN(max_id_len, 25u);
343 basic_len = 5 + id_len + 5 + active_len + sub_len;
346 basic_len += job_len + 1;
348 if (basic_len < (unsigned) columns()) {
349 unsigned extra_len, incr;
350 extra_len = columns() - basic_len;
352 /* Either UNIT already got 25, or is fully satisfied.
353 * Grant up to 25 to DESC now. */
354 incr = MIN(extra_len, 25u);
358 /* split the remaining space between UNIT and DESC,
359 * but do not give UNIT more than it needs. */
361 incr = MIN(extra_len / 2, max_id_len - id_len);
363 desc_len += extra_len - incr;
369 for (u = unit_infos; u < unit_infos + c; u++) {
370 _cleanup_free_ char *e = NULL;
371 const char *on_loaded, *off_loaded, *on = "";
372 const char *on_active, *off_active, *off = "";
374 if (!n_shown && !arg_no_legend) {
375 printf("%-*s %-*s %-*s %-*s ",
378 active_len, "ACTIVE",
382 printf("%-*s ", job_len, "JOB");
384 if (!arg_full && arg_no_pager)
385 printf("%.*s\n", desc_len, "DESCRIPTION");
387 printf("%s\n", "DESCRIPTION");
392 if (streq(u->load_state, "error") ||
393 streq(u->load_state, "not-found")) {
394 on_loaded = on = ansi_highlight_red();
395 off_loaded = off = ansi_highlight_off();
397 on_loaded = off_loaded = "";
399 if (streq(u->active_state, "failed")) {
400 on_active = on = ansi_highlight_red();
401 off_active = off = ansi_highlight_off();
403 on_active = off_active = "";
405 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
407 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
408 on, id_len, e ? e : u->id, off,
409 on_loaded, load_len, u->load_state, off_loaded,
410 on_active, active_len, u->active_state,
411 sub_len, u->sub_state, off_active,
412 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
415 printf("%.*s\n", desc_len, u->description);
417 printf("%s\n", u->description);
420 if (!arg_no_legend) {
421 const char *on, *off;
424 puts("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
425 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
426 "SUB = The low-level unit activation state, values depend on unit type.");
427 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
428 on = ansi_highlight();
429 off = ansi_highlight_off();
431 on = ansi_highlight_red();
432 off = ansi_highlight_off();
436 printf("%s%u loaded units listed.%s\n"
437 "To show all installed unit files use 'systemctl list-unit-files'.\n",
440 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
441 "To show all installed unit files use 'systemctl list-unit-files'.\n",
446 static int get_unit_list(
448 sd_bus_message **_reply,
449 UnitInfo **_unit_infos,
452 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
453 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
454 _cleanup_free_ UnitInfo *unit_infos = NULL;
463 r = sd_bus_call_method(
465 "org.freedesktop.systemd1",
466 "/org/freedesktop/systemd1",
467 "org.freedesktop.systemd1.Manager",
473 log_error("Failed to list units: %s", bus_error_message(&error, r));
477 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
479 return bus_log_parse_error(r);
481 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
482 if (!output_show_unit(&u, patterns))
485 if (!GREEDY_REALLOC(unit_infos, size, c+1))
491 return bus_log_parse_error(r);
493 r = sd_bus_message_exit_container(reply);
495 return bus_log_parse_error(r);
500 *_unit_infos = unit_infos;
506 static int list_units(sd_bus *bus, char **args) {
507 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
508 _cleanup_free_ UnitInfo *unit_infos = NULL;
511 pager_open_if_enabled();
513 r = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
517 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
518 output_units_list(unit_infos, r);
523 static int get_triggered_units(
528 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
531 r = sd_bus_get_property_strv(
533 "org.freedesktop.systemd1",
535 "org.freedesktop.systemd1.Unit",
541 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
546 static int get_listening(
548 const char* unit_path,
551 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
552 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
553 const char *type, *path;
556 r = sd_bus_get_property(
558 "org.freedesktop.systemd1",
560 "org.freedesktop.systemd1.Socket",
566 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
570 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
572 return bus_log_parse_error(r);
574 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
576 r = strv_extend(listening, type);
580 r = strv_extend(listening, path);
587 return bus_log_parse_error(r);
589 r = sd_bus_message_exit_container(reply);
591 return bus_log_parse_error(r);
602 /* Note: triggered is a list here, although it almost certainly
603 * will always be one unit. Nevertheless, dbus API allows for multiple
604 * values, so let's follow that.*/
607 /* The strv above is shared. free is set only in the first one. */
611 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
617 o = strcmp(a->path, b->path);
619 o = strcmp(a->type, b->type);
624 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
625 struct socket_info *s;
626 unsigned pathlen = sizeof("LISTEN") - 1,
627 typelen = (sizeof("TYPE") - 1) * arg_show_types,
628 socklen = sizeof("UNIT") - 1,
629 servlen = sizeof("ACTIVATES") - 1;
630 const char *on, *off;
632 for (s = socket_infos; s < socket_infos + cs; s++) {
636 socklen = MAX(socklen, strlen(s->id));
638 typelen = MAX(typelen, strlen(s->type));
639 pathlen = MAX(pathlen, strlen(s->path));
641 STRV_FOREACH(a, s->triggered)
642 tmp += strlen(*a) + 2*(a != s->triggered);
643 servlen = MAX(servlen, tmp);
648 printf("%-*s %-*.*s%-*s %s\n",
650 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
654 for (s = socket_infos; s < socket_infos + cs; s++) {
658 printf("%-*s %-*s %-*s",
659 pathlen, s->path, typelen, s->type, socklen, s->id);
662 pathlen, s->path, socklen, s->id);
663 STRV_FOREACH(a, s->triggered)
665 a == s->triggered ? "" : ",", *a);
669 on = ansi_highlight();
670 off = ansi_highlight_off();
674 on = ansi_highlight_red();
675 off = ansi_highlight_off();
678 if (!arg_no_legend) {
679 printf("%s%u sockets listed.%s\n", on, cs, off);
681 printf("Pass --all to see loaded but inactive sockets, too.\n");
687 static int list_sockets(sd_bus *bus, char **args) {
688 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
689 _cleanup_free_ UnitInfo *unit_infos = NULL;
690 _cleanup_free_ struct socket_info *socket_infos = NULL;
692 struct socket_info *s;
697 pager_open_if_enabled();
699 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
703 for (u = unit_infos; u < unit_infos + n; u++) {
704 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
707 if (!endswith(u->id, ".socket"))
710 r = get_triggered_units(bus, u->unit_path, &triggered);
714 c = get_listening(bus, u->unit_path, &listening);
720 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
725 for (i = 0; i < c; i++)
726 socket_infos[cs + i] = (struct socket_info) {
728 .type = listening[i*2],
729 .path = listening[i*2 + 1],
730 .triggered = triggered,
731 .own_triggered = i==0,
734 /* from this point on we will cleanup those socket_infos */
737 listening = triggered = NULL; /* avoid cleanup */
740 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
741 (__compar_fn_t) socket_info_compare);
743 output_sockets_list(socket_infos, cs);
746 assert(cs == 0 || socket_infos);
747 for (s = socket_infos; s < socket_infos + cs; s++) {
750 if (s->own_triggered)
751 strv_free(s->triggered);
757 static int get_next_elapse(
760 dual_timestamp *next) {
762 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
770 r = sd_bus_get_property_trivial(
772 "org.freedesktop.systemd1",
774 "org.freedesktop.systemd1.Timer",
775 "NextElapseUSecMonotonic",
780 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
784 r = sd_bus_get_property_trivial(
786 "org.freedesktop.systemd1",
788 "org.freedesktop.systemd1.Timer",
789 "NextElapseUSecRealtime",
794 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
808 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
812 if (a->next_elapse < b->next_elapse)
814 if (a->next_elapse > b->next_elapse)
817 return strcmp(a->id, b->id);
820 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
821 struct timer_info *t;
823 nextlen = sizeof("NEXT") - 1,
824 leftlen = sizeof("LEFT") - 1,
825 unitlen = sizeof("UNIT") - 1,
826 activatelen = sizeof("ACTIVATES") - 1;
828 const char *on, *off;
830 assert(timer_infos || n == 0);
832 for (t = timer_infos; t < timer_infos + n; t++) {
836 if (t->next_elapse > 0) {
837 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
839 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
840 nextlen = MAX(nextlen, strlen(tstamp) + 1);
842 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
843 leftlen = MAX(leftlen, strlen(trel));
846 unitlen = MAX(unitlen, strlen(t->id));
848 STRV_FOREACH(a, t->triggered)
849 ul += strlen(*a) + 2*(a != t->triggered);
850 activatelen = MAX(activatelen, ul);
855 printf("%-*s %-*s %-*s %s\n",
861 for (t = timer_infos; t < timer_infos + n; t++) {
862 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
865 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
866 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
868 printf("%-*s %-*s %-*s",
869 nextlen, tstamp, leftlen, trel, unitlen, t->id);
871 STRV_FOREACH(a, t->triggered)
873 a == t->triggered ? "" : ",", *a);
877 on = ansi_highlight();
878 off = ansi_highlight_off();
882 on = ansi_highlight_red();
883 off = ansi_highlight_off();
886 if (!arg_no_legend) {
887 printf("%s%u timers listed.%s\n", on, n, off);
889 printf("Pass --all to see loaded but inactive timers, too.\n");
895 static int list_timers(sd_bus *bus, char **args) {
897 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
898 _cleanup_free_ struct timer_info *timer_infos = NULL;
899 _cleanup_free_ UnitInfo *unit_infos = NULL;
900 struct timer_info *t;
907 pager_open_if_enabled();
909 n = get_unit_list(bus, &reply, &unit_infos, strv_skip_first(args));
913 dual_timestamp_get(&nw);
915 for (u = unit_infos; u < unit_infos + n; u++) {
916 _cleanup_strv_free_ char **triggered = NULL;
920 if (!endswith(u->id, ".timer"))
923 r = get_triggered_units(bus, u->unit_path, &triggered);
927 r = get_next_elapse(bus, u->unit_path, &next);
931 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
934 if (next.monotonic > nw.monotonic)
935 converted = nw.realtime + (next.monotonic - nw.monotonic);
937 converted = nw.realtime - (nw.monotonic - next.monotonic);
939 if (next.realtime != (usec_t) -1 && next.realtime > 0)
940 m = MIN(converted, next.realtime);
946 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
951 timer_infos[c++] = (struct timer_info) {
954 .triggered = triggered,
957 triggered = NULL; /* avoid cleanup */
960 qsort_safe(timer_infos, c, sizeof(struct timer_info),
961 (__compar_fn_t) timer_info_compare);
963 output_timers_list(timer_infos, c);
966 for (t = timer_infos; t < timer_infos + c; t++)
967 strv_free(t->triggered);
972 static int compare_unit_file_list(const void *a, const void *b) {
974 const UnitFileList *u = a, *v = b;
976 d1 = strrchr(u->path, '.');
977 d2 = strrchr(v->path, '.');
982 r = strcasecmp(d1, d2);
987 return strcasecmp(basename(u->path), basename(v->path));
990 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
993 if (!strv_isempty(patterns)) {
996 STRV_FOREACH(pattern, patterns)
997 if (fnmatch(*pattern, basename(u->path), FNM_NOESCAPE) == 0)
1002 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
1005 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1006 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
1007 const UnitFileList *u;
1009 max_id_len = sizeof("UNIT FILE")-1;
1010 state_cols = sizeof("STATE")-1;
1012 for (u = units; u < units + c; u++) {
1013 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1014 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1018 unsigned basic_cols;
1020 id_cols = MIN(max_id_len, 25u);
1021 basic_cols = 1 + id_cols + state_cols;
1022 if (basic_cols < (unsigned) columns())
1023 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1025 id_cols = max_id_len;
1028 printf("%-*s %-*s\n",
1029 id_cols, "UNIT FILE",
1030 state_cols, "STATE");
1032 for (u = units; u < units + c; u++) {
1033 _cleanup_free_ char *e = NULL;
1034 const char *on, *off;
1039 if (u->state == UNIT_FILE_MASKED ||
1040 u->state == UNIT_FILE_MASKED_RUNTIME ||
1041 u->state == UNIT_FILE_DISABLED ||
1042 u->state == UNIT_FILE_INVALID) {
1043 on = ansi_highlight_red();
1044 off = ansi_highlight_off();
1045 } else if (u->state == UNIT_FILE_ENABLED) {
1046 on = ansi_highlight_green();
1047 off = ansi_highlight_off();
1051 id = basename(u->path);
1053 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1055 printf("%-*s %s%-*s%s\n",
1056 id_cols, e ? e : id,
1057 on, state_cols, unit_file_state_to_string(u->state), off);
1061 printf("\n%u unit files listed.\n", n_shown);
1064 static int list_unit_files(sd_bus *bus, char **args) {
1065 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1066 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1067 _cleanup_free_ UnitFileList *units = NULL;
1075 pager_open_if_enabled();
1083 h = hashmap_new(string_hash_func, string_compare_func);
1087 r = unit_file_get_list(arg_scope, arg_root, h);
1089 unit_file_list_free(h);
1090 log_error("Failed to get unit file list: %s", strerror(-r));
1094 n_units = hashmap_size(h);
1095 units = new(UnitFileList, n_units);
1097 unit_file_list_free(h);
1101 HASHMAP_FOREACH(u, h, i) {
1102 if (!output_show_unit_file(u, strv_skip_first(args)))
1109 assert(c <= n_units);
1112 r = sd_bus_call_method(
1114 "org.freedesktop.systemd1",
1115 "/org/freedesktop/systemd1",
1116 "org.freedesktop.systemd1.Manager",
1122 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1126 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1128 return bus_log_parse_error(r);
1130 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1132 if (!GREEDY_REALLOC(units, size, c + 1))
1135 units[c] = (struct UnitFileList) {
1137 unit_file_state_from_string(state)
1140 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1145 return bus_log_parse_error(r);
1147 r = sd_bus_message_exit_container(reply);
1149 return bus_log_parse_error(r);
1153 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1154 output_unit_file_list(units, c);
1158 for (unit = units; unit < units + c; unit++)
1164 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1165 _cleanup_free_ char *n = NULL;
1166 size_t max_len = MAX(columns(),20u);
1172 for (i = level - 1; i >= 0; i--) {
1174 if (len > max_len - 3 && !arg_full) {
1175 printf("%s...\n",max_len % 2 ? "" : " ");
1178 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1182 if (len > max_len - 3 && !arg_full) {
1183 printf("%s...\n",max_len % 2 ? "" : " ");
1187 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1191 printf("%s\n", name);
1195 n = ellipsize(name, max_len-len, 100);
1203 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1205 static const char *dependencies[_DEPENDENCY_MAX] = {
1206 [DEPENDENCY_FORWARD] = "Requires\0"
1207 "RequiresOverridable\0"
1209 "RequisiteOverridable\0"
1211 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1212 "RequiredByOverridable\0"
1215 [DEPENDENCY_AFTER] = "After\0",
1216 [DEPENDENCY_BEFORE] = "Before\0",
1219 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1220 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1221 _cleanup_strv_free_ char **ret = NULL;
1222 _cleanup_free_ char *path = NULL;
1228 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1230 path = unit_dbus_path_from_name(name);
1234 r = sd_bus_call_method(
1236 "org.freedesktop.systemd1",
1238 "org.freedesktop.DBus.Properties",
1242 "s", "org.freedesktop.systemd1.Unit");
1244 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1248 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1250 return bus_log_parse_error(r);
1252 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1255 r = sd_bus_message_read(reply, "s", &prop);
1257 return bus_log_parse_error(r);
1259 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1260 r = sd_bus_message_skip(reply, "v");
1262 return bus_log_parse_error(r);
1265 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1267 return bus_log_parse_error(r);
1269 r = bus_message_read_strv_extend(reply, &ret);
1271 return bus_log_parse_error(r);
1273 r = sd_bus_message_exit_container(reply);
1275 return bus_log_parse_error(r);
1278 r = sd_bus_message_exit_container(reply);
1280 return bus_log_parse_error(r);
1284 return bus_log_parse_error(r);
1286 r = sd_bus_message_exit_container(reply);
1288 return bus_log_parse_error(r);
1296 static int list_dependencies_compare(const void *_a, const void *_b) {
1297 const char **a = (const char**) _a, **b = (const char**) _b;
1299 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1301 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1304 return strcasecmp(*a, *b);
1307 static int list_dependencies_one(
1312 unsigned int branches) {
1314 _cleanup_strv_free_ char **deps = NULL, **u;
1322 u = strv_append(*units, name);
1326 r = list_dependencies_get_dependencies(bus, name, &deps);
1330 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1332 STRV_FOREACH(c, deps) {
1335 if (strv_contains(u, *c)) {
1337 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1344 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1346 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1348 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1350 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1354 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1355 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1370 static int list_dependencies(sd_bus *bus, char **args) {
1371 _cleanup_strv_free_ char **units = NULL;
1372 _cleanup_free_ char *unit = NULL;
1378 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1383 u = SPECIAL_DEFAULT_TARGET;
1385 pager_open_if_enabled();
1389 return list_dependencies_one(bus, u, 0, &units, 0);
1392 static int get_default(sd_bus *bus, char **args) {
1393 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1394 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1395 _cleanup_free_ char *_path = NULL;
1399 if (!bus || avoid_bus()) {
1400 r = unit_file_get_default(arg_scope, arg_root, &_path);
1402 log_error("Failed to get default target: %s", strerror(-r));
1408 r = sd_bus_call_method(
1410 "org.freedesktop.systemd1",
1411 "/org/freedesktop/systemd1",
1412 "org.freedesktop.systemd1.Manager",
1418 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1422 r = sd_bus_message_read(reply, "s", &path);
1424 return bus_log_parse_error(r);
1428 printf("%s\n", path);
1433 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1436 assert(changes || n_changes == 0);
1438 for (i = 0; i < n_changes; i++) {
1439 if (changes[i].type == UNIT_FILE_SYMLINK)
1440 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1442 log_info("rm '%s'", changes[i].path);
1446 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1447 const char *type, *path, *source;
1450 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1452 return bus_log_parse_error(r);
1454 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1456 if (streq(type, "symlink"))
1457 log_info("ln -s '%s' '%s'", source, path);
1459 log_info("rm '%s'", path);
1463 return bus_log_parse_error(r);
1465 r = sd_bus_message_exit_container(m);
1467 return bus_log_parse_error(r);
1472 static int set_default(sd_bus *bus, char **args) {
1473 _cleanup_free_ char *unit = NULL;
1474 UnitFileChange *changes = NULL;
1475 unsigned n_changes = 0;
1478 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1482 if (!bus || avoid_bus()) {
1483 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1485 log_error("Failed to set default target: %s", strerror(-r));
1490 dump_unit_file_changes(changes, n_changes);
1494 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1495 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1497 r = sd_bus_call_method(
1499 "org.freedesktop.systemd1",
1500 "/org/freedesktop/systemd1",
1501 "org.freedesktop.systemd1.Manager",
1505 "sb", unit, arg_force);
1507 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1511 r = deserialize_and_dump_unit_file_changes(reply);
1515 /* Try to reload if enabeld */
1517 r = daemon_reload(bus, args);
1522 unit_file_changes_free(changes, n_changes);
1529 const char *name, *type, *state;
1532 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
1533 unsigned id_len, unit_len, type_len, state_len;
1534 const struct job_info *j;
1535 const char *on, *off;
1536 bool shorten = false;
1538 assert(n == 0 || jobs);
1541 on = ansi_highlight_green();
1542 off = ansi_highlight_off();
1544 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
1548 pager_open_if_enabled();
1550 id_len = sizeof("JOB")-1;
1551 unit_len = sizeof("UNIT")-1;
1552 type_len = sizeof("TYPE")-1;
1553 state_len = sizeof("STATE")-1;
1555 for (j = jobs; j < jobs + n; j++) {
1556 uint32_t id = j->id;
1557 assert(j->name && j->type && j->state);
1559 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1560 unit_len = MAX(unit_len, strlen(j->name));
1561 type_len = MAX(type_len, strlen(j->type));
1562 state_len = MAX(state_len, strlen(j->state));
1565 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1566 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1571 printf("%*s %-*s %-*s %-*s\n",
1575 state_len, "STATE");
1577 for (j = jobs; j < jobs + n; j++) {
1578 _cleanup_free_ char *e = NULL;
1580 if (streq(j->state, "running")) {
1581 on = ansi_highlight();
1582 off = ansi_highlight_off();
1586 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1587 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1589 on, unit_len, e ? e : j->name, off,
1591 on, state_len, j->state, off);
1594 if (!arg_no_legend) {
1595 on = ansi_highlight();
1596 off = ansi_highlight_off();
1598 printf("\n%s%u jobs listed%s.\n", on, n, off);
1602 static bool output_show_job(struct job_info *job, char **patterns) {
1603 if (!strv_isempty(patterns)) {
1606 STRV_FOREACH(pattern, patterns)
1607 if (fnmatch(*pattern, job->name, FNM_NOESCAPE) == 0)
1615 static int list_jobs(sd_bus *bus, char **args) {
1616 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1617 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1618 const char *name, *type, *state, *job_path, *unit_path;
1619 _cleanup_free_ struct job_info *jobs = NULL;
1624 bool skipped = false;
1626 r = sd_bus_call_method(
1628 "org.freedesktop.systemd1",
1629 "/org/freedesktop/systemd1",
1630 "org.freedesktop.systemd1.Manager",
1636 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1640 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1642 return bus_log_parse_error(r);
1644 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1645 struct job_info job = { id, name, type, state };
1647 if (!output_show_job(&job, strv_skip_first(args))) {
1652 if (!GREEDY_REALLOC(jobs, size, c + 1))
1658 return bus_log_parse_error(r);
1660 r = sd_bus_message_exit_container(reply);
1662 return bus_log_parse_error(r);
1664 output_jobs_list(jobs, c, skipped);
1668 static int cancel_job(sd_bus *bus, char **args) {
1669 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1674 if (strv_length(args) <= 1)
1675 return daemon_reload(bus, args);
1677 STRV_FOREACH(name, args+1) {
1681 r = safe_atou32(*name, &id);
1683 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1687 r = sd_bus_call_method(
1689 "org.freedesktop.systemd1",
1690 "/org/freedesktop/systemd1",
1691 "org.freedesktop.systemd1.Manager",
1697 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1705 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1706 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1710 /* We ignore all errors here, since this is used to show a
1713 /* We don't use unit_dbus_path_from_name() directly since we
1714 * don't want to load the unit if it isn't loaded. */
1716 r = sd_bus_call_method(
1718 "org.freedesktop.systemd1",
1719 "/org/freedesktop/systemd1",
1720 "org.freedesktop.systemd1.Manager",
1728 r = sd_bus_message_read(reply, "o", &path);
1732 r = sd_bus_get_property_trivial(
1734 "org.freedesktop.systemd1",
1736 "org.freedesktop.systemd1.Unit",
1746 typedef struct WaitData {
1753 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1760 log_debug("Got D-Bus request: %s.%s() on %s",
1761 sd_bus_message_get_interface(m),
1762 sd_bus_message_get_member(m),
1763 sd_bus_message_get_path(m));
1765 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1766 log_error("Warning! D-Bus connection terminated.");
1768 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1770 const char *path, *result, *unit;
1774 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1776 ret = set_remove(d->set, (char*) path);
1782 if (!isempty(result))
1783 d->result = strdup(result);
1786 d->name = strdup(unit);
1791 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1793 ret = set_remove(d->set, (char*) path);
1800 d->result = strdup(result);
1806 bus_log_parse_error(r);
1812 static int enable_wait_for_jobs(sd_bus *bus) {
1817 r = sd_bus_add_match(
1820 "sender='org.freedesktop.systemd1',"
1821 "interface='org.freedesktop.systemd1.Manager',"
1822 "member='JobRemoved',"
1823 "path='/org/freedesktop/systemd1'",
1826 log_error("Failed to add match");
1830 /* This is slightly dirty, since we don't undo the match registrations. */
1834 static int bus_process_wait(sd_bus *bus) {
1838 r = sd_bus_process(bus, NULL);
1843 r = sd_bus_wait(bus, (uint64_t) -1);
1849 static int check_wait_response(WaitData *d) {
1855 if (streq(d->result, "timeout"))
1856 log_error("Job for %s timed out.", strna(d->name));
1857 else if (streq(d->result, "canceled"))
1858 log_error("Job for %s canceled.", strna(d->name));
1859 else if (streq(d->result, "dependency"))
1860 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d->name));
1861 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1862 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d->name), strna(d->name));
1865 if (streq(d->result, "timeout"))
1867 else if (streq(d->result, "canceled"))
1869 else if (streq(d->result, "dependency"))
1871 else if (!streq(d->result, "done") && !streq(d->result, "skipped"))
1877 static int wait_for_jobs(sd_bus *bus, Set *s) {
1878 WaitData d = { .set = s };
1884 q = sd_bus_add_filter(bus, wait_filter, &d);
1888 while (!set_isempty(s)) {
1889 q = bus_process_wait(bus);
1891 log_error("Failed to wait for response: %s", strerror(-r));
1896 q = check_wait_response(&d);
1897 /* Return the first error as it is most likely to be
1899 if (q < 0 && r == 0)
1901 log_debug("Got result %s/%s for job %s",
1902 strna(d.result), strerror(-q), strna(d.name));
1912 q = sd_bus_remove_filter(bus, wait_filter, &d);
1913 if (q < 0 && r == 0)
1919 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1920 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1921 _cleanup_free_ char *n = NULL, *state = NULL;
1927 n = unit_name_mangle(name, MANGLE_NOGLOB);
1931 /* We don't use unit_dbus_path_from_name() directly since we
1932 * don't want to load the unit if it isn't loaded. */
1934 r = sd_bus_call_method(
1936 "org.freedesktop.systemd1",
1937 "/org/freedesktop/systemd1",
1938 "org.freedesktop.systemd1.Manager",
1949 r = sd_bus_message_read(reply, "o", &path);
1951 return bus_log_parse_error(r);
1953 r = sd_bus_get_property_string(
1955 "org.freedesktop.systemd1",
1957 "org.freedesktop.systemd1.Unit",
1970 return nulstr_contains(good_states, state);
1973 static int check_triggering_units(
1977 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1978 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1979 _cleanup_strv_free_ char **triggered_by = NULL;
1980 bool print_warning_label = true;
1984 n = unit_name_mangle(name, MANGLE_NOGLOB);
1988 path = unit_dbus_path_from_name(n);
1992 r = sd_bus_get_property_string(
1994 "org.freedesktop.systemd1",
1996 "org.freedesktop.systemd1.Unit",
2001 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2005 if (streq(state, "masked"))
2008 r = sd_bus_get_property_strv(
2010 "org.freedesktop.systemd1",
2012 "org.freedesktop.systemd1.Unit",
2017 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2021 STRV_FOREACH(i, triggered_by) {
2022 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2024 log_error("Failed to check unit: %s", strerror(-r));
2031 if (print_warning_label) {
2032 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2033 print_warning_label = false;
2036 log_warning(" %s", *i);
2042 static int start_unit_one(
2047 sd_bus_error *error,
2050 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2059 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2060 r = sd_bus_call_method(
2062 "org.freedesktop.systemd1",
2063 "/org/freedesktop/systemd1",
2064 "org.freedesktop.systemd1.Manager",
2070 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2071 /* There's always a fallback possible for
2072 * legacy actions. */
2073 return -EADDRNOTAVAIL;
2075 log_error("Failed to %s %s: %s", method, name, bus_error_message(error, r));
2079 r = sd_bus_message_read(reply, "o", &path);
2081 return bus_log_parse_error(r);
2083 if (need_daemon_reload(bus, name) > 0)
2084 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2085 name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2094 log_debug("Adding %s to the set", p);
2095 r = set_consume(s, p);
2103 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2105 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2106 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2110 STRV_FOREACH(name, names) {
2114 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2116 t = unit_name_mangle(*name, MANGLE_GLOB);
2120 if (string_is_glob(t))
2121 r = strv_push(&globs, t);
2123 r = strv_push(&mangled, t);
2130 /* Query the manager only if any of the names are a glob, since
2131 * this is fairly expensive */
2132 if (!strv_isempty(globs)) {
2133 _cleanup_free_ UnitInfo *unit_infos = NULL;
2135 r = get_unit_list(bus, &reply, &unit_infos, globs);
2139 for (i = 0; i < r; i++)
2140 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2145 mangled = NULL; /* do not free */
2149 static const struct {
2153 } action_table[_ACTION_MAX] = {
2154 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2155 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2156 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2157 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2158 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2159 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2160 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2161 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2162 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2163 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2164 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2165 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2166 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2167 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2168 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2171 static enum action verb_to_action(const char *verb) {
2174 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2175 if (streq_ptr(action_table[i].verb, verb))
2178 return _ACTION_INVALID;
2181 static int start_unit(sd_bus *bus, char **args) {
2182 _cleanup_set_free_free_ Set *s = NULL;
2183 _cleanup_strv_free_ char **names = NULL;
2184 const char *method, *mode, *one_name;
2190 ask_password_agent_open_if_enabled();
2192 if (arg_action == ACTION_SYSTEMCTL) {
2195 streq(args[0], "stop") ||
2196 streq(args[0], "condstop") ? "StopUnit" :
2197 streq(args[0], "reload") ? "ReloadUnit" :
2198 streq(args[0], "restart") ? "RestartUnit" :
2200 streq(args[0], "try-restart") ||
2201 streq(args[0], "condrestart") ? "TryRestartUnit" :
2203 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2205 streq(args[0], "reload-or-try-restart") ||
2206 streq(args[0], "condreload") ||
2207 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2209 action = verb_to_action(args[0]);
2211 mode = streq(args[0], "isolate") ? "isolate" :
2212 action_table[action].mode ?: arg_job_mode;
2214 one_name = action_table[action].target;
2216 assert(arg_action < ELEMENTSOF(action_table));
2217 assert(action_table[arg_action].target);
2219 method = "StartUnit";
2221 mode = action_table[arg_action].mode;
2222 one_name = action_table[arg_action].target;
2226 names = strv_new(one_name, NULL);
2228 r = expand_names(bus, args + 1, NULL, &names);
2230 log_error("Failed to expand names: %s", strerror(-r));
2233 if (!arg_no_block) {
2234 r = enable_wait_for_jobs(bus);
2236 log_error("Could not watch jobs: %s", strerror(-r));
2240 s = set_new(string_hash_func, string_compare_func);
2245 STRV_FOREACH(name, names) {
2246 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2249 q = start_unit_one(bus, method, *name, mode, &error, s);
2250 if (r >= 0 && q < 0)
2251 r = translate_bus_error_to_exit_status(q, &error);
2254 if (!arg_no_block) {
2257 q = wait_for_jobs(bus, s);
2261 /* When stopping units, warn if they can still be triggered by
2262 * another active unit (socket, path, timer) */
2263 if (!arg_quiet && streq(method, "StopUnit"))
2264 STRV_FOREACH(name, names)
2265 check_triggering_units(bus, *name);
2271 /* Ask systemd-logind, which might grant access to unprivileged users
2272 * through PolicyKit */
2273 static int reboot_with_logind(sd_bus *bus, enum action a) {
2275 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2282 polkit_agent_open_if_enabled();
2290 case ACTION_POWEROFF:
2291 method = "PowerOff";
2294 case ACTION_SUSPEND:
2298 case ACTION_HIBERNATE:
2299 method = "Hibernate";
2302 case ACTION_HYBRID_SLEEP:
2303 method = "HybridSleep";
2310 r = sd_bus_call_method(
2312 "org.freedesktop.login1",
2313 "/org/freedesktop/login1",
2314 "org.freedesktop.login1.Manager",
2320 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2328 static int check_inhibitors(sd_bus *bus, enum action a) {
2330 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2331 _cleanup_strv_free_ char **sessions = NULL;
2332 const char *what, *who, *why, *mode;
2341 if (arg_ignore_inhibitors || arg_force > 0)
2353 r = sd_bus_call_method(
2355 "org.freedesktop.login1",
2356 "/org/freedesktop/login1",
2357 "org.freedesktop.login1.Manager",
2363 /* If logind is not around, then there are no inhibitors... */
2366 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2368 return bus_log_parse_error(r);
2370 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2371 _cleanup_free_ char *comm = NULL, *user = NULL;
2372 _cleanup_strv_free_ char **sv = NULL;
2374 if (!streq(mode, "block"))
2377 sv = strv_split(what, ":");
2381 if (!strv_contains(sv,
2383 a == ACTION_POWEROFF ||
2384 a == ACTION_REBOOT ||
2385 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2388 get_process_comm(pid, &comm);
2389 user = uid_to_name(uid);
2391 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2392 who, (unsigned long) pid, strna(comm), strna(user), why);
2397 return bus_log_parse_error(r);
2399 r = sd_bus_message_exit_container(reply);
2401 return bus_log_parse_error(r);
2403 /* Check for current sessions */
2404 sd_get_sessions(&sessions);
2405 STRV_FOREACH(s, sessions) {
2406 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2408 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2411 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2414 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2417 sd_session_get_tty(*s, &tty);
2418 sd_session_get_seat(*s, &seat);
2419 sd_session_get_service(*s, &service);
2420 user = uid_to_name(uid);
2422 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2429 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2430 action_table[a].verb);
2438 static int start_special(sd_bus *bus, char **args) {
2444 a = verb_to_action(args[0]);
2446 r = check_inhibitors(bus, a);
2450 if (arg_force >= 2 && geteuid() != 0) {
2451 log_error("Must be root.");
2455 if (arg_force >= 2 &&
2456 (a == ACTION_HALT ||
2457 a == ACTION_POWEROFF ||
2458 a == ACTION_REBOOT))
2461 if (arg_force >= 1 &&
2462 (a == ACTION_HALT ||
2463 a == ACTION_POWEROFF ||
2464 a == ACTION_REBOOT ||
2465 a == ACTION_KEXEC ||
2467 return daemon_reload(bus, args);
2469 /* first try logind, to allow authentication with polkit */
2470 if (geteuid() != 0 &&
2471 (a == ACTION_POWEROFF ||
2472 a == ACTION_REBOOT ||
2473 a == ACTION_SUSPEND ||
2474 a == ACTION_HIBERNATE ||
2475 a == ACTION_HYBRID_SLEEP)) {
2476 r = reboot_with_logind(bus, a);
2481 r = start_unit(bus, args);
2482 if (r == EXIT_SUCCESS)
2488 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2489 _cleanup_strv_free_ char **names = NULL;
2496 r = expand_names(bus, args, NULL, &names);
2498 log_error("Failed to expand names: %s", strerror(-r));
2500 STRV_FOREACH(name, names) {
2503 state = check_one_unit(bus, *name, good_states, arg_quiet);
2513 static int check_unit_active(sd_bus *bus, char **args) {
2514 /* According to LSB: 3, "program is not running" */
2515 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
2518 static int check_unit_failed(sd_bus *bus, char **args) {
2519 return check_unit_generic(bus, 1, "failed\0", args + 1);
2522 static int kill_unit(sd_bus *bus, char **args) {
2523 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2524 _cleanup_strv_free_ char **names = NULL;
2532 arg_kill_who = "all";
2534 r = expand_names(bus, args + 1, NULL, &names);
2536 log_error("Failed to expand names: %s", strerror(-r));
2538 STRV_FOREACH(name, names) {
2539 q = sd_bus_call_method(
2541 "org.freedesktop.systemd1",
2542 "/org/freedesktop/systemd1",
2543 "org.freedesktop.systemd1.Manager",
2547 "ssi", *names, arg_kill_who, arg_signal);
2549 log_error("Failed to kill unit %s: %s",
2550 *names, bus_error_message(&error, r));
2559 typedef struct ExecStatusInfo {
2567 usec_t start_timestamp;
2568 usec_t exit_timestamp;
2573 LIST_FIELDS(struct ExecStatusInfo, exec);
2576 static void exec_status_info_free(ExecStatusInfo *i) {
2585 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2586 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2589 int32_t code, status;
2595 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2597 return bus_log_parse_error(r);
2601 r = sd_bus_message_read(m, "s", &path);
2603 return bus_log_parse_error(r);
2605 i->path = strdup(path);
2609 r = sd_bus_message_read_strv(m, &i->argv);
2611 return bus_log_parse_error(r);
2613 r = sd_bus_message_read(m,
2616 &start_timestamp, &start_timestamp_monotonic,
2617 &exit_timestamp, &exit_timestamp_monotonic,
2621 return bus_log_parse_error(r);
2624 i->start_timestamp = (usec_t) start_timestamp;
2625 i->exit_timestamp = (usec_t) exit_timestamp;
2626 i->pid = (pid_t) pid;
2630 r = sd_bus_message_exit_container(m);
2632 return bus_log_parse_error(r);
2637 typedef struct UnitStatusInfo {
2639 const char *load_state;
2640 const char *active_state;
2641 const char *sub_state;
2642 const char *unit_file_state;
2644 const char *description;
2645 const char *following;
2647 char **documentation;
2649 const char *fragment_path;
2650 const char *source_path;
2651 const char *control_group;
2653 char **dropin_paths;
2655 const char *load_error;
2658 usec_t inactive_exit_timestamp;
2659 usec_t inactive_exit_timestamp_monotonic;
2660 usec_t active_enter_timestamp;
2661 usec_t active_exit_timestamp;
2662 usec_t inactive_enter_timestamp;
2664 bool need_daemon_reload;
2669 const char *status_text;
2670 const char *pid_file;
2673 usec_t start_timestamp;
2674 usec_t exit_timestamp;
2676 int exit_code, exit_status;
2678 usec_t condition_timestamp;
2679 bool condition_result;
2680 bool failed_condition_trigger;
2681 bool failed_condition_negate;
2682 const char *failed_condition;
2683 const char *failed_condition_param;
2686 unsigned n_accepted;
2687 unsigned n_connections;
2690 /* Pairs of type, path */
2694 const char *sysfs_path;
2696 /* Mount, Automount */
2702 LIST_HEAD(ExecStatusInfo, exec);
2705 static void print_status_info(
2710 const char *on, *off, *ss;
2712 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2713 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2716 arg_all * OUTPUT_SHOW_ALL |
2717 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2718 on_tty() * OUTPUT_COLOR |
2719 !arg_quiet * OUTPUT_WARN_CUTOFF |
2720 arg_full * OUTPUT_FULL_WIDTH;
2725 /* This shows pretty information about a unit. See
2726 * print_property() for a low-level property printer */
2728 printf("%s", strna(i->id));
2730 if (i->description && !streq_ptr(i->id, i->description))
2731 printf(" - %s", i->description);
2736 printf(" Follow: unit currently follows state of %s\n", i->following);
2738 if (streq_ptr(i->load_state, "error")) {
2739 on = ansi_highlight_red();
2740 off = ansi_highlight_off();
2744 path = i->source_path ? i->source_path : i->fragment_path;
2747 printf(" Loaded: %s%s%s (Reason: %s)\n",
2748 on, strna(i->load_state), off, i->load_error);
2749 else if (path && i->unit_file_state)
2750 printf(" Loaded: %s%s%s (%s; %s)\n",
2751 on, strna(i->load_state), off, path, i->unit_file_state);
2753 printf(" Loaded: %s%s%s (%s)\n",
2754 on, strna(i->load_state), off, path);
2756 printf(" Loaded: %s%s%s\n",
2757 on, strna(i->load_state), off);
2759 if (!strv_isempty(i->dropin_paths)) {
2760 _cleanup_free_ char *dir = NULL;
2764 STRV_FOREACH(dropin, i->dropin_paths) {
2765 if (! dir || last) {
2766 printf(dir ? " " : " Drop-In: ");
2771 if (path_get_parent(*dropin, &dir) < 0) {
2776 printf("%s\n %s", dir,
2777 draw_special_char(DRAW_TREE_RIGHT));
2780 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2782 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
2786 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2788 if (streq_ptr(i->active_state, "failed")) {
2789 on = ansi_highlight_red();
2790 off = ansi_highlight_off();
2791 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2792 on = ansi_highlight_green();
2793 off = ansi_highlight_off();
2798 printf(" Active: %s%s (%s)%s",
2799 on, strna(i->active_state), ss, off);
2801 printf(" Active: %s%s%s",
2802 on, strna(i->active_state), off);
2804 if (!isempty(i->result) && !streq(i->result, "success"))
2805 printf(" (Result: %s)", i->result);
2807 timestamp = (streq_ptr(i->active_state, "active") ||
2808 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2809 (streq_ptr(i->active_state, "inactive") ||
2810 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2811 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2812 i->active_exit_timestamp;
2814 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2815 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2818 printf(" since %s; %s\n", s2, s1);
2820 printf(" since %s\n", s2);
2824 if (!i->condition_result && i->condition_timestamp > 0) {
2825 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2826 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2828 printf(" start condition failed at %s%s%s\n",
2829 s2, s1 ? "; " : "", s1 ? s1 : "");
2830 if (i->failed_condition_trigger)
2831 printf(" none of the trigger conditions were met\n");
2832 else if (i->failed_condition)
2833 printf(" %s=%s%s was not met\n",
2834 i->failed_condition,
2835 i->failed_condition_negate ? "!" : "",
2836 i->failed_condition_param);
2840 printf(" Device: %s\n", i->sysfs_path);
2842 printf(" Where: %s\n", i->where);
2844 printf(" What: %s\n", i->what);
2846 STRV_FOREACH(t, i->documentation)
2847 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2849 STRV_FOREACH_PAIR(t, t2, i->listen)
2850 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2853 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2855 LIST_FOREACH(exec, p, i->exec) {
2856 _cleanup_free_ char *argv = NULL;
2859 /* Only show exited processes here */
2863 argv = strv_join(p->argv, " ");
2864 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2866 good = is_clean_exit_lsb(p->code, p->status, NULL);
2868 on = ansi_highlight_red();
2869 off = ansi_highlight_off();
2873 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2875 if (p->code == CLD_EXITED) {
2878 printf("status=%i", p->status);
2880 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2885 printf("signal=%s", signal_to_string(p->status));
2887 printf(")%s\n", off);
2889 if (i->main_pid == p->pid &&
2890 i->start_timestamp == p->start_timestamp &&
2891 i->exit_timestamp == p->start_timestamp)
2892 /* Let's not show this twice */
2895 if (p->pid == i->control_pid)
2899 if (i->main_pid > 0 || i->control_pid > 0) {
2900 if (i->main_pid > 0) {
2901 printf(" Main PID: %u", (unsigned) i->main_pid);
2904 _cleanup_free_ char *comm = NULL;
2905 get_process_comm(i->main_pid, &comm);
2907 printf(" (%s)", comm);
2908 } else if (i->exit_code > 0) {
2909 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2911 if (i->exit_code == CLD_EXITED) {
2914 printf("status=%i", i->exit_status);
2916 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2921 printf("signal=%s", signal_to_string(i->exit_status));
2925 if (i->control_pid > 0)
2929 if (i->control_pid > 0) {
2930 _cleanup_free_ char *c = NULL;
2932 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2934 get_process_comm(i->control_pid, &c);
2943 printf(" Status: \"%s\"\n", i->status_text);
2945 if (i->control_group &&
2946 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2949 printf(" CGroup: %s\n", i->control_group);
2951 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2954 char prefix[] = " ";
2957 if (c > sizeof(prefix) - 1)
2958 c -= sizeof(prefix) - 1;
2962 if (i->main_pid > 0)
2963 extra[k++] = i->main_pid;
2965 if (i->control_pid > 0)
2966 extra[k++] = i->control_pid;
2968 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2969 c, false, extra, k, flags);
2973 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2975 show_journal_by_unit(stdout,
2979 i->inactive_exit_timestamp_monotonic,
2983 arg_scope == UNIT_FILE_SYSTEM,
2987 if (i->need_daemon_reload)
2988 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2989 ansi_highlight_red(),
2990 ansi_highlight_off(),
2991 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2994 static void show_unit_help(UnitStatusInfo *i) {
2999 if (!i->documentation) {
3000 log_info("Documentation for %s not known.", i->id);
3004 STRV_FOREACH(p, i->documentation) {
3006 if (startswith(*p, "man:")) {
3007 const char *args[4] = { "man", NULL, NULL, NULL };
3008 _cleanup_free_ char *page = NULL, *section = NULL;
3015 if ((*p)[k-1] == ')')
3016 e = strrchr(*p, '(');
3019 page = strndup((*p) + 4, e - *p - 4);
3020 section = strndup(e + 1, *p + k - e - 2);
3021 if (!page || !section) {
3033 log_error("Failed to fork: %m");
3039 execvp(args[0], (char**) args);
3040 log_error("Failed to execute man: %m");
3041 _exit(EXIT_FAILURE);
3044 wait_for_terminate(pid, NULL);
3046 log_info("Can't show: %s", *p);
3050 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3057 switch (contents[0]) {
3059 case SD_BUS_TYPE_STRING: {
3062 r = sd_bus_message_read(m, "s", &s);
3064 return bus_log_parse_error(r);
3067 if (streq(name, "Id"))
3069 else if (streq(name, "LoadState"))
3071 else if (streq(name, "ActiveState"))
3072 i->active_state = s;
3073 else if (streq(name, "SubState"))
3075 else if (streq(name, "Description"))
3077 else if (streq(name, "FragmentPath"))
3078 i->fragment_path = s;
3079 else if (streq(name, "SourcePath"))
3082 else if (streq(name, "DefaultControlGroup")) {
3084 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3086 i->control_group = e;
3089 else if (streq(name, "ControlGroup"))
3090 i->control_group = s;
3091 else if (streq(name, "StatusText"))
3093 else if (streq(name, "PIDFile"))
3095 else if (streq(name, "SysFSPath"))
3097 else if (streq(name, "Where"))
3099 else if (streq(name, "What"))
3101 else if (streq(name, "Following"))
3103 else if (streq(name, "UnitFileState"))
3104 i->unit_file_state = s;
3105 else if (streq(name, "Result"))
3112 case SD_BUS_TYPE_BOOLEAN: {
3115 r = sd_bus_message_read(m, "b", &b);
3117 return bus_log_parse_error(r);
3119 if (streq(name, "Accept"))
3121 else if (streq(name, "NeedDaemonReload"))
3122 i->need_daemon_reload = b;
3123 else if (streq(name, "ConditionResult"))
3124 i->condition_result = b;
3129 case SD_BUS_TYPE_UINT32: {
3132 r = sd_bus_message_read(m, "u", &u);
3134 return bus_log_parse_error(r);
3136 if (streq(name, "MainPID")) {
3138 i->main_pid = (pid_t) u;
3141 } else if (streq(name, "ControlPID"))
3142 i->control_pid = (pid_t) u;
3143 else if (streq(name, "ExecMainPID")) {
3145 i->main_pid = (pid_t) u;
3146 } else if (streq(name, "NAccepted"))
3148 else if (streq(name, "NConnections"))
3149 i->n_connections = u;
3154 case SD_BUS_TYPE_INT32: {
3157 r = sd_bus_message_read(m, "i", &j);
3159 return bus_log_parse_error(r);
3161 if (streq(name, "ExecMainCode"))
3162 i->exit_code = (int) j;
3163 else if (streq(name, "ExecMainStatus"))
3164 i->exit_status = (int) j;
3169 case SD_BUS_TYPE_UINT64: {
3172 r = sd_bus_message_read(m, "t", &u);
3174 return bus_log_parse_error(r);
3176 if (streq(name, "ExecMainStartTimestamp"))
3177 i->start_timestamp = (usec_t) u;
3178 else if (streq(name, "ExecMainExitTimestamp"))
3179 i->exit_timestamp = (usec_t) u;
3180 else if (streq(name, "ActiveEnterTimestamp"))
3181 i->active_enter_timestamp = (usec_t) u;
3182 else if (streq(name, "InactiveEnterTimestamp"))
3183 i->inactive_enter_timestamp = (usec_t) u;
3184 else if (streq(name, "InactiveExitTimestamp"))
3185 i->inactive_exit_timestamp = (usec_t) u;
3186 else if (streq(name, "InactiveExitTimestampMonotonic"))
3187 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3188 else if (streq(name, "ActiveExitTimestamp"))
3189 i->active_exit_timestamp = (usec_t) u;
3190 else if (streq(name, "ConditionTimestamp"))
3191 i->condition_timestamp = (usec_t) u;
3196 case SD_BUS_TYPE_ARRAY:
3198 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3199 _cleanup_free_ ExecStatusInfo *info = NULL;
3201 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3203 return bus_log_parse_error(r);
3205 info = new0(ExecStatusInfo, 1);
3209 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3211 info->name = strdup(name);
3215 LIST_PREPEND(exec, i->exec, info);
3217 info = new0(ExecStatusInfo, 1);
3223 return bus_log_parse_error(r);
3225 r = sd_bus_message_exit_container(m);
3227 return bus_log_parse_error(r);
3231 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3232 const char *type, *path;
3234 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3236 return bus_log_parse_error(r);
3238 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3240 r = strv_extend(&i->listen, type);
3244 r = strv_extend(&i->listen, path);
3249 return bus_log_parse_error(r);
3251 r = sd_bus_message_exit_container(m);
3253 return bus_log_parse_error(r);
3257 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3259 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3261 return bus_log_parse_error(r);
3263 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3265 r = sd_bus_message_read_strv(m, &i->documentation);
3267 return bus_log_parse_error(r);
3269 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3270 const char *cond, *param;
3271 int trigger, negate;
3274 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3276 return bus_log_parse_error(r);
3278 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3279 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3280 if (state < 0 && (!trigger || !i->failed_condition)) {
3281 i->failed_condition = cond;
3282 i->failed_condition_trigger = trigger;
3283 i->failed_condition_negate = negate;
3284 i->failed_condition_param = param;
3288 return bus_log_parse_error(r);
3290 r = sd_bus_message_exit_container(m);
3292 return bus_log_parse_error(r);
3299 case SD_BUS_TYPE_STRUCT_BEGIN:
3301 if (streq(name, "LoadError")) {
3302 const char *n, *message;
3304 r = sd_bus_message_read(m, "(ss)", &n, &message);
3306 return bus_log_parse_error(r);
3308 if (!isempty(message))
3309 i->load_error = message;
3322 r = sd_bus_message_skip(m, contents);
3324 return bus_log_parse_error(r);
3329 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3335 /* This is a low-level property printer, see
3336 * print_status_info() for the nicer output */
3338 if (arg_properties && !strv_find(arg_properties, name)) {
3339 /* skip what we didn't read */
3340 r = sd_bus_message_skip(m, contents);
3344 switch (contents[0]) {
3346 case SD_BUS_TYPE_STRUCT_BEGIN:
3348 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3351 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3353 return bus_log_parse_error(r);
3356 printf("%s=%u\n", name, (unsigned) u);
3358 printf("%s=\n", name);
3362 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3365 r = sd_bus_message_read(m, "(so)", &s, NULL);
3367 return bus_log_parse_error(r);
3369 if (arg_all || !isempty(s))
3370 printf("%s=%s\n", name, s);
3374 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3375 const char *a = NULL, *b = NULL;
3377 r = sd_bus_message_read(m, "(ss)", &a, &b);
3379 return bus_log_parse_error(r);
3381 if (arg_all || !isempty(a) || !isempty(b))
3382 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3389 case SD_BUS_TYPE_ARRAY:
3391 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3395 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3397 return bus_log_parse_error(r);
3399 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3400 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3403 return bus_log_parse_error(r);
3405 r = sd_bus_message_exit_container(m);
3407 return bus_log_parse_error(r);
3411 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3412 const char *type, *path;
3414 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3416 return bus_log_parse_error(r);
3418 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3419 printf("%s=%s\n", type, path);
3421 return bus_log_parse_error(r);
3423 r = sd_bus_message_exit_container(m);
3425 return bus_log_parse_error(r);
3429 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3430 const char *type, *path;
3432 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3434 return bus_log_parse_error(r);
3436 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3437 printf("Listen%s=%s\n", type, path);
3439 return bus_log_parse_error(r);
3441 r = sd_bus_message_exit_container(m);
3443 return bus_log_parse_error(r);
3447 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3449 uint64_t value, next_elapse;
3451 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3453 return bus_log_parse_error(r);
3455 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3456 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3458 printf("%s={ value=%s ; next_elapse=%s }\n",
3460 format_timespan(timespan1, sizeof(timespan1), value, 0),
3461 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3464 return bus_log_parse_error(r);
3466 r = sd_bus_message_exit_container(m);
3468 return bus_log_parse_error(r);
3472 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3473 ExecStatusInfo info = {};
3475 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3477 return bus_log_parse_error(r);
3479 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3480 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3481 _cleanup_free_ char *tt;
3483 tt = strv_join(info.argv, " ");
3485 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3489 yes_no(info.ignore),
3490 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3491 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3492 (unsigned) info. pid,
3493 sigchld_code_to_string(info.code),
3495 info.code == CLD_EXITED ? "" : "/",
3496 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3499 strv_free(info.argv);
3503 r = sd_bus_message_exit_container(m);
3505 return bus_log_parse_error(r);
3509 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3510 const char *path, *rwm;
3512 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3514 return bus_log_parse_error(r);
3516 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3517 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3519 return bus_log_parse_error(r);
3521 r = sd_bus_message_exit_container(m);
3523 return bus_log_parse_error(r);
3527 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3531 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3533 return bus_log_parse_error(r);
3535 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3536 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3538 return bus_log_parse_error(r);
3540 r = sd_bus_message_exit_container(m);
3542 return bus_log_parse_error(r);
3546 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3550 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3552 return bus_log_parse_error(r);
3554 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3555 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3557 return bus_log_parse_error(r);
3559 r = sd_bus_message_exit_container(m);
3561 return bus_log_parse_error(r);
3569 r = bus_print_property(name, m, arg_all);
3571 return bus_log_parse_error(r);
3574 r = sd_bus_message_skip(m, contents);
3576 return bus_log_parse_error(r);
3579 printf("%s=[unprintable]\n", name);
3585 static int show_one(
3589 bool show_properties,
3593 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3594 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3595 UnitStatusInfo info = {};
3602 log_debug("Showing one %s", path);
3604 r = sd_bus_call_method(
3606 "org.freedesktop.systemd1",
3608 "org.freedesktop.DBus.Properties",
3614 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3618 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3620 return bus_log_parse_error(r);
3627 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3628 const char *name, *contents;
3630 r = sd_bus_message_read(reply, "s", &name);
3632 return bus_log_parse_error(r);
3634 r = sd_bus_message_peek_type(reply, NULL, &contents);
3636 return bus_log_parse_error(r);
3638 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3640 return bus_log_parse_error(r);
3642 if (show_properties)
3643 r = print_property(name, reply, contents);
3645 r = status_property(name, reply, &info, contents);
3649 r = sd_bus_message_exit_container(reply);
3651 return bus_log_parse_error(r);
3653 r = sd_bus_message_exit_container(reply);
3655 return bus_log_parse_error(r);
3658 return bus_log_parse_error(r);
3660 r = sd_bus_message_exit_container(reply);
3662 return bus_log_parse_error(r);
3666 if (!show_properties) {
3667 if (streq(verb, "help"))
3668 show_unit_help(&info);
3670 print_status_info(&info, ellipsized);
3673 strv_free(info.documentation);
3674 strv_free(info.dropin_paths);
3675 strv_free(info.listen);
3677 if (!streq_ptr(info.active_state, "active") &&
3678 !streq_ptr(info.active_state, "reloading") &&
3679 streq(verb, "status")) {
3680 /* According to LSB: "program not running" */
3681 /* 0: program is running or service is OK
3682 * 1: program is dead and /var/run pid file exists
3683 * 2: program is dead and /var/lock lock file exists
3684 * 3: program is not running
3685 * 4: program or service status is unknown
3687 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3693 while ((p = info.exec)) {
3694 LIST_REMOVE(exec, info.exec, p);
3695 exec_status_info_free(p);
3701 static int get_unit_dbus_path_by_pid(
3706 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3707 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3711 r = sd_bus_call_method(
3713 "org.freedesktop.systemd1",
3714 "/org/freedesktop/systemd1",
3715 "org.freedesktop.systemd1.Manager",
3721 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3725 r = sd_bus_message_read(reply, "o", &u);
3727 return bus_log_parse_error(r);
3737 static int show_all(
3740 bool show_properties,
3744 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3745 _cleanup_free_ UnitInfo *unit_infos = NULL;
3750 r = get_unit_list(bus, &reply, &unit_infos, NULL);
3754 pager_open_if_enabled();
3758 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3760 for (u = unit_infos; u < unit_infos + c; u++) {
3761 _cleanup_free_ char *p = NULL;
3763 p = unit_dbus_path_from_name(u->id);
3767 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3775 static int cat(sd_bus *bus, char **args) {
3776 _cleanup_free_ char *unit = NULL;
3777 _cleanup_strv_free_ char **names = NULL;
3785 r = expand_names(bus, args + 1, NULL, &names);
3787 log_error("Failed to expand names: %s", strerror(-r));
3789 pager_open_if_enabled();
3791 STRV_FOREACH(name, names) {
3792 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3793 _cleanup_strv_free_ char **dropin_paths = NULL;
3794 _cleanup_free_ char *fragment_path = NULL;
3797 unit = unit_dbus_path_from_name(*name);
3801 if (need_daemon_reload(bus, *name) > 0)
3802 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3803 *name, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3805 r = sd_bus_get_property_string(
3807 "org.freedesktop.systemd1",
3809 "org.freedesktop.systemd1.Unit",
3814 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3818 r = sd_bus_get_property_strv(
3820 "org.freedesktop.systemd1",
3822 "org.freedesktop.systemd1.Unit",
3827 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3836 if (!isempty(fragment_path)) {
3837 printf("%s# %s%s\n",
3838 ansi_highlight_blue(),
3840 ansi_highlight_off());
3843 r = sendfile_full(STDOUT_FILENO, fragment_path);
3845 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3850 STRV_FOREACH(path, dropin_paths) {
3851 printf("%s%s# %s%s\n",
3852 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3853 ansi_highlight_blue(),
3855 ansi_highlight_off());
3858 r = sendfile_full(STDOUT_FILENO, *path);
3860 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3866 return r < 0 ? r : 0;
3869 static int show(sd_bus *bus, char **args) {
3870 bool show_properties, show_status, new_line = false;
3871 bool ellipsized = false;
3877 show_properties = streq(args[0], "show");
3878 show_status = streq(args[0], "status");
3880 if (show_properties)
3881 pager_open_if_enabled();
3883 /* If no argument is specified inspect the manager itself */
3885 if (show_properties && strv_length(args) <= 1)
3886 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3888 if (show_status && strv_length(args) <= 1)
3889 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3891 _cleanup_free_ char **patterns = NULL;
3894 STRV_FOREACH(name, args + 1) {
3895 _cleanup_free_ char *unit = NULL;
3898 if (safe_atou32(*name, &id) < 0) {
3899 if (strv_push(&patterns, *name) < 0)
3903 } else if (show_properties) {
3904 /* Interpret as job id */
3905 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3909 /* Interpret as PID */
3910 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3917 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3920 if (!strv_isempty(patterns)) {
3921 _cleanup_strv_free_ char **names = NULL;
3923 r = expand_names(bus, patterns, NULL, &names);
3925 log_error("Failed to expand names: %s", strerror(-r));
3927 STRV_FOREACH(name, names) {
3928 _cleanup_free_ char *unit;
3930 unit = unit_dbus_path_from_name(*name);
3934 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3939 if (ellipsized && !arg_quiet)
3940 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3945 static int append_assignment(sd_bus_message *m, const char *assignment) {
3953 eq = strchr(assignment, '=');
3955 log_error("Not an assignment: %s", assignment);
3959 field = strndupa(assignment, eq - assignment);
3962 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3964 return bus_log_create_error(r);
3966 if (streq(field, "CPUAccounting") ||
3967 streq(field, "MemoryAccounting") ||
3968 streq(field, "BlockIOAccounting")) {
3970 r = parse_boolean(eq);
3972 log_error("Failed to parse boolean assignment %s.", assignment);
3976 r = sd_bus_message_append(m, "v", "b", r);
3978 } else if (streq(field, "MemoryLimit")) {
3981 r = parse_bytes(eq, &bytes);
3983 log_error("Failed to parse bytes specification %s", assignment);
3987 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3989 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3992 r = safe_atou64(eq, &u);
3994 log_error("Failed to parse %s value %s.", field, eq);
3998 r = sd_bus_message_append(m, "v", "t", u);
4000 } else if (streq(field, "DevicePolicy"))
4001 r = sd_bus_message_append(m, "v", "s", eq);
4003 else if (streq(field, "DeviceAllow")) {
4006 r = sd_bus_message_append(m, "v", "a(ss)", 0);
4008 const char *path, *rwm;
4011 e = strchr(eq, ' ');
4013 path = strndupa(eq, e - eq);
4020 if (!path_startswith(path, "/dev")) {
4021 log_error("%s is not a device file in /dev.", path);
4025 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
4028 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
4031 r = sd_bus_message_append(m, "v", "a(st)", 0);
4033 const char *path, *bandwidth;
4037 e = strchr(eq, ' ');
4039 path = strndupa(eq, e - eq);
4042 log_error("Failed to parse %s value %s.", field, eq);
4046 if (!path_startswith(path, "/dev")) {
4047 log_error("%s is not a device file in /dev.", path);
4051 r = parse_bytes(bandwidth, &bytes);
4053 log_error("Failed to parse byte value %s.", bandwidth);
4057 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
4060 } else if (streq(field, "BlockIODeviceWeight")) {
4063 r = sd_bus_message_append(m, "v", "a(st)", 0);
4065 const char *path, *weight;
4069 e = strchr(eq, ' ');
4071 path = strndupa(eq, e - eq);
4074 log_error("Failed to parse %s value %s.", field, eq);
4078 if (!path_startswith(path, "/dev")) {
4079 log_error("%s is not a device file in /dev.", path);
4083 r = safe_atou64(weight, &u);
4085 log_error("Failed to parse %s value %s.", field, weight);
4088 r = sd_bus_message_append(m, "v", "a(st)", path, u);
4092 log_error("Unknown assignment %s.", assignment);
4097 return bus_log_create_error(r);
4102 static int set_property(sd_bus *bus, char **args) {
4103 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4104 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4105 _cleanup_free_ char *n = NULL;
4109 r = sd_bus_message_new_method_call(
4111 "org.freedesktop.systemd1",
4112 "/org/freedesktop/systemd1",
4113 "org.freedesktop.systemd1.Manager",
4114 "SetUnitProperties",
4117 return bus_log_create_error(r);
4119 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4123 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4125 return bus_log_create_error(r);
4127 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4129 return bus_log_create_error(r);
4131 STRV_FOREACH(i, args + 2) {
4132 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4134 return bus_log_create_error(r);
4136 r = append_assignment(m, *i);
4140 r = sd_bus_message_close_container(m);
4142 return bus_log_create_error(r);
4145 r = sd_bus_message_close_container(m);
4147 return bus_log_create_error(r);
4149 r = sd_bus_call(bus, m, 0, &error, NULL);
4151 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4158 static int snapshot(sd_bus *bus, char **args) {
4159 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4160 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4161 _cleanup_free_ char *n = NULL, *id = NULL;
4165 if (strv_length(args) > 1)
4166 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4172 r = sd_bus_call_method(
4174 "org.freedesktop.systemd1",
4175 "/org/freedesktop/systemd1",
4176 "org.freedesktop.systemd1.Manager",
4182 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4186 r = sd_bus_message_read(reply, "o", &path);
4188 return bus_log_parse_error(r);
4190 r = sd_bus_get_property_string(
4192 "org.freedesktop.systemd1",
4194 "org.freedesktop.systemd1.Unit",
4199 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4209 static int delete_snapshot(sd_bus *bus, char **args) {
4210 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4211 _cleanup_strv_free_ char **names = NULL;
4217 r = expand_names(bus, args + 1, ".snapshot", &names);
4219 log_error("Failed to expand names: %s", strerror(-r));
4221 STRV_FOREACH(name, names) {
4222 q = sd_bus_call_method(
4224 "org.freedesktop.systemd1",
4225 "/org/freedesktop/systemd1",
4226 "org.freedesktop.systemd1.Manager",
4232 log_error("Failed to remove snapshot %s: %s",
4233 *name, bus_error_message(&error, r));
4242 static int daemon_reload(sd_bus *bus, char **args) {
4243 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4247 if (arg_action == ACTION_RELOAD)
4249 else if (arg_action == ACTION_REEXEC)
4250 method = "Reexecute";
4252 assert(arg_action == ACTION_SYSTEMCTL);
4255 streq(args[0], "clear-jobs") ||
4256 streq(args[0], "cancel") ? "ClearJobs" :
4257 streq(args[0], "daemon-reexec") ? "Reexecute" :
4258 streq(args[0], "reset-failed") ? "ResetFailed" :
4259 streq(args[0], "halt") ? "Halt" :
4260 streq(args[0], "poweroff") ? "PowerOff" :
4261 streq(args[0], "reboot") ? "Reboot" :
4262 streq(args[0], "kexec") ? "KExec" :
4263 streq(args[0], "exit") ? "Exit" :
4264 /* "daemon-reload" */ "Reload";
4267 r = sd_bus_call_method(
4269 "org.freedesktop.systemd1",
4270 "/org/freedesktop/systemd1",
4271 "org.freedesktop.systemd1.Manager",
4277 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4278 /* There's always a fallback possible for
4279 * legacy actions. */
4281 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4282 /* On reexecution, we expect a disconnect, not a
4286 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4288 return r < 0 ? r : 0;
4291 static int reset_failed(sd_bus *bus, char **args) {
4292 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4293 _cleanup_strv_free_ char **names = NULL;
4297 if (strv_length(args) <= 1)
4298 return daemon_reload(bus, args);
4300 r = expand_names(bus, args + 1, NULL, &names);
4302 log_error("Failed to expand names: %s", strerror(-r));
4304 STRV_FOREACH(name, names) {
4305 q = sd_bus_call_method(
4307 "org.freedesktop.systemd1",
4308 "/org/freedesktop/systemd1",
4309 "org.freedesktop.systemd1.Manager",
4315 log_error("Failed to reset failed state of unit %s: %s",
4316 *name, bus_error_message(&error, r));
4325 static int show_environment(sd_bus *bus, char **args) {
4326 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4327 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4331 pager_open_if_enabled();
4333 r = sd_bus_get_property(
4335 "org.freedesktop.systemd1",
4336 "/org/freedesktop/systemd1",
4337 "org.freedesktop.systemd1.Manager",
4343 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4347 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4349 return bus_log_parse_error(r);
4351 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4354 return bus_log_parse_error(r);
4356 r = sd_bus_message_exit_container(reply);
4358 return bus_log_parse_error(r);
4363 static int switch_root(sd_bus *bus, char **args) {
4364 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4365 _cleanup_free_ char *init = NULL;
4370 l = strv_length(args);
4371 if (l < 2 || l > 3) {
4372 log_error("Wrong number of arguments.");
4379 init = strdup(args[2]);
4381 parse_env_file("/proc/cmdline", WHITESPACE,
4392 log_debug("switching root - root: %s; init: %s", root, init);
4394 r = sd_bus_call_method(
4396 "org.freedesktop.systemd1",
4397 "/org/freedesktop/systemd1",
4398 "org.freedesktop.systemd1.Manager",
4404 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4411 static int set_environment(sd_bus *bus, char **args) {
4412 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4413 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4420 method = streq(args[0], "set-environment")
4422 : "UnsetEnvironment";
4424 r = sd_bus_message_new_method_call(
4426 "org.freedesktop.systemd1",
4427 "/org/freedesktop/systemd1",
4428 "org.freedesktop.systemd1.Manager",
4432 return bus_log_create_error(r);
4434 r = sd_bus_message_append_strv(m, args + 1);
4436 return bus_log_create_error(r);
4438 r = sd_bus_call(bus, m, 0, &error, NULL);
4440 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4447 static int enable_sysv_units(const char *verb, char **args) {
4450 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4451 unsigned f = 1, t = 1;
4452 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4454 if (arg_scope != UNIT_FILE_SYSTEM)
4457 if (!streq(verb, "enable") &&
4458 !streq(verb, "disable") &&
4459 !streq(verb, "is-enabled"))
4462 /* Processes all SysV units, and reshuffles the array so that
4463 * afterwards only the native units remain */
4465 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4470 for (f = 0; args[f]; f++) {
4472 _cleanup_free_ char *p = NULL, *q = NULL;
4473 bool found_native = false, found_sysv;
4475 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4483 if (!endswith(name, ".service"))
4486 if (path_is_absolute(name))
4489 STRV_FOREACH(k, paths.unit_path) {
4490 if (!isempty(arg_root))
4491 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4493 asprintf(&p, "%s/%s", *k, name);
4500 found_native = access(p, F_OK) >= 0;
4511 if (!isempty(arg_root))
4512 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4514 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4520 p[strlen(p) - sizeof(".service") + 1] = 0;
4521 found_sysv = access(p, F_OK) >= 0;
4526 /* Mark this entry, so that we don't try enabling it as native unit */
4527 args[f] = (char*) "";
4529 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4531 if (!isempty(arg_root))
4532 argv[c++] = q = strappend("--root=", arg_root);
4534 argv[c++] = basename(p);
4536 streq(verb, "enable") ? "on" :
4537 streq(verb, "disable") ? "off" : "--level=5";
4540 l = strv_join((char**)argv, " ");
4546 log_info("Executing %s", l);
4551 log_error("Failed to fork: %m");
4554 } else if (pid == 0) {
4557 execv(argv[0], (char**) argv);
4558 _exit(EXIT_FAILURE);
4561 j = wait_for_terminate(pid, &status);
4563 log_error("Failed to wait for child: %s", strerror(-r));
4568 if (status.si_code == CLD_EXITED) {
4569 if (streq(verb, "is-enabled")) {
4570 if (status.si_status == 0) {
4579 } else if (status.si_status != 0) {
4590 /* Drop all SysV units */
4591 for (f = 0, t = 0; args[f]; f++) {
4593 if (isempty(args[f]))
4596 args[t++] = args[f];
4605 static int mangle_names(char **original_names, char ***mangled_names) {
4606 char **i, **l, **name;
4608 l = new(char*, strv_length(original_names) + 1);
4613 STRV_FOREACH(name, original_names) {
4615 /* When enabling units qualified path names are OK,
4616 * too, hence allow them explicitly. */
4621 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
4637 static int enable_unit(sd_bus *bus, char **args) {
4638 _cleanup_strv_free_ char **names = NULL;
4639 const char *verb = args[0];
4640 UnitFileChange *changes = NULL;
4641 unsigned n_changes = 0;
4642 int carries_install_info = -1;
4648 r = mangle_names(args+1, &names);
4652 r = enable_sysv_units(verb, names);
4656 if (!bus || avoid_bus()) {
4657 if (streq(verb, "enable")) {
4658 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4659 carries_install_info = r;
4660 } else if (streq(verb, "disable"))
4661 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4662 else if (streq(verb, "reenable")) {
4663 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4664 carries_install_info = r;
4665 } else if (streq(verb, "link"))
4666 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4667 else if (streq(verb, "preset")) {
4668 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4669 carries_install_info = r;
4670 } else if (streq(verb, "mask"))
4671 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
4672 else if (streq(verb, "unmask"))
4673 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
4675 assert_not_reached("Unknown verb");
4678 log_error("Operation failed: %s", strerror(-r));
4683 dump_unit_file_changes(changes, n_changes);
4687 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4688 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4689 int expect_carries_install_info = false;
4690 bool send_force = true;
4693 if (streq(verb, "enable")) {
4694 method = "EnableUnitFiles";
4695 expect_carries_install_info = true;
4696 } else if (streq(verb, "disable")) {
4697 method = "DisableUnitFiles";
4699 } else if (streq(verb, "reenable")) {
4700 method = "ReenableUnitFiles";
4701 expect_carries_install_info = true;
4702 } else if (streq(verb, "link"))
4703 method = "LinkUnitFiles";
4704 else if (streq(verb, "preset")) {
4705 method = "PresetUnitFiles";
4706 expect_carries_install_info = true;
4707 } else if (streq(verb, "mask"))
4708 method = "MaskUnitFiles";
4709 else if (streq(verb, "unmask")) {
4710 method = "UnmaskUnitFiles";
4713 assert_not_reached("Unknown verb");
4715 r = sd_bus_message_new_method_call(
4717 "org.freedesktop.systemd1",
4718 "/org/freedesktop/systemd1",
4719 "org.freedesktop.systemd1.Manager",
4723 return bus_log_create_error(r);
4725 r = sd_bus_message_append_strv(m, names);
4727 return bus_log_create_error(r);
4729 r = sd_bus_message_append(m, "b", arg_runtime);
4731 return bus_log_create_error(r);
4734 r = sd_bus_message_append(m, "b", arg_force);
4736 return bus_log_create_error(r);
4739 r = sd_bus_call(bus, m, 0, &error, &reply);
4741 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4745 if (expect_carries_install_info) {
4746 r = sd_bus_message_read(reply, "b", &carries_install_info);
4748 return bus_log_parse_error(r);
4751 r = deserialize_and_dump_unit_file_changes(reply);
4755 /* Try to reload if enabeld */
4757 r = daemon_reload(bus, args);
4762 if (carries_install_info == 0)
4763 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4764 "using systemctl.\n"
4765 "Possible reasons for having this kind of units are:\n"
4766 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4767 " .wants/ or .requires/ directory.\n"
4768 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4769 " a requirement dependency on it.\n"
4770 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4771 " D-Bus, udev, scripted systemctl call, ...).\n");
4774 unit_file_changes_free(changes, n_changes);
4779 static int unit_is_enabled(sd_bus *bus, char **args) {
4781 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4782 _cleanup_strv_free_ char **names = NULL;
4787 r = mangle_names(args+1, &names);
4791 r = enable_sysv_units(args[0], names);
4797 if (!bus || avoid_bus()) {
4799 STRV_FOREACH(name, names) {
4800 UnitFileState state;
4802 state = unit_file_get_state(arg_scope, arg_root, *name);
4804 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4808 if (state == UNIT_FILE_ENABLED ||
4809 state == UNIT_FILE_ENABLED_RUNTIME ||
4810 state == UNIT_FILE_STATIC)
4814 puts(unit_file_state_to_string(state));
4818 STRV_FOREACH(name, names) {
4819 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4822 r = sd_bus_call_method(
4824 "org.freedesktop.systemd1",
4825 "/org/freedesktop/systemd1",
4826 "org.freedesktop.systemd1.Manager",
4832 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4836 r = sd_bus_message_read(reply, "s", &s);
4838 return bus_log_parse_error(r);
4840 if (streq(s, "enabled") ||
4841 streq(s, "enabled-runtime") ||
4853 static int systemctl_help(void) {
4855 pager_open_if_enabled();
4857 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4858 "Query or send control commands to the systemd manager.\n\n"
4859 " -h --help Show this help\n"
4860 " --version Show package version\n"
4861 " --system Connect to system manager\n"
4862 " --user Connect to user service manager\n"
4863 " -H --host=[USER@]HOST\n"
4864 " Operate on remote host\n"
4865 " -M --machine=CONTAINER\n"
4866 " Operate on local container\n"
4867 " -t --type=TYPE List only units of a particular type\n"
4868 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4869 " -p --property=NAME Show only properties by this name\n"
4870 " -a --all Show all loaded units/properties, including dead/empty\n"
4871 " ones. To list all units installed on the system, use\n"
4872 " the 'list-unit-files' command instead.\n"
4873 " -l --full Don't ellipsize unit names on output\n"
4874 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4875 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4876 " queueing a new job\n"
4877 " --show-types When showing sockets, explicitly show their type\n"
4878 " -i --ignore-inhibitors\n"
4879 " When shutting down or sleeping, ignore inhibitors\n"
4880 " --kill-who=WHO Who to send signal to\n"
4881 " -s --signal=SIGNAL Which signal to send\n"
4882 " -q --quiet Suppress output\n"
4883 " --no-block Do not wait until operation finished\n"
4884 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4885 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4887 " --no-legend Do not print a legend (column headers and hints)\n"
4888 " --no-pager Do not pipe output into a pager\n"
4889 " --no-ask-password\n"
4890 " Do not ask for system passwords\n"
4891 " --global Enable/disable unit files globally\n"
4892 " --runtime Enable unit files only temporarily until next reboot\n"
4893 " -f --force When enabling unit files, override existing symlinks\n"
4894 " When shutting down, execute action immediately\n"
4895 " --root=PATH Enable unit files in the specified root directory\n"
4896 " -n --lines=INTEGER Number of journal entries to show\n"
4897 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4898 " verbose, export, json, json-pretty, json-sse, cat)\n"
4899 " --plain Print unit dependencies as a list instead of a tree\n\n"
4901 " list-units [PATTERN...] List loaded units\n"
4902 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4903 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4904 " start NAME... Start (activate) one or more units\n"
4905 " stop NAME... Stop (deactivate) one or more units\n"
4906 " reload NAME... Reload one or more units\n"
4907 " restart NAME... Start or restart one or more units\n"
4908 " try-restart NAME... Restart one or more units if active\n"
4909 " reload-or-restart NAME... Reload one or more units if possible,\n"
4910 " otherwise start or restart\n"
4911 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
4912 " otherwise restart if active\n"
4913 " isolate NAME Start one unit and stop all others\n"
4914 " kill NAME... Send signal to processes of a unit\n"
4915 " is-active NAME... Check whether units are active\n"
4916 " is-failed NAME... Check whether units are failed\n"
4917 " status [NAME...|PID...] Show runtime status of one or more units\n"
4918 " show [NAME...|JOB...] Show properties of one or more\n"
4919 " units/jobs or the manager\n"
4920 " cat NAME... Show files and drop-ins of one or more units\n"
4921 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
4922 " help NAME...|PID... Show manual for one or more units\n"
4923 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4925 " list-dependencies [NAME] Recursively show units which are required\n"
4926 " or wanted by this unit or by which this\n"
4927 " unit is required or wanted\n\n"
4928 "Unit File Commands:\n"
4929 " list-unit-files [PATTERN...] List installed unit files\n"
4930 " enable NAME... Enable one or more unit files\n"
4931 " disable NAME... Disable one or more unit files\n"
4932 " reenable NAME... Reenable one or more unit files\n"
4933 " preset NAME... Enable/disable one or more unit files\n"
4934 " based on preset configuration\n"
4935 " is-enabled NAME... Check whether unit files are enabled\n\n"
4936 " mask NAME... Mask one or more units\n"
4937 " unmask NAME... Unmask one or more units\n"
4938 " link PATH... Link one or more units files into\n"
4939 " the search path\n"
4940 " get-default Get the name of the default target\n"
4941 " set-default NAME Set the default target\n\n"
4943 " list-jobs [PATTERN...] List jobs\n"
4944 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4945 "Snapshot Commands:\n"
4946 " snapshot [NAME] Create a snapshot\n"
4947 " delete NAME... Remove one or more snapshots\n\n"
4948 "Environment Commands:\n"
4949 " show-environment Dump environment\n"
4950 " set-environment NAME=VALUE... Set one or more environment variables\n"
4951 " unset-environment NAME... Unset one or more environment variables\n\n"
4952 "Manager Lifecycle Commands:\n"
4953 " daemon-reload Reload systemd manager configuration\n"
4954 " daemon-reexec Reexecute systemd manager\n\n"
4955 "System Commands:\n"
4956 " default Enter system default mode\n"
4957 " rescue Enter system rescue mode\n"
4958 " emergency Enter system emergency mode\n"
4959 " halt Shut down and halt the system\n"
4960 " poweroff Shut down and power-off the system\n"
4961 " reboot [ARG] Shut down and reboot the system\n"
4962 " kexec Shut down and reboot the system with kexec\n"
4963 " exit Request user instance exit\n"
4964 " switch-root ROOT [INIT] Change to a different root file system\n"
4965 " suspend Suspend the system\n"
4966 " hibernate Hibernate the system\n"
4967 " hybrid-sleep Hibernate and suspend the system\n",
4968 program_invocation_short_name);
4973 static int halt_help(void) {
4975 printf("%s [OPTIONS...]%s\n\n"
4976 "%s the system.\n\n"
4977 " --help Show this help\n"
4978 " --halt Halt the machine\n"
4979 " -p --poweroff Switch off the machine\n"
4980 " --reboot Reboot the machine\n"
4981 " -f --force Force immediate halt/power-off/reboot\n"
4982 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4983 " -d --no-wtmp Don't write wtmp record\n"
4984 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4985 program_invocation_short_name,
4986 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4987 arg_action == ACTION_REBOOT ? "Reboot" :
4988 arg_action == ACTION_POWEROFF ? "Power off" :
4994 static int shutdown_help(void) {
4996 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4997 "Shut down the system.\n\n"
4998 " --help Show this help\n"
4999 " -H --halt Halt the machine\n"
5000 " -P --poweroff Power-off the machine\n"
5001 " -r --reboot Reboot the machine\n"
5002 " -h Equivalent to --poweroff, overridden by --halt\n"
5003 " -k Don't halt/power-off/reboot, just send warnings\n"
5004 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5005 " -c Cancel a pending shutdown\n",
5006 program_invocation_short_name);
5011 static int telinit_help(void) {
5013 printf("%s [OPTIONS...] {COMMAND}\n\n"
5014 "Send control commands to the init daemon.\n\n"
5015 " --help Show this help\n"
5016 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5018 " 0 Power-off the machine\n"
5019 " 6 Reboot the machine\n"
5020 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5021 " 1, s, S Enter rescue mode\n"
5022 " q, Q Reload init daemon configuration\n"
5023 " u, U Reexecute init daemon\n",
5024 program_invocation_short_name);
5029 static int runlevel_help(void) {
5031 printf("%s [OPTIONS...]\n\n"
5032 "Prints the previous and current runlevel of the init system.\n\n"
5033 " --help Show this help\n",
5034 program_invocation_short_name);
5039 static int help_types(void) {
5043 puts("Available unit types:");
5044 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
5045 t = unit_type_to_string(i);
5053 static int systemctl_parse_argv(int argc, char *argv[]) {
5062 ARG_IGNORE_DEPENDENCIES,
5074 ARG_NO_ASK_PASSWORD,
5083 static const struct option options[] = {
5084 { "help", no_argument, NULL, 'h' },
5085 { "version", no_argument, NULL, ARG_VERSION },
5086 { "type", required_argument, NULL, 't' },
5087 { "property", required_argument, NULL, 'p' },
5088 { "all", no_argument, NULL, 'a' },
5089 { "reverse", no_argument, NULL, ARG_REVERSE },
5090 { "after", no_argument, NULL, ARG_AFTER },
5091 { "before", no_argument, NULL, ARG_BEFORE },
5092 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
5093 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
5094 { "full", no_argument, NULL, 'l' },
5095 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
5096 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
5097 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
5098 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
5099 { "ignore-inhibitors", no_argument, NULL, 'i' },
5100 { "user", no_argument, NULL, ARG_USER },
5101 { "system", no_argument, NULL, ARG_SYSTEM },
5102 { "global", no_argument, NULL, ARG_GLOBAL },
5103 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
5104 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
5105 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
5106 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5107 { "quiet", no_argument, NULL, 'q' },
5108 { "root", required_argument, NULL, ARG_ROOT },
5109 { "force", no_argument, NULL, ARG_FORCE },
5110 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
5111 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
5112 { "signal", required_argument, NULL, 's' },
5113 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
5114 { "host", required_argument, NULL, 'H' },
5115 { "machine", required_argument, NULL, 'M' },
5116 { "runtime", no_argument, NULL, ARG_RUNTIME },
5117 { "lines", required_argument, NULL, 'n' },
5118 { "output", required_argument, NULL, 'o' },
5119 { "plain", no_argument, NULL, ARG_PLAIN },
5120 { "state", required_argument, NULL, ARG_STATE },
5129 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5134 return systemctl_help();
5137 puts(PACKAGE_STRING);
5138 puts(SYSTEMD_FEATURES);
5145 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5146 _cleanup_free_ char *type;
5148 type = strndup(word, size);
5152 if (streq(type, "help")) {
5157 if (unit_type_from_string(type) >= 0) {
5158 if (strv_push(&arg_types, type))
5164 /* It's much nicer to use --state= for
5165 * load states, but let's support this
5166 * in --types= too for compatibility
5167 * with old versions */
5168 if (unit_load_state_from_string(optarg) >= 0) {
5169 if (strv_push(&arg_states, type) < 0)
5175 log_error("Unknown unit type or load state '%s'.", type);
5176 log_info("Use -t help to see a list of allowed values.");
5184 /* Make sure that if the empty property list
5185 was specified, we won't show any properties. */
5186 if (isempty(optarg) && !arg_properties) {
5187 arg_properties = new0(char*, 1);
5188 if (!arg_properties)
5194 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5197 prop = strndup(word, size);
5201 if (strv_push(&arg_properties, prop) < 0) {
5208 /* If the user asked for a particular
5209 * property, show it to him, even if it is
5221 arg_dependency = DEPENDENCY_REVERSE;
5225 arg_dependency = DEPENDENCY_AFTER;
5229 arg_dependency = DEPENDENCY_BEFORE;
5232 case ARG_SHOW_TYPES:
5233 arg_show_types = true;
5237 arg_job_mode = optarg;
5241 arg_job_mode = "fail";
5244 case ARG_IRREVERSIBLE:
5245 arg_job_mode = "replace-irreversibly";
5248 case ARG_IGNORE_DEPENDENCIES:
5249 arg_job_mode = "ignore-dependencies";
5253 arg_scope = UNIT_FILE_USER;
5257 arg_scope = UNIT_FILE_SYSTEM;
5261 arg_scope = UNIT_FILE_GLOBAL;
5265 arg_no_block = true;
5269 arg_no_legend = true;
5273 arg_no_pager = true;
5289 if (strv_extend(&arg_states, "failed") < 0)
5307 arg_no_reload = true;
5311 arg_kill_who = optarg;
5315 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5316 log_error("Failed to parse signal string %s.", optarg);
5321 case ARG_NO_ASK_PASSWORD:
5322 arg_ask_password = false;
5326 arg_transport = BUS_TRANSPORT_REMOTE;
5331 arg_transport = BUS_TRANSPORT_CONTAINER;
5340 if (safe_atou(optarg, &arg_lines) < 0) {
5341 log_error("Failed to parse lines '%s'", optarg);
5347 arg_output = output_mode_from_string(optarg);
5348 if (arg_output < 0) {
5349 log_error("Unknown output '%s'.", optarg);
5355 arg_ignore_inhibitors = true;
5366 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5369 s = strndup(word, size);
5373 if (strv_push(&arg_states, s) < 0) {
5385 assert_not_reached("Unhandled option");
5389 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5390 log_error("Cannot access user instance remotely.");
5397 static int halt_parse_argv(int argc, char *argv[]) {
5406 static const struct option options[] = {
5407 { "help", no_argument, NULL, ARG_HELP },
5408 { "halt", no_argument, NULL, ARG_HALT },
5409 { "poweroff", no_argument, NULL, 'p' },
5410 { "reboot", no_argument, NULL, ARG_REBOOT },
5411 { "force", no_argument, NULL, 'f' },
5412 { "wtmp-only", no_argument, NULL, 'w' },
5413 { "no-wtmp", no_argument, NULL, 'd' },
5414 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5423 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5424 if (runlevel == '0' || runlevel == '6')
5427 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5434 arg_action = ACTION_HALT;
5438 if (arg_action != ACTION_REBOOT)
5439 arg_action = ACTION_POWEROFF;
5443 arg_action = ACTION_REBOOT;
5465 /* Compatibility nops */
5472 assert_not_reached("Unhandled option");
5476 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5477 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5479 log_error("Failed to write reboot param to "
5480 REBOOT_PARAM_FILE": %s", strerror(-r));
5483 } else if (optind < argc) {
5484 log_error("Too many arguments.");
5491 static int parse_time_spec(const char *t, usec_t *_u) {
5495 if (streq(t, "now"))
5497 else if (!strchr(t, ':')) {
5500 if (safe_atou64(t, &u) < 0)
5503 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5512 hour = strtol(t, &e, 10);
5513 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5516 minute = strtol(e+1, &e, 10);
5517 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5520 n = now(CLOCK_REALTIME);
5521 s = (time_t) (n / USEC_PER_SEC);
5523 assert_se(localtime_r(&s, &tm));
5525 tm.tm_hour = (int) hour;
5526 tm.tm_min = (int) minute;
5529 assert_se(s = mktime(&tm));
5531 *_u = (usec_t) s * USEC_PER_SEC;
5534 *_u += USEC_PER_DAY;
5540 static int shutdown_parse_argv(int argc, char *argv[]) {
5547 static const struct option options[] = {
5548 { "help", no_argument, NULL, ARG_HELP },
5549 { "halt", no_argument, NULL, 'H' },
5550 { "poweroff", no_argument, NULL, 'P' },
5551 { "reboot", no_argument, NULL, 'r' },
5552 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5553 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5562 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5566 return shutdown_help();
5569 arg_action = ACTION_HALT;
5573 arg_action = ACTION_POWEROFF;
5578 arg_action = ACTION_KEXEC;
5580 arg_action = ACTION_REBOOT;
5584 arg_action = ACTION_KEXEC;
5588 if (arg_action != ACTION_HALT)
5589 arg_action = ACTION_POWEROFF;
5602 /* Compatibility nops */
5606 arg_action = ACTION_CANCEL_SHUTDOWN;
5613 assert_not_reached("Unhandled option");
5617 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5618 r = parse_time_spec(argv[optind], &arg_when);
5620 log_error("Failed to parse time specification: %s", argv[optind]);
5624 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5626 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5627 /* No time argument for shutdown cancel */
5628 arg_wall = argv + optind;
5629 else if (argc > optind + 1)
5630 /* We skip the time argument */
5631 arg_wall = argv + optind + 1;
5638 static int telinit_parse_argv(int argc, char *argv[]) {
5645 static const struct option options[] = {
5646 { "help", no_argument, NULL, ARG_HELP },
5647 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5651 static const struct {
5655 { '0', ACTION_POWEROFF },
5656 { '6', ACTION_REBOOT },
5657 { '1', ACTION_RESCUE },
5658 { '2', ACTION_RUNLEVEL2 },
5659 { '3', ACTION_RUNLEVEL3 },
5660 { '4', ACTION_RUNLEVEL4 },
5661 { '5', ACTION_RUNLEVEL5 },
5662 { 's', ACTION_RESCUE },
5663 { 'S', ACTION_RESCUE },
5664 { 'q', ACTION_RELOAD },
5665 { 'Q', ACTION_RELOAD },
5666 { 'u', ACTION_REEXEC },
5667 { 'U', ACTION_REEXEC }
5676 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5680 return telinit_help();
5690 assert_not_reached("Unhandled option");
5694 if (optind >= argc) {
5699 if (optind + 1 < argc) {
5700 log_error("Too many arguments.");
5704 if (strlen(argv[optind]) != 1) {
5705 log_error("Expected single character argument.");
5709 for (i = 0; i < ELEMENTSOF(table); i++)
5710 if (table[i].from == argv[optind][0])
5713 if (i >= ELEMENTSOF(table)) {
5714 log_error("Unknown command '%s'.", argv[optind]);
5718 arg_action = table[i].to;
5725 static int runlevel_parse_argv(int argc, char *argv[]) {
5731 static const struct option options[] = {
5732 { "help", no_argument, NULL, ARG_HELP },
5741 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5745 return runlevel_help();
5752 assert_not_reached("Unhandled option");
5756 if (optind < argc) {
5757 log_error("Too many arguments.");
5764 static int parse_argv(int argc, char *argv[]) {
5768 if (program_invocation_short_name) {
5770 if (strstr(program_invocation_short_name, "halt")) {
5771 arg_action = ACTION_HALT;
5772 return halt_parse_argv(argc, argv);
5773 } else if (strstr(program_invocation_short_name, "poweroff")) {
5774 arg_action = ACTION_POWEROFF;
5775 return halt_parse_argv(argc, argv);
5776 } else if (strstr(program_invocation_short_name, "reboot")) {
5778 arg_action = ACTION_KEXEC;
5780 arg_action = ACTION_REBOOT;
5781 return halt_parse_argv(argc, argv);
5782 } else if (strstr(program_invocation_short_name, "shutdown")) {
5783 arg_action = ACTION_POWEROFF;
5784 return shutdown_parse_argv(argc, argv);
5785 } else if (strstr(program_invocation_short_name, "init")) {
5787 if (sd_booted() > 0) {
5788 arg_action = _ACTION_INVALID;
5789 return telinit_parse_argv(argc, argv);
5791 /* Hmm, so some other init system is
5792 * running, we need to forward this
5793 * request to it. For now we simply
5794 * guess that it is Upstart. */
5796 execv(TELINIT, argv);
5798 log_error("Couldn't find an alternative telinit implementation to spawn.");
5802 } else if (strstr(program_invocation_short_name, "runlevel")) {
5803 arg_action = ACTION_RUNLEVEL;
5804 return runlevel_parse_argv(argc, argv);
5808 arg_action = ACTION_SYSTEMCTL;
5809 return systemctl_parse_argv(argc, argv);
5812 _pure_ static int action_to_runlevel(void) {
5814 static const char table[_ACTION_MAX] = {
5815 [ACTION_HALT] = '0',
5816 [ACTION_POWEROFF] = '0',
5817 [ACTION_REBOOT] = '6',
5818 [ACTION_RUNLEVEL2] = '2',
5819 [ACTION_RUNLEVEL3] = '3',
5820 [ACTION_RUNLEVEL4] = '4',
5821 [ACTION_RUNLEVEL5] = '5',
5822 [ACTION_RESCUE] = '1'
5825 assert(arg_action < _ACTION_MAX);
5827 return table[arg_action];
5830 static int talk_initctl(void) {
5832 struct init_request request = {
5833 .magic = INIT_MAGIC,
5835 .cmd = INIT_CMD_RUNLVL
5838 _cleanup_close_ int fd = -1;
5842 rl = action_to_runlevel();
5846 request.runlevel = rl;
5848 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5850 if (errno == ENOENT)
5853 log_error("Failed to open "INIT_FIFO": %m");
5858 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5860 log_error("Failed to write to "INIT_FIFO": %m");
5861 return errno > 0 ? -errno : -EIO;
5867 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5869 static const struct {
5877 int (* const dispatch)(sd_bus *bus, char **args);
5883 { "list-units", MORE, 0, list_units },
5884 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
5885 { "list-sockets", MORE, 1, list_sockets },
5886 { "list-timers", MORE, 1, list_timers },
5887 { "list-jobs", MORE, 1, list_jobs },
5888 { "clear-jobs", EQUAL, 1, daemon_reload },
5889 { "cancel", MORE, 2, cancel_job },
5890 { "start", MORE, 2, start_unit },
5891 { "stop", MORE, 2, start_unit },
5892 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5893 { "reload", MORE, 2, start_unit },
5894 { "restart", MORE, 2, start_unit },
5895 { "try-restart", MORE, 2, start_unit },
5896 { "reload-or-restart", MORE, 2, start_unit },
5897 { "reload-or-try-restart", MORE, 2, start_unit },
5898 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5899 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5900 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5901 { "isolate", EQUAL, 2, start_unit },
5902 { "kill", MORE, 2, kill_unit },
5903 { "is-active", MORE, 2, check_unit_active },
5904 { "check", MORE, 2, check_unit_active },
5905 { "is-failed", MORE, 2, check_unit_failed },
5906 { "show", MORE, 1, show },
5907 { "cat", MORE, 2, cat },
5908 { "status", MORE, 1, show },
5909 { "help", MORE, 2, show },
5910 { "snapshot", LESS, 2, snapshot },
5911 { "delete", MORE, 2, delete_snapshot },
5912 { "daemon-reload", EQUAL, 1, daemon_reload },
5913 { "daemon-reexec", EQUAL, 1, daemon_reload },
5914 { "show-environment", EQUAL, 1, show_environment },
5915 { "set-environment", MORE, 2, set_environment },
5916 { "unset-environment", MORE, 2, set_environment },
5917 { "halt", EQUAL, 1, start_special, FORCE },
5918 { "poweroff", EQUAL, 1, start_special, FORCE },
5919 { "reboot", EQUAL, 1, start_special, FORCE },
5920 { "kexec", EQUAL, 1, start_special },
5921 { "suspend", EQUAL, 1, start_special },
5922 { "hibernate", EQUAL, 1, start_special },
5923 { "hybrid-sleep", EQUAL, 1, start_special },
5924 { "default", EQUAL, 1, start_special },
5925 { "rescue", EQUAL, 1, start_special },
5926 { "emergency", EQUAL, 1, start_special },
5927 { "exit", EQUAL, 1, start_special },
5928 { "reset-failed", MORE, 1, reset_failed },
5929 { "enable", MORE, 2, enable_unit, NOBUS },
5930 { "disable", MORE, 2, enable_unit, NOBUS },
5931 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
5932 { "reenable", MORE, 2, enable_unit, NOBUS },
5933 { "preset", MORE, 2, enable_unit, NOBUS },
5934 { "mask", MORE, 2, enable_unit, NOBUS },
5935 { "unmask", MORE, 2, enable_unit, NOBUS },
5936 { "link", MORE, 2, enable_unit, NOBUS },
5937 { "switch-root", MORE, 2, switch_root },
5938 { "list-dependencies", LESS, 2, list_dependencies },
5939 { "set-default", EQUAL, 2, set_default, NOBUS },
5940 { "get-default", EQUAL, 1, get_default, NOBUS },
5941 { "set-property", MORE, 3, set_property },
5950 left = argc - optind;
5952 /* Special rule: no arguments (left == 0) means "list-units" */
5954 if (streq(argv[optind], "help") && !argv[optind+1]) {
5955 log_error("This command expects one or more "
5956 "unit names. Did you mean --help?");
5960 for (; verb->verb; verb++)
5961 if (streq(argv[optind], verb->verb))
5964 log_error("Unknown operation '%s'.", argv[optind]);
5969 switch (verb->argc_cmp) {
5972 if (left != verb->argc) {
5973 log_error("Invalid number of arguments.");
5980 if (left < verb->argc) {
5981 log_error("Too few arguments.");
5988 if (left > verb->argc) {
5989 log_error("Too many arguments.");
5996 assert_not_reached("Unknown comparison operator.");
5999 /* Require a bus connection for all operations but
6001 if (verb->bus == NOBUS) {
6002 if (!bus && !avoid_bus()) {
6003 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6008 if (running_in_chroot() > 0) {
6009 log_info("Running in chroot, ignoring request.");
6013 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
6014 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error));
6019 return verb->dispatch(bus, argv + optind);
6022 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
6024 struct sd_shutdown_command c = {
6031 union sockaddr_union sockaddr = {
6032 .un.sun_family = AF_UNIX,
6033 .un.sun_path = "/run/systemd/shutdownd",
6036 struct iovec iovec[2] = {{
6037 .iov_base = (char*) &c,
6038 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
6041 struct msghdr msghdr = {
6042 .msg_name = &sockaddr,
6043 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
6044 + sizeof("/run/systemd/shutdownd") - 1,
6049 _cleanup_close_ int fd;
6051 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
6055 if (!isempty(message)) {
6056 iovec[1].iov_base = (char*) message;
6057 iovec[1].iov_len = strlen(message);
6058 msghdr.msg_iovlen++;
6061 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
6067 static int reload_with_fallback(sd_bus *bus) {
6070 /* First, try systemd via D-Bus. */
6071 if (daemon_reload(bus, NULL) >= 0)
6075 /* Nothing else worked, so let's try signals */
6076 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
6078 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
6079 log_error("kill() failed: %m");
6086 static int start_with_fallback(sd_bus *bus) {
6089 /* First, try systemd via D-Bus. */
6090 if (start_unit(bus, NULL) >= 0)
6094 /* Nothing else worked, so let's try
6096 if (talk_initctl() > 0)
6099 log_error("Failed to talk to init daemon.");
6103 warn_wall(arg_action);
6107 static int halt_now(enum action a) {
6109 /* Make sure C-A-D is handled by the kernel from this
6111 reboot(RB_ENABLE_CAD);
6116 log_info("Halting.");
6117 reboot(RB_HALT_SYSTEM);
6120 case ACTION_POWEROFF:
6121 log_info("Powering off.");
6122 reboot(RB_POWER_OFF);
6125 case ACTION_REBOOT: {
6126 _cleanup_free_ char *param = NULL;
6128 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6129 log_info("Rebooting with argument '%s'.", param);
6130 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6131 LINUX_REBOOT_CMD_RESTART2, param);
6134 log_info("Rebooting.");
6135 reboot(RB_AUTOBOOT);
6140 assert_not_reached("Unknown action.");
6144 static int halt_main(sd_bus *bus) {
6147 r = check_inhibitors(bus, arg_action);
6151 if (geteuid() != 0) {
6152 /* Try logind if we are a normal user and no special
6153 * mode applies. Maybe PolicyKit allows us to shutdown
6156 if (arg_when <= 0 &&
6159 (arg_action == ACTION_POWEROFF ||
6160 arg_action == ACTION_REBOOT)) {
6161 r = reboot_with_logind(bus, arg_action);
6166 log_error("Must be root.");
6171 _cleanup_free_ char *m;
6173 m = strv_join(arg_wall, " ");
6177 r = send_shutdownd(arg_when,
6178 arg_action == ACTION_HALT ? 'H' :
6179 arg_action == ACTION_POWEROFF ? 'P' :
6180 arg_action == ACTION_KEXEC ? 'K' :
6187 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6189 char date[FORMAT_TIMESTAMP_MAX];
6191 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6192 format_timestamp(date, sizeof(date), arg_when));
6197 if (!arg_dry && !arg_force)
6198 return start_with_fallback(bus);
6201 if (sd_booted() > 0)
6202 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6204 r = utmp_put_shutdown();
6206 log_warning("Failed to write utmp record: %s", strerror(-r));
6213 r = halt_now(arg_action);
6214 log_error("Failed to reboot: %s", strerror(-r));
6219 static int runlevel_main(void) {
6220 int r, runlevel, previous;
6222 r = utmp_get_runlevel(&runlevel, &previous);
6229 previous <= 0 ? 'N' : previous,
6230 runlevel <= 0 ? 'N' : runlevel);
6235 int main(int argc, char*argv[]) {
6236 _cleanup_bus_unref_ sd_bus *bus = NULL;
6239 setlocale(LC_ALL, "");
6240 log_parse_environment();
6243 /* Explicitly not on_tty() to avoid setting cached value.
6244 * This becomes relevant for piping output which might be
6246 original_stdout_is_tty = isatty(STDOUT_FILENO);
6248 r = parse_argv(argc, argv);
6252 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6253 * let's shortcut this */
6254 if (arg_action == ACTION_RUNLEVEL) {
6255 r = runlevel_main();
6259 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6260 log_info("Running in chroot, ignoring request.");
6266 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6268 /* systemctl_main() will print an error message for the bus
6269 * connection, but only if it needs to */
6271 switch (arg_action) {
6273 case ACTION_SYSTEMCTL:
6274 r = systemctl_main(bus, argc, argv, r);
6278 case ACTION_POWEROFF:
6284 case ACTION_RUNLEVEL2:
6285 case ACTION_RUNLEVEL3:
6286 case ACTION_RUNLEVEL4:
6287 case ACTION_RUNLEVEL5:
6289 case ACTION_EMERGENCY:
6290 case ACTION_DEFAULT:
6291 r = start_with_fallback(bus);
6296 r = reload_with_fallback(bus);
6299 case ACTION_CANCEL_SHUTDOWN: {
6300 _cleanup_free_ char *m = NULL;
6303 m = strv_join(arg_wall, " ");
6310 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6312 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6316 case ACTION_RUNLEVEL:
6317 case _ACTION_INVALID:
6319 assert_not_reached("Unknown action");
6324 ask_password_agent_close();
6325 polkit_agent_close();
6327 strv_free(arg_types);
6328 strv_free(arg_states);
6329 strv_free(arg_properties);
6331 return r < 0 ? EXIT_FAILURE : r;