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>
41 #include "sd-daemon.h"
42 #include "sd-shutdown.h"
49 #include "utmp-wtmp.h"
52 #include "path-util.h"
54 #include "cgroup-show.h"
55 #include "cgroup-util.h"
57 #include "path-lookup.h"
58 #include "conf-parser.h"
59 #include "exit-status.h"
60 #include "bus-errors.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "socket-util.h"
71 #include "bus-message.h"
72 #include "bus-error.h"
73 #include "bus-errors.h"
75 static char **arg_types = NULL;
76 static char **arg_states = NULL;
77 static char **arg_properties = NULL;
78 static bool arg_all = false;
79 static bool original_stdout_is_tty;
80 static enum dependency {
86 } arg_dependency = DEPENDENCY_FORWARD;
87 static const char *arg_job_mode = "replace";
88 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
89 static bool arg_no_block = false;
90 static bool arg_no_legend = false;
91 static bool arg_no_pager = false;
92 static bool arg_no_wtmp = false;
93 static bool arg_no_wall = false;
94 static bool arg_no_reload = false;
95 static bool arg_show_types = false;
96 static bool arg_ignore_inhibitors = false;
97 static bool arg_dry = false;
98 static bool arg_quiet = false;
99 static bool arg_full = false;
100 static int arg_force = 0;
101 static bool arg_ask_password = true;
102 static bool arg_runtime = false;
103 static char **arg_wall = NULL;
104 static const char *arg_kill_who = NULL;
105 static int arg_signal = SIGTERM;
106 static const char *arg_root = NULL;
107 static usec_t arg_when = 0;
129 ACTION_CANCEL_SHUTDOWN,
131 } arg_action = ACTION_SYSTEMCTL;
132 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
133 static char *arg_host = NULL;
134 static unsigned arg_lines = 10;
135 static OutputMode arg_output = OUTPUT_SHORT;
136 static bool arg_plain = false;
138 static int daemon_reload(sd_bus *bus, char **args);
139 static int halt_now(enum action a);
141 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
143 static void pager_open_if_enabled(void) {
151 static void ask_password_agent_open_if_enabled(void) {
153 /* Open the password agent as a child process if necessary */
155 if (!arg_ask_password)
158 if (arg_scope != UNIT_FILE_SYSTEM)
161 if (arg_transport != BUS_TRANSPORT_LOCAL)
164 ask_password_agent_open();
168 static void polkit_agent_open_if_enabled(void) {
170 /* Open the polkit agent as a child process if necessary */
172 if (!arg_ask_password)
175 if (arg_scope != UNIT_FILE_SYSTEM)
178 if (arg_transport != BUS_TRANSPORT_LOCAL)
185 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
188 if (!sd_bus_error_is_set(error))
191 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
192 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
193 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
194 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
195 return EXIT_NOPERMISSION;
197 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
198 return EXIT_NOTINSTALLED;
200 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
201 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
202 return EXIT_NOTIMPLEMENTED;
204 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
205 return EXIT_NOTCONFIGURED;
213 static void warn_wall(enum action a) {
214 static const char *table[_ACTION_MAX] = {
215 [ACTION_HALT] = "The system is going down for system halt NOW!",
216 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
217 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
218 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
219 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
220 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
221 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
228 _cleanup_free_ char *p;
230 p = strv_join(arg_wall, " ");
245 utmp_wall(table[a], NULL);
248 static bool avoid_bus(void) {
250 if (running_in_chroot() > 0)
253 if (sd_booted() <= 0)
256 if (!isempty(arg_root))
259 if (arg_scope == UNIT_FILE_GLOBAL)
265 static int compare_unit_info(const void *a, const void *b) {
266 const UnitInfo *u = a, *v = b;
269 d1 = strrchr(u->id, '.');
270 d2 = strrchr(v->id, '.');
275 r = strcasecmp(d1, d2);
280 return strcasecmp(u->id, v->id);
283 static bool output_show_unit(const UnitInfo *u) {
286 if (!strv_isempty(arg_states))
288 strv_contains(arg_states, u->load_state) ||
289 strv_contains(arg_states, u->sub_state) ||
290 strv_contains(arg_states, u->active_state);
292 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
293 strv_find(arg_types, dot+1))) &&
294 (arg_all || !(streq(u->active_state, "inactive")
295 || u->following[0]) || u->job_id > 0);
298 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
299 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
301 unsigned n_shown = 0;
304 max_id_len = sizeof("UNIT")-1;
305 load_len = sizeof("LOAD")-1;
306 active_len = sizeof("ACTIVE")-1;
307 sub_len = sizeof("SUB")-1;
308 job_len = sizeof("JOB")-1;
311 for (u = unit_infos; u < unit_infos + c; u++) {
312 if (!output_show_unit(u))
315 max_id_len = MAX(max_id_len, strlen(u->id));
316 load_len = MAX(load_len, strlen(u->load_state));
317 active_len = MAX(active_len, strlen(u->active_state));
318 sub_len = MAX(sub_len, strlen(u->sub_state));
320 if (u->job_id != 0) {
321 job_len = MAX(job_len, strlen(u->job_type));
326 if (!arg_full && original_stdout_is_tty) {
329 id_len = MIN(max_id_len, 25u);
330 basic_len = 5 + id_len + 5 + active_len + sub_len;
333 basic_len += job_len + 1;
335 if (basic_len < (unsigned) columns()) {
336 unsigned extra_len, incr;
337 extra_len = columns() - basic_len;
339 /* Either UNIT already got 25, or is fully satisfied.
340 * Grant up to 25 to DESC now. */
341 incr = MIN(extra_len, 25u);
345 /* split the remaining space between UNIT and DESC,
346 * but do not give UNIT more than it needs. */
348 incr = MIN(extra_len / 2, max_id_len - id_len);
350 desc_len += extra_len - incr;
356 for (u = unit_infos; u < unit_infos + c; u++) {
357 _cleanup_free_ char *e = NULL;
358 const char *on_loaded, *off_loaded, *on = "";
359 const char *on_active, *off_active, *off = "";
361 if (!output_show_unit(u))
364 if (!n_shown && !arg_no_legend) {
365 printf("%-*s %-*s %-*s %-*s ",
368 active_len, "ACTIVE",
372 printf("%-*s ", job_len, "JOB");
374 if (!arg_full && arg_no_pager)
375 printf("%.*s\n", desc_len, "DESCRIPTION");
377 printf("%s\n", "DESCRIPTION");
382 if (streq(u->load_state, "error") ||
383 streq(u->load_state, "not-found")) {
384 on_loaded = on = ansi_highlight_red();
385 off_loaded = off = ansi_highlight_off();
387 on_loaded = off_loaded = "";
389 if (streq(u->active_state, "failed")) {
390 on_active = on = ansi_highlight_red();
391 off_active = off = ansi_highlight_off();
393 on_active = off_active = "";
395 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
397 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
398 on, id_len, e ? e : u->id, off,
399 on_loaded, load_len, u->load_state, off_loaded,
400 on_active, active_len, u->active_state,
401 sub_len, u->sub_state, off_active,
402 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
405 printf("%.*s\n", desc_len, u->description);
407 printf("%s\n", u->description);
410 if (!arg_no_legend) {
411 const char *on, *off;
414 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
415 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
416 "SUB = The low-level unit activation state, values depend on unit type.\n");
418 printf("JOB = Pending job for the unit.\n");
420 on = ansi_highlight();
421 off = ansi_highlight_off();
423 on = ansi_highlight_red();
424 off = ansi_highlight_off();
428 printf("%s%u loaded units listed.%s\n"
429 "To show all installed unit files use 'systemctl list-unit-files'.\n",
432 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
433 "To show all installed unit files use 'systemctl list-unit-files'.\n",
438 static int get_unit_list(
440 sd_bus_message **_reply,
441 UnitInfo **_unit_infos) {
443 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
444 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
445 _cleanup_free_ UnitInfo *unit_infos = NULL;
454 r = sd_bus_call_method(
456 "org.freedesktop.systemd1",
457 "/org/freedesktop/systemd1",
458 "org.freedesktop.systemd1.Manager",
464 log_error("Failed to list units: %s", bus_error_message(&error, r));
468 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
470 return bus_log_parse_error(r);
472 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
474 if (!GREEDY_REALLOC(unit_infos, size, c+1))
480 return bus_log_parse_error(r);
482 r = sd_bus_message_exit_container(reply);
484 return bus_log_parse_error(r);
489 *_unit_infos = unit_infos;
495 static int list_units(sd_bus *bus, char **args) {
496 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
497 _cleanup_free_ UnitInfo *unit_infos = NULL;
500 pager_open_if_enabled();
502 r = get_unit_list(bus, &reply, &unit_infos);
506 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
507 output_units_list(unit_infos, r);
512 static int get_triggered_units(
517 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
520 r = sd_bus_get_property_strv(
522 "org.freedesktop.systemd1",
524 "org.freedesktop.systemd1.Unit",
530 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
535 static int get_listening(
537 const char* unit_path,
540 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
541 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
542 const char *type, *path;
545 r = sd_bus_get_property(
547 "org.freedesktop.systemd1",
549 "org.freedesktop.systemd1.Socket",
555 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
559 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
561 return bus_log_parse_error(r);
563 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
565 r = strv_extend(listening, type);
569 r = strv_extend(listening, path);
576 return bus_log_parse_error(r);
578 r = sd_bus_message_exit_container(reply);
580 return bus_log_parse_error(r);
591 /* Note: triggered is a list here, although it almost certainly
592 * will always be one unit. Nevertheless, dbus API allows for multiple
593 * values, so let's follow that.*/
596 /* The strv above is shared. free is set only in the first one. */
600 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
606 o = strcmp(a->path, b->path);
608 o = strcmp(a->type, b->type);
613 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
614 struct socket_info *s;
615 unsigned pathlen = sizeof("LISTEN") - 1,
616 typelen = (sizeof("TYPE") - 1) * arg_show_types,
617 socklen = sizeof("UNIT") - 1,
618 servlen = sizeof("ACTIVATES") - 1;
619 const char *on, *off;
621 for (s = socket_infos; s < socket_infos + cs; s++) {
625 socklen = MAX(socklen, strlen(s->id));
627 typelen = MAX(typelen, strlen(s->type));
628 pathlen = MAX(pathlen, strlen(s->path));
630 STRV_FOREACH(a, s->triggered)
631 tmp += strlen(*a) + 2*(a != s->triggered);
632 servlen = MAX(servlen, tmp);
637 printf("%-*s %-*.*s%-*s %s\n",
639 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
643 for (s = socket_infos; s < socket_infos + cs; s++) {
647 printf("%-*s %-*s %-*s",
648 pathlen, s->path, typelen, s->type, socklen, s->id);
651 pathlen, s->path, socklen, s->id);
652 STRV_FOREACH(a, s->triggered)
654 a == s->triggered ? "" : ",", *a);
658 on = ansi_highlight();
659 off = ansi_highlight_off();
663 on = ansi_highlight_red();
664 off = ansi_highlight_off();
667 if (!arg_no_legend) {
668 printf("%s%u sockets listed.%s\n", on, cs, off);
670 printf("Pass --all to see loaded but inactive sockets, too.\n");
676 static int list_sockets(sd_bus *bus, char **args) {
677 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
678 _cleanup_free_ UnitInfo *unit_infos = NULL;
679 struct socket_info *socket_infos = NULL;
681 struct socket_info *s;
686 pager_open_if_enabled();
688 n = get_unit_list(bus, &reply, &unit_infos);
692 for (u = unit_infos; u < unit_infos + n; u++) {
693 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
696 if (!output_show_unit(u))
699 if (!endswith(u->id, ".socket"))
702 r = get_triggered_units(bus, u->unit_path, &triggered);
706 c = get_listening(bus, u->unit_path, &listening);
712 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
717 for (i = 0; i < c; i++)
718 socket_infos[cs + i] = (struct socket_info) {
720 .type = listening[i*2],
721 .path = listening[i*2 + 1],
722 .triggered = triggered,
723 .own_triggered = i==0,
726 /* from this point on we will cleanup those socket_infos */
729 listening = triggered = NULL; /* avoid cleanup */
732 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
733 (__compar_fn_t) socket_info_compare);
735 output_sockets_list(socket_infos, cs);
738 assert(cs == 0 || socket_infos);
739 for (s = socket_infos; s < socket_infos + cs; s++) {
742 if (s->own_triggered)
743 strv_free(s->triggered);
750 static int get_next_elapse(
753 dual_timestamp *next) {
755 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
763 r = sd_bus_get_property_trivial(
765 "org.freedesktop.systemd1",
767 "org.freedesktop.systemd1.Timer",
768 "NextElapseUSecMonotonic",
773 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
777 r = sd_bus_get_property_trivial(
779 "org.freedesktop.systemd1",
781 "org.freedesktop.systemd1.Timer",
782 "NextElapseUSecRealtime",
787 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
801 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
805 if (a->next_elapse < b->next_elapse)
807 if (a->next_elapse > b->next_elapse)
810 return strcmp(a->id, b->id);
813 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
814 struct timer_info *t;
816 nextlen = sizeof("NEXT") - 1,
817 leftlen = sizeof("LEFT") - 1,
818 unitlen = sizeof("UNIT") - 1,
819 activatelen = sizeof("ACTIVATES") - 1;
821 const char *on, *off;
823 assert(timer_infos || n == 0);
825 for (t = timer_infos; t < timer_infos + n; t++) {
829 if (t->next_elapse > 0) {
830 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
832 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
833 nextlen = MAX(nextlen, strlen(tstamp) + 1);
835 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
836 leftlen = MAX(leftlen, strlen(trel));
839 unitlen = MAX(unitlen, strlen(t->id));
841 STRV_FOREACH(a, t->triggered)
842 ul += strlen(*a) + 2*(a != t->triggered);
843 activatelen = MAX(activatelen, ul);
848 printf("%-*s %-*s %-*s %s\n",
854 for (t = timer_infos; t < timer_infos + n; t++) {
855 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
858 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
859 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
861 printf("%-*s %-*s %-*s",
862 nextlen, tstamp, leftlen, trel, unitlen, t->id);
864 STRV_FOREACH(a, t->triggered)
866 a == t->triggered ? "" : ",", *a);
870 on = ansi_highlight();
871 off = ansi_highlight_off();
875 on = ansi_highlight_red();
876 off = ansi_highlight_off();
879 if (!arg_no_legend) {
880 printf("%s%u timers listed.%s\n", on, n, off);
882 printf("Pass --all to see loaded but inactive timers, too.\n");
888 static int list_timers(sd_bus *bus, char **args) {
890 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
891 _cleanup_free_ struct timer_info *timer_infos = NULL;
892 _cleanup_free_ UnitInfo *unit_infos = NULL;
893 struct timer_info *t;
900 pager_open_if_enabled();
902 n = get_unit_list(bus, &reply, &unit_infos);
906 dual_timestamp_get(&nw);
908 for (u = unit_infos; u < unit_infos + n; u++) {
909 _cleanup_strv_free_ char **triggered = NULL;
913 if (!output_show_unit(u))
916 if (!endswith(u->id, ".timer"))
919 r = get_triggered_units(bus, u->unit_path, &triggered);
923 r = get_next_elapse(bus, u->unit_path, &next);
927 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
930 if (next.monotonic > nw.monotonic)
931 converted = nw.realtime + (next.monotonic - nw.monotonic);
933 converted = nw.realtime - (nw.monotonic - next.monotonic);
935 if (next.realtime != (usec_t) -1 && next.realtime > 0)
936 m = MIN(converted, next.realtime);
942 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
947 timer_infos[c++] = (struct timer_info) {
950 .triggered = triggered,
953 triggered = NULL; /* avoid cleanup */
956 qsort_safe(timer_infos, c, sizeof(struct timer_info),
957 (__compar_fn_t) timer_info_compare);
959 output_timers_list(timer_infos, c);
962 for (t = timer_infos; t < timer_infos + c; t++)
963 strv_free(t->triggered);
968 static int compare_unit_file_list(const void *a, const void *b) {
970 const UnitFileList *u = a, *v = b;
972 d1 = strrchr(u->path, '.');
973 d2 = strrchr(v->path, '.');
978 r = strcasecmp(d1, d2);
983 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
986 static bool output_show_unit_file(const UnitFileList *u) {
989 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
992 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
993 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
994 const UnitFileList *u;
996 max_id_len = sizeof("UNIT FILE")-1;
997 state_cols = sizeof("STATE")-1;
999 for (u = units; u < units + c; u++) {
1000 if (!output_show_unit_file(u))
1003 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
1004 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1008 unsigned basic_cols;
1010 id_cols = MIN(max_id_len, 25u);
1011 basic_cols = 1 + id_cols + state_cols;
1012 if (basic_cols < (unsigned) columns())
1013 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1015 id_cols = max_id_len;
1018 printf("%-*s %-*s\n",
1019 id_cols, "UNIT FILE",
1020 state_cols, "STATE");
1022 for (u = units; u < units + c; u++) {
1023 _cleanup_free_ char *e = NULL;
1024 const char *on, *off;
1027 if (!output_show_unit_file(u))
1032 if (u->state == UNIT_FILE_MASKED ||
1033 u->state == UNIT_FILE_MASKED_RUNTIME ||
1034 u->state == UNIT_FILE_DISABLED ||
1035 u->state == UNIT_FILE_INVALID) {
1036 on = ansi_highlight_red();
1037 off = ansi_highlight_off();
1038 } else if (u->state == UNIT_FILE_ENABLED) {
1039 on = ansi_highlight_green();
1040 off = ansi_highlight_off();
1044 id = path_get_file_name(u->path);
1046 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1048 printf("%-*s %s%-*s%s\n",
1049 id_cols, e ? e : id,
1050 on, state_cols, unit_file_state_to_string(u->state), off);
1054 printf("\n%u unit files listed.\n", n_shown);
1057 static int list_unit_files(sd_bus *bus, char **args) {
1058 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1059 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1060 _cleanup_free_ UnitFileList *units = NULL;
1066 pager_open_if_enabled();
1074 h = hashmap_new(string_hash_func, string_compare_func);
1078 r = unit_file_get_list(arg_scope, arg_root, h);
1080 unit_file_list_free(h);
1081 log_error("Failed to get unit file list: %s", strerror(-r));
1085 n_units = hashmap_size(h);
1086 units = new(UnitFileList, n_units);
1088 unit_file_list_free(h);
1092 HASHMAP_FOREACH(u, h, i) {
1093 memcpy(units + c++, u, sizeof(UnitFileList));
1097 assert(c == n_units);
1102 r = sd_bus_call_method(
1104 "org.freedesktop.systemd1",
1105 "/org/freedesktop/systemd1",
1106 "org.freedesktop.systemd1.Manager",
1112 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1116 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1118 return bus_log_parse_error(r);
1120 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1122 if (!GREEDY_REALLOC(units, size, c + 1))
1125 units[c++] = (struct UnitFileList) {
1127 unit_file_state_from_string(state)
1131 return bus_log_parse_error(r);
1133 r = sd_bus_message_exit_container(reply);
1135 return bus_log_parse_error(r);
1139 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1140 output_unit_file_list(units, c);
1146 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1147 _cleanup_free_ char *n = NULL;
1148 size_t max_len = MAX(columns(),20u);
1154 for (i = level - 1; i >= 0; i--) {
1156 if (len > max_len - 3 && !arg_full) {
1157 printf("%s...\n",max_len % 2 ? "" : " ");
1160 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1164 if (len > max_len - 3 && !arg_full) {
1165 printf("%s...\n",max_len % 2 ? "" : " ");
1169 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1173 printf("%s\n", name);
1177 n = ellipsize(name, max_len-len, 100);
1185 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1187 static const char *dependencies[_DEPENDENCY_MAX] = {
1188 [DEPENDENCY_FORWARD] = "Requires\0"
1189 "RequiresOverridable\0"
1191 "RequisiteOverridable\0"
1193 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1194 "RequiredByOverridable\0"
1197 [DEPENDENCY_AFTER] = "After\0",
1198 [DEPENDENCY_BEFORE] = "Before\0",
1201 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1202 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1203 _cleanup_strv_free_ char **ret = NULL;
1204 _cleanup_free_ char *path = NULL;
1210 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1212 path = unit_dbus_path_from_name(name);
1216 r = sd_bus_call_method(
1218 "org.freedesktop.systemd1",
1220 "org.freedesktop.DBus.Properties",
1224 "s", "org.freedesktop.systemd1.Unit");
1226 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1230 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1232 return bus_log_parse_error(r);
1234 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1237 r = sd_bus_message_read(reply, "s", &prop);
1239 return bus_log_parse_error(r);
1241 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1242 r = sd_bus_message_skip(reply, "v");
1244 return bus_log_parse_error(r);
1247 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1249 return bus_log_parse_error(r);
1251 r = bus_message_read_strv_extend(reply, &ret);
1253 return bus_log_parse_error(r);
1255 r = sd_bus_message_exit_container(reply);
1257 return bus_log_parse_error(r);
1260 r = sd_bus_message_exit_container(reply);
1262 return bus_log_parse_error(r);
1266 return bus_log_parse_error(r);
1268 r = sd_bus_message_exit_container(reply);
1270 return bus_log_parse_error(r);
1278 static int list_dependencies_compare(const void *_a, const void *_b) {
1279 const char **a = (const char**) _a, **b = (const char**) _b;
1281 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1283 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1286 return strcasecmp(*a, *b);
1289 static int list_dependencies_one(
1294 unsigned int branches) {
1296 _cleanup_strv_free_ char **deps = NULL, **u;
1304 u = strv_append(*units, name);
1308 r = list_dependencies_get_dependencies(bus, name, &deps);
1312 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1314 STRV_FOREACH(c, deps) {
1317 if (strv_contains(u, *c)) {
1319 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1326 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1328 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1330 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1332 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1336 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1337 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1352 static int list_dependencies(sd_bus *bus, char **args) {
1353 _cleanup_strv_free_ char **units = NULL;
1354 _cleanup_free_ char *unit = NULL;
1360 unit = unit_name_mangle(args[1]);
1365 u = SPECIAL_DEFAULT_TARGET;
1367 pager_open_if_enabled();
1371 return list_dependencies_one(bus, u, 0, &units, 0);
1374 static int get_default(sd_bus *bus, char **args) {
1375 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1376 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1377 _cleanup_free_ char *_path = NULL;
1381 if (!bus || avoid_bus()) {
1382 r = unit_file_get_default(arg_scope, arg_root, &_path);
1384 log_error("Failed to get default target: %s", strerror(-r));
1390 r = sd_bus_call_method(
1392 "org.freedesktop.systemd1",
1393 "/org/freedesktop/systemd1",
1394 "org.freedesktop.systemd1.Manager",
1400 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1404 r = sd_bus_message_read(reply, "s", &path);
1406 return bus_log_parse_error(r);
1410 printf("%s\n", path);
1415 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1418 assert(changes || n_changes == 0);
1420 for (i = 0; i < n_changes; i++) {
1421 if (changes[i].type == UNIT_FILE_SYMLINK)
1422 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1424 log_info("rm '%s'", changes[i].path);
1428 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1429 const char *type, *path, *source;
1432 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1434 return bus_log_parse_error(r);
1436 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1438 if (streq(type, "symlink"))
1439 log_info("ln -s '%s' '%s'", source, path);
1441 log_info("rm '%s'", path);
1445 return bus_log_parse_error(r);
1447 r = sd_bus_message_exit_container(m);
1449 return bus_log_parse_error(r);
1454 static int set_default(sd_bus *bus, char **args) {
1455 _cleanup_free_ char *unit = NULL;
1456 UnitFileChange *changes = NULL;
1457 unsigned n_changes = 0;
1460 unit = unit_name_mangle_with_suffix(args[1], ".target");
1464 if (!bus || avoid_bus()) {
1465 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1467 log_error("Failed to set default target: %s", strerror(-r));
1472 dump_unit_file_changes(changes, n_changes);
1476 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1477 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1479 r = sd_bus_call_method(
1481 "org.freedesktop.systemd1",
1482 "/org/freedesktop/systemd1",
1483 "org.freedesktop.systemd1.Manager",
1487 "sb", unit, arg_force);
1489 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1493 r = deserialize_and_dump_unit_file_changes(reply);
1497 /* Try to reload if enabeld */
1499 r = daemon_reload(bus, args);
1504 unit_file_changes_free(changes, n_changes);
1511 const char *name, *type, *state;
1514 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1515 unsigned id_len, unit_len, type_len, state_len;
1516 const struct job_info *j;
1517 const char *on, *off;
1518 bool shorten = false;
1520 assert(n == 0 || jobs);
1523 on = ansi_highlight_green();
1524 off = ansi_highlight_off();
1526 printf("%sNo jobs running.%s\n", on, off);
1530 pager_open_if_enabled();
1532 id_len = sizeof("JOB")-1;
1533 unit_len = sizeof("UNIT")-1;
1534 type_len = sizeof("TYPE")-1;
1535 state_len = sizeof("STATE")-1;
1537 for (j = jobs; j < jobs + n; j++) {
1538 uint32_t id = j->id;
1539 assert(j->name && j->type && j->state);
1541 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1542 unit_len = MAX(unit_len, strlen(j->name));
1543 type_len = MAX(type_len, strlen(j->type));
1544 state_len = MAX(state_len, strlen(j->state));
1547 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1548 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1553 printf("%*s %-*s %-*s %-*s\n",
1557 state_len, "STATE");
1559 for (j = jobs; j < jobs + n; j++) {
1560 _cleanup_free_ char *e = NULL;
1562 if (streq(j->state, "running")) {
1563 on = ansi_highlight();
1564 off = ansi_highlight_off();
1568 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1569 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1571 on, unit_len, e ? e : j->name, off,
1573 on, state_len, j->state, off);
1576 if (!arg_no_legend) {
1577 on = ansi_highlight();
1578 off = ansi_highlight_off();
1580 printf("\n%s%u jobs listed%s.\n", on, n, off);
1584 static int list_jobs(sd_bus *bus, char **args) {
1585 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1586 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1587 const char *name, *type, *state, *job_path, *unit_path;
1588 _cleanup_free_ struct job_info *jobs = NULL;
1594 r = sd_bus_call_method(
1596 "org.freedesktop.systemd1",
1597 "/org/freedesktop/systemd1",
1598 "org.freedesktop.systemd1.Manager",
1604 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1608 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1610 return bus_log_parse_error(r);
1612 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1614 if (!GREEDY_REALLOC(jobs, size, c + 1))
1617 jobs[c++] = (struct job_info) {
1625 return bus_log_parse_error(r);
1627 r = sd_bus_message_exit_container(reply);
1629 return bus_log_parse_error(r);
1631 output_jobs_list(jobs, c);
1635 static int cancel_job(sd_bus *bus, char **args) {
1636 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1641 if (strv_length(args) <= 1)
1642 return daemon_reload(bus, args);
1644 STRV_FOREACH(name, args+1) {
1648 r = safe_atou32(*name, &id);
1650 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1654 r = sd_bus_call_method(
1656 "org.freedesktop.systemd1",
1657 "/org/freedesktop/systemd1",
1658 "org.freedesktop.systemd1.Manager",
1664 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1672 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1673 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1674 _cleanup_free_ char *n = NULL;
1678 /* We ignore all errors here, since this is used to show a
1681 n = unit_name_mangle(unit);
1685 /* We don't use unit_dbus_path_from_name() directly since we
1686 * don't want to load the unit if it isn't loaded. */
1688 r = sd_bus_call_method(
1690 "org.freedesktop.systemd1",
1691 "/org/freedesktop/systemd1",
1692 "org.freedesktop.systemd1.Manager",
1700 r = sd_bus_message_read(reply, "o", &path);
1704 r = sd_bus_get_property_trivial(
1706 "org.freedesktop.systemd1",
1708 "org.freedesktop.systemd1.Unit",
1718 typedef struct WaitData {
1725 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1732 log_debug("Got D-Bus request: %s.%s() on %s",
1733 sd_bus_message_get_interface(m),
1734 sd_bus_message_get_member(m),
1735 sd_bus_message_get_path(m));
1737 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1738 log_error("Warning! D-Bus connection terminated.");
1740 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1742 const char *path, *result, *unit;
1746 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1748 ret = set_remove(d->set, (char*) path);
1754 if (!isempty(result))
1755 d->result = strdup(result);
1758 d->name = strdup(unit);
1763 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1765 ret = set_remove(d->set, (char*) path);
1772 d->result = strdup(result);
1778 bus_log_parse_error(r);
1784 static int enable_wait_for_jobs(sd_bus *bus) {
1789 r = sd_bus_add_match(
1792 "sender='org.freedesktop.systemd1',"
1793 "interface='org.freedesktop.systemd1.Manager',"
1794 "member='JobRemoved',"
1795 "path='/org/freedesktop/systemd1'",
1798 log_error("Failed to add match");
1802 /* This is slightly dirty, since we don't undo the match registrations. */
1806 static int wait_for_jobs(sd_bus *bus, Set *s) {
1807 WaitData d = { .set = s };
1813 r = sd_bus_add_filter(bus, wait_filter, &d);
1817 while (!set_isempty(s)) {
1819 r = sd_bus_process(bus, NULL);
1824 r = sd_bus_wait(bus, (uint64_t) -1);
1833 if (streq(d.result, "timeout"))
1834 log_error("Job for %s timed out.", strna(d.name));
1835 else if (streq(d.result, "canceled"))
1836 log_error("Job for %s canceled.", strna(d.name));
1837 else if (streq(d.result, "dependency"))
1838 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1839 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1840 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1843 if (streq_ptr(d.result, "timeout"))
1845 else if (streq_ptr(d.result, "canceled"))
1847 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1858 return sd_bus_remove_filter(bus, wait_filter, &d);
1861 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1862 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1863 _cleanup_free_ char *n = NULL, *state = NULL;
1869 n = unit_name_mangle(name);
1873 /* We don't use unit_dbus_path_from_name() directly since we
1874 * don't want to load the unit if it isn't loaded. */
1876 r = sd_bus_call_method(
1878 "org.freedesktop.systemd1",
1879 "/org/freedesktop/systemd1",
1880 "org.freedesktop.systemd1.Manager",
1891 r = sd_bus_message_read(reply, "o", &path);
1893 return bus_log_parse_error(r);
1895 r = sd_bus_get_property_string(
1897 "org.freedesktop.systemd1",
1899 "org.freedesktop.systemd1.Unit",
1912 return nulstr_contains(good_states, state);
1915 static int check_triggering_units(
1919 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1920 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1921 _cleanup_strv_free_ char **triggered_by = NULL;
1922 bool print_warning_label = true;
1926 n = unit_name_mangle(name);
1930 path = unit_dbus_path_from_name(n);
1934 r = sd_bus_get_property_string(
1936 "org.freedesktop.systemd1",
1938 "org.freedesktop.systemd1.Unit",
1943 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1947 if (streq(state, "masked"))
1950 r = sd_bus_get_property_strv(
1952 "org.freedesktop.systemd1",
1954 "org.freedesktop.systemd1.Unit",
1959 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1963 STRV_FOREACH(i, triggered_by) {
1964 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1966 log_error("Failed to check unit: %s", strerror(-r));
1973 if (print_warning_label) {
1974 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1975 print_warning_label = false;
1978 log_warning(" %s", *i);
1984 static int start_unit_one(
1989 sd_bus_error *error,
1992 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1993 _cleanup_free_ char *n;
2002 n = unit_name_mangle(name);
2006 r = sd_bus_call_method(
2008 "org.freedesktop.systemd1",
2009 "/org/freedesktop/systemd1",
2010 "org.freedesktop.systemd1.Manager",
2016 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2017 /* There's always a fallback possible for
2018 * legacy actions. */
2019 return -EADDRNOTAVAIL;
2021 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
2025 r = sd_bus_message_read(reply, "o", &path);
2027 return bus_log_parse_error(r);
2029 if (need_daemon_reload(bus, n) > 0)
2030 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2031 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2040 r = set_consume(s, p);
2048 static const struct {
2052 } action_table[_ACTION_MAX] = {
2053 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2054 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2055 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2056 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2057 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2058 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2059 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2060 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2061 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2062 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2063 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2064 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2065 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2066 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2067 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2070 static enum action verb_to_action(const char *verb) {
2073 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2074 if (streq_ptr(action_table[i].verb, verb))
2077 return _ACTION_INVALID;
2080 static int start_unit(sd_bus *bus, char **args) {
2081 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2082 _cleanup_set_free_free_ Set *s = NULL;
2083 const char *method, *mode, *one_name;
2089 ask_password_agent_open_if_enabled();
2091 if (arg_action == ACTION_SYSTEMCTL) {
2094 streq(args[0], "stop") ||
2095 streq(args[0], "condstop") ? "StopUnit" :
2096 streq(args[0], "reload") ? "ReloadUnit" :
2097 streq(args[0], "restart") ? "RestartUnit" :
2099 streq(args[0], "try-restart") ||
2100 streq(args[0], "condrestart") ? "TryRestartUnit" :
2102 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2104 streq(args[0], "reload-or-try-restart") ||
2105 streq(args[0], "condreload") ||
2106 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2108 action = verb_to_action(args[0]);
2110 mode = streq(args[0], "isolate") ? "isolate" :
2111 action_table[action].mode ?: arg_job_mode;
2113 one_name = action_table[action].target;
2115 assert(arg_action < ELEMENTSOF(action_table));
2116 assert(action_table[arg_action].target);
2118 method = "StartUnit";
2120 mode = action_table[arg_action].mode;
2121 one_name = action_table[arg_action].target;
2124 if (!arg_no_block) {
2125 r = enable_wait_for_jobs(bus);
2127 log_error("Could not watch jobs: %s", strerror(-r));
2131 s = set_new(string_hash_func, string_compare_func);
2137 r = start_unit_one(bus, method, one_name, mode, &error, s);
2139 r = translate_bus_error_to_exit_status(r, &error);
2143 STRV_FOREACH(name, args+1) {
2146 q = start_unit_one(bus, method, *name, mode, &error, s);
2148 r = translate_bus_error_to_exit_status(q, &error);
2149 sd_bus_error_free(&error);
2154 if (!arg_no_block) {
2157 q = wait_for_jobs(bus, s);
2161 /* When stopping units, warn if they can still be triggered by
2162 * another active unit (socket, path, timer) */
2163 if (!arg_quiet && streq(method, "StopUnit")) {
2165 check_triggering_units(bus, one_name);
2167 STRV_FOREACH(name, args+1)
2168 check_triggering_units(bus, *name);
2175 /* Ask systemd-logind, which might grant access to unprivileged users
2176 * through PolicyKit */
2177 static int reboot_with_logind(sd_bus *bus, enum action a) {
2179 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2186 polkit_agent_open_if_enabled();
2194 case ACTION_POWEROFF:
2195 method = "PowerOff";
2198 case ACTION_SUSPEND:
2202 case ACTION_HIBERNATE:
2203 method = "Hibernate";
2206 case ACTION_HYBRID_SLEEP:
2207 method = "HybridSleep";
2214 r = sd_bus_call_method(
2216 "org.freedesktop.login1",
2217 "/org/freedesktop/login1",
2218 "org.freedesktop.login1.Manager",
2224 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2232 static int check_inhibitors(sd_bus *bus, enum action a) {
2234 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2235 _cleanup_strv_free_ char **sessions = NULL;
2236 const char *what, *who, *why, *mode;
2245 if (arg_ignore_inhibitors || arg_force > 0)
2257 r = sd_bus_call_method(
2259 "org.freedesktop.login1",
2260 "/org/freedesktop/login1",
2261 "org.freedesktop.login1.Manager",
2267 /* If logind is not around, then there are no inhibitors... */
2270 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2272 return bus_log_parse_error(r);
2274 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2275 _cleanup_free_ char *comm = NULL, *user = NULL;
2276 _cleanup_strv_free_ char **sv = NULL;
2278 if (!streq(mode, "block"))
2281 sv = strv_split(what, ":");
2285 if (!strv_contains(sv,
2287 a == ACTION_POWEROFF ||
2288 a == ACTION_REBOOT ||
2289 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2292 get_process_comm(pid, &comm);
2293 user = uid_to_name(uid);
2295 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2296 who, (unsigned long) pid, strna(comm), strna(user), why);
2301 return bus_log_parse_error(r);
2303 r = sd_bus_message_exit_container(reply);
2305 return bus_log_parse_error(r);
2307 /* Check for current sessions */
2308 sd_get_sessions(&sessions);
2309 STRV_FOREACH(s, sessions) {
2310 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2312 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2315 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2318 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2321 sd_session_get_tty(*s, &tty);
2322 sd_session_get_seat(*s, &seat);
2323 sd_session_get_service(*s, &service);
2324 user = uid_to_name(uid);
2326 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2333 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2334 action_table[a].verb);
2342 static int start_special(sd_bus *bus, char **args) {
2348 a = verb_to_action(args[0]);
2350 r = check_inhibitors(bus, a);
2354 if (arg_force >= 2 && geteuid() != 0) {
2355 log_error("Must be root.");
2359 if (arg_force >= 2 &&
2360 (a == ACTION_HALT ||
2361 a == ACTION_POWEROFF ||
2362 a == ACTION_REBOOT))
2365 if (arg_force >= 1 &&
2366 (a == ACTION_HALT ||
2367 a == ACTION_POWEROFF ||
2368 a == ACTION_REBOOT ||
2369 a == ACTION_KEXEC ||
2371 return daemon_reload(bus, args);
2373 /* first try logind, to allow authentication with polkit */
2374 if (geteuid() != 0 &&
2375 (a == ACTION_POWEROFF ||
2376 a == ACTION_REBOOT ||
2377 a == ACTION_SUSPEND ||
2378 a == ACTION_HIBERNATE ||
2379 a == ACTION_HYBRID_SLEEP)) {
2380 r = reboot_with_logind(bus, a);
2385 r = start_unit(bus, args);
2386 if (r == EXIT_SUCCESS)
2392 static int check_unit_active(sd_bus *bus, char **args) {
2394 int r = 3; /* According to LSB: "program is not running" */
2399 STRV_FOREACH(name, args+1) {
2402 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2412 static int check_unit_failed(sd_bus *bus, char **args) {
2419 STRV_FOREACH(name, args+1) {
2422 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2432 static int kill_unit(sd_bus *bus, char **args) {
2433 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2441 arg_kill_who = "all";
2443 STRV_FOREACH(name, args+1) {
2444 _cleanup_free_ char *n = NULL;
2446 n = unit_name_mangle(*name);
2450 r = sd_bus_call_method(
2452 "org.freedesktop.systemd1",
2453 "/org/freedesktop/systemd1",
2454 "org.freedesktop.systemd1.Manager",
2458 "ssi", n, arg_kill_who, arg_signal);
2460 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2468 typedef struct ExecStatusInfo {
2476 usec_t start_timestamp;
2477 usec_t exit_timestamp;
2482 LIST_FIELDS(struct ExecStatusInfo, exec);
2485 static void exec_status_info_free(ExecStatusInfo *i) {
2494 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2495 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2498 int32_t code, status;
2504 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2506 return bus_log_parse_error(r);
2510 r = sd_bus_message_read(m, "s", &path);
2512 return bus_log_parse_error(r);
2514 i->path = strdup(path);
2518 r = sd_bus_message_read_strv(m, &i->argv);
2520 return bus_log_parse_error(r);
2522 r = sd_bus_message_read(m,
2525 &start_timestamp, &start_timestamp_monotonic,
2526 &exit_timestamp, &exit_timestamp_monotonic,
2530 return bus_log_parse_error(r);
2533 i->start_timestamp = (usec_t) start_timestamp;
2534 i->exit_timestamp = (usec_t) exit_timestamp;
2535 i->pid = (pid_t) pid;
2539 r = sd_bus_message_exit_container(m);
2541 return bus_log_parse_error(r);
2546 typedef struct UnitStatusInfo {
2548 const char *load_state;
2549 const char *active_state;
2550 const char *sub_state;
2551 const char *unit_file_state;
2553 const char *description;
2554 const char *following;
2556 char **documentation;
2558 const char *fragment_path;
2559 const char *source_path;
2560 const char *control_group;
2562 char **dropin_paths;
2564 const char *load_error;
2567 usec_t inactive_exit_timestamp;
2568 usec_t inactive_exit_timestamp_monotonic;
2569 usec_t active_enter_timestamp;
2570 usec_t active_exit_timestamp;
2571 usec_t inactive_enter_timestamp;
2573 bool need_daemon_reload;
2578 const char *status_text;
2579 const char *pid_file;
2582 usec_t start_timestamp;
2583 usec_t exit_timestamp;
2585 int exit_code, exit_status;
2587 usec_t condition_timestamp;
2588 bool condition_result;
2589 bool failed_condition_trigger;
2590 bool failed_condition_negate;
2591 const char *failed_condition;
2592 const char *failed_condition_param;
2595 unsigned n_accepted;
2596 unsigned n_connections;
2599 /* Pairs of type, path */
2603 const char *sysfs_path;
2605 /* Mount, Automount */
2611 LIST_HEAD(ExecStatusInfo, exec);
2614 static void print_status_info(
2619 const char *on, *off, *ss;
2621 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2622 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2625 arg_all * OUTPUT_SHOW_ALL |
2626 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2627 on_tty() * OUTPUT_COLOR |
2628 !arg_quiet * OUTPUT_WARN_CUTOFF |
2629 arg_full * OUTPUT_FULL_WIDTH;
2634 /* This shows pretty information about a unit. See
2635 * print_property() for a low-level property printer */
2637 printf("%s", strna(i->id));
2639 if (i->description && !streq_ptr(i->id, i->description))
2640 printf(" - %s", i->description);
2645 printf(" Follow: unit currently follows state of %s\n", i->following);
2647 if (streq_ptr(i->load_state, "error")) {
2648 on = ansi_highlight_red();
2649 off = ansi_highlight_off();
2653 path = i->source_path ? i->source_path : i->fragment_path;
2656 printf(" Loaded: %s%s%s (Reason: %s)\n",
2657 on, strna(i->load_state), off, i->load_error);
2658 else if (path && i->unit_file_state)
2659 printf(" Loaded: %s%s%s (%s; %s)\n",
2660 on, strna(i->load_state), off, path, i->unit_file_state);
2662 printf(" Loaded: %s%s%s (%s)\n",
2663 on, strna(i->load_state), off, path);
2665 printf(" Loaded: %s%s%s\n",
2666 on, strna(i->load_state), off);
2668 if (!strv_isempty(i->dropin_paths)) {
2669 _cleanup_free_ char *dir = NULL;
2673 STRV_FOREACH(dropin, i->dropin_paths) {
2674 if (! dir || last) {
2675 printf(dir ? " " : " Drop-In: ");
2680 if (path_get_parent(*dropin, &dir) < 0) {
2685 printf("%s\n %s", dir,
2686 draw_special_char(DRAW_TREE_RIGHT));
2689 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2691 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2695 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2697 if (streq_ptr(i->active_state, "failed")) {
2698 on = ansi_highlight_red();
2699 off = ansi_highlight_off();
2700 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2701 on = ansi_highlight_green();
2702 off = ansi_highlight_off();
2707 printf(" Active: %s%s (%s)%s",
2708 on, strna(i->active_state), ss, off);
2710 printf(" Active: %s%s%s",
2711 on, strna(i->active_state), off);
2713 if (!isempty(i->result) && !streq(i->result, "success"))
2714 printf(" (Result: %s)", i->result);
2716 timestamp = (streq_ptr(i->active_state, "active") ||
2717 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2718 (streq_ptr(i->active_state, "inactive") ||
2719 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2720 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2721 i->active_exit_timestamp;
2723 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2724 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2727 printf(" since %s; %s\n", s2, s1);
2729 printf(" since %s\n", s2);
2733 if (!i->condition_result && i->condition_timestamp > 0) {
2734 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2735 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2737 printf(" start condition failed at %s%s%s\n",
2738 s2, s1 ? "; " : "", s1 ? s1 : "");
2739 if (i->failed_condition_trigger)
2740 printf(" none of the trigger conditions were met\n");
2741 else if (i->failed_condition)
2742 printf(" %s=%s%s was not met\n",
2743 i->failed_condition,
2744 i->failed_condition_negate ? "!" : "",
2745 i->failed_condition_param);
2749 printf(" Device: %s\n", i->sysfs_path);
2751 printf(" Where: %s\n", i->where);
2753 printf(" What: %s\n", i->what);
2755 STRV_FOREACH(t, i->documentation)
2756 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2758 STRV_FOREACH_PAIR(t, t2, i->listen)
2759 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2762 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2764 LIST_FOREACH(exec, p, i->exec) {
2765 _cleanup_free_ char *argv = NULL;
2768 /* Only show exited processes here */
2772 argv = strv_join(p->argv, " ");
2773 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2775 good = is_clean_exit_lsb(p->code, p->status, NULL);
2777 on = ansi_highlight_red();
2778 off = ansi_highlight_off();
2782 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2784 if (p->code == CLD_EXITED) {
2787 printf("status=%i", p->status);
2789 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2794 printf("signal=%s", signal_to_string(p->status));
2796 printf(")%s\n", off);
2798 if (i->main_pid == p->pid &&
2799 i->start_timestamp == p->start_timestamp &&
2800 i->exit_timestamp == p->start_timestamp)
2801 /* Let's not show this twice */
2804 if (p->pid == i->control_pid)
2808 if (i->main_pid > 0 || i->control_pid > 0) {
2809 if (i->main_pid > 0) {
2810 printf(" Main PID: %u", (unsigned) i->main_pid);
2813 _cleanup_free_ char *comm = NULL;
2814 get_process_comm(i->main_pid, &comm);
2816 printf(" (%s)", comm);
2817 } else if (i->exit_code > 0) {
2818 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2820 if (i->exit_code == CLD_EXITED) {
2823 printf("status=%i", i->exit_status);
2825 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2830 printf("signal=%s", signal_to_string(i->exit_status));
2834 if (i->control_pid > 0)
2838 if (i->control_pid > 0) {
2839 _cleanup_free_ char *c = NULL;
2841 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2843 get_process_comm(i->control_pid, &c);
2852 printf(" Status: \"%s\"\n", i->status_text);
2854 if (i->control_group &&
2855 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2858 printf(" CGroup: %s\n", i->control_group);
2860 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2863 char prefix[] = " ";
2866 if (c > sizeof(prefix) - 1)
2867 c -= sizeof(prefix) - 1;
2871 if (i->main_pid > 0)
2872 extra[k++] = i->main_pid;
2874 if (i->control_pid > 0)
2875 extra[k++] = i->control_pid;
2877 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2878 c, false, extra, k, flags);
2882 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2884 show_journal_by_unit(stdout,
2888 i->inactive_exit_timestamp_monotonic,
2892 arg_scope == UNIT_FILE_SYSTEM,
2896 if (i->need_daemon_reload)
2897 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2898 ansi_highlight_red(),
2899 ansi_highlight_off(),
2900 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2903 static void show_unit_help(UnitStatusInfo *i) {
2908 if (!i->documentation) {
2909 log_info("Documentation for %s not known.", i->id);
2913 STRV_FOREACH(p, i->documentation) {
2915 if (startswith(*p, "man:")) {
2916 const char *args[4] = { "man", NULL, NULL, NULL };
2917 _cleanup_free_ char *page = NULL, *section = NULL;
2924 if ((*p)[k-1] == ')')
2925 e = strrchr(*p, '(');
2928 page = strndup((*p) + 4, e - *p - 4);
2929 section = strndup(e + 1, *p + k - e - 2);
2930 if (!page || !section) {
2942 log_error("Failed to fork: %m");
2948 execvp(args[0], (char**) args);
2949 log_error("Failed to execute man: %m");
2950 _exit(EXIT_FAILURE);
2953 wait_for_terminate(pid, NULL);
2955 log_info("Can't show: %s", *p);
2959 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2966 switch (contents[0]) {
2968 case SD_BUS_TYPE_STRING: {
2971 r = sd_bus_message_read(m, "s", &s);
2973 return bus_log_parse_error(r);
2976 if (streq(name, "Id"))
2978 else if (streq(name, "LoadState"))
2980 else if (streq(name, "ActiveState"))
2981 i->active_state = s;
2982 else if (streq(name, "SubState"))
2984 else if (streq(name, "Description"))
2986 else if (streq(name, "FragmentPath"))
2987 i->fragment_path = s;
2988 else if (streq(name, "SourcePath"))
2991 else if (streq(name, "DefaultControlGroup")) {
2993 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2995 i->control_group = e;
2998 else if (streq(name, "ControlGroup"))
2999 i->control_group = s;
3000 else if (streq(name, "StatusText"))
3002 else if (streq(name, "PIDFile"))
3004 else if (streq(name, "SysFSPath"))
3006 else if (streq(name, "Where"))
3008 else if (streq(name, "What"))
3010 else if (streq(name, "Following"))
3012 else if (streq(name, "UnitFileState"))
3013 i->unit_file_state = s;
3014 else if (streq(name, "Result"))
3021 case SD_BUS_TYPE_BOOLEAN: {
3024 r = sd_bus_message_read(m, "b", &b);
3026 return bus_log_parse_error(r);
3028 if (streq(name, "Accept"))
3030 else if (streq(name, "NeedDaemonReload"))
3031 i->need_daemon_reload = b;
3032 else if (streq(name, "ConditionResult"))
3033 i->condition_result = b;
3038 case SD_BUS_TYPE_UINT32: {
3041 r = sd_bus_message_read(m, "u", &u);
3043 return bus_log_parse_error(r);
3045 if (streq(name, "MainPID")) {
3047 i->main_pid = (pid_t) u;
3050 } else if (streq(name, "ControlPID"))
3051 i->control_pid = (pid_t) u;
3052 else if (streq(name, "ExecMainPID")) {
3054 i->main_pid = (pid_t) u;
3055 } else if (streq(name, "NAccepted"))
3057 else if (streq(name, "NConnections"))
3058 i->n_connections = u;
3063 case SD_BUS_TYPE_INT32: {
3066 r = sd_bus_message_read(m, "i", &j);
3068 return bus_log_parse_error(r);
3070 if (streq(name, "ExecMainCode"))
3071 i->exit_code = (int) j;
3072 else if (streq(name, "ExecMainStatus"))
3073 i->exit_status = (int) j;
3078 case SD_BUS_TYPE_UINT64: {
3081 r = sd_bus_message_read(m, "t", &u);
3083 return bus_log_parse_error(r);
3085 if (streq(name, "ExecMainStartTimestamp"))
3086 i->start_timestamp = (usec_t) u;
3087 else if (streq(name, "ExecMainExitTimestamp"))
3088 i->exit_timestamp = (usec_t) u;
3089 else if (streq(name, "ActiveEnterTimestamp"))
3090 i->active_enter_timestamp = (usec_t) u;
3091 else if (streq(name, "InactiveEnterTimestamp"))
3092 i->inactive_enter_timestamp = (usec_t) u;
3093 else if (streq(name, "InactiveExitTimestamp"))
3094 i->inactive_exit_timestamp = (usec_t) u;
3095 else if (streq(name, "InactiveExitTimestampMonotonic"))
3096 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3097 else if (streq(name, "ActiveExitTimestamp"))
3098 i->active_exit_timestamp = (usec_t) u;
3099 else if (streq(name, "ConditionTimestamp"))
3100 i->condition_timestamp = (usec_t) u;
3105 case SD_BUS_TYPE_ARRAY:
3107 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3108 _cleanup_free_ ExecStatusInfo *info = NULL;
3110 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3112 return bus_log_parse_error(r);
3114 info = new0(ExecStatusInfo, 1);
3118 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3120 info->name = strdup(name);
3124 LIST_PREPEND(exec, i->exec, info);
3126 info = new0(ExecStatusInfo, 1);
3132 return bus_log_parse_error(r);
3134 r = sd_bus_message_exit_container(m);
3136 return bus_log_parse_error(r);
3140 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3141 const char *type, *path;
3143 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3145 return bus_log_parse_error(r);
3147 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3149 r = strv_extend(&i->listen, type);
3153 r = strv_extend(&i->listen, path);
3158 return bus_log_parse_error(r);
3160 r = sd_bus_message_exit_container(m);
3162 return bus_log_parse_error(r);
3166 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3168 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3170 return bus_log_parse_error(r);
3172 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3174 r = sd_bus_message_read_strv(m, &i->documentation);
3176 return bus_log_parse_error(r);
3178 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3179 const char *cond, *param;
3180 int trigger, negate;
3183 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3185 return bus_log_parse_error(r);
3187 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3188 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3189 if (state < 0 && (!trigger || !i->failed_condition)) {
3190 i->failed_condition = cond;
3191 i->failed_condition_trigger = trigger;
3192 i->failed_condition_negate = negate;
3193 i->failed_condition_param = param;
3197 return bus_log_parse_error(r);
3199 r = sd_bus_message_exit_container(m);
3201 return bus_log_parse_error(r);
3208 case SD_BUS_TYPE_STRUCT_BEGIN:
3210 if (streq(name, "LoadError")) {
3211 const char *n, *message;
3213 r = sd_bus_message_read(m, "(ss)", &n, &message);
3215 return bus_log_parse_error(r);
3217 if (!isempty(message))
3218 i->load_error = message;
3231 r = sd_bus_message_skip(m, contents);
3233 return bus_log_parse_error(r);
3238 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3244 /* This is a low-level property printer, see
3245 * print_status_info() for the nicer output */
3247 if (arg_properties && !strv_find(arg_properties, name)) {
3248 /* skip what we didn't read */
3249 r = sd_bus_message_skip(m, contents);
3253 switch (contents[0]) {
3255 case SD_BUS_TYPE_STRUCT_BEGIN:
3257 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3260 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3262 return bus_log_parse_error(r);
3265 printf("%s=%u\n", name, (unsigned) u);
3267 printf("%s=\n", name);
3271 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3274 r = sd_bus_message_read(m, "(so)", &s, NULL);
3276 return bus_log_parse_error(r);
3278 if (arg_all || !isempty(s))
3279 printf("%s=%s\n", name, s);
3283 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3284 const char *a = NULL, *b = NULL;
3286 r = sd_bus_message_read(m, "(ss)", &a, &b);
3288 return bus_log_parse_error(r);
3290 if (arg_all || !isempty(a) || !isempty(b))
3291 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3298 case SD_BUS_TYPE_ARRAY:
3300 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3304 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3306 return bus_log_parse_error(r);
3308 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3309 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3312 return bus_log_parse_error(r);
3314 r = sd_bus_message_exit_container(m);
3316 return bus_log_parse_error(r);
3320 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3321 const char *type, *path;
3323 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3325 return bus_log_parse_error(r);
3327 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3328 printf("%s=%s\n", type, path);
3330 return bus_log_parse_error(r);
3332 r = sd_bus_message_exit_container(m);
3334 return bus_log_parse_error(r);
3338 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3339 const char *type, *path;
3341 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3343 return bus_log_parse_error(r);
3345 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3346 printf("Listen%s=%s\n", type, path);
3348 return bus_log_parse_error(r);
3350 r = sd_bus_message_exit_container(m);
3352 return bus_log_parse_error(r);
3356 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3358 uint64_t value, next_elapse;
3360 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3362 return bus_log_parse_error(r);
3364 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3365 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3367 printf("%s={ value=%s ; next_elapse=%s }\n",
3369 format_timespan(timespan1, sizeof(timespan1), value, 0),
3370 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3373 return bus_log_parse_error(r);
3375 r = sd_bus_message_exit_container(m);
3377 return bus_log_parse_error(r);
3381 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3382 ExecStatusInfo info = {};
3384 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3386 return bus_log_parse_error(r);
3388 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3389 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3390 _cleanup_free_ char *tt;
3392 tt = strv_join(info.argv, " ");
3394 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3398 yes_no(info.ignore),
3399 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3400 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3401 (unsigned) info. pid,
3402 sigchld_code_to_string(info.code),
3404 info.code == CLD_EXITED ? "" : "/",
3405 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3408 strv_free(info.argv);
3412 r = sd_bus_message_exit_container(m);
3414 return bus_log_parse_error(r);
3418 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3419 const char *path, *rwm;
3421 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3423 return bus_log_parse_error(r);
3425 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3426 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3428 return bus_log_parse_error(r);
3430 r = sd_bus_message_exit_container(m);
3432 return bus_log_parse_error(r);
3436 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3440 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3442 return bus_log_parse_error(r);
3444 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3445 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3447 return bus_log_parse_error(r);
3449 r = sd_bus_message_exit_container(m);
3451 return bus_log_parse_error(r);
3455 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3459 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3461 return bus_log_parse_error(r);
3463 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3464 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3466 return bus_log_parse_error(r);
3468 r = sd_bus_message_exit_container(m);
3470 return bus_log_parse_error(r);
3478 r = bus_print_property(name, m, arg_all);
3480 return bus_log_parse_error(r);
3483 r = sd_bus_message_skip(m, contents);
3485 return bus_log_parse_error(r);
3488 printf("%s=[unprintable]\n", name);
3494 static int show_one(
3498 bool show_properties,
3502 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3503 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3504 UnitStatusInfo info = {};
3511 r = sd_bus_call_method(
3513 "org.freedesktop.systemd1",
3515 "org.freedesktop.DBus.Properties",
3521 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3525 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3527 return bus_log_parse_error(r);
3534 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3535 const char *name, *contents;
3537 r = sd_bus_message_read(reply, "s", &name);
3539 return bus_log_parse_error(r);
3541 r = sd_bus_message_peek_type(reply, NULL, &contents);
3543 return bus_log_parse_error(r);
3545 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3547 return bus_log_parse_error(r);
3549 if (show_properties)
3550 r = print_property(name, reply, contents);
3552 r = status_property(name, reply, &info, contents);
3556 r = sd_bus_message_exit_container(reply);
3558 return bus_log_parse_error(r);
3560 r = sd_bus_message_exit_container(reply);
3562 return bus_log_parse_error(r);
3565 return bus_log_parse_error(r);
3567 r = sd_bus_message_exit_container(reply);
3569 return bus_log_parse_error(r);
3573 if (!show_properties) {
3574 if (streq(verb, "help"))
3575 show_unit_help(&info);
3577 print_status_info(&info, ellipsized);
3580 strv_free(info.documentation);
3581 strv_free(info.dropin_paths);
3582 strv_free(info.listen);
3584 if (!streq_ptr(info.active_state, "active") &&
3585 !streq_ptr(info.active_state, "reloading") &&
3586 streq(verb, "status")) {
3587 /* According to LSB: "program not running" */
3588 /* 0: program is running or service is OK
3589 * 1: program is dead and /var/run pid file exists
3590 * 2: program is dead and /var/lock lock file exists
3591 * 3: program is not running
3592 * 4: program or service status is unknown
3594 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3600 while ((p = info.exec)) {
3601 LIST_REMOVE(exec, info.exec, p);
3602 exec_status_info_free(p);
3608 static int get_unit_dbus_path_by_pid(
3613 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3614 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3617 r = sd_bus_call_method(
3619 "org.freedesktop.systemd1",
3620 "/org/freedesktop/systemd1",
3621 "org.freedesktop.systemd1.Manager",
3627 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3631 r = sd_bus_message_read(reply, "o", unit);
3633 return bus_log_parse_error(r);
3638 static int show_all(
3641 bool show_properties,
3645 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3646 _cleanup_free_ UnitInfo *unit_infos = NULL;
3651 r = get_unit_list(bus, &reply, &unit_infos);
3655 pager_open_if_enabled();
3659 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3661 for (u = unit_infos; u < unit_infos + c; u++) {
3662 _cleanup_free_ char *p = NULL;
3664 if (!output_show_unit(u))
3667 p = unit_dbus_path_from_name(u->id);
3671 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3679 static int cat(sd_bus *bus, char **args) {
3683 _cleanup_free_ char *unit = NULL, *n = NULL;
3688 pager_open_if_enabled();
3690 STRV_FOREACH(name, args+1) {
3691 _cleanup_free_ char *fragment_path = NULL;
3692 _cleanup_strv_free_ char **dropin_paths = NULL;
3696 n = unit_name_mangle(*name);
3700 unit = unit_dbus_path_from_name(n);
3704 if (need_daemon_reload(bus, n) > 0)
3705 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3706 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
3708 r = sd_bus_get_property_string(
3710 "org.freedesktop.systemd1",
3712 "org.freedesktop.systemd1.Unit",
3717 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error, r));
3721 r = sd_bus_get_property_strv(
3723 "org.freedesktop.systemd1",
3725 "org.freedesktop.systemd1.Unit",
3730 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error, r));
3734 if (!isempty(fragment_path)) {
3735 fprintf(stdout, "# %s\n", fragment_path);
3737 r = sendfile_full(STDOUT_FILENO, fragment_path);
3739 log_warning("Failed to cat %s: %s", fragment_path, strerror(-r));
3744 STRV_FOREACH(path, dropin_paths) {
3745 fprintf(stdout, "%s# %s\n",
3746 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
3749 r = sendfile_full(STDOUT_FILENO, *path);
3751 log_warning("Failed to cat %s: %s", *path, strerror(-r));
3760 static int show(sd_bus *bus, char **args) {
3762 bool show_properties, show_status, new_line = false;
3764 bool ellipsized = false;
3769 show_properties = streq(args[0], "show");
3770 show_status = streq(args[0], "status");
3772 if (show_properties)
3773 pager_open_if_enabled();
3775 /* If no argument is specified inspect the manager itself */
3777 if (show_properties && strv_length(args) <= 1)
3778 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3780 if (show_status && strv_length(args) <= 1)
3781 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3783 STRV_FOREACH(name, args+1) {
3784 _cleanup_free_ char *unit = NULL;
3787 if (safe_atou32(*name, &id) < 0) {
3788 _cleanup_free_ char *n = NULL;
3789 /* Interpret as unit name */
3791 n = unit_name_mangle(*name);
3795 unit = unit_dbus_path_from_name(n);
3799 } else if (show_properties) {
3800 /* Interpret as job id */
3801 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
3805 /* Interpret as PID */
3806 r = get_unit_dbus_path_by_pid(bus, id, &unit);
3811 show_one(args[0], bus, unit, show_properties, &new_line, &ellipsized);
3814 if (ellipsized && !arg_quiet)
3815 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3820 static int append_assignment(sd_bus_message *m, const char *assignment) {
3828 eq = strchr(assignment, '=');
3830 log_error("Not an assignment: %s", assignment);
3834 field = strndupa(assignment, eq - assignment);
3837 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3839 return bus_log_create_error(r);
3841 if (streq(field, "CPUAccounting") ||
3842 streq(field, "MemoryAccounting") ||
3843 streq(field, "BlockIOAccounting")) {
3845 r = parse_boolean(eq);
3847 log_error("Failed to parse boolean assignment %s.", assignment);
3851 r = sd_bus_message_append(m, "v", "b", r);
3853 } else if (streq(field, "MemoryLimit")) {
3856 r = parse_bytes(eq, &bytes);
3858 log_error("Failed to parse bytes specification %s", assignment);
3862 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3864 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3867 r = safe_atou64(eq, &u);
3869 log_error("Failed to parse %s value %s.", field, eq);
3873 r = sd_bus_message_append(m, "v", "t", u);
3875 } else if (streq(field, "DevicePolicy"))
3876 r = sd_bus_message_append(m, "v", "s", eq);
3878 else if (streq(field, "DeviceAllow")) {
3881 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3883 const char *path, *rwm;
3886 e = strchr(eq, ' ');
3888 path = strndupa(eq, e - eq);
3895 if (!path_startswith(path, "/dev")) {
3896 log_error("%s is not a device file in /dev.", path);
3900 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3903 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3906 r = sd_bus_message_append(m, "v", "a(st)", 0);
3908 const char *path, *bandwidth;
3912 e = strchr(eq, ' ');
3914 path = strndupa(eq, e - eq);
3917 log_error("Failed to parse %s value %s.", field, eq);
3921 if (!path_startswith(path, "/dev")) {
3922 log_error("%s is not a device file in /dev.", path);
3926 r = parse_bytes(bandwidth, &bytes);
3928 log_error("Failed to parse byte value %s.", bandwidth);
3932 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3935 } else if (streq(field, "BlockIODeviceWeight")) {
3938 r = sd_bus_message_append(m, "v", "a(st)", 0);
3940 const char *path, *weight;
3944 e = strchr(eq, ' ');
3946 path = strndupa(eq, e - eq);
3949 log_error("Failed to parse %s value %s.", field, eq);
3953 if (!path_startswith(path, "/dev")) {
3954 log_error("%s is not a device file in /dev.", path);
3958 r = safe_atou64(weight, &u);
3960 log_error("Failed to parse %s value %s.", field, weight);
3963 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3967 log_error("Unknown assignment %s.", assignment);
3972 return bus_log_create_error(r);
3977 static int set_property(sd_bus *bus, char **args) {
3978 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3979 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3980 _cleanup_free_ char *n = NULL;
3984 r = sd_bus_message_new_method_call(
3986 "org.freedesktop.systemd1",
3987 "/org/freedesktop/systemd1",
3988 "org.freedesktop.systemd1.Manager",
3989 "SetUnitProperties",
3992 return bus_log_create_error(r);
3994 n = unit_name_mangle(args[1]);
3998 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4000 return bus_log_create_error(r);
4002 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4004 return bus_log_create_error(r);
4006 STRV_FOREACH(i, args + 2) {
4007 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4009 return bus_log_create_error(r);
4011 r = append_assignment(m, *i);
4015 r = sd_bus_message_close_container(m);
4017 return bus_log_create_error(r);
4020 r = sd_bus_message_close_container(m);
4022 return bus_log_create_error(r);
4024 r = sd_bus_call(bus, m, 0, &error, NULL);
4026 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4033 static int snapshot(sd_bus *bus, char **args) {
4034 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4035 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4036 _cleanup_free_ char *n = NULL, *id = NULL;
4040 if (strv_length(args) > 1)
4041 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
4047 r = sd_bus_call_method(
4049 "org.freedesktop.systemd1",
4050 "/org/freedesktop/systemd1",
4051 "org.freedesktop.systemd1.Manager",
4057 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4061 r = sd_bus_message_read(reply, "o", &path);
4063 return bus_log_parse_error(r);
4065 r = sd_bus_get_property_string(
4067 "org.freedesktop.systemd1",
4069 "org.freedesktop.systemd1.Unit",
4074 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4084 static int delete_snapshot(sd_bus *bus, char **args) {
4085 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4091 STRV_FOREACH(name, args+1) {
4092 _cleanup_free_ char *n = NULL;
4094 n = unit_name_mangle_with_suffix(*name, ".snapshot");
4098 r = sd_bus_call_method(
4100 "org.freedesktop.systemd1",
4101 "/org/freedesktop/systemd1",
4102 "org.freedesktop.systemd1.Manager",
4108 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
4116 static int daemon_reload(sd_bus *bus, char **args) {
4117 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4121 if (arg_action == ACTION_RELOAD)
4123 else if (arg_action == ACTION_REEXEC)
4124 method = "Reexecute";
4126 assert(arg_action == ACTION_SYSTEMCTL);
4129 streq(args[0], "clear-jobs") ||
4130 streq(args[0], "cancel") ? "ClearJobs" :
4131 streq(args[0], "daemon-reexec") ? "Reexecute" :
4132 streq(args[0], "reset-failed") ? "ResetFailed" :
4133 streq(args[0], "halt") ? "Halt" :
4134 streq(args[0], "poweroff") ? "PowerOff" :
4135 streq(args[0], "reboot") ? "Reboot" :
4136 streq(args[0], "kexec") ? "KExec" :
4137 streq(args[0], "exit") ? "Exit" :
4138 /* "daemon-reload" */ "Reload";
4141 r = sd_bus_call_method(
4143 "org.freedesktop.systemd1",
4144 "/org/freedesktop/systemd1",
4145 "org.freedesktop.systemd1.Manager",
4151 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4152 /* There's always a fallback possible for
4153 * legacy actions. */
4155 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4156 /* On reexecution, we expect a disconnect, not a
4160 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4162 return r < 0 ? r : 0;
4165 static int reset_failed(sd_bus *bus, char **args) {
4166 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4170 if (strv_length(args) <= 1)
4171 return daemon_reload(bus, args);
4173 STRV_FOREACH(name, args+1) {
4174 _cleanup_free_ char *n;
4176 n = unit_name_mangle(*name);
4180 r = sd_bus_call_method(
4182 "org.freedesktop.systemd1",
4183 "/org/freedesktop/systemd1",
4184 "org.freedesktop.systemd1.Manager",
4190 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4198 static int show_environment(sd_bus *bus, char **args) {
4199 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4200 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4204 pager_open_if_enabled();
4206 r = sd_bus_get_property(
4208 "org.freedesktop.systemd1",
4209 "/org/freedesktop/systemd1",
4210 "org.freedesktop.systemd1.Manager",
4216 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4220 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4222 return bus_log_parse_error(r);
4224 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4227 return bus_log_parse_error(r);
4229 r = sd_bus_message_exit_container(reply);
4231 return bus_log_parse_error(r);
4236 static int switch_root(sd_bus *bus, char **args) {
4237 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4238 _cleanup_free_ char *init = NULL;
4243 l = strv_length(args);
4244 if (l < 2 || l > 3) {
4245 log_error("Wrong number of arguments.");
4252 init = strdup(args[2]);
4254 parse_env_file("/proc/cmdline", WHITESPACE,
4265 log_debug("switching root - root: %s; init: %s", root, init);
4267 r = sd_bus_call_method(
4269 "org.freedesktop.systemd1",
4270 "/org/freedesktop/systemd1",
4271 "org.freedesktop.systemd1.Manager",
4277 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4284 static int set_environment(sd_bus *bus, char **args) {
4285 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4286 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4293 method = streq(args[0], "set-environment")
4295 : "UnsetEnvironment";
4297 r = sd_bus_message_new_method_call(
4299 "org.freedesktop.systemd1",
4300 "/org/freedesktop/systemd1",
4301 "org.freedesktop.systemd1.Manager",
4305 return bus_log_create_error(r);
4307 r = sd_bus_message_append_strv(m, args + 1);
4309 return bus_log_create_error(r);
4311 r = sd_bus_call(bus, m, 0, &error, NULL);
4313 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4320 static int enable_sysv_units(const char *verb, char **args) {
4323 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4324 unsigned f = 1, t = 1;
4325 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4327 if (arg_scope != UNIT_FILE_SYSTEM)
4330 if (!streq(verb, "enable") &&
4331 !streq(verb, "disable") &&
4332 !streq(verb, "is-enabled"))
4335 /* Processes all SysV units, and reshuffles the array so that
4336 * afterwards only the native units remain */
4338 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4343 for (f = 0; args[f]; f++) {
4345 _cleanup_free_ char *p = NULL, *q = NULL;
4346 bool found_native = false, found_sysv;
4348 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4356 if (!endswith(name, ".service"))
4359 if (path_is_absolute(name))
4362 STRV_FOREACH(k, paths.unit_path) {
4363 if (!isempty(arg_root))
4364 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4366 asprintf(&p, "%s/%s", *k, name);
4373 found_native = access(p, F_OK) >= 0;
4384 if (!isempty(arg_root))
4385 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4387 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4393 p[strlen(p) - sizeof(".service") + 1] = 0;
4394 found_sysv = access(p, F_OK) >= 0;
4399 /* Mark this entry, so that we don't try enabling it as native unit */
4400 args[f] = (char*) "";
4402 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4404 if (!isempty(arg_root))
4405 argv[c++] = q = strappend("--root=", arg_root);
4407 argv[c++] = path_get_file_name(p);
4409 streq(verb, "enable") ? "on" :
4410 streq(verb, "disable") ? "off" : "--level=5";
4413 l = strv_join((char**)argv, " ");
4419 log_info("Executing %s", l);
4424 log_error("Failed to fork: %m");
4427 } else if (pid == 0) {
4430 execv(argv[0], (char**) argv);
4431 _exit(EXIT_FAILURE);
4434 j = wait_for_terminate(pid, &status);
4436 log_error("Failed to wait for child: %s", strerror(-r));
4441 if (status.si_code == CLD_EXITED) {
4442 if (streq(verb, "is-enabled")) {
4443 if (status.si_status == 0) {
4452 } else if (status.si_status != 0) {
4463 /* Drop all SysV units */
4464 for (f = 0, t = 0; args[f]; f++) {
4466 if (isempty(args[f]))
4469 args[t++] = args[f];
4478 static int mangle_names(char **original_names, char ***mangled_names) {
4479 char **i, **l, **name;
4481 l = new(char*, strv_length(original_names) + 1);
4486 STRV_FOREACH(name, original_names) {
4488 /* When enabling units qualified path names are OK,
4489 * too, hence allow them explicitly. */
4494 *i = unit_name_mangle(*name);
4510 static int enable_unit(sd_bus *bus, char **args) {
4511 _cleanup_strv_free_ char **mangled_names = NULL;
4512 const char *verb = args[0];
4513 UnitFileChange *changes = NULL;
4514 unsigned n_changes = 0;
4515 int carries_install_info = -1;
4521 r = mangle_names(args+1, &mangled_names);
4525 r = enable_sysv_units(verb, mangled_names);
4529 if (!bus || avoid_bus()) {
4530 if (streq(verb, "enable")) {
4531 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4532 carries_install_info = r;
4533 } else if (streq(verb, "disable"))
4534 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4535 else if (streq(verb, "reenable")) {
4536 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4537 carries_install_info = r;
4538 } else if (streq(verb, "link"))
4539 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4540 else if (streq(verb, "preset")) {
4541 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4542 carries_install_info = r;
4543 } else if (streq(verb, "mask"))
4544 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4545 else if (streq(verb, "unmask"))
4546 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4548 assert_not_reached("Unknown verb");
4551 log_error("Operation failed: %s", strerror(-r));
4556 dump_unit_file_changes(changes, n_changes);
4560 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4561 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4562 int expect_carries_install_info = false;
4563 bool send_force = true;
4566 if (streq(verb, "enable")) {
4567 method = "EnableUnitFiles";
4568 expect_carries_install_info = true;
4569 } else if (streq(verb, "disable")) {
4570 method = "DisableUnitFiles";
4572 } else if (streq(verb, "reenable")) {
4573 method = "ReenableUnitFiles";
4574 expect_carries_install_info = true;
4575 } else if (streq(verb, "link"))
4576 method = "LinkUnitFiles";
4577 else if (streq(verb, "preset")) {
4578 method = "PresetUnitFiles";
4579 expect_carries_install_info = true;
4580 } else if (streq(verb, "mask"))
4581 method = "MaskUnitFiles";
4582 else if (streq(verb, "unmask")) {
4583 method = "UnmaskUnitFiles";
4586 assert_not_reached("Unknown verb");
4588 r = sd_bus_message_new_method_call(
4590 "org.freedesktop.systemd1",
4591 "/org/freedesktop/systemd1",
4592 "org.freedesktop.systemd1.Manager",
4596 return bus_log_create_error(r);
4598 r = sd_bus_message_append_strv(m, mangled_names);
4600 return bus_log_create_error(r);
4602 r = sd_bus_message_append(m, "b", arg_runtime);
4604 return bus_log_create_error(r);
4607 r = sd_bus_message_append(m, "b", arg_force);
4609 return bus_log_create_error(r);
4612 r = sd_bus_call(bus, m, 0, &error, &reply);
4614 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4618 if (expect_carries_install_info) {
4619 r = sd_bus_message_read(reply, "b", &carries_install_info);
4621 return bus_log_parse_error(r);
4624 r = deserialize_and_dump_unit_file_changes(reply);
4628 /* Try to reload if enabeld */
4630 r = daemon_reload(bus, args);
4635 if (carries_install_info == 0)
4636 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4637 "using systemctl.\n"
4638 "Possible reasons for having this kind of units are:\n"
4639 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4640 " .wants/ or .requires/ directory.\n"
4641 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4642 " a requirement dependency on it.\n"
4643 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4644 " D-Bus, udev, scripted systemctl call, ...).\n");
4647 unit_file_changes_free(changes, n_changes);
4652 static int unit_is_enabled(sd_bus *bus, char **args) {
4654 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4655 _cleanup_strv_free_ char **mangled_names = NULL;
4660 r = mangle_names(args+1, &mangled_names);
4664 r = enable_sysv_units(args[0], mangled_names);
4670 if (!bus || avoid_bus()) {
4672 STRV_FOREACH(name, mangled_names) {
4673 UnitFileState state;
4675 state = unit_file_get_state(arg_scope, arg_root, *name);
4677 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4681 if (state == UNIT_FILE_ENABLED ||
4682 state == UNIT_FILE_ENABLED_RUNTIME ||
4683 state == UNIT_FILE_STATIC)
4687 puts(unit_file_state_to_string(state));
4691 STRV_FOREACH(name, mangled_names) {
4692 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4695 r = sd_bus_call_method(
4697 "org.freedesktop.systemd1",
4698 "/org/freedesktop/systemd1",
4699 "org.freedesktop.systemd1.Manager",
4705 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4709 r = sd_bus_message_read(reply, "s", &s);
4711 return bus_log_parse_error(r);
4713 if (streq(s, "enabled") ||
4714 streq(s, "enabled-runtime") ||
4726 static int systemctl_help(void) {
4728 pager_open_if_enabled();
4730 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4731 "Query or send control commands to the systemd manager.\n\n"
4732 " -h --help Show this help\n"
4733 " --version Show package version\n"
4734 " --system Connect to system manager\n"
4735 " --user Connect to user service manager\n"
4736 " -H --host=[USER@]HOST\n"
4737 " Operate on remote host\n"
4738 " -M --machine=CONTAINER\n"
4739 " Operate on local container\n"
4740 " -t --type=TYPE List only units of a particular type\n"
4741 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4742 " -p --property=NAME Show only properties by this name\n"
4743 " -a --all Show all loaded units/properties, including dead/empty\n"
4744 " ones. To list all units installed on the system, use\n"
4745 " the 'list-unit-files' command instead.\n"
4746 " -l --full Don't ellipsize unit names on output\n"
4747 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4748 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4749 " queueing a new job\n"
4750 " --show-types When showing sockets, explicitly show their type\n"
4751 " -i --ignore-inhibitors\n"
4752 " When shutting down or sleeping, ignore inhibitors\n"
4753 " --kill-who=WHO Who to send signal to\n"
4754 " -s --signal=SIGNAL Which signal to send\n"
4755 " -q --quiet Suppress output\n"
4756 " --no-block Do not wait until operation finished\n"
4757 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4758 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4760 " --no-legend Do not print a legend (column headers and hints)\n"
4761 " --no-pager Do not pipe output into a pager\n"
4762 " --no-ask-password\n"
4763 " Do not ask for system passwords\n"
4764 " --global Enable/disable unit files globally\n"
4765 " --runtime Enable unit files only temporarily until next reboot\n"
4766 " -f --force When enabling unit files, override existing symlinks\n"
4767 " When shutting down, execute action immediately\n"
4768 " --root=PATH Enable unit files in the specified root directory\n"
4769 " -n --lines=INTEGER Number of journal entries to show\n"
4770 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4771 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4773 " list-units List loaded units\n"
4774 " list-sockets List loaded sockets ordered by address\n"
4775 " list-timers List loaded timers ordered by next elapse\n"
4776 " start [NAME...] Start (activate) one or more units\n"
4777 " stop [NAME...] Stop (deactivate) one or more units\n"
4778 " reload [NAME...] Reload one or more units\n"
4779 " restart [NAME...] Start or restart one or more units\n"
4780 " try-restart [NAME...] Restart one or more units if active\n"
4781 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4782 " otherwise start or restart\n"
4783 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4784 " otherwise restart if active\n"
4785 " isolate [NAME] Start one unit and stop all others\n"
4786 " kill [NAME...] Send signal to processes of a unit\n"
4787 " is-active [NAME...] Check whether units are active\n"
4788 " is-failed [NAME...] Check whether units are failed\n"
4789 " status [NAME...|PID...] Show runtime status of one or more units\n"
4790 " show [NAME...|JOB...] Show properties of one or more\n"
4791 " units/jobs or the manager\n"
4792 " cat [NAME...] Show files and drop-ins of one or more units\n"
4793 " set-property [NAME] [ASSIGNMENT...]\n"
4794 " Sets one or more properties of a unit\n"
4795 " help [NAME...|PID...] Show manual for one or more units\n"
4796 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4798 " list-dependencies [NAME] Recursively show units which are required\n"
4799 " or wanted by this unit or by which this\n"
4800 " unit is required or wanted\n\n"
4801 "Unit File Commands:\n"
4802 " list-unit-files List installed unit files\n"
4803 " enable [NAME...] Enable one or more unit files\n"
4804 " disable [NAME...] Disable one or more unit files\n"
4805 " reenable [NAME...] Reenable one or more unit files\n"
4806 " preset [NAME...] Enable/disable one or more unit files\n"
4807 " based on preset configuration\n"
4808 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4809 " mask [NAME...] Mask one or more units\n"
4810 " unmask [NAME...] Unmask one or more units\n"
4811 " link [PATH...] Link one or more units files into\n"
4812 " the search path\n"
4813 " get-default Get the name of the default target\n"
4814 " set-default NAME Set the default target\n\n"
4816 " list-jobs List jobs\n"
4817 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4818 "Snapshot Commands:\n"
4819 " snapshot [NAME] Create a snapshot\n"
4820 " delete [NAME...] Remove one or more snapshots\n\n"
4821 "Environment Commands:\n"
4822 " show-environment Dump environment\n"
4823 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4824 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4825 "Manager Lifecycle Commands:\n"
4826 " daemon-reload Reload systemd manager configuration\n"
4827 " daemon-reexec Reexecute systemd manager\n\n"
4828 "System Commands:\n"
4829 " default Enter system default mode\n"
4830 " rescue Enter system rescue mode\n"
4831 " emergency Enter system emergency mode\n"
4832 " halt Shut down and halt the system\n"
4833 " poweroff Shut down and power-off the system\n"
4834 " reboot [ARG] Shut down and reboot the system\n"
4835 " kexec Shut down and reboot the system with kexec\n"
4836 " exit Request user instance exit\n"
4837 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4838 " suspend Suspend the system\n"
4839 " hibernate Hibernate the system\n"
4840 " hybrid-sleep Hibernate and suspend the system\n",
4841 program_invocation_short_name);
4846 static int halt_help(void) {
4848 printf("%s [OPTIONS...]%s\n\n"
4849 "%s the system.\n\n"
4850 " --help Show this help\n"
4851 " --halt Halt the machine\n"
4852 " -p --poweroff Switch off the machine\n"
4853 " --reboot Reboot the machine\n"
4854 " -f --force Force immediate halt/power-off/reboot\n"
4855 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4856 " -d --no-wtmp Don't write wtmp record\n"
4857 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4858 program_invocation_short_name,
4859 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4860 arg_action == ACTION_REBOOT ? "Reboot" :
4861 arg_action == ACTION_POWEROFF ? "Power off" :
4867 static int shutdown_help(void) {
4869 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4870 "Shut down the system.\n\n"
4871 " --help Show this help\n"
4872 " -H --halt Halt the machine\n"
4873 " -P --poweroff Power-off the machine\n"
4874 " -r --reboot Reboot the machine\n"
4875 " -h Equivalent to --poweroff, overridden by --halt\n"
4876 " -k Don't halt/power-off/reboot, just send warnings\n"
4877 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4878 " -c Cancel a pending shutdown\n",
4879 program_invocation_short_name);
4884 static int telinit_help(void) {
4886 printf("%s [OPTIONS...] {COMMAND}\n\n"
4887 "Send control commands to the init daemon.\n\n"
4888 " --help Show this help\n"
4889 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4891 " 0 Power-off the machine\n"
4892 " 6 Reboot the machine\n"
4893 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4894 " 1, s, S Enter rescue mode\n"
4895 " q, Q Reload init daemon configuration\n"
4896 " u, U Reexecute init daemon\n",
4897 program_invocation_short_name);
4902 static int runlevel_help(void) {
4904 printf("%s [OPTIONS...]\n\n"
4905 "Prints the previous and current runlevel of the init system.\n\n"
4906 " --help Show this help\n",
4907 program_invocation_short_name);
4912 static int help_types(void) {
4916 puts("Available unit types:");
4917 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
4918 t = unit_type_to_string(i);
4926 static int systemctl_parse_argv(int argc, char *argv[]) {
4935 ARG_IGNORE_DEPENDENCIES,
4947 ARG_NO_ASK_PASSWORD,
4956 static const struct option options[] = {
4957 { "help", no_argument, NULL, 'h' },
4958 { "version", no_argument, NULL, ARG_VERSION },
4959 { "type", required_argument, NULL, 't' },
4960 { "property", required_argument, NULL, 'p' },
4961 { "all", no_argument, NULL, 'a' },
4962 { "reverse", no_argument, NULL, ARG_REVERSE },
4963 { "after", no_argument, NULL, ARG_AFTER },
4964 { "before", no_argument, NULL, ARG_BEFORE },
4965 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4966 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4967 { "full", no_argument, NULL, 'l' },
4968 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
4969 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
4970 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
4971 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
4972 { "ignore-inhibitors", no_argument, NULL, 'i' },
4973 { "user", no_argument, NULL, ARG_USER },
4974 { "system", no_argument, NULL, ARG_SYSTEM },
4975 { "global", no_argument, NULL, ARG_GLOBAL },
4976 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4977 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4978 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4979 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4980 { "quiet", no_argument, NULL, 'q' },
4981 { "root", required_argument, NULL, ARG_ROOT },
4982 { "force", no_argument, NULL, ARG_FORCE },
4983 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4984 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4985 { "signal", required_argument, NULL, 's' },
4986 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4987 { "host", required_argument, NULL, 'H' },
4988 { "machine", required_argument, NULL, 'M' },
4989 { "runtime", no_argument, NULL, ARG_RUNTIME },
4990 { "lines", required_argument, NULL, 'n' },
4991 { "output", required_argument, NULL, 'o' },
4992 { "plain", no_argument, NULL, ARG_PLAIN },
4993 { "state", required_argument, NULL, ARG_STATE },
5002 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
5007 return systemctl_help();
5010 puts(PACKAGE_STRING);
5011 puts(SYSTEMD_FEATURES);
5018 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5019 _cleanup_free_ char *type;
5021 type = strndup(word, size);
5025 if (streq(type, "help")) {
5030 if (unit_type_from_string(type) >= 0) {
5031 if (strv_push(&arg_types, type))
5037 /* It's much nicer to use --state= for
5038 * load states, but let's support this
5039 * in --types= too for compatibility
5040 * with old versions */
5041 if (unit_load_state_from_string(optarg) >= 0) {
5042 if (strv_push(&arg_states, type) < 0)
5048 log_error("Unknown unit type or load state '%s'.", type);
5049 log_info("Use -t help to see a list of allowed values.");
5057 /* Make sure that if the empty property list
5058 was specified, we won't show any properties. */
5059 if (isempty(optarg) && !arg_properties) {
5060 arg_properties = new0(char*, 1);
5061 if (!arg_properties)
5067 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5070 prop = strndup(word, size);
5074 if (strv_push(&arg_properties, prop) < 0) {
5081 /* If the user asked for a particular
5082 * property, show it to him, even if it is
5094 arg_dependency = DEPENDENCY_REVERSE;
5098 arg_dependency = DEPENDENCY_AFTER;
5102 arg_dependency = DEPENDENCY_BEFORE;
5105 case ARG_SHOW_TYPES:
5106 arg_show_types = true;
5110 arg_job_mode = optarg;
5114 arg_job_mode = "fail";
5117 case ARG_IRREVERSIBLE:
5118 arg_job_mode = "replace-irreversibly";
5121 case ARG_IGNORE_DEPENDENCIES:
5122 arg_job_mode = "ignore-dependencies";
5126 arg_scope = UNIT_FILE_USER;
5130 arg_scope = UNIT_FILE_SYSTEM;
5134 arg_scope = UNIT_FILE_GLOBAL;
5138 arg_no_block = true;
5142 arg_no_legend = true;
5146 arg_no_pager = true;
5162 if (strv_extend(&arg_states, "failed") < 0)
5180 arg_no_reload = true;
5184 arg_kill_who = optarg;
5188 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5189 log_error("Failed to parse signal string %s.", optarg);
5194 case ARG_NO_ASK_PASSWORD:
5195 arg_ask_password = false;
5199 arg_transport = BUS_TRANSPORT_REMOTE;
5204 arg_transport = BUS_TRANSPORT_CONTAINER;
5213 if (safe_atou(optarg, &arg_lines) < 0) {
5214 log_error("Failed to parse lines '%s'", optarg);
5220 arg_output = output_mode_from_string(optarg);
5221 if (arg_output < 0) {
5222 log_error("Unknown output '%s'.", optarg);
5228 arg_ignore_inhibitors = true;
5239 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5242 s = strndup(word, size);
5246 if (strv_push(&arg_states, s) < 0) {
5258 assert_not_reached("Unhandled option");
5262 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5263 log_error("Cannot access user instance remotely.");
5270 static int halt_parse_argv(int argc, char *argv[]) {
5279 static const struct option options[] = {
5280 { "help", no_argument, NULL, ARG_HELP },
5281 { "halt", no_argument, NULL, ARG_HALT },
5282 { "poweroff", no_argument, NULL, 'p' },
5283 { "reboot", no_argument, NULL, ARG_REBOOT },
5284 { "force", no_argument, NULL, 'f' },
5285 { "wtmp-only", no_argument, NULL, 'w' },
5286 { "no-wtmp", no_argument, NULL, 'd' },
5287 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5296 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5297 if (runlevel == '0' || runlevel == '6')
5300 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5307 arg_action = ACTION_HALT;
5311 if (arg_action != ACTION_REBOOT)
5312 arg_action = ACTION_POWEROFF;
5316 arg_action = ACTION_REBOOT;
5338 /* Compatibility nops */
5345 assert_not_reached("Unhandled option");
5349 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5350 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5352 log_error("Failed to write reboot param to "
5353 REBOOT_PARAM_FILE": %s", strerror(-r));
5356 } else if (optind < argc) {
5357 log_error("Too many arguments.");
5364 static int parse_time_spec(const char *t, usec_t *_u) {
5368 if (streq(t, "now"))
5370 else if (!strchr(t, ':')) {
5373 if (safe_atou64(t, &u) < 0)
5376 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5385 hour = strtol(t, &e, 10);
5386 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5389 minute = strtol(e+1, &e, 10);
5390 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5393 n = now(CLOCK_REALTIME);
5394 s = (time_t) (n / USEC_PER_SEC);
5396 assert_se(localtime_r(&s, &tm));
5398 tm.tm_hour = (int) hour;
5399 tm.tm_min = (int) minute;
5402 assert_se(s = mktime(&tm));
5404 *_u = (usec_t) s * USEC_PER_SEC;
5407 *_u += USEC_PER_DAY;
5413 static int shutdown_parse_argv(int argc, char *argv[]) {
5420 static const struct option options[] = {
5421 { "help", no_argument, NULL, ARG_HELP },
5422 { "halt", no_argument, NULL, 'H' },
5423 { "poweroff", no_argument, NULL, 'P' },
5424 { "reboot", no_argument, NULL, 'r' },
5425 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5426 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5435 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5439 return shutdown_help();
5442 arg_action = ACTION_HALT;
5446 arg_action = ACTION_POWEROFF;
5451 arg_action = ACTION_KEXEC;
5453 arg_action = ACTION_REBOOT;
5457 arg_action = ACTION_KEXEC;
5461 if (arg_action != ACTION_HALT)
5462 arg_action = ACTION_POWEROFF;
5475 /* Compatibility nops */
5479 arg_action = ACTION_CANCEL_SHUTDOWN;
5486 assert_not_reached("Unhandled option");
5490 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5491 r = parse_time_spec(argv[optind], &arg_when);
5493 log_error("Failed to parse time specification: %s", argv[optind]);
5497 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5499 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5500 /* No time argument for shutdown cancel */
5501 arg_wall = argv + optind;
5502 else if (argc > optind + 1)
5503 /* We skip the time argument */
5504 arg_wall = argv + optind + 1;
5511 static int telinit_parse_argv(int argc, char *argv[]) {
5518 static const struct option options[] = {
5519 { "help", no_argument, NULL, ARG_HELP },
5520 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5524 static const struct {
5528 { '0', ACTION_POWEROFF },
5529 { '6', ACTION_REBOOT },
5530 { '1', ACTION_RESCUE },
5531 { '2', ACTION_RUNLEVEL2 },
5532 { '3', ACTION_RUNLEVEL3 },
5533 { '4', ACTION_RUNLEVEL4 },
5534 { '5', ACTION_RUNLEVEL5 },
5535 { 's', ACTION_RESCUE },
5536 { 'S', ACTION_RESCUE },
5537 { 'q', ACTION_RELOAD },
5538 { 'Q', ACTION_RELOAD },
5539 { 'u', ACTION_REEXEC },
5540 { 'U', ACTION_REEXEC }
5549 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5553 return telinit_help();
5563 assert_not_reached("Unhandled option");
5567 if (optind >= argc) {
5572 if (optind + 1 < argc) {
5573 log_error("Too many arguments.");
5577 if (strlen(argv[optind]) != 1) {
5578 log_error("Expected single character argument.");
5582 for (i = 0; i < ELEMENTSOF(table); i++)
5583 if (table[i].from == argv[optind][0])
5586 if (i >= ELEMENTSOF(table)) {
5587 log_error("Unknown command '%s'.", argv[optind]);
5591 arg_action = table[i].to;
5598 static int runlevel_parse_argv(int argc, char *argv[]) {
5604 static const struct option options[] = {
5605 { "help", no_argument, NULL, ARG_HELP },
5614 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5618 return runlevel_help();
5625 assert_not_reached("Unhandled option");
5629 if (optind < argc) {
5630 log_error("Too many arguments.");
5637 static int parse_argv(int argc, char *argv[]) {
5641 if (program_invocation_short_name) {
5643 if (strstr(program_invocation_short_name, "halt")) {
5644 arg_action = ACTION_HALT;
5645 return halt_parse_argv(argc, argv);
5646 } else if (strstr(program_invocation_short_name, "poweroff")) {
5647 arg_action = ACTION_POWEROFF;
5648 return halt_parse_argv(argc, argv);
5649 } else if (strstr(program_invocation_short_name, "reboot")) {
5651 arg_action = ACTION_KEXEC;
5653 arg_action = ACTION_REBOOT;
5654 return halt_parse_argv(argc, argv);
5655 } else if (strstr(program_invocation_short_name, "shutdown")) {
5656 arg_action = ACTION_POWEROFF;
5657 return shutdown_parse_argv(argc, argv);
5658 } else if (strstr(program_invocation_short_name, "init")) {
5660 if (sd_booted() > 0) {
5661 arg_action = _ACTION_INVALID;
5662 return telinit_parse_argv(argc, argv);
5664 /* Hmm, so some other init system is
5665 * running, we need to forward this
5666 * request to it. For now we simply
5667 * guess that it is Upstart. */
5669 execv(TELINIT, argv);
5671 log_error("Couldn't find an alternative telinit implementation to spawn.");
5675 } else if (strstr(program_invocation_short_name, "runlevel")) {
5676 arg_action = ACTION_RUNLEVEL;
5677 return runlevel_parse_argv(argc, argv);
5681 arg_action = ACTION_SYSTEMCTL;
5682 return systemctl_parse_argv(argc, argv);
5685 _pure_ static int action_to_runlevel(void) {
5687 static const char table[_ACTION_MAX] = {
5688 [ACTION_HALT] = '0',
5689 [ACTION_POWEROFF] = '0',
5690 [ACTION_REBOOT] = '6',
5691 [ACTION_RUNLEVEL2] = '2',
5692 [ACTION_RUNLEVEL3] = '3',
5693 [ACTION_RUNLEVEL4] = '4',
5694 [ACTION_RUNLEVEL5] = '5',
5695 [ACTION_RESCUE] = '1'
5698 assert(arg_action < _ACTION_MAX);
5700 return table[arg_action];
5703 static int talk_initctl(void) {
5705 struct init_request request = {
5706 .magic = INIT_MAGIC,
5708 .cmd = INIT_CMD_RUNLVL
5711 _cleanup_close_ int fd = -1;
5715 rl = action_to_runlevel();
5719 request.runlevel = rl;
5721 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5723 if (errno == ENOENT)
5726 log_error("Failed to open "INIT_FIFO": %m");
5731 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5733 log_error("Failed to write to "INIT_FIFO": %m");
5734 return errno > 0 ? -errno : -EIO;
5740 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5742 static const struct {
5750 int (* const dispatch)(sd_bus *bus, char **args);
5752 { "list-units", LESS, 1, list_units },
5753 { "list-unit-files", EQUAL, 1, list_unit_files },
5754 { "list-sockets", LESS, 1, list_sockets },
5755 { "list-timers", LESS, 1, list_timers },
5756 { "list-jobs", EQUAL, 1, list_jobs },
5757 { "clear-jobs", EQUAL, 1, daemon_reload },
5758 { "cancel", MORE, 2, cancel_job },
5759 { "start", MORE, 2, start_unit },
5760 { "stop", MORE, 2, start_unit },
5761 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5762 { "reload", MORE, 2, start_unit },
5763 { "restart", MORE, 2, start_unit },
5764 { "try-restart", MORE, 2, start_unit },
5765 { "reload-or-restart", MORE, 2, start_unit },
5766 { "reload-or-try-restart", MORE, 2, start_unit },
5767 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5768 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5769 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5770 { "isolate", EQUAL, 2, start_unit },
5771 { "kill", MORE, 2, kill_unit },
5772 { "is-active", MORE, 2, check_unit_active },
5773 { "check", MORE, 2, check_unit_active },
5774 { "is-failed", MORE, 2, check_unit_failed },
5775 { "show", MORE, 1, show },
5776 { "cat", MORE, 2, cat },
5777 { "status", MORE, 1, show },
5778 { "help", MORE, 2, show },
5779 { "snapshot", LESS, 2, snapshot },
5780 { "delete", MORE, 2, delete_snapshot },
5781 { "daemon-reload", EQUAL, 1, daemon_reload },
5782 { "daemon-reexec", EQUAL, 1, daemon_reload },
5783 { "show-environment", EQUAL, 1, show_environment },
5784 { "set-environment", MORE, 2, set_environment },
5785 { "unset-environment", MORE, 2, set_environment },
5786 { "halt", EQUAL, 1, start_special },
5787 { "poweroff", EQUAL, 1, start_special },
5788 { "reboot", EQUAL, 1, start_special },
5789 { "kexec", EQUAL, 1, start_special },
5790 { "suspend", EQUAL, 1, start_special },
5791 { "hibernate", EQUAL, 1, start_special },
5792 { "hybrid-sleep", EQUAL, 1, start_special },
5793 { "default", EQUAL, 1, start_special },
5794 { "rescue", EQUAL, 1, start_special },
5795 { "emergency", EQUAL, 1, start_special },
5796 { "exit", EQUAL, 1, start_special },
5797 { "reset-failed", MORE, 1, reset_failed },
5798 { "enable", MORE, 2, enable_unit },
5799 { "disable", MORE, 2, enable_unit },
5800 { "is-enabled", MORE, 2, unit_is_enabled },
5801 { "reenable", MORE, 2, enable_unit },
5802 { "preset", MORE, 2, enable_unit },
5803 { "mask", MORE, 2, enable_unit },
5804 { "unmask", MORE, 2, enable_unit },
5805 { "link", MORE, 2, enable_unit },
5806 { "switch-root", MORE, 2, switch_root },
5807 { "list-dependencies", LESS, 2, list_dependencies },
5808 { "set-default", EQUAL, 2, set_default },
5809 { "get-default", EQUAL, 1, get_default },
5810 { "set-property", MORE, 3, set_property },
5819 left = argc - optind;
5822 /* Special rule: no arguments means "list-units" */
5825 if (streq(argv[optind], "help") && !argv[optind+1]) {
5826 log_error("This command expects one or more "
5827 "unit names. Did you mean --help?");
5831 for (i = 0; i < ELEMENTSOF(verbs); i++)
5832 if (streq(argv[optind], verbs[i].verb))
5835 if (i >= ELEMENTSOF(verbs)) {
5836 log_error("Unknown operation '%s'.", argv[optind]);
5841 switch (verbs[i].argc_cmp) {
5844 if (left != verbs[i].argc) {
5845 log_error("Invalid number of arguments.");
5852 if (left < verbs[i].argc) {
5853 log_error("Too few arguments.");
5860 if (left > verbs[i].argc) {
5861 log_error("Too many arguments.");
5868 assert_not_reached("Unknown comparison operator.");
5871 /* Require a bus connection for all operations but
5873 if (!streq(verbs[i].verb, "enable") &&
5874 !streq(verbs[i].verb, "disable") &&
5875 !streq(verbs[i].verb, "is-enabled") &&
5876 !streq(verbs[i].verb, "list-unit-files") &&
5877 !streq(verbs[i].verb, "reenable") &&
5878 !streq(verbs[i].verb, "preset") &&
5879 !streq(verbs[i].verb, "mask") &&
5880 !streq(verbs[i].verb, "unmask") &&
5881 !streq(verbs[i].verb, "link") &&
5882 !streq(verbs[i].verb, "set-default") &&
5883 !streq(verbs[i].verb, "get-default")) {
5885 if (running_in_chroot() > 0) {
5886 log_info("Running in chroot, ignoring request.");
5890 if (((!streq(verbs[i].verb, "reboot") &&
5891 !streq(verbs[i].verb, "halt") &&
5892 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5893 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5899 if (!bus && !avoid_bus()) {
5900 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5905 return verbs[i].dispatch(bus, argv + optind);
5908 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5910 struct sd_shutdown_command c = {
5917 union sockaddr_union sockaddr = {
5918 .un.sun_family = AF_UNIX,
5919 .un.sun_path = "/run/systemd/shutdownd",
5922 struct iovec iovec[2] = {{
5923 .iov_base = (char*) &c,
5924 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5927 struct msghdr msghdr = {
5928 .msg_name = &sockaddr,
5929 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5930 + sizeof("/run/systemd/shutdownd") - 1,
5935 _cleanup_close_ int fd;
5937 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5941 if (!isempty(message)) {
5942 iovec[1].iov_base = (char*) message;
5943 iovec[1].iov_len = strlen(message);
5944 msghdr.msg_iovlen++;
5947 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5953 static int reload_with_fallback(sd_bus *bus) {
5956 /* First, try systemd via D-Bus. */
5957 if (daemon_reload(bus, NULL) >= 0)
5961 /* Nothing else worked, so let's try signals */
5962 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5964 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5965 log_error("kill() failed: %m");
5972 static int start_with_fallback(sd_bus *bus) {
5975 /* First, try systemd via D-Bus. */
5976 if (start_unit(bus, NULL) >= 0)
5980 /* Nothing else worked, so let's try
5982 if (talk_initctl() > 0)
5985 log_error("Failed to talk to init daemon.");
5989 warn_wall(arg_action);
5993 static int halt_now(enum action a) {
5995 /* Make sure C-A-D is handled by the kernel from this
5997 reboot(RB_ENABLE_CAD);
6002 log_info("Halting.");
6003 reboot(RB_HALT_SYSTEM);
6006 case ACTION_POWEROFF:
6007 log_info("Powering off.");
6008 reboot(RB_POWER_OFF);
6011 case ACTION_REBOOT: {
6012 _cleanup_free_ char *param = NULL;
6014 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
6015 log_info("Rebooting with argument '%s'.", param);
6016 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
6017 LINUX_REBOOT_CMD_RESTART2, param);
6020 log_info("Rebooting.");
6021 reboot(RB_AUTOBOOT);
6026 assert_not_reached("Unknown action.");
6030 static int halt_main(sd_bus *bus) {
6033 r = check_inhibitors(bus, arg_action);
6037 if (geteuid() != 0) {
6038 /* Try logind if we are a normal user and no special
6039 * mode applies. Maybe PolicyKit allows us to shutdown
6042 if (arg_when <= 0 &&
6045 (arg_action == ACTION_POWEROFF ||
6046 arg_action == ACTION_REBOOT)) {
6047 r = reboot_with_logind(bus, arg_action);
6052 log_error("Must be root.");
6057 _cleanup_free_ char *m;
6059 m = strv_join(arg_wall, " ");
6063 r = send_shutdownd(arg_when,
6064 arg_action == ACTION_HALT ? 'H' :
6065 arg_action == ACTION_POWEROFF ? 'P' :
6066 arg_action == ACTION_KEXEC ? 'K' :
6073 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
6075 char date[FORMAT_TIMESTAMP_MAX];
6077 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6078 format_timestamp(date, sizeof(date), arg_when));
6083 if (!arg_dry && !arg_force)
6084 return start_with_fallback(bus);
6087 if (sd_booted() > 0)
6088 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6090 r = utmp_put_shutdown();
6092 log_warning("Failed to write utmp record: %s", strerror(-r));
6099 r = halt_now(arg_action);
6100 log_error("Failed to reboot: %s", strerror(-r));
6105 static int runlevel_main(void) {
6106 int r, runlevel, previous;
6108 r = utmp_get_runlevel(&runlevel, &previous);
6115 previous <= 0 ? 'N' : previous,
6116 runlevel <= 0 ? 'N' : runlevel);
6121 int main(int argc, char*argv[]) {
6122 _cleanup_bus_unref_ sd_bus *bus = NULL;
6125 setlocale(LC_ALL, "");
6126 log_parse_environment();
6129 /* Explicitly not on_tty() to avoid setting cached value.
6130 * This becomes relevant for piping output which might be
6132 original_stdout_is_tty = isatty(STDOUT_FILENO);
6134 r = parse_argv(argc, argv);
6138 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6139 * let's shortcut this */
6140 if (arg_action == ACTION_RUNLEVEL) {
6141 r = runlevel_main();
6145 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6146 log_info("Running in chroot, ignoring request.");
6152 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6154 /* systemctl_main() will print an error message for the bus
6155 * connection, but only if it needs to */
6157 switch (arg_action) {
6159 case ACTION_SYSTEMCTL:
6160 r = systemctl_main(bus, argc, argv, r);
6164 case ACTION_POWEROFF:
6170 case ACTION_RUNLEVEL2:
6171 case ACTION_RUNLEVEL3:
6172 case ACTION_RUNLEVEL4:
6173 case ACTION_RUNLEVEL5:
6175 case ACTION_EMERGENCY:
6176 case ACTION_DEFAULT:
6177 r = start_with_fallback(bus);
6182 r = reload_with_fallback(bus);
6185 case ACTION_CANCEL_SHUTDOWN: {
6186 _cleanup_free_ char *m = NULL;
6189 m = strv_join(arg_wall, " ");
6196 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6198 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6202 case ACTION_RUNLEVEL:
6203 case _ACTION_INVALID:
6205 assert_not_reached("Unknown action");
6210 ask_password_agent_close();
6211 polkit_agent_close();
6213 strv_free(arg_types);
6214 strv_free(arg_states);
6215 strv_free(arg_properties);
6217 return r < 0 ? EXIT_FAILURE : r;