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 {
85 } arg_dependency = DEPENDENCY_FORWARD;
86 static const char *arg_job_mode = "replace";
87 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
88 static bool arg_no_block = false;
89 static bool arg_no_legend = false;
90 static bool arg_no_pager = false;
91 static bool arg_no_wtmp = false;
92 static bool arg_no_wall = false;
93 static bool arg_no_reload = false;
94 static bool arg_show_types = false;
95 static bool arg_ignore_inhibitors = false;
96 static bool arg_dry = false;
97 static bool arg_quiet = false;
98 static bool arg_full = false;
99 static int arg_force = 0;
100 static bool arg_ask_password = true;
101 static bool arg_runtime = false;
102 static char **arg_wall = NULL;
103 static const char *arg_kill_who = NULL;
104 static int arg_signal = SIGTERM;
105 static const char *arg_root = NULL;
106 static usec_t arg_when = 0;
128 ACTION_CANCEL_SHUTDOWN,
130 } arg_action = ACTION_SYSTEMCTL;
131 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
132 static char *arg_host = NULL;
133 static unsigned arg_lines = 10;
134 static OutputMode arg_output = OUTPUT_SHORT;
135 static bool arg_plain = false;
137 static int daemon_reload(sd_bus *bus, char **args);
138 static int halt_now(enum action a);
140 static void pager_open_if_enabled(void) {
148 static void ask_password_agent_open_if_enabled(void) {
150 /* Open the password agent as a child process if necessary */
152 if (!arg_ask_password)
155 if (arg_scope != UNIT_FILE_SYSTEM)
158 if (arg_transport != BUS_TRANSPORT_LOCAL)
161 ask_password_agent_open();
165 static void polkit_agent_open_if_enabled(void) {
167 /* Open the polkit agent as a child process if necessary */
169 if (!arg_ask_password)
172 if (arg_scope != UNIT_FILE_SYSTEM)
175 if (arg_transport != BUS_TRANSPORT_LOCAL)
182 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
185 if (!sd_bus_error_is_set(error))
188 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
189 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
190 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
191 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
192 return EXIT_NOPERMISSION;
194 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
195 return EXIT_NOTINSTALLED;
197 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
198 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
199 return EXIT_NOTIMPLEMENTED;
201 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
202 return EXIT_NOTCONFIGURED;
210 static void warn_wall(enum action a) {
211 static const char *table[_ACTION_MAX] = {
212 [ACTION_HALT] = "The system is going down for system halt NOW!",
213 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
214 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
215 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
216 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
217 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
218 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
225 _cleanup_free_ char *p;
227 p = strv_join(arg_wall, " ");
242 utmp_wall(table[a], NULL);
245 static bool avoid_bus(void) {
247 if (running_in_chroot() > 0)
250 if (sd_booted() <= 0)
253 if (!isempty(arg_root))
256 if (arg_scope == UNIT_FILE_GLOBAL)
262 static int compare_unit_info(const void *a, const void *b) {
263 const UnitInfo *u = a, *v = b;
266 d1 = strrchr(u->id, '.');
267 d2 = strrchr(v->id, '.');
272 r = strcasecmp(d1, d2);
277 return strcasecmp(u->id, v->id);
280 static bool output_show_unit(const UnitInfo *u) {
283 if (!strv_isempty(arg_states))
285 strv_contains(arg_states, u->load_state) ||
286 strv_contains(arg_states, u->sub_state) ||
287 strv_contains(arg_states, u->active_state);
289 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
290 strv_find(arg_types, dot+1))) &&
291 (arg_all || !(streq(u->active_state, "inactive")
292 || u->following[0]) || u->job_id > 0);
295 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
296 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
298 unsigned n_shown = 0;
301 max_id_len = sizeof("UNIT")-1;
302 load_len = sizeof("LOAD")-1;
303 active_len = sizeof("ACTIVE")-1;
304 sub_len = sizeof("SUB")-1;
305 job_len = sizeof("JOB")-1;
308 for (u = unit_infos; u < unit_infos + c; u++) {
309 if (!output_show_unit(u))
312 max_id_len = MAX(max_id_len, strlen(u->id));
313 load_len = MAX(load_len, strlen(u->load_state));
314 active_len = MAX(active_len, strlen(u->active_state));
315 sub_len = MAX(sub_len, strlen(u->sub_state));
317 if (u->job_id != 0) {
318 job_len = MAX(job_len, strlen(u->job_type));
323 if (!arg_full && original_stdout_is_tty) {
326 id_len = MIN(max_id_len, 25u);
327 basic_len = 5 + id_len + 5 + active_len + sub_len;
330 basic_len += job_len + 1;
332 if (basic_len < (unsigned) columns()) {
333 unsigned extra_len, incr;
334 extra_len = columns() - basic_len;
336 /* Either UNIT already got 25, or is fully satisfied.
337 * Grant up to 25 to DESC now. */
338 incr = MIN(extra_len, 25u);
342 /* split the remaining space between UNIT and DESC,
343 * but do not give UNIT more than it needs. */
345 incr = MIN(extra_len / 2, max_id_len - id_len);
347 desc_len += extra_len - incr;
353 for (u = unit_infos; u < unit_infos + c; u++) {
354 _cleanup_free_ char *e = NULL;
355 const char *on_loaded, *off_loaded, *on = "";
356 const char *on_active, *off_active, *off = "";
358 if (!output_show_unit(u))
361 if (!n_shown && !arg_no_legend) {
362 printf("%-*s %-*s %-*s %-*s ",
365 active_len, "ACTIVE",
369 printf("%-*s ", job_len, "JOB");
371 if (!arg_full && arg_no_pager)
372 printf("%.*s\n", desc_len, "DESCRIPTION");
374 printf("%s\n", "DESCRIPTION");
379 if (streq(u->load_state, "error") ||
380 streq(u->load_state, "not-found")) {
381 on_loaded = on = ansi_highlight_red();
382 off_loaded = off = ansi_highlight_off();
384 on_loaded = off_loaded = "";
386 if (streq(u->active_state, "failed")) {
387 on_active = on = ansi_highlight_red();
388 off_active = off = ansi_highlight_off();
390 on_active = off_active = "";
392 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
394 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
395 on, id_len, e ? e : u->id, off,
396 on_loaded, load_len, u->load_state, off_loaded,
397 on_active, active_len, u->active_state,
398 sub_len, u->sub_state, off_active,
399 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
402 printf("%.*s\n", desc_len, u->description);
404 printf("%s\n", u->description);
407 if (!arg_no_legend) {
408 const char *on, *off;
411 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
412 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
413 "SUB = The low-level unit activation state, values depend on unit type.\n");
415 printf("JOB = Pending job for the unit.\n");
417 on = ansi_highlight();
418 off = ansi_highlight_off();
420 on = ansi_highlight_red();
421 off = ansi_highlight_off();
425 printf("%s%u loaded units listed.%s\n"
426 "To show all installed unit files use 'systemctl list-unit-files'.\n",
429 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
430 "To show all installed unit files use 'systemctl list-unit-files'.\n",
435 static int get_unit_list(
437 sd_bus_message **_reply,
438 UnitInfo **_unit_infos) {
440 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
441 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
442 _cleanup_free_ UnitInfo *unit_infos = NULL;
451 r = sd_bus_call_method(
453 "org.freedesktop.systemd1",
454 "/org/freedesktop/systemd1",
455 "org.freedesktop.systemd1.Manager",
461 log_error("Failed to list units: %s", bus_error_message(&error, r));
465 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
467 return bus_log_parse_error(r);
469 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
471 if (!GREEDY_REALLOC(unit_infos, size, c+1))
477 return bus_log_parse_error(r);
479 r = sd_bus_message_exit_container(reply);
481 return bus_log_parse_error(r);
486 *_unit_infos = unit_infos;
492 static int list_units(sd_bus *bus, char **args) {
493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
494 _cleanup_free_ UnitInfo *unit_infos = NULL;
497 pager_open_if_enabled();
499 r = get_unit_list(bus, &reply, &unit_infos);
503 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
504 output_units_list(unit_infos, r);
509 static int get_triggered_units(
514 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
517 r = sd_bus_get_property_strv(
519 "org.freedesktop.systemd1",
521 "org.freedesktop.systemd1.Unit",
527 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
532 static int get_listening(
534 const char* unit_path,
537 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
538 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
539 const char *type, *path;
542 r = sd_bus_get_property(
544 "org.freedesktop.systemd1",
546 "org.freedesktop.systemd1.Socket",
552 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
556 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
558 return bus_log_parse_error(r);
560 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
562 r = strv_extend(listening, type);
566 r = strv_extend(listening, path);
573 return bus_log_parse_error(r);
575 r = sd_bus_message_exit_container(reply);
577 return bus_log_parse_error(r);
588 /* Note: triggered is a list here, although it almost certainly
589 * will always be one unit. Nevertheless, dbus API allows for multiple
590 * values, so let's follow that.*/
593 /* The strv above is shared. free is set only in the first one. */
597 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
603 o = strcmp(a->path, b->path);
605 o = strcmp(a->type, b->type);
610 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
611 struct socket_info *s;
612 unsigned pathlen = sizeof("LISTEN") - 1,
613 typelen = (sizeof("TYPE") - 1) * arg_show_types,
614 socklen = sizeof("UNIT") - 1,
615 servlen = sizeof("ACTIVATES") - 1;
616 const char *on, *off;
618 for (s = socket_infos; s < socket_infos + cs; s++) {
622 socklen = MAX(socklen, strlen(s->id));
624 typelen = MAX(typelen, strlen(s->type));
625 pathlen = MAX(pathlen, strlen(s->path));
627 STRV_FOREACH(a, s->triggered)
628 tmp += strlen(*a) + 2*(a != s->triggered);
629 servlen = MAX(servlen, tmp);
634 printf("%-*s %-*.*s%-*s %s\n",
636 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
640 for (s = socket_infos; s < socket_infos + cs; s++) {
644 printf("%-*s %-*s %-*s",
645 pathlen, s->path, typelen, s->type, socklen, s->id);
648 pathlen, s->path, socklen, s->id);
649 STRV_FOREACH(a, s->triggered)
651 a == s->triggered ? "" : ",", *a);
655 on = ansi_highlight();
656 off = ansi_highlight_off();
660 on = ansi_highlight_red();
661 off = ansi_highlight_off();
664 if (!arg_no_legend) {
665 printf("%s%u sockets listed.%s\n", on, cs, off);
667 printf("Pass --all to see loaded but inactive sockets, too.\n");
673 static int list_sockets(sd_bus *bus, char **args) {
674 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
675 _cleanup_free_ UnitInfo *unit_infos = NULL;
676 struct socket_info *socket_infos = NULL;
678 struct socket_info *s;
683 pager_open_if_enabled();
685 n = get_unit_list(bus, &reply, &unit_infos);
689 for (u = unit_infos; u < unit_infos + n; u++) {
690 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
693 if (!output_show_unit(u))
696 if (!endswith(u->id, ".socket"))
699 r = get_triggered_units(bus, u->unit_path, &triggered);
703 c = get_listening(bus, u->unit_path, &listening);
709 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
714 for (i = 0; i < c; i++)
715 socket_infos[cs + i] = (struct socket_info) {
717 .type = listening[i*2],
718 .path = listening[i*2 + 1],
719 .triggered = triggered,
720 .own_triggered = i==0,
723 /* from this point on we will cleanup those socket_infos */
726 listening = triggered = NULL; /* avoid cleanup */
729 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
730 (__compar_fn_t) socket_info_compare);
732 output_sockets_list(socket_infos, cs);
735 assert(cs == 0 || socket_infos);
736 for (s = socket_infos; s < socket_infos + cs; s++) {
739 if (s->own_triggered)
740 strv_free(s->triggered);
747 static int get_next_elapse(
750 dual_timestamp *next) {
752 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
760 r = sd_bus_get_property_trivial(
762 "org.freedesktop.systemd1",
764 "org.freedesktop.systemd1.Timer",
765 "NextElapseUSecMonotonic",
770 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
774 r = sd_bus_get_property_trivial(
776 "org.freedesktop.systemd1",
778 "org.freedesktop.systemd1.Timer",
779 "NextElapseUSecRealtime",
784 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
798 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
802 if (a->next_elapse < b->next_elapse)
804 if (a->next_elapse > b->next_elapse)
807 return strcmp(a->id, b->id);
810 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
811 struct timer_info *t;
813 nextlen = sizeof("NEXT") - 1,
814 leftlen = sizeof("LEFT") - 1,
815 unitlen = sizeof("UNIT") - 1,
816 activatelen = sizeof("ACTIVATES") - 1;
818 const char *on, *off;
820 assert(timer_infos || n == 0);
822 for (t = timer_infos; t < timer_infos + n; t++) {
826 if (t->next_elapse > 0) {
827 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
829 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
830 nextlen = MAX(nextlen, strlen(tstamp) + 1);
832 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
833 leftlen = MAX(leftlen, strlen(trel));
836 unitlen = MAX(unitlen, strlen(t->id));
838 STRV_FOREACH(a, t->triggered)
839 ul += strlen(*a) + 2*(a != t->triggered);
840 activatelen = MAX(activatelen, ul);
845 printf("%-*s %-*s %-*s %s\n",
851 for (t = timer_infos; t < timer_infos + n; t++) {
852 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
855 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
856 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
858 printf("%-*s %-*s %-*s",
859 nextlen, tstamp, leftlen, trel, unitlen, t->id);
861 STRV_FOREACH(a, t->triggered)
863 a == t->triggered ? "" : ",", *a);
867 on = ansi_highlight();
868 off = ansi_highlight_off();
872 on = ansi_highlight_red();
873 off = ansi_highlight_off();
876 if (!arg_no_legend) {
877 printf("%s%u timers listed.%s\n", on, n, off);
879 printf("Pass --all to see loaded but inactive timers, too.\n");
885 static int list_timers(sd_bus *bus, char **args) {
887 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
888 _cleanup_free_ struct timer_info *timer_infos = NULL;
889 _cleanup_free_ UnitInfo *unit_infos = NULL;
890 struct timer_info *t;
897 pager_open_if_enabled();
899 n = get_unit_list(bus, &reply, &unit_infos);
903 dual_timestamp_get(&nw);
905 for (u = unit_infos; u < unit_infos + n; u++) {
906 _cleanup_strv_free_ char **triggered = NULL;
910 if (!output_show_unit(u))
913 if (!endswith(u->id, ".timer"))
916 r = get_triggered_units(bus, u->unit_path, &triggered);
920 r = get_next_elapse(bus, u->unit_path, &next);
924 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
927 if (next.monotonic > nw.monotonic)
928 converted = nw.realtime + (next.monotonic - nw.monotonic);
930 converted = nw.realtime - (nw.monotonic - next.monotonic);
932 if (next.realtime != (usec_t) -1 && next.realtime > 0)
933 m = MIN(converted, next.realtime);
939 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
944 timer_infos[c++] = (struct timer_info) {
947 .triggered = triggered,
950 triggered = NULL; /* avoid cleanup */
953 qsort_safe(timer_infos, c, sizeof(struct timer_info),
954 (__compar_fn_t) timer_info_compare);
956 output_timers_list(timer_infos, c);
959 for (t = timer_infos; t < timer_infos + c; t++)
960 strv_free(t->triggered);
965 static int compare_unit_file_list(const void *a, const void *b) {
967 const UnitFileList *u = a, *v = b;
969 d1 = strrchr(u->path, '.');
970 d2 = strrchr(v->path, '.');
975 r = strcasecmp(d1, d2);
980 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
983 static bool output_show_unit_file(const UnitFileList *u) {
986 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
989 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
990 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
991 const UnitFileList *u;
993 max_id_len = sizeof("UNIT FILE")-1;
994 state_cols = sizeof("STATE")-1;
996 for (u = units; u < units + c; u++) {
997 if (!output_show_unit_file(u))
1000 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
1001 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1005 unsigned basic_cols;
1007 id_cols = MIN(max_id_len, 25u);
1008 basic_cols = 1 + id_cols + state_cols;
1009 if (basic_cols < (unsigned) columns())
1010 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1012 id_cols = max_id_len;
1015 printf("%-*s %-*s\n",
1016 id_cols, "UNIT FILE",
1017 state_cols, "STATE");
1019 for (u = units; u < units + c; u++) {
1020 _cleanup_free_ char *e = NULL;
1021 const char *on, *off;
1024 if (!output_show_unit_file(u))
1029 if (u->state == UNIT_FILE_MASKED ||
1030 u->state == UNIT_FILE_MASKED_RUNTIME ||
1031 u->state == UNIT_FILE_DISABLED ||
1032 u->state == UNIT_FILE_INVALID) {
1033 on = ansi_highlight_red();
1034 off = ansi_highlight_off();
1035 } else if (u->state == UNIT_FILE_ENABLED) {
1036 on = ansi_highlight_green();
1037 off = ansi_highlight_off();
1041 id = path_get_file_name(u->path);
1043 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1045 printf("%-*s %s%-*s%s\n",
1046 id_cols, e ? e : id,
1047 on, state_cols, unit_file_state_to_string(u->state), off);
1051 printf("\n%u unit files listed.\n", n_shown);
1054 static int list_unit_files(sd_bus *bus, char **args) {
1055 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1056 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1057 _cleanup_free_ UnitFileList *units = NULL;
1063 pager_open_if_enabled();
1071 h = hashmap_new(string_hash_func, string_compare_func);
1075 r = unit_file_get_list(arg_scope, arg_root, h);
1077 unit_file_list_free(h);
1078 log_error("Failed to get unit file list: %s", strerror(-r));
1082 n_units = hashmap_size(h);
1083 units = new(UnitFileList, n_units);
1085 unit_file_list_free(h);
1089 HASHMAP_FOREACH(u, h, i) {
1090 memcpy(units + c++, u, sizeof(UnitFileList));
1094 assert(c == n_units);
1099 r = sd_bus_call_method(
1101 "org.freedesktop.systemd1",
1102 "/org/freedesktop/systemd1",
1103 "org.freedesktop.systemd1.Manager",
1109 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1113 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1115 return bus_log_parse_error(r);
1117 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1119 if (!GREEDY_REALLOC(units, size, c + 1))
1122 units[c++] = (struct UnitFileList) {
1124 unit_file_state_from_string(state)
1128 return bus_log_parse_error(r);
1130 r = sd_bus_message_exit_container(reply);
1132 return bus_log_parse_error(r);
1136 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1137 output_unit_file_list(units, c);
1143 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1144 _cleanup_free_ char *n = NULL;
1145 size_t max_len = MAX(columns(),20u);
1151 for (i = level - 1; i >= 0; i--) {
1153 if(len > max_len - 3 && !arg_full) {
1154 printf("%s...\n",max_len % 2 ? "" : " ");
1157 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1161 if(len > max_len - 3 && !arg_full) {
1162 printf("%s...\n",max_len % 2 ? "" : " ");
1166 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1170 printf("%s\n", name);
1174 n = ellipsize(name, max_len-len, 100);
1182 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1184 static const char *dependencies[] = {
1185 [DEPENDENCY_FORWARD] = "Requires\0"
1186 "RequiresOverridable\0"
1188 "RequisiteOverridable\0"
1190 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1191 "RequiredByOverridable\0"
1194 [DEPENDENCY_AFTER] = "After\0",
1195 [DEPENDENCY_BEFORE] = "Before\0",
1198 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1199 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1200 _cleanup_strv_free_ char **ret = NULL;
1201 _cleanup_free_ char *path = NULL;
1207 assert(arg_dependency < ELEMENTSOF(dependencies));
1209 path = unit_dbus_path_from_name(name);
1213 r = sd_bus_call_method(
1215 "org.freedesktop.systemd1",
1217 "org.freedesktop.DBus.Properties",
1221 "s", "org.freedesktop.systemd1.Unit");
1223 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1227 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1229 return bus_log_parse_error(r);
1231 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1234 r = sd_bus_message_read(reply, "s", &prop);
1236 return bus_log_parse_error(r);
1238 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1239 r = sd_bus_message_skip(reply, "v");
1241 return bus_log_parse_error(r);
1244 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1246 return bus_log_parse_error(r);
1248 r = bus_message_read_strv_extend(reply, &ret);
1250 return bus_log_parse_error(r);
1252 r = sd_bus_message_exit_container(reply);
1254 return bus_log_parse_error(r);
1257 r = sd_bus_message_exit_container(reply);
1259 return bus_log_parse_error(r);
1263 return bus_log_parse_error(r);
1265 r = sd_bus_message_exit_container(reply);
1267 return bus_log_parse_error(r);
1275 static int list_dependencies_compare(const void *_a, const void *_b) {
1276 const char **a = (const char**) _a, **b = (const char**) _b;
1278 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1280 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1283 return strcasecmp(*a, *b);
1286 static int list_dependencies_one(
1291 unsigned int branches) {
1293 _cleanup_strv_free_ char **deps = NULL, **u;
1301 u = strv_append(*units, name);
1305 r = list_dependencies_get_dependencies(bus, name, &deps);
1309 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1311 STRV_FOREACH(c, deps) {
1312 if (strv_contains(u, *c)) {
1314 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1321 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1325 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1326 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1341 static int list_dependencies(sd_bus *bus, char **args) {
1342 _cleanup_strv_free_ char **units = NULL;
1343 _cleanup_free_ char *unit = NULL;
1349 unit = unit_name_mangle(args[1]);
1354 u = SPECIAL_DEFAULT_TARGET;
1356 pager_open_if_enabled();
1360 return list_dependencies_one(bus, u, 0, &units, 0);
1363 static int get_default(sd_bus *bus, char **args) {
1364 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1365 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1366 _cleanup_free_ char *_path = NULL;
1370 if (!bus || avoid_bus()) {
1371 r = unit_file_get_default(arg_scope, arg_root, &_path);
1373 log_error("Failed to get default target: %s", strerror(-r));
1379 r = sd_bus_call_method(
1381 "org.freedesktop.systemd1",
1382 "/org/freedesktop/systemd1",
1383 "org.freedesktop.systemd1.Manager",
1389 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1393 r = sd_bus_message_read(reply, "s", &path);
1395 return bus_log_parse_error(r);
1399 printf("%s\n", path);
1404 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1407 assert(changes || n_changes == 0);
1409 for (i = 0; i < n_changes; i++) {
1410 if (changes[i].type == UNIT_FILE_SYMLINK)
1411 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
1413 log_info("rm '%s'", changes[i].path);
1417 static int deserialize_and_dump_unit_file_changes(sd_bus_message *m) {
1418 const char *type, *path, *source;
1421 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sss)");
1423 return bus_log_parse_error(r);
1425 while ((r = sd_bus_message_read(m, "(sss)", &type, &path, &source)) > 0) {
1427 if (streq(type, "symlink"))
1428 log_info("ln -s '%s' '%s'", source, path);
1430 log_info("rm '%s'", path);
1434 return bus_log_parse_error(r);
1436 r = sd_bus_message_exit_container(m);
1438 return bus_log_parse_error(r);
1443 static int set_default(sd_bus *bus, char **args) {
1444 _cleanup_free_ char *unit = NULL;
1445 UnitFileChange *changes = NULL;
1446 unsigned n_changes = 0;
1449 unit = unit_name_mangle_with_suffix(args[1], ".target");
1453 if (!bus || avoid_bus()) {
1454 r = unit_file_set_default(arg_scope, arg_root, unit, arg_force, &changes, &n_changes);
1456 log_error("Failed to set default target: %s", strerror(-r));
1461 dump_unit_file_changes(changes, n_changes);
1465 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1466 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1468 r = sd_bus_call_method(
1470 "org.freedesktop.systemd1",
1471 "/org/freedesktop/systemd1",
1472 "org.freedesktop.systemd1.Manager",
1476 "sb", unit, arg_force);
1478 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1482 r = deserialize_and_dump_unit_file_changes(reply);
1486 /* Try to reload if enabeld */
1488 r = daemon_reload(bus, args);
1493 unit_file_changes_free(changes, n_changes);
1500 const char *name, *type, *state;
1503 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1504 unsigned id_len, unit_len, type_len, state_len;
1505 const struct job_info *j;
1506 const char *on, *off;
1507 bool shorten = false;
1509 assert(n == 0 || jobs);
1512 on = ansi_highlight_green();
1513 off = ansi_highlight_off();
1515 printf("%sNo jobs running.%s\n", on, off);
1519 pager_open_if_enabled();
1521 id_len = sizeof("JOB")-1;
1522 unit_len = sizeof("UNIT")-1;
1523 type_len = sizeof("TYPE")-1;
1524 state_len = sizeof("STATE")-1;
1526 for (j = jobs; j < jobs + n; j++) {
1527 uint32_t id = j->id;
1528 assert(j->name && j->type && j->state);
1530 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1531 unit_len = MAX(unit_len, strlen(j->name));
1532 type_len = MAX(type_len, strlen(j->type));
1533 state_len = MAX(state_len, strlen(j->state));
1536 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1537 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1542 printf("%*s %-*s %-*s %-*s\n",
1546 state_len, "STATE");
1548 for (j = jobs; j < jobs + n; j++) {
1549 _cleanup_free_ char *e = NULL;
1551 if (streq(j->state, "running")) {
1552 on = ansi_highlight();
1553 off = ansi_highlight_off();
1557 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1558 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1560 on, unit_len, e ? e : j->name, off,
1562 on, state_len, j->state, off);
1565 if (!arg_no_legend) {
1566 on = ansi_highlight();
1567 off = ansi_highlight_off();
1569 printf("\n%s%u jobs listed%s.\n", on, n, off);
1573 static int list_jobs(sd_bus *bus, char **args) {
1574 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1575 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1576 const char *name, *type, *state, *job_path, *unit_path;
1577 _cleanup_free_ struct job_info *jobs = NULL;
1583 r = sd_bus_call_method(
1585 "org.freedesktop.systemd1",
1586 "/org/freedesktop/systemd1",
1587 "org.freedesktop.systemd1.Manager",
1593 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1597 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1599 return bus_log_parse_error(r);
1601 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1603 if (!GREEDY_REALLOC(jobs, size, c + 1))
1606 jobs[c++] = (struct job_info) {
1614 return bus_log_parse_error(r);
1616 r = sd_bus_message_exit_container(reply);
1618 return bus_log_parse_error(r);
1620 output_jobs_list(jobs, c);
1624 static int cancel_job(sd_bus *bus, char **args) {
1625 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1630 if (strv_length(args) <= 1)
1631 return daemon_reload(bus, args);
1633 STRV_FOREACH(name, args+1) {
1637 r = safe_atou32(*name, &id);
1639 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1643 r = sd_bus_call_method(
1645 "org.freedesktop.systemd1",
1646 "/org/freedesktop/systemd1",
1647 "org.freedesktop.systemd1.Manager",
1653 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1661 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1662 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1663 _cleanup_free_ char *n = NULL;
1667 /* We ignore all errors here, since this is used to show a
1670 n = unit_name_mangle(unit);
1674 /* We don't use unit_dbus_path_from_name() directly since we
1675 * don't want to load the unit if it isn't loaded. */
1677 r = sd_bus_call_method(
1679 "org.freedesktop.systemd1",
1680 "/org/freedesktop/systemd1",
1681 "org.freedesktop.systemd1.Manager",
1689 r = sd_bus_message_read(reply, "o", &path);
1693 r = sd_bus_get_property_trivial(
1695 "org.freedesktop.systemd1",
1697 "org.freedesktop.systemd1.Unit",
1707 typedef struct WaitData {
1714 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data, sd_bus_error *error) {
1721 log_debug("Got D-Bus request: %s.%s() on %s",
1722 sd_bus_message_get_interface(m),
1723 sd_bus_message_get_member(m),
1724 sd_bus_message_get_path(m));
1726 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1727 log_error("Warning! D-Bus connection terminated.");
1729 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1731 const char *path, *result, *unit;
1735 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1737 ret = set_remove(d->set, (char*) path);
1743 if (!isempty(result))
1744 d->result = strdup(result);
1747 d->name = strdup(unit);
1752 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1754 ret = set_remove(d->set, (char*) path);
1761 d->result = strdup(result);
1767 bus_log_parse_error(r);
1773 static int enable_wait_for_jobs(sd_bus *bus) {
1778 r = sd_bus_add_match(
1781 "sender='org.freedesktop.systemd1',"
1782 "interface='org.freedesktop.systemd1.Manager',"
1783 "member='JobRemoved',"
1784 "path='/org/freedesktop/systemd1'",
1787 log_error("Failed to add match");
1791 /* This is slightly dirty, since we don't undo the match registrations. */
1795 static int wait_for_jobs(sd_bus *bus, Set *s) {
1796 WaitData d = { .set = s };
1802 r = sd_bus_add_filter(bus, wait_filter, &d);
1806 while (!set_isempty(s)) {
1808 r = sd_bus_process(bus, NULL);
1813 r = sd_bus_wait(bus, (uint64_t) -1);
1822 if (streq(d.result, "timeout"))
1823 log_error("Job for %s timed out.", strna(d.name));
1824 else if (streq(d.result, "canceled"))
1825 log_error("Job for %s canceled.", strna(d.name));
1826 else if (streq(d.result, "dependency"))
1827 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1828 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1829 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1832 if (streq_ptr(d.result, "timeout"))
1834 else if (streq_ptr(d.result, "canceled"))
1836 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1847 return sd_bus_remove_filter(bus, wait_filter, &d);
1850 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1851 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1852 _cleanup_free_ char *n = NULL, *state = NULL;
1858 n = unit_name_mangle(name);
1862 /* We don't use unit_dbus_path_from_name() directly since we
1863 * don't want to load the unit if it isn't loaded. */
1865 r = sd_bus_call_method(
1867 "org.freedesktop.systemd1",
1868 "/org/freedesktop/systemd1",
1869 "org.freedesktop.systemd1.Manager",
1880 r = sd_bus_message_read(reply, "o", &path);
1882 return bus_log_parse_error(r);
1884 r = sd_bus_get_property_string(
1886 "org.freedesktop.systemd1",
1888 "org.freedesktop.systemd1.Unit",
1901 return nulstr_contains(good_states, state);
1904 static int check_triggering_units(
1908 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1909 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1910 _cleanup_strv_free_ char **triggered_by = NULL;
1911 bool print_warning_label = true;
1915 n = unit_name_mangle(name);
1919 path = unit_dbus_path_from_name(n);
1923 r = sd_bus_get_property_string(
1925 "org.freedesktop.systemd1",
1927 "org.freedesktop.systemd1.Unit",
1932 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1936 if (streq(state, "masked"))
1939 r = sd_bus_get_property_strv(
1941 "org.freedesktop.systemd1",
1943 "org.freedesktop.systemd1.Unit",
1948 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1952 STRV_FOREACH(i, triggered_by) {
1953 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1955 log_error("Failed to check unit: %s", strerror(-r));
1962 if (print_warning_label) {
1963 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1964 print_warning_label = false;
1967 log_warning(" %s", *i);
1973 static int start_unit_one(
1978 sd_bus_error *error,
1981 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1982 _cleanup_free_ char *n;
1991 n = unit_name_mangle(name);
1995 r = sd_bus_call_method(
1997 "org.freedesktop.systemd1",
1998 "/org/freedesktop/systemd1",
1999 "org.freedesktop.systemd1.Manager",
2005 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2006 /* There's always a fallback possible for
2007 * legacy actions. */
2008 return -EADDRNOTAVAIL;
2010 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
2014 r = sd_bus_message_read(reply, "o", &path);
2016 return bus_log_parse_error(r);
2018 if (need_daemon_reload(bus, n) > 0)
2019 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2020 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2029 r = set_consume(s, p);
2037 static const struct {
2041 } action_table[_ACTION_MAX] = {
2042 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2043 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2044 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2045 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2046 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2047 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2048 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2049 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2050 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2051 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2052 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2053 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2054 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2055 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2056 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2059 static enum action verb_to_action(const char *verb) {
2062 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2063 if (streq_ptr(action_table[i].verb, verb))
2066 return _ACTION_INVALID;
2069 static int start_unit(sd_bus *bus, char **args) {
2070 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2071 _cleanup_set_free_free_ Set *s = NULL;
2072 const char *method, *mode, *one_name;
2078 ask_password_agent_open_if_enabled();
2080 if (arg_action == ACTION_SYSTEMCTL) {
2083 streq(args[0], "stop") ||
2084 streq(args[0], "condstop") ? "StopUnit" :
2085 streq(args[0], "reload") ? "ReloadUnit" :
2086 streq(args[0], "restart") ? "RestartUnit" :
2088 streq(args[0], "try-restart") ||
2089 streq(args[0], "condrestart") ? "TryRestartUnit" :
2091 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2093 streq(args[0], "reload-or-try-restart") ||
2094 streq(args[0], "condreload") ||
2095 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2097 action = verb_to_action(args[0]);
2099 mode = streq(args[0], "isolate") ? "isolate" :
2100 action_table[action].mode ?: arg_job_mode;
2102 one_name = action_table[action].target;
2104 assert(arg_action < ELEMENTSOF(action_table));
2105 assert(action_table[arg_action].target);
2107 method = "StartUnit";
2109 mode = action_table[arg_action].mode;
2110 one_name = action_table[arg_action].target;
2113 if (!arg_no_block) {
2114 r = enable_wait_for_jobs(bus);
2116 log_error("Could not watch jobs: %s", strerror(-r));
2120 s = set_new(string_hash_func, string_compare_func);
2126 r = start_unit_one(bus, method, one_name, mode, &error, s);
2128 r = translate_bus_error_to_exit_status(r, &error);
2132 STRV_FOREACH(name, args+1) {
2135 q = start_unit_one(bus, method, *name, mode, &error, s);
2137 r = translate_bus_error_to_exit_status(r, &error);
2138 sd_bus_error_free(&error);
2143 if (!arg_no_block) {
2146 q = wait_for_jobs(bus, s);
2150 /* When stopping units, warn if they can still be triggered by
2151 * another active unit (socket, path, timer) */
2152 if (!arg_quiet && streq(method, "StopUnit")) {
2154 check_triggering_units(bus, one_name);
2156 STRV_FOREACH(name, args+1)
2157 check_triggering_units(bus, *name);
2164 /* Ask systemd-logind, which might grant access to unprivileged users
2165 * through PolicyKit */
2166 static int reboot_with_logind(sd_bus *bus, enum action a) {
2168 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2175 polkit_agent_open_if_enabled();
2183 case ACTION_POWEROFF:
2184 method = "PowerOff";
2187 case ACTION_SUSPEND:
2191 case ACTION_HIBERNATE:
2192 method = "Hibernate";
2195 case ACTION_HYBRID_SLEEP:
2196 method = "HybridSleep";
2203 r = sd_bus_call_method(
2205 "org.freedesktop.login1",
2206 "/org/freedesktop/login1",
2207 "org.freedesktop.login1.Manager",
2213 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2221 static int check_inhibitors(sd_bus *bus, enum action a) {
2223 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2224 _cleanup_strv_free_ char **sessions = NULL;
2225 const char *what, *who, *why, *mode;
2234 if (arg_ignore_inhibitors || arg_force > 0)
2246 r = sd_bus_call_method(
2248 "org.freedesktop.login1",
2249 "/org/freedesktop/login1",
2250 "org.freedesktop.login1.Manager",
2256 /* If logind is not around, then there are no inhibitors... */
2259 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2261 return bus_log_parse_error(r);
2263 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2264 _cleanup_free_ char *comm = NULL, *user = NULL;
2265 _cleanup_strv_free_ char **sv = NULL;
2267 if (!streq(mode, "block"))
2270 sv = strv_split(what, ":");
2274 if (!strv_contains(sv,
2276 a == ACTION_POWEROFF ||
2277 a == ACTION_REBOOT ||
2278 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2281 get_process_comm(pid, &comm);
2282 user = uid_to_name(uid);
2284 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2285 who, (unsigned long) pid, strna(comm), strna(user), why);
2290 return bus_log_parse_error(r);
2292 r = sd_bus_message_exit_container(reply);
2294 return bus_log_parse_error(r);
2296 /* Check for current sessions */
2297 sd_get_sessions(&sessions);
2298 STRV_FOREACH(s, sessions) {
2299 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2301 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2304 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2307 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2310 sd_session_get_tty(*s, &tty);
2311 sd_session_get_seat(*s, &seat);
2312 sd_session_get_service(*s, &service);
2313 user = uid_to_name(uid);
2315 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2322 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2323 action_table[a].verb);
2331 static int start_special(sd_bus *bus, char **args) {
2337 a = verb_to_action(args[0]);
2339 r = check_inhibitors(bus, a);
2343 if (arg_force >= 2 && geteuid() != 0) {
2344 log_error("Must be root.");
2348 if (arg_force >= 2 &&
2349 (a == ACTION_HALT ||
2350 a == ACTION_POWEROFF ||
2351 a == ACTION_REBOOT))
2354 if (arg_force >= 1 &&
2355 (a == ACTION_HALT ||
2356 a == ACTION_POWEROFF ||
2357 a == ACTION_REBOOT ||
2358 a == ACTION_KEXEC ||
2360 return daemon_reload(bus, args);
2362 /* first try logind, to allow authentication with polkit */
2363 if (geteuid() != 0 &&
2364 (a == ACTION_POWEROFF ||
2365 a == ACTION_REBOOT ||
2366 a == ACTION_SUSPEND ||
2367 a == ACTION_HIBERNATE ||
2368 a == ACTION_HYBRID_SLEEP)) {
2369 r = reboot_with_logind(bus, a);
2374 r = start_unit(bus, args);
2375 if (r == EXIT_SUCCESS)
2381 static int check_unit_active(sd_bus *bus, char **args) {
2383 int r = 3; /* According to LSB: "program is not running" */
2388 STRV_FOREACH(name, args+1) {
2391 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2401 static int check_unit_failed(sd_bus *bus, char **args) {
2408 STRV_FOREACH(name, args+1) {
2411 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2421 static int kill_unit(sd_bus *bus, char **args) {
2422 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2430 arg_kill_who = "all";
2432 STRV_FOREACH(name, args+1) {
2433 _cleanup_free_ char *n = NULL;
2435 n = unit_name_mangle(*name);
2439 r = sd_bus_call_method(
2441 "org.freedesktop.systemd1",
2442 "/org/freedesktop/systemd1",
2443 "org.freedesktop.systemd1.Manager",
2447 "ssi", n, arg_kill_who, arg_signal);
2449 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2457 typedef struct ExecStatusInfo {
2465 usec_t start_timestamp;
2466 usec_t exit_timestamp;
2471 LIST_FIELDS(struct ExecStatusInfo, exec);
2474 static void exec_status_info_free(ExecStatusInfo *i) {
2483 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2484 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2487 int32_t code, status;
2493 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2495 return bus_log_parse_error(r);
2499 r = sd_bus_message_read(m, "s", &path);
2501 return bus_log_parse_error(r);
2503 i->path = strdup(path);
2507 r = sd_bus_message_read_strv(m, &i->argv);
2509 return bus_log_parse_error(r);
2511 r = sd_bus_message_read(m,
2514 &start_timestamp, &start_timestamp_monotonic,
2515 &exit_timestamp, &exit_timestamp_monotonic,
2519 return bus_log_parse_error(r);
2522 i->start_timestamp = (usec_t) start_timestamp;
2523 i->exit_timestamp = (usec_t) exit_timestamp;
2524 i->pid = (pid_t) pid;
2528 r = sd_bus_message_exit_container(m);
2530 return bus_log_parse_error(r);
2535 typedef struct UnitStatusInfo {
2537 const char *load_state;
2538 const char *active_state;
2539 const char *sub_state;
2540 const char *unit_file_state;
2542 const char *description;
2543 const char *following;
2545 char **documentation;
2547 const char *fragment_path;
2548 const char *source_path;
2549 const char *control_group;
2551 char **dropin_paths;
2553 const char *load_error;
2556 usec_t inactive_exit_timestamp;
2557 usec_t inactive_exit_timestamp_monotonic;
2558 usec_t active_enter_timestamp;
2559 usec_t active_exit_timestamp;
2560 usec_t inactive_enter_timestamp;
2562 bool need_daemon_reload;
2567 const char *status_text;
2568 const char *pid_file;
2571 usec_t start_timestamp;
2572 usec_t exit_timestamp;
2574 int exit_code, exit_status;
2576 usec_t condition_timestamp;
2577 bool condition_result;
2578 bool failed_condition_trigger;
2579 bool failed_condition_negate;
2580 const char *failed_condition;
2581 const char *failed_condition_param;
2584 unsigned n_accepted;
2585 unsigned n_connections;
2588 /* Pairs of type, path */
2592 const char *sysfs_path;
2594 /* Mount, Automount */
2600 LIST_HEAD(ExecStatusInfo, exec);
2603 static void print_status_info(
2608 const char *on, *off, *ss;
2610 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2611 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2614 arg_all * OUTPUT_SHOW_ALL |
2615 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2616 on_tty() * OUTPUT_COLOR |
2617 !arg_quiet * OUTPUT_WARN_CUTOFF |
2618 arg_full * OUTPUT_FULL_WIDTH;
2623 /* This shows pretty information about a unit. See
2624 * print_property() for a low-level property printer */
2626 printf("%s", strna(i->id));
2628 if (i->description && !streq_ptr(i->id, i->description))
2629 printf(" - %s", i->description);
2634 printf(" Follow: unit currently follows state of %s\n", i->following);
2636 if (streq_ptr(i->load_state, "error")) {
2637 on = ansi_highlight_red();
2638 off = ansi_highlight_off();
2642 path = i->source_path ? i->source_path : i->fragment_path;
2645 printf(" Loaded: %s%s%s (Reason: %s)\n",
2646 on, strna(i->load_state), off, i->load_error);
2647 else if (path && i->unit_file_state)
2648 printf(" Loaded: %s%s%s (%s; %s)\n",
2649 on, strna(i->load_state), off, path, i->unit_file_state);
2651 printf(" Loaded: %s%s%s (%s)\n",
2652 on, strna(i->load_state), off, path);
2654 printf(" Loaded: %s%s%s\n",
2655 on, strna(i->load_state), off);
2657 if (!strv_isempty(i->dropin_paths)) {
2658 _cleanup_free_ char *dir = NULL;
2662 STRV_FOREACH(dropin, i->dropin_paths) {
2663 if (! dir || last) {
2664 printf(dir ? " " : " Drop-In: ");
2669 if (path_get_parent(*dropin, &dir) < 0) {
2674 printf("%s\n %s", dir,
2675 draw_special_char(DRAW_TREE_RIGHT));
2678 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2680 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2684 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2686 if (streq_ptr(i->active_state, "failed")) {
2687 on = ansi_highlight_red();
2688 off = ansi_highlight_off();
2689 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2690 on = ansi_highlight_green();
2691 off = ansi_highlight_off();
2696 printf(" Active: %s%s (%s)%s",
2697 on, strna(i->active_state), ss, off);
2699 printf(" Active: %s%s%s",
2700 on, strna(i->active_state), off);
2702 if (!isempty(i->result) && !streq(i->result, "success"))
2703 printf(" (Result: %s)", i->result);
2705 timestamp = (streq_ptr(i->active_state, "active") ||
2706 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2707 (streq_ptr(i->active_state, "inactive") ||
2708 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2709 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2710 i->active_exit_timestamp;
2712 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2713 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2716 printf(" since %s; %s\n", s2, s1);
2718 printf(" since %s\n", s2);
2722 if (!i->condition_result && i->condition_timestamp > 0) {
2723 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2724 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2726 printf(" start condition failed at %s%s%s\n",
2727 s2, s1 ? "; " : "", s1 ? s1 : "");
2728 if (i->failed_condition_trigger)
2729 printf(" none of the trigger conditions were met\n");
2730 else if (i->failed_condition)
2731 printf(" %s=%s%s was not met\n",
2732 i->failed_condition,
2733 i->failed_condition_negate ? "!" : "",
2734 i->failed_condition_param);
2738 printf(" Device: %s\n", i->sysfs_path);
2740 printf(" Where: %s\n", i->where);
2742 printf(" What: %s\n", i->what);
2744 STRV_FOREACH(t, i->documentation)
2745 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2747 STRV_FOREACH_PAIR(t, t2, i->listen)
2748 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2751 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2753 LIST_FOREACH(exec, p, i->exec) {
2754 _cleanup_free_ char *argv = NULL;
2757 /* Only show exited processes here */
2761 argv = strv_join(p->argv, " ");
2762 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2764 good = is_clean_exit_lsb(p->code, p->status, NULL);
2766 on = ansi_highlight_red();
2767 off = ansi_highlight_off();
2771 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2773 if (p->code == CLD_EXITED) {
2776 printf("status=%i", p->status);
2778 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2783 printf("signal=%s", signal_to_string(p->status));
2785 printf(")%s\n", off);
2787 if (i->main_pid == p->pid &&
2788 i->start_timestamp == p->start_timestamp &&
2789 i->exit_timestamp == p->start_timestamp)
2790 /* Let's not show this twice */
2793 if (p->pid == i->control_pid)
2797 if (i->main_pid > 0 || i->control_pid > 0) {
2798 if (i->main_pid > 0) {
2799 printf(" Main PID: %u", (unsigned) i->main_pid);
2802 _cleanup_free_ char *comm = NULL;
2803 get_process_comm(i->main_pid, &comm);
2805 printf(" (%s)", comm);
2806 } else if (i->exit_code > 0) {
2807 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2809 if (i->exit_code == CLD_EXITED) {
2812 printf("status=%i", i->exit_status);
2814 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2819 printf("signal=%s", signal_to_string(i->exit_status));
2823 if (i->control_pid > 0)
2827 if (i->control_pid > 0) {
2828 _cleanup_free_ char *c = NULL;
2830 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2832 get_process_comm(i->control_pid, &c);
2841 printf(" Status: \"%s\"\n", i->status_text);
2843 if (i->control_group &&
2844 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2847 printf(" CGroup: %s\n", i->control_group);
2849 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2852 char prefix[] = " ";
2855 if (c > sizeof(prefix) - 1)
2856 c -= sizeof(prefix) - 1;
2860 if (i->main_pid > 0)
2861 extra[k++] = i->main_pid;
2863 if (i->control_pid > 0)
2864 extra[k++] = i->control_pid;
2866 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2867 c, false, extra, k, flags);
2871 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2873 show_journal_by_unit(stdout,
2877 i->inactive_exit_timestamp_monotonic,
2881 arg_scope == UNIT_FILE_SYSTEM,
2885 if (i->need_daemon_reload)
2886 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2887 ansi_highlight_red(),
2888 ansi_highlight_off(),
2889 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2892 static void show_unit_help(UnitStatusInfo *i) {
2897 if (!i->documentation) {
2898 log_info("Documentation for %s not known.", i->id);
2902 STRV_FOREACH(p, i->documentation) {
2904 if (startswith(*p, "man:")) {
2905 const char *args[4] = { "man", NULL, NULL, NULL };
2906 _cleanup_free_ char *page = NULL, *section = NULL;
2913 if ((*p)[k-1] == ')')
2914 e = strrchr(*p, '(');
2917 page = strndup((*p) + 4, e - *p - 4);
2918 section = strndup(e + 1, *p + k - e - 2);
2919 if (!page || !section) {
2931 log_error("Failed to fork: %m");
2937 execvp(args[0], (char**) args);
2938 log_error("Failed to execute man: %m");
2939 _exit(EXIT_FAILURE);
2942 wait_for_terminate(pid, NULL);
2944 log_info("Can't show: %s", *p);
2948 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2955 switch (contents[0]) {
2957 case SD_BUS_TYPE_STRING: {
2960 r = sd_bus_message_read(m, "s", &s);
2962 return bus_log_parse_error(r);
2965 if (streq(name, "Id"))
2967 else if (streq(name, "LoadState"))
2969 else if (streq(name, "ActiveState"))
2970 i->active_state = s;
2971 else if (streq(name, "SubState"))
2973 else if (streq(name, "Description"))
2975 else if (streq(name, "FragmentPath"))
2976 i->fragment_path = s;
2977 else if (streq(name, "SourcePath"))
2980 else if (streq(name, "DefaultControlGroup")) {
2982 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2984 i->control_group = e;
2987 else if (streq(name, "ControlGroup"))
2988 i->control_group = s;
2989 else if (streq(name, "StatusText"))
2991 else if (streq(name, "PIDFile"))
2993 else if (streq(name, "SysFSPath"))
2995 else if (streq(name, "Where"))
2997 else if (streq(name, "What"))
2999 else if (streq(name, "Following"))
3001 else if (streq(name, "UnitFileState"))
3002 i->unit_file_state = s;
3003 else if (streq(name, "Result"))
3010 case SD_BUS_TYPE_BOOLEAN: {
3013 r = sd_bus_message_read(m, "b", &b);
3015 return bus_log_parse_error(r);
3017 if (streq(name, "Accept"))
3019 else if (streq(name, "NeedDaemonReload"))
3020 i->need_daemon_reload = b;
3021 else if (streq(name, "ConditionResult"))
3022 i->condition_result = b;
3027 case SD_BUS_TYPE_UINT32: {
3030 r = sd_bus_message_read(m, "u", &u);
3032 return bus_log_parse_error(r);
3034 if (streq(name, "MainPID")) {
3036 i->main_pid = (pid_t) u;
3039 } else if (streq(name, "ControlPID"))
3040 i->control_pid = (pid_t) u;
3041 else if (streq(name, "ExecMainPID")) {
3043 i->main_pid = (pid_t) u;
3044 } else if (streq(name, "NAccepted"))
3046 else if (streq(name, "NConnections"))
3047 i->n_connections = u;
3052 case SD_BUS_TYPE_INT32: {
3055 r = sd_bus_message_read(m, "i", &j);
3057 return bus_log_parse_error(r);
3059 if (streq(name, "ExecMainCode"))
3060 i->exit_code = (int) j;
3061 else if (streq(name, "ExecMainStatus"))
3062 i->exit_status = (int) j;
3067 case SD_BUS_TYPE_UINT64: {
3070 r = sd_bus_message_read(m, "t", &u);
3072 return bus_log_parse_error(r);
3074 if (streq(name, "ExecMainStartTimestamp"))
3075 i->start_timestamp = (usec_t) u;
3076 else if (streq(name, "ExecMainExitTimestamp"))
3077 i->exit_timestamp = (usec_t) u;
3078 else if (streq(name, "ActiveEnterTimestamp"))
3079 i->active_enter_timestamp = (usec_t) u;
3080 else if (streq(name, "InactiveEnterTimestamp"))
3081 i->inactive_enter_timestamp = (usec_t) u;
3082 else if (streq(name, "InactiveExitTimestamp"))
3083 i->inactive_exit_timestamp = (usec_t) u;
3084 else if (streq(name, "InactiveExitTimestampMonotonic"))
3085 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3086 else if (streq(name, "ActiveExitTimestamp"))
3087 i->active_exit_timestamp = (usec_t) u;
3088 else if (streq(name, "ConditionTimestamp"))
3089 i->condition_timestamp = (usec_t) u;
3094 case SD_BUS_TYPE_ARRAY:
3096 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3097 _cleanup_free_ ExecStatusInfo *info = NULL;
3099 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3101 return bus_log_parse_error(r);
3103 info = new0(ExecStatusInfo, 1);
3107 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3109 info->name = strdup(name);
3113 LIST_PREPEND(exec, i->exec, info);
3115 info = new0(ExecStatusInfo, 1);
3121 return bus_log_parse_error(r);
3123 r = sd_bus_message_exit_container(m);
3125 return bus_log_parse_error(r);
3129 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3130 const char *type, *path;
3132 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3134 return bus_log_parse_error(r);
3136 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3138 r = strv_extend(&i->listen, type);
3142 r = strv_extend(&i->listen, path);
3147 return bus_log_parse_error(r);
3149 r = sd_bus_message_exit_container(m);
3151 return bus_log_parse_error(r);
3155 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3157 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3159 return bus_log_parse_error(r);
3161 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3163 r = sd_bus_message_read_strv(m, &i->documentation);
3165 return bus_log_parse_error(r);
3167 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3168 const char *cond, *param;
3169 int trigger, negate;
3172 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3174 return bus_log_parse_error(r);
3176 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3177 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3178 if (state < 0 && (!trigger || !i->failed_condition)) {
3179 i->failed_condition = cond;
3180 i->failed_condition_trigger = trigger;
3181 i->failed_condition_negate = negate;
3182 i->failed_condition_param = param;
3186 return bus_log_parse_error(r);
3188 r = sd_bus_message_exit_container(m);
3190 return bus_log_parse_error(r);
3197 case SD_BUS_TYPE_STRUCT_BEGIN:
3199 if (streq(name, "LoadError")) {
3200 const char *n, *message;
3202 r = sd_bus_message_read(m, "(ss)", &n, &message);
3204 return bus_log_parse_error(r);
3206 if (!isempty(message))
3207 i->load_error = message;
3220 r = sd_bus_message_skip(m, contents);
3222 return bus_log_parse_error(r);
3227 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3233 /* This is a low-level property printer, see
3234 * print_status_info() for the nicer output */
3236 if (arg_properties && !strv_find(arg_properties, name)) {
3237 /* skip what we didn't read */
3238 r = sd_bus_message_skip(m, contents);
3242 switch (contents[0]) {
3244 case SD_BUS_TYPE_STRUCT_BEGIN:
3246 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3249 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3251 return bus_log_parse_error(r);
3254 printf("%s=%u\n", name, (unsigned) u);
3256 printf("%s=\n", name);
3260 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3263 r = sd_bus_message_read(m, "(so)", &s, NULL);
3265 return bus_log_parse_error(r);
3267 if (arg_all || !isempty(s))
3268 printf("%s=%s\n", name, s);
3272 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3273 const char *a = NULL, *b = NULL;
3275 r = sd_bus_message_read(m, "(ss)", &a, &b);
3277 return bus_log_parse_error(r);
3279 if (arg_all || !isempty(a) || !isempty(b))
3280 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3287 case SD_BUS_TYPE_ARRAY:
3289 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3293 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3295 return bus_log_parse_error(r);
3297 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3298 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3301 return bus_log_parse_error(r);
3303 r = sd_bus_message_exit_container(m);
3305 return bus_log_parse_error(r);
3309 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3310 const char *type, *path;
3312 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3314 return bus_log_parse_error(r);
3316 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3317 printf("%s=%s\n", type, path);
3319 return bus_log_parse_error(r);
3321 r = sd_bus_message_exit_container(m);
3323 return bus_log_parse_error(r);
3327 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3328 const char *type, *path;
3330 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3332 return bus_log_parse_error(r);
3334 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3335 printf("Listen%s=%s\n", type, path);
3337 return bus_log_parse_error(r);
3339 r = sd_bus_message_exit_container(m);
3341 return bus_log_parse_error(r);
3345 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3347 uint64_t value, next_elapse;
3349 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3351 return bus_log_parse_error(r);
3353 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3354 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3356 printf("%s={ value=%s ; next_elapse=%s }\n",
3358 format_timespan(timespan1, sizeof(timespan1), value, 0),
3359 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3362 return bus_log_parse_error(r);
3364 r = sd_bus_message_exit_container(m);
3366 return bus_log_parse_error(r);
3370 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3371 ExecStatusInfo info = {};
3373 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3375 return bus_log_parse_error(r);
3377 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3378 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3379 _cleanup_free_ char *tt;
3381 tt = strv_join(info.argv, " ");
3383 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3387 yes_no(info.ignore),
3388 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3389 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3390 (unsigned) info. pid,
3391 sigchld_code_to_string(info.code),
3393 info.code == CLD_EXITED ? "" : "/",
3394 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3397 strv_free(info.argv);
3401 r = sd_bus_message_exit_container(m);
3403 return bus_log_parse_error(r);
3407 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3408 const char *path, *rwm;
3410 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3412 return bus_log_parse_error(r);
3414 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3415 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3417 return bus_log_parse_error(r);
3419 r = sd_bus_message_exit_container(m);
3421 return bus_log_parse_error(r);
3425 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3429 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3431 return bus_log_parse_error(r);
3433 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3434 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3436 return bus_log_parse_error(r);
3438 r = sd_bus_message_exit_container(m);
3440 return bus_log_parse_error(r);
3444 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3448 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3450 return bus_log_parse_error(r);
3452 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3453 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3455 return bus_log_parse_error(r);
3457 r = sd_bus_message_exit_container(m);
3459 return bus_log_parse_error(r);
3467 r = bus_print_property(name, m, arg_all);
3469 return bus_log_parse_error(r);
3472 r = sd_bus_message_skip(m, contents);
3474 return bus_log_parse_error(r);
3477 printf("%s=[unprintable]\n", name);
3483 static int show_one(
3487 bool show_properties,
3491 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3492 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3493 UnitStatusInfo info = {};
3500 r = sd_bus_call_method(
3502 "org.freedesktop.systemd1",
3504 "org.freedesktop.DBus.Properties",
3510 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3514 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3516 return bus_log_parse_error(r);
3523 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3524 const char *name, *contents;
3526 r = sd_bus_message_read(reply, "s", &name);
3528 return bus_log_parse_error(r);
3530 r = sd_bus_message_peek_type(reply, NULL, &contents);
3532 return bus_log_parse_error(r);
3534 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3536 return bus_log_parse_error(r);
3538 if (show_properties)
3539 r = print_property(name, reply, contents);
3541 r = status_property(name, reply, &info, contents);
3545 r = sd_bus_message_exit_container(reply);
3547 return bus_log_parse_error(r);
3549 r = sd_bus_message_exit_container(reply);
3551 return bus_log_parse_error(r);
3554 return bus_log_parse_error(r);
3556 r = sd_bus_message_exit_container(reply);
3558 return bus_log_parse_error(r);
3562 if (!show_properties) {
3563 if (streq(verb, "help"))
3564 show_unit_help(&info);
3566 print_status_info(&info, ellipsized);
3569 strv_free(info.documentation);
3570 strv_free(info.dropin_paths);
3571 strv_free(info.listen);
3573 if (!streq_ptr(info.active_state, "active") &&
3574 !streq_ptr(info.active_state, "reloading") &&
3575 streq(verb, "status")) {
3576 /* According to LSB: "program not running" */
3577 /* 0: program is running or service is OK
3578 * 1: program is dead and /var/run pid file exists
3579 * 2: program is dead and /var/lock lock file exists
3580 * 3: program is not running
3581 * 4: program or service status is unknown
3583 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3589 while ((p = info.exec)) {
3590 LIST_REMOVE(exec, info.exec, p);
3591 exec_status_info_free(p);
3597 static int show_one_by_pid(
3604 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3605 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3606 const char *path = NULL;
3609 r = sd_bus_call_method(
3611 "org.freedesktop.systemd1",
3612 "/org/freedesktop/systemd1",
3613 "org.freedesktop.systemd1.Manager",
3619 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3623 r = sd_bus_message_read(reply, "o", &path);
3625 return bus_log_parse_error(r);
3627 return show_one(verb, bus, path, false, new_line, ellipsized);
3630 static int show_all(
3633 bool show_properties,
3637 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3638 _cleanup_free_ UnitInfo *unit_infos = NULL;
3643 r = get_unit_list(bus, &reply, &unit_infos);
3649 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3651 for (u = unit_infos; u < unit_infos + c; u++) {
3652 _cleanup_free_ char *p = NULL;
3654 if (!output_show_unit(u))
3657 p = unit_dbus_path_from_name(u->id);
3661 printf("%s -> '%s'\n", u->id, p);
3663 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3671 static int show(sd_bus *bus, char **args) {
3673 bool show_properties, show_status, new_line = false;
3675 bool ellipsized = false;
3680 show_properties = streq(args[0], "show");
3681 show_status = streq(args[0], "status");
3683 if (show_properties)
3684 pager_open_if_enabled();
3686 /* If no argument is specified inspect the manager itself */
3688 if (show_properties && strv_length(args) <= 1)
3689 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3691 if (show_status && strv_length(args) <= 1)
3692 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3694 STRV_FOREACH(name, args+1) {
3697 if (safe_atou32(*name, &id) < 0) {
3698 _cleanup_free_ char *p = NULL, *n = NULL;
3699 /* Interpret as unit name */
3701 n = unit_name_mangle(*name);
3705 p = unit_dbus_path_from_name(n);
3709 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3713 } else if (show_properties) {
3714 _cleanup_free_ char *p = NULL;
3716 /* Interpret as job id */
3717 if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
3720 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3725 /* Interpret as PID */
3726 r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized);
3732 if (ellipsized && !arg_quiet)
3733 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3738 static int append_assignment(sd_bus_message *m, const char *assignment) {
3746 eq = strchr(assignment, '=');
3748 log_error("Not an assignment: %s", assignment);
3752 field = strndupa(assignment, eq - assignment);
3755 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3757 return bus_log_create_error(r);
3759 if (streq(field, "CPUAccounting") ||
3760 streq(field, "MemoryAccounting") ||
3761 streq(field, "BlockIOAccounting")) {
3763 r = parse_boolean(eq);
3765 log_error("Failed to parse boolean assignment %s.", assignment);
3769 r = sd_bus_message_append(m, "v", "b", r);
3771 } else if (streq(field, "MemoryLimit")) {
3774 r = parse_bytes(eq, &bytes);
3776 log_error("Failed to parse bytes specification %s", assignment);
3780 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3782 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3785 r = safe_atou64(eq, &u);
3787 log_error("Failed to parse %s value %s.", field, eq);
3791 r = sd_bus_message_append(m, "v", "t", u);
3793 } else if (streq(field, "DevicePolicy"))
3794 r = sd_bus_message_append(m, "v", "s", eq);
3796 else if (streq(field, "DeviceAllow")) {
3799 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3801 const char *path, *rwm;
3804 e = strchr(eq, ' ');
3806 path = strndupa(eq, e - eq);
3813 if (!path_startswith(path, "/dev")) {
3814 log_error("%s is not a device file in /dev.", path);
3818 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3821 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3824 r = sd_bus_message_append(m, "v", "a(st)", 0);
3826 const char *path, *bandwidth;
3830 e = strchr(eq, ' ');
3832 path = strndupa(eq, e - eq);
3835 log_error("Failed to parse %s value %s.", field, eq);
3839 if (!path_startswith(path, "/dev")) {
3840 log_error("%s is not a device file in /dev.", path);
3844 r = parse_bytes(bandwidth, &bytes);
3846 log_error("Failed to parse byte value %s.", bandwidth);
3850 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3853 } else if (streq(field, "BlockIODeviceWeight")) {
3856 r = sd_bus_message_append(m, "v", "a(st)", 0);
3858 const char *path, *weight;
3862 e = strchr(eq, ' ');
3864 path = strndupa(eq, e - eq);
3867 log_error("Failed to parse %s value %s.", field, eq);
3871 if (!path_startswith(path, "/dev")) {
3872 log_error("%s is not a device file in /dev.", path);
3876 r = safe_atou64(weight, &u);
3878 log_error("Failed to parse %s value %s.", field, weight);
3881 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3885 log_error("Unknown assignment %s.", assignment);
3890 return bus_log_create_error(r);
3895 static int set_property(sd_bus *bus, char **args) {
3896 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3897 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3898 _cleanup_free_ char *n = NULL;
3902 r = sd_bus_message_new_method_call(
3904 "org.freedesktop.systemd1",
3905 "/org/freedesktop/systemd1",
3906 "org.freedesktop.systemd1.Manager",
3907 "SetUnitProperties",
3910 return bus_log_create_error(r);
3912 n = unit_name_mangle(args[1]);
3916 r = sd_bus_message_append(m, "sb", n, arg_runtime);
3918 return bus_log_create_error(r);
3920 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
3922 return bus_log_create_error(r);
3924 STRV_FOREACH(i, args + 2) {
3925 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
3927 return bus_log_create_error(r);
3929 r = append_assignment(m, *i);
3933 r = sd_bus_message_close_container(m);
3935 return bus_log_create_error(r);
3938 r = sd_bus_message_close_container(m);
3940 return bus_log_create_error(r);
3942 r = sd_bus_call(bus, m, 0, &error, NULL);
3944 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
3951 static int snapshot(sd_bus *bus, char **args) {
3952 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3953 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3954 _cleanup_free_ char *n = NULL, *id = NULL;
3958 if (strv_length(args) > 1)
3959 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
3965 r = sd_bus_call_method(
3967 "org.freedesktop.systemd1",
3968 "/org/freedesktop/systemd1",
3969 "org.freedesktop.systemd1.Manager",
3975 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
3979 r = sd_bus_message_read(reply, "o", &path);
3981 return bus_log_parse_error(r);
3983 r = sd_bus_get_property_string(
3985 "org.freedesktop.systemd1",
3987 "org.freedesktop.systemd1.Unit",
3992 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4002 static int delete_snapshot(sd_bus *bus, char **args) {
4003 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4009 STRV_FOREACH(name, args+1) {
4010 _cleanup_free_ char *n = NULL;
4012 n = unit_name_mangle_with_suffix(*name, ".snapshot");
4016 r = sd_bus_call_method(
4018 "org.freedesktop.systemd1",
4019 "/org/freedesktop/systemd1",
4020 "org.freedesktop.systemd1.Manager",
4026 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
4034 static int daemon_reload(sd_bus *bus, char **args) {
4035 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4039 if (arg_action == ACTION_RELOAD)
4041 else if (arg_action == ACTION_REEXEC)
4042 method = "Reexecute";
4044 assert(arg_action == ACTION_SYSTEMCTL);
4047 streq(args[0], "clear-jobs") ||
4048 streq(args[0], "cancel") ? "ClearJobs" :
4049 streq(args[0], "daemon-reexec") ? "Reexecute" :
4050 streq(args[0], "reset-failed") ? "ResetFailed" :
4051 streq(args[0], "halt") ? "Halt" :
4052 streq(args[0], "poweroff") ? "PowerOff" :
4053 streq(args[0], "reboot") ? "Reboot" :
4054 streq(args[0], "kexec") ? "KExec" :
4055 streq(args[0], "exit") ? "Exit" :
4056 /* "daemon-reload" */ "Reload";
4059 r = sd_bus_call_method(
4061 "org.freedesktop.systemd1",
4062 "/org/freedesktop/systemd1",
4063 "org.freedesktop.systemd1.Manager",
4069 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4070 /* There's always a fallback possible for
4071 * legacy actions. */
4073 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4074 /* On reexecution, we expect a disconnect, not a
4078 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4080 return r < 0 ? r : 0;
4083 static int reset_failed(sd_bus *bus, char **args) {
4084 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4088 if (strv_length(args) <= 1)
4089 return daemon_reload(bus, args);
4091 STRV_FOREACH(name, args+1) {
4092 _cleanup_free_ char *n;
4094 n = unit_name_mangle(*name);
4098 r = sd_bus_call_method(
4100 "org.freedesktop.systemd1",
4101 "/org/freedesktop/systemd1",
4102 "org.freedesktop.systemd1.Manager",
4108 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4116 static int show_environment(sd_bus *bus, char **args) {
4117 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4118 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4122 pager_open_if_enabled();
4124 r = sd_bus_get_property(
4126 "org.freedesktop.systemd1",
4127 "/org/freedesktop/systemd1",
4128 "org.freedesktop.systemd1.Manager",
4134 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4138 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4140 return bus_log_parse_error(r);
4142 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4145 return bus_log_parse_error(r);
4147 r = sd_bus_message_exit_container(reply);
4149 return bus_log_parse_error(r);
4154 static int switch_root(sd_bus *bus, char **args) {
4155 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4156 _cleanup_free_ char *init = NULL;
4161 l = strv_length(args);
4162 if (l < 2 || l > 3) {
4163 log_error("Wrong number of arguments.");
4170 init = strdup(args[2]);
4172 parse_env_file("/proc/cmdline", WHITESPACE,
4183 log_debug("switching root - root: %s; init: %s", root, init);
4185 r = sd_bus_call_method(
4187 "org.freedesktop.systemd1",
4188 "/org/freedesktop/systemd1",
4189 "org.freedesktop.systemd1.Manager",
4195 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4202 static int set_environment(sd_bus *bus, char **args) {
4203 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4204 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4211 method = streq(args[0], "set-environment")
4213 : "UnsetEnvironment";
4215 r = sd_bus_message_new_method_call(
4217 "org.freedesktop.systemd1",
4218 "/org/freedesktop/systemd1",
4219 "org.freedesktop.systemd1.Manager",
4223 return bus_log_create_error(r);
4225 r = sd_bus_message_append_strv(m, args + 1);
4227 return bus_log_create_error(r);
4229 r = sd_bus_call(bus, m, 0, &error, NULL);
4231 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4238 static int enable_sysv_units(const char *verb, char **args) {
4241 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4242 unsigned f = 1, t = 1;
4243 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4245 if (arg_scope != UNIT_FILE_SYSTEM)
4248 if (!streq(verb, "enable") &&
4249 !streq(verb, "disable") &&
4250 !streq(verb, "is-enabled"))
4253 /* Processes all SysV units, and reshuffles the array so that
4254 * afterwards only the native units remain */
4256 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4261 for (f = 0; args[f]; f++) {
4263 _cleanup_free_ char *p = NULL, *q = NULL;
4264 bool found_native = false, found_sysv;
4266 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4274 if (!endswith(name, ".service"))
4277 if (path_is_absolute(name))
4280 STRV_FOREACH(k, paths.unit_path) {
4281 if (!isempty(arg_root))
4282 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4284 asprintf(&p, "%s/%s", *k, name);
4291 found_native = access(p, F_OK) >= 0;
4302 if (!isempty(arg_root))
4303 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4305 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4311 p[strlen(p) - sizeof(".service") + 1] = 0;
4312 found_sysv = access(p, F_OK) >= 0;
4317 /* Mark this entry, so that we don't try enabling it as native unit */
4318 args[f] = (char*) "";
4320 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4322 if (!isempty(arg_root))
4323 argv[c++] = q = strappend("--root=", arg_root);
4325 argv[c++] = path_get_file_name(p);
4327 streq(verb, "enable") ? "on" :
4328 streq(verb, "disable") ? "off" : "--level=5";
4331 l = strv_join((char**)argv, " ");
4337 log_info("Executing %s", l);
4342 log_error("Failed to fork: %m");
4345 } else if (pid == 0) {
4348 execv(argv[0], (char**) argv);
4349 _exit(EXIT_FAILURE);
4352 j = wait_for_terminate(pid, &status);
4354 log_error("Failed to wait for child: %s", strerror(-r));
4359 if (status.si_code == CLD_EXITED) {
4360 if (streq(verb, "is-enabled")) {
4361 if (status.si_status == 0) {
4370 } else if (status.si_status != 0) {
4381 /* Drop all SysV units */
4382 for (f = 0, t = 0; args[f]; f++) {
4384 if (isempty(args[f]))
4387 args[t++] = args[f];
4396 static int mangle_names(char **original_names, char ***mangled_names) {
4397 char **i, **l, **name;
4399 l = new(char*, strv_length(original_names) + 1);
4404 STRV_FOREACH(name, original_names) {
4406 /* When enabling units qualified path names are OK,
4407 * too, hence allow them explicitly. */
4412 *i = unit_name_mangle(*name);
4428 static int enable_unit(sd_bus *bus, char **args) {
4429 _cleanup_strv_free_ char **mangled_names = NULL;
4430 const char *verb = args[0];
4431 UnitFileChange *changes = NULL;
4432 unsigned n_changes = 0;
4433 int carries_install_info = -1;
4439 r = mangle_names(args+1, &mangled_names);
4443 r = enable_sysv_units(verb, mangled_names);
4447 if (!bus || avoid_bus()) {
4448 if (streq(verb, "enable")) {
4449 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4450 carries_install_info = r;
4451 } else if (streq(verb, "disable"))
4452 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4453 else if (streq(verb, "reenable")) {
4454 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4455 carries_install_info = r;
4456 } else if (streq(verb, "link"))
4457 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4458 else if (streq(verb, "preset")) {
4459 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4460 carries_install_info = r;
4461 } else if (streq(verb, "mask"))
4462 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4463 else if (streq(verb, "unmask"))
4464 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4466 assert_not_reached("Unknown verb");
4469 log_error("Operation failed: %s", strerror(-r));
4474 dump_unit_file_changes(changes, n_changes);
4478 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4479 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4480 int expect_carries_install_info = false;
4481 bool send_force = true;
4484 if (streq(verb, "enable")) {
4485 method = "EnableUnitFiles";
4486 expect_carries_install_info = true;
4487 } else if (streq(verb, "disable")) {
4488 method = "DisableUnitFiles";
4490 } else if (streq(verb, "reenable")) {
4491 method = "ReenableUnitFiles";
4492 expect_carries_install_info = true;
4493 } else if (streq(verb, "link"))
4494 method = "LinkUnitFiles";
4495 else if (streq(verb, "preset")) {
4496 method = "PresetUnitFiles";
4497 expect_carries_install_info = true;
4498 } else if (streq(verb, "mask"))
4499 method = "MaskUnitFiles";
4500 else if (streq(verb, "unmask")) {
4501 method = "UnmaskUnitFiles";
4504 assert_not_reached("Unknown verb");
4506 r = sd_bus_message_new_method_call(
4508 "org.freedesktop.systemd1",
4509 "/org/freedesktop/systemd1",
4510 "org.freedesktop.systemd1.Manager",
4514 return bus_log_create_error(r);
4516 r = sd_bus_message_append_strv(m, mangled_names);
4518 return bus_log_create_error(r);
4520 r = sd_bus_message_append(m, "b", arg_runtime);
4522 return bus_log_create_error(r);
4525 r = sd_bus_message_append(m, "b", arg_force);
4527 return bus_log_create_error(r);
4530 r = sd_bus_call(bus, m, 0, &error, &reply);
4532 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4536 if (expect_carries_install_info) {
4537 r = sd_bus_message_read(reply, "b", &carries_install_info);
4539 return bus_log_parse_error(r);
4542 r = deserialize_and_dump_unit_file_changes(m);
4546 /* Try to reload if enabeld */
4548 r = daemon_reload(bus, args);
4553 if (carries_install_info == 0)
4554 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4555 "using systemctl.\n"
4556 "Possible reasons for having this kind of units are:\n"
4557 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4558 " .wants/ or .requires/ directory.\n"
4559 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4560 " a requirement dependency on it.\n"
4561 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4562 " D-Bus, udev, scripted systemctl call, ...).\n");
4565 unit_file_changes_free(changes, n_changes);
4570 static int unit_is_enabled(sd_bus *bus, char **args) {
4572 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4573 _cleanup_strv_free_ char **mangled_names = NULL;
4578 r = mangle_names(args+1, &mangled_names);
4582 r = enable_sysv_units(args[0], mangled_names);
4588 if (!bus || avoid_bus()) {
4590 STRV_FOREACH(name, mangled_names) {
4591 UnitFileState state;
4593 state = unit_file_get_state(arg_scope, arg_root, *name);
4595 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4599 if (state == UNIT_FILE_ENABLED ||
4600 state == UNIT_FILE_ENABLED_RUNTIME ||
4601 state == UNIT_FILE_STATIC)
4605 puts(unit_file_state_to_string(state));
4609 STRV_FOREACH(name, mangled_names) {
4610 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4613 r = sd_bus_call_method(
4615 "org.freedesktop.systemd1",
4616 "/org/freedesktop/systemd1",
4617 "org.freedesktop.systemd1.Manager",
4623 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4627 r = sd_bus_message_read(reply, "s", &s);
4629 return bus_log_parse_error(r);
4631 if (streq(s, "enabled") ||
4632 streq(s, "enabled-runtime") ||
4644 static int systemctl_help(void) {
4646 pager_open_if_enabled();
4648 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4649 "Query or send control commands to the systemd manager.\n\n"
4650 " -h --help Show this help\n"
4651 " --version Show package version\n"
4652 " --system Connect to system manager\n"
4653 " --user Connect to user service manager\n"
4654 " -H --host=[USER@]HOST\n"
4655 " Operate on remote host\n"
4656 " -M --machine=CONTAINER\n"
4657 " Operate on local container\n"
4658 " -t --type=TYPE List only units of a particular type\n"
4659 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4660 " -p --property=NAME Show only properties by this name\n"
4661 " -a --all Show all loaded units/properties, including dead/empty\n"
4662 " ones. To list all units installed on the system, use\n"
4663 " the 'list-unit-files' command instead.\n"
4664 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4665 " -l --full Don't ellipsize unit names on output\n"
4666 " --fail When queueing a new job, fail if conflicting jobs are\n"
4668 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4670 " --ignore-dependencies\n"
4671 " When queueing a new job, ignore all its dependencies\n"
4672 " --show-types When showing sockets, explicitly show their type\n"
4673 " -i --ignore-inhibitors\n"
4674 " When shutting down or sleeping, ignore inhibitors\n"
4675 " --kill-who=WHO Who to send signal to\n"
4676 " -s --signal=SIGNAL Which signal to send\n"
4677 " -q --quiet Suppress output\n"
4678 " --no-block Do not wait until operation finished\n"
4679 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4680 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4682 " --no-legend Do not print a legend (column headers and hints)\n"
4683 " --no-pager Do not pipe output into a pager\n"
4684 " --no-ask-password\n"
4685 " Do not ask for system passwords\n"
4686 " --global Enable/disable unit files globally\n"
4687 " --runtime Enable unit files only temporarily until next reboot\n"
4688 " -f --force When enabling unit files, override existing symlinks\n"
4689 " When shutting down, execute action immediately\n"
4690 " --root=PATH Enable unit files in the specified root directory\n"
4691 " -n --lines=INTEGER Number of journal entries to show\n"
4692 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4693 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4695 " list-units List loaded units\n"
4696 " list-sockets List loaded sockets ordered by address\n"
4697 " list-timers List loaded timers ordered by next elapse\n"
4698 " start [NAME...] Start (activate) one or more units\n"
4699 " stop [NAME...] Stop (deactivate) one or more units\n"
4700 " reload [NAME...] Reload one or more units\n"
4701 " restart [NAME...] Start or restart one or more units\n"
4702 " try-restart [NAME...] Restart one or more units if active\n"
4703 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4704 " otherwise start or restart\n"
4705 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4706 " otherwise restart if active\n"
4707 " isolate [NAME] Start one unit and stop all others\n"
4708 " kill [NAME...] Send signal to processes of a unit\n"
4709 " is-active [NAME...] Check whether units are active\n"
4710 " is-failed [NAME...] Check whether units are failed\n"
4711 " status [NAME...|PID...] Show runtime status of one or more units\n"
4712 " show [NAME...|JOB...] Show properties of one or more\n"
4713 " units/jobs or the manager\n"
4714 " set-property [NAME] [ASSIGNMENT...]\n"
4715 " Sets one or more properties of a unit\n"
4716 " help [NAME...|PID...] Show manual for one or more units\n"
4717 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4719 " list-dependencies [NAME] Recursively show units which are required\n"
4720 " or wanted by this unit or by which this\n"
4721 " unit is required or wanted\n\n"
4722 "Unit File Commands:\n"
4723 " list-unit-files List installed unit files\n"
4724 " enable [NAME...] Enable one or more unit files\n"
4725 " disable [NAME...] Disable one or more unit files\n"
4726 " reenable [NAME...] Reenable one or more unit files\n"
4727 " preset [NAME...] Enable/disable one or more unit files\n"
4728 " based on preset configuration\n"
4729 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4730 " mask [NAME...] Mask one or more units\n"
4731 " unmask [NAME...] Unmask one or more units\n"
4732 " link [PATH...] Link one or more units files into\n"
4733 " the search path\n"
4734 " get-default Get the name of the default target\n"
4735 " set-default NAME Set the default target\n\n"
4737 " list-jobs List jobs\n"
4738 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4739 "Snapshot Commands:\n"
4740 " snapshot [NAME] Create a snapshot\n"
4741 " delete [NAME...] Remove one or more snapshots\n\n"
4742 "Environment Commands:\n"
4743 " show-environment Dump environment\n"
4744 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4745 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4746 "Manager Lifecycle Commands:\n"
4747 " daemon-reload Reload systemd manager configuration\n"
4748 " daemon-reexec Reexecute systemd manager\n\n"
4749 "System Commands:\n"
4750 " default Enter system default mode\n"
4751 " rescue Enter system rescue mode\n"
4752 " emergency Enter system emergency mode\n"
4753 " halt Shut down and halt the system\n"
4754 " poweroff Shut down and power-off the system\n"
4755 " reboot [ARG] Shut down and reboot the system\n"
4756 " kexec Shut down and reboot the system with kexec\n"
4757 " exit Request user instance exit\n"
4758 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4759 " suspend Suspend the system\n"
4760 " hibernate Hibernate the system\n"
4761 " hybrid-sleep Hibernate and suspend the system\n",
4762 program_invocation_short_name);
4767 static int halt_help(void) {
4769 printf("%s [OPTIONS...]%s\n\n"
4770 "%s the system.\n\n"
4771 " --help Show this help\n"
4772 " --halt Halt the machine\n"
4773 " -p --poweroff Switch off the machine\n"
4774 " --reboot Reboot the machine\n"
4775 " -f --force Force immediate halt/power-off/reboot\n"
4776 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4777 " -d --no-wtmp Don't write wtmp record\n"
4778 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4779 program_invocation_short_name,
4780 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4781 arg_action == ACTION_REBOOT ? "Reboot" :
4782 arg_action == ACTION_POWEROFF ? "Power off" :
4788 static int shutdown_help(void) {
4790 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4791 "Shut down the system.\n\n"
4792 " --help Show this help\n"
4793 " -H --halt Halt the machine\n"
4794 " -P --poweroff Power-off the machine\n"
4795 " -r --reboot Reboot the machine\n"
4796 " -h Equivalent to --poweroff, overridden by --halt\n"
4797 " -k Don't halt/power-off/reboot, just send warnings\n"
4798 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4799 " -c Cancel a pending shutdown\n",
4800 program_invocation_short_name);
4805 static int telinit_help(void) {
4807 printf("%s [OPTIONS...] {COMMAND}\n\n"
4808 "Send control commands to the init daemon.\n\n"
4809 " --help Show this help\n"
4810 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4812 " 0 Power-off the machine\n"
4813 " 6 Reboot the machine\n"
4814 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4815 " 1, s, S Enter rescue mode\n"
4816 " q, Q Reload init daemon configuration\n"
4817 " u, U Reexecute init daemon\n",
4818 program_invocation_short_name);
4823 static int runlevel_help(void) {
4825 printf("%s [OPTIONS...]\n\n"
4826 "Prints the previous and current runlevel of the init system.\n\n"
4827 " --help Show this help\n",
4828 program_invocation_short_name);
4833 static int help_types(void) {
4837 puts("Available unit types:");
4838 for(i = 0; i < _UNIT_TYPE_MAX; i++) {
4839 t = unit_type_to_string(i);
4847 static int systemctl_parse_argv(int argc, char *argv[]) {
4856 ARG_IGNORE_DEPENDENCIES,
4868 ARG_NO_ASK_PASSWORD,
4876 static const struct option options[] = {
4877 { "help", no_argument, NULL, 'h' },
4878 { "version", no_argument, NULL, ARG_VERSION },
4879 { "type", required_argument, NULL, 't' },
4880 { "property", required_argument, NULL, 'p' },
4881 { "all", no_argument, NULL, 'a' },
4882 { "reverse", no_argument, NULL, ARG_REVERSE },
4883 { "after", no_argument, NULL, ARG_AFTER },
4884 { "before", no_argument, NULL, ARG_BEFORE },
4885 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4886 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4887 { "full", no_argument, NULL, 'l' },
4888 { "fail", no_argument, NULL, ARG_FAIL },
4889 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
4890 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
4891 { "ignore-inhibitors", no_argument, NULL, 'i' },
4892 { "user", no_argument, NULL, ARG_USER },
4893 { "system", no_argument, NULL, ARG_SYSTEM },
4894 { "global", no_argument, NULL, ARG_GLOBAL },
4895 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4896 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4897 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4898 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4899 { "quiet", no_argument, NULL, 'q' },
4900 { "root", required_argument, NULL, ARG_ROOT },
4901 { "force", no_argument, NULL, ARG_FORCE },
4902 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4903 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4904 { "signal", required_argument, NULL, 's' },
4905 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4906 { "host", required_argument, NULL, 'H' },
4907 { "machine", required_argument, NULL, 'M' },
4908 { "runtime", no_argument, NULL, ARG_RUNTIME },
4909 { "lines", required_argument, NULL, 'n' },
4910 { "output", required_argument, NULL, 'o' },
4911 { "plain", no_argument, NULL, ARG_PLAIN },
4912 { "state", required_argument, NULL, ARG_STATE },
4921 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
4926 return systemctl_help();
4929 puts(PACKAGE_STRING);
4930 puts(SYSTEMD_FEATURES);
4937 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4938 _cleanup_free_ char *type;
4940 type = strndup(word, size);
4944 if (streq(type, "help")) {
4949 if (unit_type_from_string(type) >= 0) {
4950 if (strv_push(&arg_types, type))
4956 /* It's much nicer to use --state= for
4957 * load states, but let's support this
4958 * in --types= too for compatibility
4959 * with old versions */
4960 if (unit_load_state_from_string(optarg) >= 0) {
4961 if (strv_push(&arg_states, type) < 0)
4967 log_error("Unknown unit type or load state '%s'.", type);
4968 log_info("Use -t help to see a list of allowed values.");
4976 /* Make sure that if the empty property list
4977 was specified, we won't show any properties. */
4978 if (isempty(optarg) && !arg_properties) {
4979 arg_properties = new0(char*, 1);
4980 if (!arg_properties)
4986 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4989 prop = strndup(word, size);
4993 if (strv_push(&arg_properties, prop) < 0) {
5000 /* If the user asked for a particular
5001 * property, show it to him, even if it is
5013 arg_dependency = DEPENDENCY_REVERSE;
5017 arg_dependency = DEPENDENCY_AFTER;
5021 arg_dependency = DEPENDENCY_BEFORE;
5024 case ARG_SHOW_TYPES:
5025 arg_show_types = true;
5029 arg_job_mode = "fail";
5032 case ARG_IRREVERSIBLE:
5033 arg_job_mode = "replace-irreversibly";
5036 case ARG_IGNORE_DEPENDENCIES:
5037 arg_job_mode = "ignore-dependencies";
5041 arg_scope = UNIT_FILE_USER;
5045 arg_scope = UNIT_FILE_SYSTEM;
5049 arg_scope = UNIT_FILE_GLOBAL;
5053 arg_no_block = true;
5057 arg_no_legend = true;
5061 arg_no_pager = true;
5077 if (strv_extend(&arg_states, "failed") < 0)
5095 arg_no_reload = true;
5099 arg_kill_who = optarg;
5103 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5104 log_error("Failed to parse signal string %s.", optarg);
5109 case ARG_NO_ASK_PASSWORD:
5110 arg_ask_password = false;
5114 arg_transport = BUS_TRANSPORT_REMOTE;
5119 arg_transport = BUS_TRANSPORT_CONTAINER;
5128 if (safe_atou(optarg, &arg_lines) < 0) {
5129 log_error("Failed to parse lines '%s'", optarg);
5135 arg_output = output_mode_from_string(optarg);
5136 if (arg_output < 0) {
5137 log_error("Unknown output '%s'.", optarg);
5143 arg_ignore_inhibitors = true;
5154 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5157 s = strndup(word, size);
5161 if (strv_push(&arg_states, s) < 0) {
5173 assert_not_reached("Unhandled option");
5177 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5178 log_error("Cannot access user instance remotely.");
5185 static int halt_parse_argv(int argc, char *argv[]) {
5194 static const struct option options[] = {
5195 { "help", no_argument, NULL, ARG_HELP },
5196 { "halt", no_argument, NULL, ARG_HALT },
5197 { "poweroff", no_argument, NULL, 'p' },
5198 { "reboot", no_argument, NULL, ARG_REBOOT },
5199 { "force", no_argument, NULL, 'f' },
5200 { "wtmp-only", no_argument, NULL, 'w' },
5201 { "no-wtmp", no_argument, NULL, 'd' },
5202 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5211 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5212 if (runlevel == '0' || runlevel == '6')
5215 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5222 arg_action = ACTION_HALT;
5226 if (arg_action != ACTION_REBOOT)
5227 arg_action = ACTION_POWEROFF;
5231 arg_action = ACTION_REBOOT;
5253 /* Compatibility nops */
5260 assert_not_reached("Unhandled option");
5264 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5265 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5267 log_error("Failed to write reboot param to "
5268 REBOOT_PARAM_FILE": %s", strerror(-r));
5271 } else if (optind < argc) {
5272 log_error("Too many arguments.");
5279 static int parse_time_spec(const char *t, usec_t *_u) {
5283 if (streq(t, "now"))
5285 else if (!strchr(t, ':')) {
5288 if (safe_atou64(t, &u) < 0)
5291 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5300 hour = strtol(t, &e, 10);
5301 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5304 minute = strtol(e+1, &e, 10);
5305 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5308 n = now(CLOCK_REALTIME);
5309 s = (time_t) (n / USEC_PER_SEC);
5311 assert_se(localtime_r(&s, &tm));
5313 tm.tm_hour = (int) hour;
5314 tm.tm_min = (int) minute;
5317 assert_se(s = mktime(&tm));
5319 *_u = (usec_t) s * USEC_PER_SEC;
5322 *_u += USEC_PER_DAY;
5328 static int shutdown_parse_argv(int argc, char *argv[]) {
5335 static const struct option options[] = {
5336 { "help", no_argument, NULL, ARG_HELP },
5337 { "halt", no_argument, NULL, 'H' },
5338 { "poweroff", no_argument, NULL, 'P' },
5339 { "reboot", no_argument, NULL, 'r' },
5340 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5341 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5350 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5354 return shutdown_help();
5357 arg_action = ACTION_HALT;
5361 arg_action = ACTION_POWEROFF;
5366 arg_action = ACTION_KEXEC;
5368 arg_action = ACTION_REBOOT;
5372 arg_action = ACTION_KEXEC;
5376 if (arg_action != ACTION_HALT)
5377 arg_action = ACTION_POWEROFF;
5390 /* Compatibility nops */
5394 arg_action = ACTION_CANCEL_SHUTDOWN;
5401 assert_not_reached("Unhandled option");
5405 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5406 r = parse_time_spec(argv[optind], &arg_when);
5408 log_error("Failed to parse time specification: %s", argv[optind]);
5412 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5414 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5415 /* No time argument for shutdown cancel */
5416 arg_wall = argv + optind;
5417 else if (argc > optind + 1)
5418 /* We skip the time argument */
5419 arg_wall = argv + optind + 1;
5426 static int telinit_parse_argv(int argc, char *argv[]) {
5433 static const struct option options[] = {
5434 { "help", no_argument, NULL, ARG_HELP },
5435 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5439 static const struct {
5443 { '0', ACTION_POWEROFF },
5444 { '6', ACTION_REBOOT },
5445 { '1', ACTION_RESCUE },
5446 { '2', ACTION_RUNLEVEL2 },
5447 { '3', ACTION_RUNLEVEL3 },
5448 { '4', ACTION_RUNLEVEL4 },
5449 { '5', ACTION_RUNLEVEL5 },
5450 { 's', ACTION_RESCUE },
5451 { 'S', ACTION_RESCUE },
5452 { 'q', ACTION_RELOAD },
5453 { 'Q', ACTION_RELOAD },
5454 { 'u', ACTION_REEXEC },
5455 { 'U', ACTION_REEXEC }
5464 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5468 return telinit_help();
5478 assert_not_reached("Unhandled option");
5482 if (optind >= argc) {
5487 if (optind + 1 < argc) {
5488 log_error("Too many arguments.");
5492 if (strlen(argv[optind]) != 1) {
5493 log_error("Expected single character argument.");
5497 for (i = 0; i < ELEMENTSOF(table); i++)
5498 if (table[i].from == argv[optind][0])
5501 if (i >= ELEMENTSOF(table)) {
5502 log_error("Unknown command '%s'.", argv[optind]);
5506 arg_action = table[i].to;
5513 static int runlevel_parse_argv(int argc, char *argv[]) {
5519 static const struct option options[] = {
5520 { "help", no_argument, NULL, ARG_HELP },
5529 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5533 return runlevel_help();
5540 assert_not_reached("Unhandled option");
5544 if (optind < argc) {
5545 log_error("Too many arguments.");
5552 static int parse_argv(int argc, char *argv[]) {
5556 if (program_invocation_short_name) {
5558 if (strstr(program_invocation_short_name, "halt")) {
5559 arg_action = ACTION_HALT;
5560 return halt_parse_argv(argc, argv);
5561 } else if (strstr(program_invocation_short_name, "poweroff")) {
5562 arg_action = ACTION_POWEROFF;
5563 return halt_parse_argv(argc, argv);
5564 } else if (strstr(program_invocation_short_name, "reboot")) {
5566 arg_action = ACTION_KEXEC;
5568 arg_action = ACTION_REBOOT;
5569 return halt_parse_argv(argc, argv);
5570 } else if (strstr(program_invocation_short_name, "shutdown")) {
5571 arg_action = ACTION_POWEROFF;
5572 return shutdown_parse_argv(argc, argv);
5573 } else if (strstr(program_invocation_short_name, "init")) {
5575 if (sd_booted() > 0) {
5576 arg_action = _ACTION_INVALID;
5577 return telinit_parse_argv(argc, argv);
5579 /* Hmm, so some other init system is
5580 * running, we need to forward this
5581 * request to it. For now we simply
5582 * guess that it is Upstart. */
5584 execv(TELINIT, argv);
5586 log_error("Couldn't find an alternative telinit implementation to spawn.");
5590 } else if (strstr(program_invocation_short_name, "runlevel")) {
5591 arg_action = ACTION_RUNLEVEL;
5592 return runlevel_parse_argv(argc, argv);
5596 arg_action = ACTION_SYSTEMCTL;
5597 return systemctl_parse_argv(argc, argv);
5600 _pure_ static int action_to_runlevel(void) {
5602 static const char table[_ACTION_MAX] = {
5603 [ACTION_HALT] = '0',
5604 [ACTION_POWEROFF] = '0',
5605 [ACTION_REBOOT] = '6',
5606 [ACTION_RUNLEVEL2] = '2',
5607 [ACTION_RUNLEVEL3] = '3',
5608 [ACTION_RUNLEVEL4] = '4',
5609 [ACTION_RUNLEVEL5] = '5',
5610 [ACTION_RESCUE] = '1'
5613 assert(arg_action < _ACTION_MAX);
5615 return table[arg_action];
5618 static int talk_initctl(void) {
5620 struct init_request request = {
5621 .magic = INIT_MAGIC,
5623 .cmd = INIT_CMD_RUNLVL
5626 _cleanup_close_ int fd = -1;
5630 rl = action_to_runlevel();
5634 request.runlevel = rl;
5636 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5638 if (errno == ENOENT)
5641 log_error("Failed to open "INIT_FIFO": %m");
5646 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5648 log_error("Failed to write to "INIT_FIFO": %m");
5649 return errno > 0 ? -errno : -EIO;
5655 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5657 static const struct {
5665 int (* const dispatch)(sd_bus *bus, char **args);
5667 { "list-units", LESS, 1, list_units },
5668 { "list-unit-files", EQUAL, 1, list_unit_files },
5669 { "list-sockets", LESS, 1, list_sockets },
5670 { "list-timers", LESS, 1, list_timers },
5671 { "list-jobs", EQUAL, 1, list_jobs },
5672 { "clear-jobs", EQUAL, 1, daemon_reload },
5673 { "cancel", MORE, 2, cancel_job },
5674 { "start", MORE, 2, start_unit },
5675 { "stop", MORE, 2, start_unit },
5676 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5677 { "reload", MORE, 2, start_unit },
5678 { "restart", MORE, 2, start_unit },
5679 { "try-restart", MORE, 2, start_unit },
5680 { "reload-or-restart", MORE, 2, start_unit },
5681 { "reload-or-try-restart", MORE, 2, start_unit },
5682 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5683 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5684 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5685 { "isolate", EQUAL, 2, start_unit },
5686 { "kill", MORE, 2, kill_unit },
5687 { "is-active", MORE, 2, check_unit_active },
5688 { "check", MORE, 2, check_unit_active },
5689 { "is-failed", MORE, 2, check_unit_failed },
5690 { "show", MORE, 1, show },
5691 { "status", MORE, 1, show },
5692 { "help", MORE, 2, show },
5693 { "snapshot", LESS, 2, snapshot },
5694 { "delete", MORE, 2, delete_snapshot },
5695 { "daemon-reload", EQUAL, 1, daemon_reload },
5696 { "daemon-reexec", EQUAL, 1, daemon_reload },
5697 { "show-environment", EQUAL, 1, show_environment },
5698 { "set-environment", MORE, 2, set_environment },
5699 { "unset-environment", MORE, 2, set_environment },
5700 { "halt", EQUAL, 1, start_special },
5701 { "poweroff", EQUAL, 1, start_special },
5702 { "reboot", EQUAL, 1, start_special },
5703 { "kexec", EQUAL, 1, start_special },
5704 { "suspend", EQUAL, 1, start_special },
5705 { "hibernate", EQUAL, 1, start_special },
5706 { "hybrid-sleep", EQUAL, 1, start_special },
5707 { "default", EQUAL, 1, start_special },
5708 { "rescue", EQUAL, 1, start_special },
5709 { "emergency", EQUAL, 1, start_special },
5710 { "exit", EQUAL, 1, start_special },
5711 { "reset-failed", MORE, 1, reset_failed },
5712 { "enable", MORE, 2, enable_unit },
5713 { "disable", MORE, 2, enable_unit },
5714 { "is-enabled", MORE, 2, unit_is_enabled },
5715 { "reenable", MORE, 2, enable_unit },
5716 { "preset", MORE, 2, enable_unit },
5717 { "mask", MORE, 2, enable_unit },
5718 { "unmask", MORE, 2, enable_unit },
5719 { "link", MORE, 2, enable_unit },
5720 { "switch-root", MORE, 2, switch_root },
5721 { "list-dependencies", LESS, 2, list_dependencies },
5722 { "set-default", EQUAL, 2, set_default },
5723 { "get-default", EQUAL, 1, get_default },
5724 { "set-property", MORE, 3, set_property },
5733 left = argc - optind;
5736 /* Special rule: no arguments means "list-units" */
5739 if (streq(argv[optind], "help") && !argv[optind+1]) {
5740 log_error("This command expects one or more "
5741 "unit names. Did you mean --help?");
5745 for (i = 0; i < ELEMENTSOF(verbs); i++)
5746 if (streq(argv[optind], verbs[i].verb))
5749 if (i >= ELEMENTSOF(verbs)) {
5750 log_error("Unknown operation '%s'.", argv[optind]);
5755 switch (verbs[i].argc_cmp) {
5758 if (left != verbs[i].argc) {
5759 log_error("Invalid number of arguments.");
5766 if (left < verbs[i].argc) {
5767 log_error("Too few arguments.");
5774 if (left > verbs[i].argc) {
5775 log_error("Too many arguments.");
5782 assert_not_reached("Unknown comparison operator.");
5785 /* Require a bus connection for all operations but
5787 if (!streq(verbs[i].verb, "enable") &&
5788 !streq(verbs[i].verb, "disable") &&
5789 !streq(verbs[i].verb, "is-enabled") &&
5790 !streq(verbs[i].verb, "list-unit-files") &&
5791 !streq(verbs[i].verb, "reenable") &&
5792 !streq(verbs[i].verb, "preset") &&
5793 !streq(verbs[i].verb, "mask") &&
5794 !streq(verbs[i].verb, "unmask") &&
5795 !streq(verbs[i].verb, "link") &&
5796 !streq(verbs[i].verb, "set-default") &&
5797 !streq(verbs[i].verb, "get-default")) {
5799 if (running_in_chroot() > 0) {
5800 log_info("Running in chroot, ignoring request.");
5804 if (((!streq(verbs[i].verb, "reboot") &&
5805 !streq(verbs[i].verb, "halt") &&
5806 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5807 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5813 if (!bus && !avoid_bus()) {
5814 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5819 return verbs[i].dispatch(bus, argv + optind);
5822 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5824 struct sd_shutdown_command c = {
5831 union sockaddr_union sockaddr = {
5832 .un.sun_family = AF_UNIX,
5833 .un.sun_path = "/run/systemd/shutdownd",
5836 struct iovec iovec[2] = {{
5837 .iov_base = (char*) &c,
5838 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5841 struct msghdr msghdr = {
5842 .msg_name = &sockaddr,
5843 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5844 + sizeof("/run/systemd/shutdownd") - 1,
5849 _cleanup_close_ int fd;
5851 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5855 if (!isempty(message)) {
5856 iovec[1].iov_base = (char*) message;
5857 iovec[1].iov_len = strlen(message);
5858 msghdr.msg_iovlen++;
5861 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5867 static int reload_with_fallback(sd_bus *bus) {
5870 /* First, try systemd via D-Bus. */
5871 if (daemon_reload(bus, NULL) >= 0)
5875 /* Nothing else worked, so let's try signals */
5876 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5878 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5879 log_error("kill() failed: %m");
5886 static int start_with_fallback(sd_bus *bus) {
5889 /* First, try systemd via D-Bus. */
5890 if (start_unit(bus, NULL) >= 0)
5894 /* Nothing else worked, so let's try
5896 if (talk_initctl() > 0)
5899 log_error("Failed to talk to init daemon.");
5903 warn_wall(arg_action);
5907 static int halt_now(enum action a) {
5909 /* Make sure C-A-D is handled by the kernel from this
5911 reboot(RB_ENABLE_CAD);
5916 log_info("Halting.");
5917 reboot(RB_HALT_SYSTEM);
5920 case ACTION_POWEROFF:
5921 log_info("Powering off.");
5922 reboot(RB_POWER_OFF);
5925 case ACTION_REBOOT: {
5926 _cleanup_free_ char *param = NULL;
5928 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
5929 log_info("Rebooting with argument '%s'.", param);
5930 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
5931 LINUX_REBOOT_CMD_RESTART2, param);
5934 log_info("Rebooting.");
5935 reboot(RB_AUTOBOOT);
5940 assert_not_reached("Unknown action.");
5944 static int halt_main(sd_bus *bus) {
5947 r = check_inhibitors(bus, arg_action);
5951 if (geteuid() != 0) {
5952 /* Try logind if we are a normal user and no special
5953 * mode applies. Maybe PolicyKit allows us to shutdown
5956 if (arg_when <= 0 &&
5959 (arg_action == ACTION_POWEROFF ||
5960 arg_action == ACTION_REBOOT)) {
5961 r = reboot_with_logind(bus, arg_action);
5966 log_error("Must be root.");
5971 _cleanup_free_ char *m;
5973 m = strv_join(arg_wall, " ");
5977 r = send_shutdownd(arg_when,
5978 arg_action == ACTION_HALT ? 'H' :
5979 arg_action == ACTION_POWEROFF ? 'P' :
5980 arg_action == ACTION_KEXEC ? 'K' :
5987 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
5989 char date[FORMAT_TIMESTAMP_MAX];
5991 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5992 format_timestamp(date, sizeof(date), arg_when));
5997 if (!arg_dry && !arg_force)
5998 return start_with_fallback(bus);
6001 if (sd_booted() > 0)
6002 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6004 r = utmp_put_shutdown();
6006 log_warning("Failed to write utmp record: %s", strerror(-r));
6013 r = halt_now(arg_action);
6014 log_error("Failed to reboot: %s", strerror(-r));
6019 static int runlevel_main(void) {
6020 int r, runlevel, previous;
6022 r = utmp_get_runlevel(&runlevel, &previous);
6029 previous <= 0 ? 'N' : previous,
6030 runlevel <= 0 ? 'N' : runlevel);
6035 int main(int argc, char*argv[]) {
6036 _cleanup_bus_unref_ sd_bus *bus = NULL;
6039 setlocale(LC_ALL, "");
6040 log_parse_environment();
6043 /* Explicitly not on_tty() to avoid setting cached value.
6044 * This becomes relevant for piping output which might be
6046 original_stdout_is_tty = isatty(STDOUT_FILENO);
6048 r = parse_argv(argc, argv);
6052 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6053 * let's shortcut this */
6054 if (arg_action == ACTION_RUNLEVEL) {
6055 r = runlevel_main();
6059 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
6060 log_info("Running in chroot, ignoring request.");
6066 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6068 /* systemctl_main() will print an error message for the bus
6069 * connection, but only if it needs to */
6071 switch (arg_action) {
6073 case ACTION_SYSTEMCTL:
6074 r = systemctl_main(bus, argc, argv, r);
6078 case ACTION_POWEROFF:
6084 case ACTION_RUNLEVEL2:
6085 case ACTION_RUNLEVEL3:
6086 case ACTION_RUNLEVEL4:
6087 case ACTION_RUNLEVEL5:
6089 case ACTION_EMERGENCY:
6090 case ACTION_DEFAULT:
6091 r = start_with_fallback(bus);
6096 r = reload_with_fallback(bus);
6099 case ACTION_CANCEL_SHUTDOWN: {
6100 _cleanup_free_ char *m = NULL;
6103 m = strv_join(arg_wall, " ");
6110 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6112 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6116 case ACTION_RUNLEVEL:
6117 case _ACTION_INVALID:
6119 assert_not_reached("Unknown action");
6124 ask_password_agent_close();
6125 polkit_agent_close();
6127 strv_free(arg_types);
6128 strv_free(arg_states);
6129 strv_free(arg_properties);
6131 return r < 0 ? EXIT_FAILURE : r;