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 "path-util.h"
69 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.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, 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);
1406 const char *name, *type, *state;
1409 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1410 unsigned id_len, unit_len, type_len, state_len;
1411 const struct job_info *j;
1412 const char *on, *off;
1413 bool shorten = false;
1415 assert(n == 0 || jobs);
1418 on = ansi_highlight_green();
1419 off = ansi_highlight_off();
1421 printf("%sNo jobs running.%s\n", on, off);
1425 pager_open_if_enabled();
1427 id_len = sizeof("JOB")-1;
1428 unit_len = sizeof("UNIT")-1;
1429 type_len = sizeof("TYPE")-1;
1430 state_len = sizeof("STATE")-1;
1432 for (j = jobs; j < jobs + n; j++) {
1433 uint32_t id = j->id;
1434 assert(j->name && j->type && j->state);
1436 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1437 unit_len = MAX(unit_len, strlen(j->name));
1438 type_len = MAX(type_len, strlen(j->type));
1439 state_len = MAX(state_len, strlen(j->state));
1442 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1443 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1448 printf("%*s %-*s %-*s %-*s\n",
1452 state_len, "STATE");
1454 for (j = jobs; j < jobs + n; j++) {
1455 _cleanup_free_ char *e = NULL;
1457 if (streq(j->state, "running")) {
1458 on = ansi_highlight();
1459 off = ansi_highlight_off();
1463 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1464 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1466 on, unit_len, e ? e : j->name, off,
1468 on, state_len, j->state, off);
1471 if (!arg_no_legend) {
1472 on = ansi_highlight();
1473 off = ansi_highlight_off();
1475 printf("\n%s%u jobs listed%s.\n", on, n, off);
1479 static int list_jobs(sd_bus *bus, char **args) {
1480 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1481 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1482 const char *name, *type, *state, *job_path, *unit_path;
1483 _cleanup_free_ struct job_info *jobs = NULL;
1489 r = sd_bus_call_method(
1491 "org.freedesktop.systemd1",
1492 "/org/freedesktop/systemd1",
1493 "org.freedesktop.systemd1.Manager",
1499 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1503 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1505 return bus_log_parse_error(r);
1507 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1509 if (!GREEDY_REALLOC(jobs, size, c + 1))
1512 jobs[c++] = (struct job_info) {
1520 return bus_log_parse_error(r);
1522 r = sd_bus_message_exit_container(reply);
1524 return bus_log_parse_error(r);
1526 output_jobs_list(jobs, c);
1530 static int cancel_job(sd_bus *bus, char **args) {
1531 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1536 if (strv_length(args) <= 1)
1537 return daemon_reload(bus, args);
1539 STRV_FOREACH(name, args+1) {
1543 r = safe_atou32(*name, &id);
1545 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1549 r = sd_bus_call_method(
1551 "org.freedesktop.systemd1",
1552 "/org/freedesktop/systemd1",
1553 "org.freedesktop.systemd1.Manager",
1559 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1567 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1568 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1569 _cleanup_free_ char *n = NULL;
1573 /* We ignore all errors here, since this is used to show a
1576 n = unit_name_mangle(unit);
1580 /* We don't use unit_dbus_path_from_name() directly since we
1581 * don't want to load the unit if it isn't loaded. */
1583 r = sd_bus_call_method(
1585 "org.freedesktop.systemd1",
1586 "/org/freedesktop/systemd1",
1587 "org.freedesktop.systemd1.Manager",
1595 r = sd_bus_message_read(reply, "o", &path);
1599 r = sd_bus_get_property_trivial(
1601 "org.freedesktop.systemd1",
1603 "org.freedesktop.systemd1.Unit",
1613 typedef struct WaitData {
1620 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1627 log_debug("Got D-Bus request: %s.%s() on %s",
1628 sd_bus_message_get_interface(m),
1629 sd_bus_message_get_member(m),
1630 sd_bus_message_get_path(m));
1632 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1633 log_error("Warning! D-Bus connection terminated.");
1635 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1637 const char *path, *result, *unit;
1641 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1643 ret = set_remove(d->set, (char*) path);
1649 if (!isempty(result))
1650 d->result = strdup(result);
1653 d->name = strdup(unit);
1658 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1660 ret = set_remove(d->set, (char*) path);
1667 d->result = strdup(result);
1673 log_error("Failed to parse message.");
1679 static int enable_wait_for_jobs(sd_bus *bus) {
1684 r = sd_bus_add_match(
1687 "sender='org.freedesktop.systemd1',"
1688 "interface='org.freedesktop.systemd1.Manager',"
1689 "member='JobRemoved',"
1690 "path='/org/freedesktop/systemd1'",
1693 log_error("Failed to add match");
1697 /* This is slightly dirty, since we don't undo the match registrations. */
1701 static int wait_for_jobs(sd_bus *bus, Set *s) {
1702 WaitData d = { .set = s };
1708 r = sd_bus_add_filter(bus, wait_filter, &d);
1712 while (!set_isempty(s)) {
1714 r = sd_bus_process(bus, NULL);
1719 r = sd_bus_wait(bus, (uint64_t) -1);
1728 if (streq(d.result, "timeout"))
1729 log_error("Job for %s timed out.", strna(d.name));
1730 else if (streq(d.result, "canceled"))
1731 log_error("Job for %s canceled.", strna(d.name));
1732 else if (streq(d.result, "dependency"))
1733 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1734 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1735 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1738 if (streq_ptr(d.result, "timeout"))
1740 else if (streq_ptr(d.result, "canceled"))
1742 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1753 return sd_bus_remove_filter(bus, wait_filter, &d);
1756 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1757 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1758 _cleanup_free_ char *n = NULL, *state = NULL;
1764 n = unit_name_mangle(name);
1768 /* We don't use unit_dbus_path_from_name() directly since we
1769 * don't want to load the unit if it isn't loaded. */
1771 r = sd_bus_call_method(
1773 "org.freedesktop.systemd1",
1774 "/org/freedesktop/systemd1",
1775 "org.freedesktop.systemd1.Manager",
1786 r = sd_bus_message_read(reply, "o", &path);
1788 return bus_log_parse_error(r);
1790 r = sd_bus_get_property_string(
1792 "org.freedesktop.systemd1",
1794 "org.freedesktop.systemd1.Unit",
1807 return nulstr_contains(good_states, state);
1810 static int check_triggering_units(
1814 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1815 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1816 _cleanup_strv_free_ char **triggered_by = NULL;
1817 bool print_warning_label = true;
1821 n = unit_name_mangle(name);
1825 path = unit_dbus_path_from_name(n);
1829 r = sd_bus_get_property_string(
1831 "org.freedesktop.systemd1",
1833 "org.freedesktop.systemd1.Unit",
1838 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1842 if (streq(state, "masked"))
1845 r = sd_bus_get_property_strv(
1847 "org.freedesktop.systemd1",
1849 "org.freedesktop.systemd1.Unit",
1854 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1858 STRV_FOREACH(i, triggered_by) {
1859 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1861 log_error("Failed to check unit: %s", strerror(-r));
1868 if (print_warning_label) {
1869 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1870 print_warning_label = false;
1873 log_warning(" %s", *i);
1879 static int start_unit_one(
1884 sd_bus_error *error,
1887 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1888 _cleanup_free_ char *n;
1897 n = unit_name_mangle(name);
1901 r = sd_bus_call_method(
1903 "org.freedesktop.systemd1",
1904 "/org/freedesktop/systemd1",
1905 "org.freedesktop.systemd1.Manager",
1911 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1912 /* There's always a fallback possible for
1913 * legacy actions. */
1914 return -EADDRNOTAVAIL;
1916 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1920 r = sd_bus_message_read(reply, "o", &path);
1922 return bus_log_parse_error(r);
1924 if (need_daemon_reload(bus, n) > 0)
1925 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1926 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1935 r = set_consume(s, p);
1943 static const struct {
1947 } action_table[_ACTION_MAX] = {
1948 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1949 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1950 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1951 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1952 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1953 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1954 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1955 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1956 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1957 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1958 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1959 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1960 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1961 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1962 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1965 static enum action verb_to_action(const char *verb) {
1968 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1969 if (streq_ptr(action_table[i].verb, verb))
1972 return _ACTION_INVALID;
1975 static int start_unit(sd_bus *bus, char **args) {
1976 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1977 _cleanup_set_free_free_ Set *s = NULL;
1978 const char *method, *mode, *one_name;
1984 ask_password_agent_open_if_enabled();
1986 if (arg_action == ACTION_SYSTEMCTL) {
1989 streq(args[0], "stop") ||
1990 streq(args[0], "condstop") ? "StopUnit" :
1991 streq(args[0], "reload") ? "ReloadUnit" :
1992 streq(args[0], "restart") ? "RestartUnit" :
1994 streq(args[0], "try-restart") ||
1995 streq(args[0], "condrestart") ? "TryRestartUnit" :
1997 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1999 streq(args[0], "reload-or-try-restart") ||
2000 streq(args[0], "condreload") ||
2001 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2003 action = verb_to_action(args[0]);
2005 mode = streq(args[0], "isolate") ? "isolate" :
2006 action_table[action].mode ?: arg_job_mode;
2008 one_name = action_table[action].target;
2010 assert(arg_action < ELEMENTSOF(action_table));
2011 assert(action_table[arg_action].target);
2013 method = "StartUnit";
2015 mode = action_table[arg_action].mode;
2016 one_name = action_table[arg_action].target;
2019 if (!arg_no_block) {
2020 r = enable_wait_for_jobs(bus);
2022 log_error("Could not watch jobs: %s", strerror(-r));
2026 s = set_new(string_hash_func, string_compare_func);
2032 r = start_unit_one(bus, method, one_name, mode, &error, s);
2034 r = translate_bus_error_to_exit_status(r, &error);
2038 STRV_FOREACH(name, args+1) {
2041 q = start_unit_one(bus, method, *name, mode, &error, s);
2043 r = translate_bus_error_to_exit_status(r, &error);
2044 sd_bus_error_free(&error);
2049 if (!arg_no_block) {
2052 q = wait_for_jobs(bus, s);
2056 /* When stopping units, warn if they can still be triggered by
2057 * another active unit (socket, path, timer) */
2058 if (!arg_quiet && streq(method, "StopUnit")) {
2060 check_triggering_units(bus, one_name);
2062 STRV_FOREACH(name, args+1)
2063 check_triggering_units(bus, *name);
2070 /* Ask systemd-logind, which might grant access to unprivileged users
2071 * through PolicyKit */
2072 static int reboot_with_logind(sd_bus *bus, enum action a) {
2074 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2081 polkit_agent_open_if_enabled();
2089 case ACTION_POWEROFF:
2090 method = "PowerOff";
2093 case ACTION_SUSPEND:
2097 case ACTION_HIBERNATE:
2098 method = "Hibernate";
2101 case ACTION_HYBRID_SLEEP:
2102 method = "HybridSleep";
2109 r = sd_bus_call_method(
2111 "org.freedesktop.login1",
2112 "/org/freedesktop/login1",
2113 "org.freedesktop.login1.Manager",
2119 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2127 static int check_inhibitors(sd_bus *bus, enum action a) {
2129 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2130 _cleanup_strv_free_ char **sessions = NULL;
2131 const char *what, *who, *why, *mode;
2140 if (arg_ignore_inhibitors || arg_force > 0)
2152 r = sd_bus_call_method(
2154 "org.freedesktop.login1",
2155 "/org/freedesktop/login1",
2156 "org.freedesktop.login1.Manager",
2162 /* If logind is not around, then there are no inhibitors... */
2165 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2167 return bus_log_parse_error(r);
2169 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2170 _cleanup_free_ char *comm = NULL, *user = NULL;
2171 _cleanup_strv_free_ char **sv = NULL;
2173 if (!streq(mode, "block"))
2176 sv = strv_split(what, ":");
2180 if (!strv_contains(sv,
2182 a == ACTION_POWEROFF ||
2183 a == ACTION_REBOOT ||
2184 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2187 get_process_comm(pid, &comm);
2188 user = uid_to_name(uid);
2190 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2191 who, (unsigned long) pid, strna(comm), strna(user), why);
2196 return bus_log_parse_error(r);
2198 r = sd_bus_message_exit_container(reply);
2200 return bus_log_parse_error(r);
2202 /* Check for current sessions */
2203 sd_get_sessions(&sessions);
2204 STRV_FOREACH(s, sessions) {
2205 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2207 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2210 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2213 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2216 sd_session_get_tty(*s, &tty);
2217 sd_session_get_seat(*s, &seat);
2218 sd_session_get_service(*s, &service);
2219 user = uid_to_name(uid);
2221 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2228 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2229 action_table[a].verb);
2237 static int start_special(sd_bus *bus, char **args) {
2243 a = verb_to_action(args[0]);
2245 r = check_inhibitors(bus, a);
2249 if (arg_force >= 2 && geteuid() != 0) {
2250 log_error("Must be root.");
2254 if (arg_force >= 2 &&
2255 (a == ACTION_HALT ||
2256 a == ACTION_POWEROFF ||
2257 a == ACTION_REBOOT))
2260 if (arg_force >= 1 &&
2261 (a == ACTION_HALT ||
2262 a == ACTION_POWEROFF ||
2263 a == ACTION_REBOOT ||
2264 a == ACTION_KEXEC ||
2266 return daemon_reload(bus, args);
2268 /* first try logind, to allow authentication with polkit */
2269 if (geteuid() != 0 &&
2270 (a == ACTION_POWEROFF ||
2271 a == ACTION_REBOOT ||
2272 a == ACTION_SUSPEND ||
2273 a == ACTION_HIBERNATE ||
2274 a == ACTION_HYBRID_SLEEP)) {
2275 r = reboot_with_logind(bus, a);
2280 r = start_unit(bus, args);
2281 if (r == EXIT_SUCCESS)
2287 static int check_unit_active(sd_bus *bus, char **args) {
2289 int r = 3; /* According to LSB: "program is not running" */
2294 STRV_FOREACH(name, args+1) {
2297 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2307 static int check_unit_failed(sd_bus *bus, char **args) {
2314 STRV_FOREACH(name, args+1) {
2317 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2327 static int kill_unit(sd_bus *bus, char **args) {
2328 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2336 arg_kill_who = "all";
2338 STRV_FOREACH(name, args+1) {
2339 _cleanup_free_ char *n = NULL;
2341 n = unit_name_mangle(*name);
2345 r = sd_bus_call_method(
2347 "org.freedesktop.systemd1",
2348 "/org/freedesktop/systemd1",
2349 "org.freedesktop.systemd1.Manager",
2353 "ssi", n, arg_kill_who, arg_signal);
2355 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2363 typedef struct ExecStatusInfo {
2371 usec_t start_timestamp;
2372 usec_t exit_timestamp;
2377 LIST_FIELDS(struct ExecStatusInfo, exec);
2380 static void exec_status_info_free(ExecStatusInfo *i) {
2389 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2390 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2393 int32_t code, status;
2399 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2401 return bus_log_parse_error(r);
2405 r = sd_bus_message_read(m, "s", &path);
2407 return bus_log_parse_error(r);
2409 i->path = strdup(path);
2413 r = sd_bus_message_read_strv(m, &i->argv);
2415 return bus_log_parse_error(r);
2417 r = sd_bus_message_read(m,
2420 &start_timestamp, &start_timestamp_monotonic,
2421 &exit_timestamp, &exit_timestamp_monotonic,
2425 return bus_log_parse_error(r);
2428 i->start_timestamp = (usec_t) start_timestamp;
2429 i->exit_timestamp = (usec_t) exit_timestamp;
2430 i->pid = (pid_t) pid;
2434 r = sd_bus_message_exit_container(m);
2436 return bus_log_parse_error(r);
2441 typedef struct UnitStatusInfo {
2443 const char *load_state;
2444 const char *active_state;
2445 const char *sub_state;
2446 const char *unit_file_state;
2448 const char *description;
2449 const char *following;
2451 char **documentation;
2453 const char *fragment_path;
2454 const char *source_path;
2455 const char *control_group;
2457 char **dropin_paths;
2459 const char *load_error;
2462 usec_t inactive_exit_timestamp;
2463 usec_t inactive_exit_timestamp_monotonic;
2464 usec_t active_enter_timestamp;
2465 usec_t active_exit_timestamp;
2466 usec_t inactive_enter_timestamp;
2468 bool need_daemon_reload;
2473 const char *status_text;
2474 const char *pid_file;
2477 usec_t start_timestamp;
2478 usec_t exit_timestamp;
2480 int exit_code, exit_status;
2482 usec_t condition_timestamp;
2483 bool condition_result;
2484 bool failed_condition_trigger;
2485 bool failed_condition_negate;
2486 const char *failed_condition;
2487 const char *failed_condition_param;
2490 unsigned n_accepted;
2491 unsigned n_connections;
2494 /* Pairs of type, path */
2498 const char *sysfs_path;
2500 /* Mount, Automount */
2506 LIST_HEAD(ExecStatusInfo, exec);
2509 static void print_status_info(
2514 const char *on, *off, *ss;
2516 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2517 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2520 arg_all * OUTPUT_SHOW_ALL |
2521 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2522 on_tty() * OUTPUT_COLOR |
2523 !arg_quiet * OUTPUT_WARN_CUTOFF |
2524 arg_full * OUTPUT_FULL_WIDTH;
2529 /* This shows pretty information about a unit. See
2530 * print_property() for a low-level property printer */
2532 printf("%s", strna(i->id));
2534 if (i->description && !streq_ptr(i->id, i->description))
2535 printf(" - %s", i->description);
2540 printf(" Follow: unit currently follows state of %s\n", i->following);
2542 if (streq_ptr(i->load_state, "error")) {
2543 on = ansi_highlight_red();
2544 off = ansi_highlight_off();
2548 path = i->source_path ? i->source_path : i->fragment_path;
2551 printf(" Loaded: %s%s%s (Reason: %s)\n",
2552 on, strna(i->load_state), off, i->load_error);
2553 else if (path && i->unit_file_state)
2554 printf(" Loaded: %s%s%s (%s; %s)\n",
2555 on, strna(i->load_state), off, path, i->unit_file_state);
2557 printf(" Loaded: %s%s%s (%s)\n",
2558 on, strna(i->load_state), off, path);
2560 printf(" Loaded: %s%s%s\n",
2561 on, strna(i->load_state), off);
2563 if (!strv_isempty(i->dropin_paths)) {
2564 _cleanup_free_ char *dir = NULL;
2568 STRV_FOREACH(dropin, i->dropin_paths) {
2569 if (! dir || last) {
2570 printf(dir ? " " : " Drop-In: ");
2575 if (path_get_parent(*dropin, &dir) < 0) {
2580 printf("%s\n %s", dir,
2581 draw_special_char(DRAW_TREE_RIGHT));
2584 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2586 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2590 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2592 if (streq_ptr(i->active_state, "failed")) {
2593 on = ansi_highlight_red();
2594 off = ansi_highlight_off();
2595 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2596 on = ansi_highlight_green();
2597 off = ansi_highlight_off();
2602 printf(" Active: %s%s (%s)%s",
2603 on, strna(i->active_state), ss, off);
2605 printf(" Active: %s%s%s",
2606 on, strna(i->active_state), off);
2608 if (!isempty(i->result) && !streq(i->result, "success"))
2609 printf(" (Result: %s)", i->result);
2611 timestamp = (streq_ptr(i->active_state, "active") ||
2612 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2613 (streq_ptr(i->active_state, "inactive") ||
2614 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2615 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2616 i->active_exit_timestamp;
2618 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2619 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2622 printf(" since %s; %s\n", s2, s1);
2624 printf(" since %s\n", s2);
2628 if (!i->condition_result && i->condition_timestamp > 0) {
2629 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2630 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2632 printf(" start condition failed at %s%s%s\n",
2633 s2, s1 ? "; " : "", s1 ? s1 : "");
2634 if (i->failed_condition_trigger)
2635 printf(" none of the trigger conditions were met\n");
2636 else if (i->failed_condition)
2637 printf(" %s=%s%s was not met\n",
2638 i->failed_condition,
2639 i->failed_condition_negate ? "!" : "",
2640 i->failed_condition_param);
2644 printf(" Device: %s\n", i->sysfs_path);
2646 printf(" Where: %s\n", i->where);
2648 printf(" What: %s\n", i->what);
2650 STRV_FOREACH(t, i->documentation)
2651 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2653 STRV_FOREACH_PAIR(t, t2, i->listen)
2654 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2657 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2659 LIST_FOREACH(exec, p, i->exec) {
2660 _cleanup_free_ char *argv = NULL;
2663 /* Only show exited processes here */
2667 argv = strv_join(p->argv, " ");
2668 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2670 good = is_clean_exit_lsb(p->code, p->status, NULL);
2672 on = ansi_highlight_red();
2673 off = ansi_highlight_off();
2677 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2679 if (p->code == CLD_EXITED) {
2682 printf("status=%i", p->status);
2684 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2689 printf("signal=%s", signal_to_string(p->status));
2691 printf(")%s\n", off);
2693 if (i->main_pid == p->pid &&
2694 i->start_timestamp == p->start_timestamp &&
2695 i->exit_timestamp == p->start_timestamp)
2696 /* Let's not show this twice */
2699 if (p->pid == i->control_pid)
2703 if (i->main_pid > 0 || i->control_pid > 0) {
2704 if (i->main_pid > 0) {
2705 printf(" Main PID: %u", (unsigned) i->main_pid);
2708 _cleanup_free_ char *comm = NULL;
2709 get_process_comm(i->main_pid, &comm);
2711 printf(" (%s)", comm);
2712 } else if (i->exit_code > 0) {
2713 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2715 if (i->exit_code == CLD_EXITED) {
2718 printf("status=%i", i->exit_status);
2720 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2725 printf("signal=%s", signal_to_string(i->exit_status));
2729 if (i->control_pid > 0)
2733 if (i->control_pid > 0) {
2734 _cleanup_free_ char *c = NULL;
2736 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2738 get_process_comm(i->control_pid, &c);
2747 printf(" Status: \"%s\"\n", i->status_text);
2749 if (i->control_group &&
2750 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2753 printf(" CGroup: %s\n", i->control_group);
2755 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2758 char prefix[] = " ";
2761 if (c > sizeof(prefix) - 1)
2762 c -= sizeof(prefix) - 1;
2766 if (i->main_pid > 0)
2767 extra[k++] = i->main_pid;
2769 if (i->control_pid > 0)
2770 extra[k++] = i->control_pid;
2772 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2773 c, false, extra, k, flags);
2777 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2779 show_journal_by_unit(stdout,
2783 i->inactive_exit_timestamp_monotonic,
2787 arg_scope == UNIT_FILE_SYSTEM,
2791 if (i->need_daemon_reload)
2792 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2793 ansi_highlight_red(),
2794 ansi_highlight_off(),
2795 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2798 static void show_unit_help(UnitStatusInfo *i) {
2803 if (!i->documentation) {
2804 log_info("Documentation for %s not known.", i->id);
2808 STRV_FOREACH(p, i->documentation) {
2810 if (startswith(*p, "man:")) {
2811 const char *args[4] = { "man", NULL, NULL, NULL };
2812 _cleanup_free_ char *page = NULL, *section = NULL;
2819 if ((*p)[k-1] == ')')
2820 e = strrchr(*p, '(');
2823 page = strndup((*p) + 4, e - *p - 4);
2824 section = strndup(e + 1, *p + k - e - 2);
2825 if (!page || !section) {
2837 log_error("Failed to fork: %m");
2843 execvp(args[0], (char**) args);
2844 log_error("Failed to execute man: %m");
2845 _exit(EXIT_FAILURE);
2848 wait_for_terminate(pid, NULL);
2850 log_info("Can't show: %s", *p);
2854 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2861 switch (contents[0]) {
2863 case SD_BUS_TYPE_STRING: {
2866 r = sd_bus_message_read(m, "s", &s);
2868 return bus_log_parse_error(r);
2871 if (streq(name, "Id"))
2873 else if (streq(name, "LoadState"))
2875 else if (streq(name, "ActiveState"))
2876 i->active_state = s;
2877 else if (streq(name, "SubState"))
2879 else if (streq(name, "Description"))
2881 else if (streq(name, "FragmentPath"))
2882 i->fragment_path = s;
2883 else if (streq(name, "SourcePath"))
2886 else if (streq(name, "DefaultControlGroup")) {
2888 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2890 i->control_group = e;
2893 else if (streq(name, "ControlGroup"))
2894 i->control_group = s;
2895 else if (streq(name, "StatusText"))
2897 else if (streq(name, "PIDFile"))
2899 else if (streq(name, "SysFSPath"))
2901 else if (streq(name, "Where"))
2903 else if (streq(name, "What"))
2905 else if (streq(name, "Following"))
2907 else if (streq(name, "UnitFileState"))
2908 i->unit_file_state = s;
2909 else if (streq(name, "Result"))
2916 case SD_BUS_TYPE_BOOLEAN: {
2919 r = sd_bus_message_read(m, "b", &b);
2921 return bus_log_parse_error(r);
2923 if (streq(name, "Accept"))
2925 else if (streq(name, "NeedDaemonReload"))
2926 i->need_daemon_reload = b;
2927 else if (streq(name, "ConditionResult"))
2928 i->condition_result = b;
2933 case SD_BUS_TYPE_UINT32: {
2936 r = sd_bus_message_read(m, "u", &u);
2938 return bus_log_parse_error(r);
2940 if (streq(name, "MainPID")) {
2942 i->main_pid = (pid_t) u;
2945 } else if (streq(name, "ControlPID"))
2946 i->control_pid = (pid_t) u;
2947 else if (streq(name, "ExecMainPID")) {
2949 i->main_pid = (pid_t) u;
2950 } else if (streq(name, "NAccepted"))
2952 else if (streq(name, "NConnections"))
2953 i->n_connections = u;
2958 case SD_BUS_TYPE_INT32: {
2961 r = sd_bus_message_read(m, "i", &j);
2963 return bus_log_parse_error(r);
2965 if (streq(name, "ExecMainCode"))
2966 i->exit_code = (int) j;
2967 else if (streq(name, "ExecMainStatus"))
2968 i->exit_status = (int) j;
2973 case SD_BUS_TYPE_UINT64: {
2976 r = sd_bus_message_read(m, "t", &u);
2978 return bus_log_parse_error(r);
2980 if (streq(name, "ExecMainStartTimestamp"))
2981 i->start_timestamp = (usec_t) u;
2982 else if (streq(name, "ExecMainExitTimestamp"))
2983 i->exit_timestamp = (usec_t) u;
2984 else if (streq(name, "ActiveEnterTimestamp"))
2985 i->active_enter_timestamp = (usec_t) u;
2986 else if (streq(name, "InactiveEnterTimestamp"))
2987 i->inactive_enter_timestamp = (usec_t) u;
2988 else if (streq(name, "InactiveExitTimestamp"))
2989 i->inactive_exit_timestamp = (usec_t) u;
2990 else if (streq(name, "InactiveExitTimestampMonotonic"))
2991 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2992 else if (streq(name, "ActiveExitTimestamp"))
2993 i->active_exit_timestamp = (usec_t) u;
2994 else if (streq(name, "ConditionTimestamp"))
2995 i->condition_timestamp = (usec_t) u;
3000 case SD_BUS_TYPE_ARRAY:
3002 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3003 _cleanup_free_ ExecStatusInfo *info = NULL;
3005 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3007 return bus_log_parse_error(r);
3009 info = new0(ExecStatusInfo, 1);
3013 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3015 info->name = strdup(name);
3019 LIST_PREPEND(exec, i->exec, info);
3021 info = new0(ExecStatusInfo, 1);
3027 return bus_log_parse_error(r);
3029 r = sd_bus_message_exit_container(m);
3031 return bus_log_parse_error(r);
3035 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3036 const char *type, *path;
3038 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3040 return bus_log_parse_error(r);
3042 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3044 r = strv_extend(&i->listen, type);
3048 r = strv_extend(&i->listen, path);
3053 return bus_log_parse_error(r);
3055 r = sd_bus_message_exit_container(m);
3057 return bus_log_parse_error(r);
3061 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3063 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3065 return bus_log_parse_error(r);
3067 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3069 r = sd_bus_message_read_strv(m, &i->documentation);
3071 return bus_log_parse_error(r);
3073 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3074 const char *cond, *param;
3075 int trigger, negate;
3078 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3080 return bus_log_parse_error(r);
3082 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3083 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3084 if (state < 0 && (!trigger || !i->failed_condition)) {
3085 i->failed_condition = cond;
3086 i->failed_condition_trigger = trigger;
3087 i->failed_condition_negate = negate;
3088 i->failed_condition_param = param;
3092 return bus_log_parse_error(r);
3094 r = sd_bus_message_exit_container(m);
3096 return bus_log_parse_error(r);
3103 case SD_BUS_TYPE_STRUCT_BEGIN:
3105 if (streq(name, "LoadError")) {
3106 const char *n, *message;
3108 r = sd_bus_message_read(m, "(ss)", &n, &message);
3110 return bus_log_parse_error(r);
3112 if (!isempty(message))
3113 i->load_error = message;
3126 r = sd_bus_message_skip(m, contents);
3128 return bus_log_parse_error(r);
3133 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3139 /* This is a low-level property printer, see
3140 * print_status_info() for the nicer output */
3142 if (arg_properties && !strv_find(arg_properties, name)) {
3143 /* skip what we didn't read */
3144 r = sd_bus_message_skip(m, contents);
3148 switch (contents[0]) {
3150 case SD_BUS_TYPE_STRUCT_BEGIN:
3152 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3155 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3157 return bus_log_parse_error(r);
3160 printf("%s=%u\n", name, (unsigned) u);
3162 printf("%s=\n", name);
3166 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3169 r = sd_bus_message_read(m, "(so)", &s, NULL);
3171 return bus_log_parse_error(r);
3173 if (arg_all || !isempty(s))
3174 printf("%s=%s\n", name, s);
3178 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3179 const char *a = NULL, *b = NULL;
3181 r = sd_bus_message_read(m, "(ss)", &a, &b);
3183 return bus_log_parse_error(r);
3185 if (arg_all || !isempty(a) || !isempty(b))
3186 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3193 case SD_BUS_TYPE_ARRAY:
3195 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3199 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3201 return bus_log_parse_error(r);
3203 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3204 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3207 return bus_log_parse_error(r);
3209 r = sd_bus_message_exit_container(m);
3211 return bus_log_parse_error(r);
3215 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3216 const char *type, *path;
3218 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3220 return bus_log_parse_error(r);
3222 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3223 printf("%s=%s\n", type, path);
3225 return bus_log_parse_error(r);
3227 r = sd_bus_message_exit_container(m);
3229 return bus_log_parse_error(r);
3233 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3234 const char *type, *path;
3236 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3238 return bus_log_parse_error(r);
3240 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3241 printf("Listen%s=%s\n", type, path);
3243 return bus_log_parse_error(r);
3245 r = sd_bus_message_exit_container(m);
3247 return bus_log_parse_error(r);
3251 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3253 uint64_t value, next_elapse;
3255 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3257 return bus_log_parse_error(r);
3259 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3260 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3262 printf("%s={ value=%s ; next_elapse=%s }\n",
3264 format_timespan(timespan1, sizeof(timespan1), value, 0),
3265 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3268 return bus_log_parse_error(r);
3270 r = sd_bus_message_exit_container(m);
3272 return bus_log_parse_error(r);
3276 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3277 ExecStatusInfo info = {};
3279 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3281 return bus_log_parse_error(r);
3283 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3284 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3285 _cleanup_free_ char *tt;
3287 tt = strv_join(info.argv, " ");
3289 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3293 yes_no(info.ignore),
3294 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3295 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3296 (unsigned) info. pid,
3297 sigchld_code_to_string(info.code),
3299 info.code == CLD_EXITED ? "" : "/",
3300 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3303 strv_free(info.argv);
3307 r = sd_bus_message_exit_container(m);
3309 return bus_log_parse_error(r);
3313 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3314 const char *path, *rwm;
3316 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3318 return bus_log_parse_error(r);
3320 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3321 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3323 return bus_log_parse_error(r);
3325 r = sd_bus_message_exit_container(m);
3327 return bus_log_parse_error(r);
3331 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3335 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3337 return bus_log_parse_error(r);
3339 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3340 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3342 return bus_log_parse_error(r);
3344 r = sd_bus_message_exit_container(m);
3346 return bus_log_parse_error(r);
3350 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3354 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3356 return bus_log_parse_error(r);
3358 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3359 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3361 return bus_log_parse_error(r);
3363 r = sd_bus_message_exit_container(m);
3365 return bus_log_parse_error(r);
3373 r = bus_print_property(name, m, arg_all);
3375 return bus_log_parse_error(r);
3378 r = sd_bus_message_skip(m, contents);
3380 return bus_log_parse_error(r);
3383 printf("%s=[unprintable]\n", name);
3389 static int show_one(
3393 bool show_properties,
3397 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3398 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3399 UnitStatusInfo info = {};
3406 r = sd_bus_call_method(
3408 "org.freedesktop.systemd1",
3410 "org.freedesktop.DBus.Properties",
3416 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3420 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3422 return bus_log_parse_error(r);
3429 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3430 const char *name, *contents;
3432 r = sd_bus_message_read(reply, "s", &name);
3434 return bus_log_parse_error(r);
3436 r = sd_bus_message_peek_type(reply, NULL, &contents);
3438 return bus_log_parse_error(r);
3440 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3442 return bus_log_parse_error(r);
3444 if (show_properties)
3445 r = print_property(name, reply, contents);
3447 r = status_property(name, reply, &info, contents);
3451 r = sd_bus_message_exit_container(reply);
3453 return bus_log_parse_error(r);
3455 r = sd_bus_message_exit_container(reply);
3457 return bus_log_parse_error(r);
3460 return bus_log_parse_error(r);
3462 r = sd_bus_message_exit_container(reply);
3464 return bus_log_parse_error(r);
3468 if (!show_properties) {
3469 if (streq(verb, "help"))
3470 show_unit_help(&info);
3472 print_status_info(&info, ellipsized);
3475 strv_free(info.documentation);
3476 strv_free(info.dropin_paths);
3477 strv_free(info.listen);
3479 if (!streq_ptr(info.active_state, "active") &&
3480 !streq_ptr(info.active_state, "reloading") &&
3481 streq(verb, "status")) {
3482 /* According to LSB: "program not running" */
3483 /* 0: program is running or service is OK
3484 * 1: program is dead and /var/run pid file exists
3485 * 2: program is dead and /var/lock lock file exists
3486 * 3: program is not running
3487 * 4: program or service status is unknown
3489 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3495 while ((p = info.exec)) {
3496 LIST_REMOVE(exec, info.exec, p);
3497 exec_status_info_free(p);
3503 static int show_one_by_pid(
3510 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3511 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3512 const char *path = NULL;
3515 r = sd_bus_call_method(
3517 "org.freedesktop.systemd1",
3518 "/org/freedesktop/systemd1",
3519 "org.freedesktop.systemd1.Manager",
3525 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3529 r = sd_bus_message_read(reply, "o", &path);
3531 return bus_log_parse_error(r);
3533 return show_one(verb, bus, path, false, new_line, ellipsized);
3536 static int show_all(
3539 bool show_properties,
3543 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3544 _cleanup_free_ UnitInfo *unit_infos = NULL;
3549 r = get_unit_list(bus, &reply, &unit_infos);
3555 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3557 for (u = unit_infos; u < unit_infos + c; u++) {
3558 _cleanup_free_ char *p = NULL;
3560 if (!output_show_unit(u))
3563 p = unit_dbus_path_from_name(u->id);
3567 printf("%s -> '%s'\n", u->id, p);
3569 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3577 static int show(sd_bus *bus, char **args) {
3579 bool show_properties, show_status, new_line = false;
3581 bool ellipsized = false;
3586 show_properties = streq(args[0], "show");
3587 show_status = streq(args[0], "status");
3589 if (show_properties)
3590 pager_open_if_enabled();
3592 /* If no argument is specified inspect the manager itself */
3594 if (show_properties && strv_length(args) <= 1)
3595 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3597 if (show_status && strv_length(args) <= 1)
3598 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3600 STRV_FOREACH(name, args+1) {
3603 if (safe_atou32(*name, &id) < 0) {
3604 _cleanup_free_ char *p = NULL, *n = NULL;
3605 /* Interpret as unit name */
3607 n = unit_name_mangle(*name);
3611 p = unit_dbus_path_from_name(n);
3615 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3619 } else if (show_properties) {
3620 _cleanup_free_ char *p = NULL;
3622 /* Interpret as job id */
3623 if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
3626 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3631 /* Interpret as PID */
3632 r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized);
3638 if (ellipsized && !arg_quiet)
3639 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3644 static int append_assignment(sd_bus_message *m, const char *assignment) {
3652 eq = strchr(assignment, '=');
3654 log_error("Not an assignment: %s", assignment);
3658 field = strndupa(assignment, eq - assignment);
3661 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3663 return bus_log_create_error(r);
3665 if (streq(field, "CPUAccounting") ||
3666 streq(field, "MemoryAccounting") ||
3667 streq(field, "BlockIOAccounting")) {
3669 r = parse_boolean(eq);
3671 log_error("Failed to parse boolean assignment %s.", assignment);
3675 r = sd_bus_message_append(m, "v", "b", r);
3677 } else if (streq(field, "MemoryLimit")) {
3680 r = parse_bytes(eq, &bytes);
3682 log_error("Failed to parse bytes specification %s", assignment);
3686 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3688 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3691 r = safe_atou64(eq, &u);
3693 log_error("Failed to parse %s value %s.", field, eq);
3697 r = sd_bus_message_append(m, "v", "t", u);
3699 } else if (streq(field, "DevicePolicy"))
3700 r = sd_bus_message_append(m, "v", "s", eq);
3702 else if (streq(field, "DeviceAllow")) {
3705 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3707 const char *path, *rwm;
3710 e = strchr(eq, ' ');
3712 path = strndupa(eq, e - eq);
3719 if (!path_startswith(path, "/dev")) {
3720 log_error("%s is not a device file in /dev.", path);
3724 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3727 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3730 r = sd_bus_message_append(m, "v", "a(st)", 0);
3732 const char *path, *bandwidth;
3736 e = strchr(eq, ' ');
3738 path = strndupa(eq, e - eq);
3741 log_error("Failed to parse %s value %s.", field, eq);
3745 if (!path_startswith(path, "/dev")) {
3746 log_error("%s is not a device file in /dev.", path);
3750 r = parse_bytes(bandwidth, &bytes);
3752 log_error("Failed to parse byte value %s.", bandwidth);
3756 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3759 } else if (streq(field, "BlockIODeviceWeight")) {
3762 r = sd_bus_message_append(m, "v", "a(st)", 0);
3764 const char *path, *weight;
3768 e = strchr(eq, ' ');
3770 path = strndupa(eq, e - eq);
3773 log_error("Failed to parse %s value %s.", field, eq);
3777 if (!path_startswith(path, "/dev")) {
3778 log_error("%s is not a device file in /dev.", path);
3782 r = safe_atou64(weight, &u);
3784 log_error("Failed to parse %s value %s.", field, weight);
3787 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3791 log_error("Unknown assignment %s.", assignment);
3796 return bus_log_create_error(r);
3801 static int set_property(sd_bus *bus, char **args) {
3802 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3803 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3804 _cleanup_free_ char *n = NULL;
3808 r = sd_bus_message_new_method_call(
3810 "org.freedesktop.systemd1",
3811 "/org/freedesktop/systemd1",
3812 "org.freedesktop.systemd1.Manager",
3813 "SetUnitProperties",
3816 return bus_log_create_error(r);
3818 n = unit_name_mangle(args[1]);
3822 r = sd_bus_message_append(m, "sb", n, arg_runtime);
3824 return bus_log_create_error(r);
3826 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
3828 return bus_log_create_error(r);
3830 STRV_FOREACH(i, args + 2) {
3831 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
3833 return bus_log_create_error(r);
3835 r = append_assignment(m, *i);
3839 r = sd_bus_message_close_container(m);
3841 return bus_log_create_error(r);
3844 r = sd_bus_message_close_container(m);
3846 return bus_log_create_error(r);
3848 r = sd_bus_call(bus, m, 0, &error, NULL);
3850 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
3857 static int snapshot(sd_bus *bus, char **args) {
3858 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3859 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3860 _cleanup_free_ char *n = NULL, *id = NULL;
3864 if (strv_length(args) > 1)
3865 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
3871 r = sd_bus_call_method(
3873 "org.freedesktop.systemd1",
3874 "/org/freedesktop/systemd1",
3875 "org.freedesktop.systemd1.Manager",
3881 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
3885 r = sd_bus_message_read(reply, "o", &path);
3887 return bus_log_parse_error(r);
3889 r = sd_bus_get_property_string(
3891 "org.freedesktop.systemd1",
3893 "org.freedesktop.systemd1.Unit",
3898 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
3908 static int delete_snapshot(sd_bus *bus, char **args) {
3909 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3915 STRV_FOREACH(name, args+1) {
3916 _cleanup_free_ char *n = NULL;
3918 n = unit_name_mangle_with_suffix(*name, ".snapshot");
3922 r = sd_bus_call_method(
3924 "org.freedesktop.systemd1",
3925 "/org/freedesktop/systemd1",
3926 "org.freedesktop.systemd1.Manager",
3932 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
3940 static int daemon_reload(sd_bus *bus, char **args) {
3941 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3945 if (arg_action == ACTION_RELOAD)
3947 else if (arg_action == ACTION_REEXEC)
3948 method = "Reexecute";
3950 assert(arg_action == ACTION_SYSTEMCTL);
3953 streq(args[0], "clear-jobs") ||
3954 streq(args[0], "cancel") ? "ClearJobs" :
3955 streq(args[0], "daemon-reexec") ? "Reexecute" :
3956 streq(args[0], "reset-failed") ? "ResetFailed" :
3957 streq(args[0], "halt") ? "Halt" :
3958 streq(args[0], "poweroff") ? "PowerOff" :
3959 streq(args[0], "reboot") ? "Reboot" :
3960 streq(args[0], "kexec") ? "KExec" :
3961 streq(args[0], "exit") ? "Exit" :
3962 /* "daemon-reload" */ "Reload";
3965 r = sd_bus_call_method(
3967 "org.freedesktop.systemd1",
3968 "/org/freedesktop/systemd1",
3969 "org.freedesktop.systemd1.Manager",
3975 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
3976 /* There's always a fallback possible for
3977 * legacy actions. */
3979 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
3980 /* On reexecution, we expect a disconnect, not a
3984 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3986 return r < 0 ? r : 0;
3989 static int reset_failed(sd_bus *bus, char **args) {
3990 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3994 if (strv_length(args) <= 1)
3995 return daemon_reload(bus, args);
3997 STRV_FOREACH(name, args+1) {
3998 _cleanup_free_ char *n;
4000 n = unit_name_mangle(*name);
4004 r = sd_bus_call_method(
4006 "org.freedesktop.systemd1",
4007 "/org/freedesktop/systemd1",
4008 "org.freedesktop.systemd1.Manager",
4014 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4022 static int show_environment(sd_bus *bus, char **args) {
4023 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4024 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4028 pager_open_if_enabled();
4030 r = sd_bus_get_property(
4032 "org.freedesktop.systemd1",
4033 "/org/freedesktop/systemd1",
4034 "org.freedesktop.systemd1.Manager",
4040 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4044 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4046 return bus_log_parse_error(r);
4048 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4051 return bus_log_parse_error(r);
4053 r = sd_bus_message_exit_container(reply);
4055 return bus_log_parse_error(r);
4060 static int switch_root(sd_bus *bus, char **args) {
4061 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4062 _cleanup_free_ char *init = NULL;
4067 l = strv_length(args);
4068 if (l < 2 || l > 3) {
4069 log_error("Wrong number of arguments.");
4076 init = strdup(args[2]);
4078 parse_env_file("/proc/cmdline", WHITESPACE,
4089 log_debug("switching root - root: %s; init: %s", root, init);
4091 r = sd_bus_call_method(
4093 "org.freedesktop.systemd1",
4094 "/org/freedesktop/systemd1",
4095 "org.freedesktop.systemd1.Manager",
4101 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4108 static int set_environment(sd_bus *bus, char **args) {
4109 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4110 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4117 method = streq(args[0], "set-environment")
4119 : "UnsetEnvironment";
4121 r = sd_bus_message_new_method_call(
4123 "org.freedesktop.systemd1",
4124 "/org/freedesktop/systemd1",
4125 "org.freedesktop.systemd1.Manager",
4129 return bus_log_create_error(r);
4131 r = sd_bus_message_append_strv(m, args + 1);
4133 return bus_log_create_error(r);
4135 r = sd_bus_call(bus, m, 0, &error, NULL);
4137 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4144 static int enable_sysv_units(const char *verb, char **args) {
4147 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4148 unsigned f = 1, t = 1;
4149 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4151 if (arg_scope != UNIT_FILE_SYSTEM)
4154 if (!streq(verb, "enable") &&
4155 !streq(verb, "disable") &&
4156 !streq(verb, "is-enabled"))
4159 /* Processes all SysV units, and reshuffles the array so that
4160 * afterwards only the native units remain */
4162 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4167 for (f = 0; args[f]; f++) {
4169 _cleanup_free_ char *p = NULL, *q = NULL;
4170 bool found_native = false, found_sysv;
4172 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4180 if (!endswith(name, ".service"))
4183 if (path_is_absolute(name))
4186 STRV_FOREACH(k, paths.unit_path) {
4187 if (!isempty(arg_root))
4188 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4190 asprintf(&p, "%s/%s", *k, name);
4197 found_native = access(p, F_OK) >= 0;
4208 if (!isempty(arg_root))
4209 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4211 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4217 p[strlen(p) - sizeof(".service") + 1] = 0;
4218 found_sysv = access(p, F_OK) >= 0;
4223 /* Mark this entry, so that we don't try enabling it as native unit */
4224 args[f] = (char*) "";
4226 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4228 if (!isempty(arg_root))
4229 argv[c++] = q = strappend("--root=", arg_root);
4231 argv[c++] = path_get_file_name(p);
4233 streq(verb, "enable") ? "on" :
4234 streq(verb, "disable") ? "off" : "--level=5";
4237 l = strv_join((char**)argv, " ");
4243 log_info("Executing %s", l);
4248 log_error("Failed to fork: %m");
4251 } else if (pid == 0) {
4254 execv(argv[0], (char**) argv);
4255 _exit(EXIT_FAILURE);
4258 j = wait_for_terminate(pid, &status);
4260 log_error("Failed to wait for child: %s", strerror(-r));
4265 if (status.si_code == CLD_EXITED) {
4266 if (streq(verb, "is-enabled")) {
4267 if (status.si_status == 0) {
4276 } else if (status.si_status != 0) {
4287 /* Drop all SysV units */
4288 for (f = 0, t = 0; args[f]; f++) {
4290 if (isempty(args[f]))
4293 args[t++] = args[f];
4302 static int mangle_names(char **original_names, char ***mangled_names) {
4303 char **i, **l, **name;
4305 l = new(char*, strv_length(original_names) + 1);
4310 STRV_FOREACH(name, original_names) {
4312 /* When enabling units qualified path names are OK,
4313 * too, hence allow them explicitly. */
4318 *i = unit_name_mangle(*name);
4334 static int enable_unit(sd_bus *bus, char **args) {
4335 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4336 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4337 _cleanup_strv_free_ char **mangled_names = NULL;
4338 const char *verb = args[0];
4339 UnitFileChange *changes = NULL;
4340 unsigned n_changes = 0, i;
4341 int carries_install_info = -1;
4347 r = mangle_names(args+1, &mangled_names);
4351 r = enable_sysv_units(verb, mangled_names);
4355 if (!bus || avoid_bus()) {
4356 if (streq(verb, "enable")) {
4357 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4358 carries_install_info = r;
4359 } else if (streq(verb, "disable"))
4360 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4361 else if (streq(verb, "reenable")) {
4362 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4363 carries_install_info = r;
4364 } else if (streq(verb, "link"))
4365 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4366 else if (streq(verb, "preset")) {
4367 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4368 carries_install_info = r;
4369 } else if (streq(verb, "mask"))
4370 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4371 else if (streq(verb, "unmask"))
4372 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4373 else if (streq(verb, "set-default"))
4374 r = unit_file_set_default(arg_scope, arg_root, args[1], &changes, &n_changes);
4376 assert_not_reached("Unknown verb");
4379 log_error("Operation failed: %s", strerror(-r));
4384 for (i = 0; i < n_changes; i++) {
4385 if (changes[i].type == UNIT_FILE_SYMLINK)
4386 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
4388 log_info("rm '%s'", changes[i].path);
4394 const char *method, *type, *path, *source;
4395 int expect_carries_install_info = false;
4396 bool send_force = true;
4398 if (streq(verb, "enable")) {
4399 method = "EnableUnitFiles";
4400 expect_carries_install_info = true;
4401 } else if (streq(verb, "disable")) {
4402 method = "DisableUnitFiles";
4404 } else if (streq(verb, "reenable")) {
4405 method = "ReenableUnitFiles";
4406 expect_carries_install_info = true;
4407 } else if (streq(verb, "link"))
4408 method = "LinkUnitFiles";
4409 else if (streq(verb, "preset")) {
4410 method = "PresetUnitFiles";
4411 expect_carries_install_info = true;
4412 } else if (streq(verb, "mask"))
4413 method = "MaskUnitFiles";
4414 else if (streq(verb, "unmask")) {
4415 method = "UnmaskUnitFiles";
4417 } else if (streq(verb, "set-default")) {
4418 method = "SetDefaultTarget";
4420 assert_not_reached("Unknown verb");
4422 r = sd_bus_message_new_method_call(
4424 "org.freedesktop.systemd1",
4425 "/org/freedesktop/systemd1",
4426 "org.freedesktop.systemd1.Manager",
4430 return bus_log_create_error(r);
4432 r = sd_bus_message_append_strv(m, mangled_names);
4434 return bus_log_create_error(r);
4436 r = sd_bus_message_append(m, "b", arg_runtime);
4438 return bus_log_create_error(r);
4441 r = sd_bus_message_append(m, "b", arg_force);
4443 return bus_log_create_error(r);
4446 r = sd_bus_call(bus, m, 0, &error, &reply);
4448 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4452 if (expect_carries_install_info) {
4453 r = sd_bus_message_read(reply, "b", &carries_install_info);
4455 return bus_log_parse_error(r);
4458 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(sss)");
4460 return bus_log_parse_error(r);
4462 while ((r = sd_bus_message_read(reply, "(sss)", &type, &path, &source)) > 0) {
4464 if (streq(type, "symlink"))
4465 log_info("ln -s '%s' '%s'", source, path);
4467 log_info("rm '%s'", path);
4471 return bus_log_parse_error(r);
4473 r = sd_bus_message_exit_container(reply);
4475 return bus_log_parse_error(r);
4477 /* Try to reload if enabeld */
4479 r = daemon_reload(bus, args);
4484 if (carries_install_info == 0)
4485 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4486 "using systemctl.\n"
4487 "Possible reasons for having this kind of units are:\n"
4488 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4489 " .wants/ or .requires/ directory.\n"
4490 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4491 " a requirement dependency on it.\n"
4492 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4493 " D-Bus, udev, scripted systemctl call, ...).\n");
4496 unit_file_changes_free(changes, n_changes);
4501 static int unit_is_enabled(sd_bus *bus, char **args) {
4503 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4504 _cleanup_strv_free_ char **mangled_names = NULL;
4509 r = mangle_names(args+1, &mangled_names);
4513 r = enable_sysv_units(args[0], mangled_names);
4519 if (!bus || avoid_bus()) {
4521 STRV_FOREACH(name, mangled_names) {
4522 UnitFileState state;
4524 state = unit_file_get_state(arg_scope, arg_root, *name);
4526 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4530 if (state == UNIT_FILE_ENABLED ||
4531 state == UNIT_FILE_ENABLED_RUNTIME ||
4532 state == UNIT_FILE_STATIC)
4536 puts(unit_file_state_to_string(state));
4540 STRV_FOREACH(name, mangled_names) {
4541 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4544 r = sd_bus_call_method(
4546 "org.freedesktop.systemd1",
4547 "/org/freedesktop/systemd1",
4548 "org.freedesktop.systemd1.Manager",
4554 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4558 r = sd_bus_message_read(reply, "s", &s);
4560 return bus_log_parse_error(r);
4562 if (streq(s, "enabled") ||
4563 streq(s, "enabled-runtime") ||
4575 static int systemctl_help(void) {
4577 pager_open_if_enabled();
4579 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4580 "Query or send control commands to the systemd manager.\n\n"
4581 " -h --help Show this help\n"
4582 " --version Show package version\n"
4583 " --system Connect to system manager\n"
4584 " --user Connect to user service manager\n"
4585 " -H --host=[USER@]HOST\n"
4586 " Operate on remote host\n"
4587 " -M --machine=CONTAINER\n"
4588 " Operate on local container\n"
4589 " -t --type=TYPE List only units of a particular type\n"
4590 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4591 " -p --property=NAME Show only properties by this name\n"
4592 " -a --all Show all loaded units/properties, including dead/empty\n"
4593 " ones. To list all units installed on the system, use\n"
4594 " the 'list-unit-files' command instead.\n"
4595 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4596 " -l --full Don't ellipsize unit names on output\n"
4597 " --fail When queueing a new job, fail if conflicting jobs are\n"
4599 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4601 " --ignore-dependencies\n"
4602 " When queueing a new job, ignore all its dependencies\n"
4603 " --show-types When showing sockets, explicitly show their type\n"
4604 " -i --ignore-inhibitors\n"
4605 " When shutting down or sleeping, ignore inhibitors\n"
4606 " --kill-who=WHO Who to send signal to\n"
4607 " -s --signal=SIGNAL Which signal to send\n"
4608 " -q --quiet Suppress output\n"
4609 " --no-block Do not wait until operation finished\n"
4610 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4611 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4613 " --no-legend Do not print a legend (column headers and hints)\n"
4614 " --no-pager Do not pipe output into a pager\n"
4615 " --no-ask-password\n"
4616 " Do not ask for system passwords\n"
4617 " --global Enable/disable unit files globally\n"
4618 " --runtime Enable unit files only temporarily until next reboot\n"
4619 " -f --force When enabling unit files, override existing symlinks\n"
4620 " When shutting down, execute action immediately\n"
4621 " --root=PATH Enable unit files in the specified root directory\n"
4622 " -n --lines=INTEGER Number of journal entries to show\n"
4623 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4624 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4626 " list-units List loaded units\n"
4627 " list-sockets List loaded sockets ordered by address\n"
4628 " list-timers List loaded timers ordered by next elapse\n"
4629 " start [NAME...] Start (activate) one or more units\n"
4630 " stop [NAME...] Stop (deactivate) one or more units\n"
4631 " reload [NAME...] Reload one or more units\n"
4632 " restart [NAME...] Start or restart one or more units\n"
4633 " try-restart [NAME...] Restart one or more units if active\n"
4634 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4635 " otherwise start or restart\n"
4636 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4637 " otherwise restart if active\n"
4638 " isolate [NAME] Start one unit and stop all others\n"
4639 " kill [NAME...] Send signal to processes of a unit\n"
4640 " is-active [NAME...] Check whether units are active\n"
4641 " is-failed [NAME...] Check whether units are failed\n"
4642 " status [NAME...|PID...] Show runtime status of one or more units\n"
4643 " show [NAME...|JOB...] Show properties of one or more\n"
4644 " units/jobs or the manager\n"
4645 " set-property [NAME] [ASSIGNMENT...]\n"
4646 " Sets one or more properties of a unit\n"
4647 " help [NAME...|PID...] Show manual for one or more units\n"
4648 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4650 " list-dependencies [NAME] Recursively show units which are required\n"
4651 " or wanted by this unit or by which this\n"
4652 " unit is required or wanted\n\n"
4653 "Unit File Commands:\n"
4654 " list-unit-files List installed unit files\n"
4655 " enable [NAME...] Enable one or more unit files\n"
4656 " disable [NAME...] Disable one or more unit files\n"
4657 " reenable [NAME...] Reenable one or more unit files\n"
4658 " preset [NAME...] Enable/disable one or more unit files\n"
4659 " based on preset configuration\n"
4660 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4661 " mask [NAME...] Mask one or more units\n"
4662 " unmask [NAME...] Unmask one or more units\n"
4663 " link [PATH...] Link one or more units files into\n"
4664 " the search path\n"
4665 " get-default Get the name of the default target\n"
4666 " set-default NAME Set the default target\n\n"
4668 " list-jobs List jobs\n"
4669 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4670 "Snapshot Commands:\n"
4671 " snapshot [NAME] Create a snapshot\n"
4672 " delete [NAME...] Remove one or more snapshots\n\n"
4673 "Environment Commands:\n"
4674 " show-environment Dump environment\n"
4675 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4676 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4677 "Manager Lifecycle Commands:\n"
4678 " daemon-reload Reload systemd manager configuration\n"
4679 " daemon-reexec Reexecute systemd manager\n\n"
4680 "System Commands:\n"
4681 " default Enter system default mode\n"
4682 " rescue Enter system rescue mode\n"
4683 " emergency Enter system emergency mode\n"
4684 " halt Shut down and halt the system\n"
4685 " poweroff Shut down and power-off the system\n"
4686 " reboot [ARG] Shut down and reboot the system\n"
4687 " kexec Shut down and reboot the system with kexec\n"
4688 " exit Request user instance exit\n"
4689 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4690 " suspend Suspend the system\n"
4691 " hibernate Hibernate the system\n"
4692 " hybrid-sleep Hibernate and suspend the system\n",
4693 program_invocation_short_name);
4698 static int halt_help(void) {
4700 printf("%s [OPTIONS...]%s\n\n"
4701 "%s the system.\n\n"
4702 " --help Show this help\n"
4703 " --halt Halt the machine\n"
4704 " -p --poweroff Switch off the machine\n"
4705 " --reboot Reboot the machine\n"
4706 " -f --force Force immediate halt/power-off/reboot\n"
4707 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4708 " -d --no-wtmp Don't write wtmp record\n"
4709 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4710 program_invocation_short_name,
4711 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4712 arg_action == ACTION_REBOOT ? "Reboot" :
4713 arg_action == ACTION_POWEROFF ? "Power off" :
4719 static int shutdown_help(void) {
4721 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4722 "Shut down the system.\n\n"
4723 " --help Show this help\n"
4724 " -H --halt Halt the machine\n"
4725 " -P --poweroff Power-off the machine\n"
4726 " -r --reboot Reboot the machine\n"
4727 " -h Equivalent to --poweroff, overridden by --halt\n"
4728 " -k Don't halt/power-off/reboot, just send warnings\n"
4729 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4730 " -c Cancel a pending shutdown\n",
4731 program_invocation_short_name);
4736 static int telinit_help(void) {
4738 printf("%s [OPTIONS...] {COMMAND}\n\n"
4739 "Send control commands to the init daemon.\n\n"
4740 " --help Show this help\n"
4741 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4743 " 0 Power-off the machine\n"
4744 " 6 Reboot the machine\n"
4745 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4746 " 1, s, S Enter rescue mode\n"
4747 " q, Q Reload init daemon configuration\n"
4748 " u, U Reexecute init daemon\n",
4749 program_invocation_short_name);
4754 static int runlevel_help(void) {
4756 printf("%s [OPTIONS...]\n\n"
4757 "Prints the previous and current runlevel of the init system.\n\n"
4758 " --help Show this help\n",
4759 program_invocation_short_name);
4764 static int help_types(void) {
4768 puts("Available unit types:");
4769 for(i = 0; i < _UNIT_TYPE_MAX; i++) {
4770 t = unit_type_to_string(i);
4778 static int systemctl_parse_argv(int argc, char *argv[]) {
4787 ARG_IGNORE_DEPENDENCIES,
4799 ARG_NO_ASK_PASSWORD,
4807 static const struct option options[] = {
4808 { "help", no_argument, NULL, 'h' },
4809 { "version", no_argument, NULL, ARG_VERSION },
4810 { "type", required_argument, NULL, 't' },
4811 { "property", required_argument, NULL, 'p' },
4812 { "all", no_argument, NULL, 'a' },
4813 { "reverse", no_argument, NULL, ARG_REVERSE },
4814 { "after", no_argument, NULL, ARG_AFTER },
4815 { "before", no_argument, NULL, ARG_BEFORE },
4816 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4817 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4818 { "full", no_argument, NULL, 'l' },
4819 { "fail", no_argument, NULL, ARG_FAIL },
4820 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
4821 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
4822 { "ignore-inhibitors", no_argument, NULL, 'i' },
4823 { "user", no_argument, NULL, ARG_USER },
4824 { "system", no_argument, NULL, ARG_SYSTEM },
4825 { "global", no_argument, NULL, ARG_GLOBAL },
4826 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4827 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4828 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4829 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4830 { "quiet", no_argument, NULL, 'q' },
4831 { "root", required_argument, NULL, ARG_ROOT },
4832 { "force", no_argument, NULL, ARG_FORCE },
4833 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4834 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4835 { "signal", required_argument, NULL, 's' },
4836 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4837 { "host", required_argument, NULL, 'H' },
4838 { "machine", required_argument, NULL, 'M' },
4839 { "runtime", no_argument, NULL, ARG_RUNTIME },
4840 { "lines", required_argument, NULL, 'n' },
4841 { "output", required_argument, NULL, 'o' },
4842 { "plain", no_argument, NULL, ARG_PLAIN },
4843 { "state", required_argument, NULL, ARG_STATE },
4852 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
4857 return systemctl_help();
4860 puts(PACKAGE_STRING);
4861 puts(SYSTEMD_FEATURES);
4868 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4869 _cleanup_free_ char *type;
4871 type = strndup(word, size);
4875 if (streq(type, "help")) {
4880 if (unit_type_from_string(type) >= 0) {
4881 if (strv_push(&arg_types, type))
4887 /* It's much nicer to use --state= for
4888 * load states, but let's support this
4889 * in --types= too for compatibility
4890 * with old versions */
4891 if (unit_load_state_from_string(optarg) >= 0) {
4892 if (strv_push(&arg_states, type) < 0)
4898 log_error("Unknown unit type or load state '%s'.", type);
4899 log_info("Use -t help to see a list of allowed values.");
4907 /* Make sure that if the empty property list
4908 was specified, we won't show any properties. */
4909 if (isempty(optarg) && !arg_properties) {
4910 arg_properties = new0(char*, 1);
4911 if (!arg_properties)
4917 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4920 prop = strndup(word, size);
4924 if (strv_push(&arg_properties, prop) < 0) {
4931 /* If the user asked for a particular
4932 * property, show it to him, even if it is
4944 arg_dependency = DEPENDENCY_REVERSE;
4948 arg_dependency = DEPENDENCY_AFTER;
4952 arg_dependency = DEPENDENCY_BEFORE;
4955 case ARG_SHOW_TYPES:
4956 arg_show_types = true;
4960 arg_job_mode = "fail";
4963 case ARG_IRREVERSIBLE:
4964 arg_job_mode = "replace-irreversibly";
4967 case ARG_IGNORE_DEPENDENCIES:
4968 arg_job_mode = "ignore-dependencies";
4972 arg_scope = UNIT_FILE_USER;
4976 arg_scope = UNIT_FILE_SYSTEM;
4980 arg_scope = UNIT_FILE_GLOBAL;
4984 arg_no_block = true;
4988 arg_no_legend = true;
4992 arg_no_pager = true;
5008 if (strv_extend(&arg_states, "failed") < 0)
5026 arg_no_reload = true;
5030 arg_kill_who = optarg;
5034 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5035 log_error("Failed to parse signal string %s.", optarg);
5040 case ARG_NO_ASK_PASSWORD:
5041 arg_ask_password = false;
5045 arg_transport = BUS_TRANSPORT_REMOTE;
5050 arg_transport = BUS_TRANSPORT_CONTAINER;
5059 if (safe_atou(optarg, &arg_lines) < 0) {
5060 log_error("Failed to parse lines '%s'", optarg);
5066 arg_output = output_mode_from_string(optarg);
5067 if (arg_output < 0) {
5068 log_error("Unknown output '%s'.", optarg);
5074 arg_ignore_inhibitors = true;
5085 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5088 s = strndup(word, size);
5092 if (strv_push(&arg_states, s) < 0) {
5104 assert_not_reached("Unhandled option");
5108 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5109 log_error("Cannot access user instance remotely.");
5116 static int halt_parse_argv(int argc, char *argv[]) {
5125 static const struct option options[] = {
5126 { "help", no_argument, NULL, ARG_HELP },
5127 { "halt", no_argument, NULL, ARG_HALT },
5128 { "poweroff", no_argument, NULL, 'p' },
5129 { "reboot", no_argument, NULL, ARG_REBOOT },
5130 { "force", no_argument, NULL, 'f' },
5131 { "wtmp-only", no_argument, NULL, 'w' },
5132 { "no-wtmp", no_argument, NULL, 'd' },
5133 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5142 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5143 if (runlevel == '0' || runlevel == '6')
5146 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5153 arg_action = ACTION_HALT;
5157 if (arg_action != ACTION_REBOOT)
5158 arg_action = ACTION_POWEROFF;
5162 arg_action = ACTION_REBOOT;
5184 /* Compatibility nops */
5191 assert_not_reached("Unhandled option");
5195 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5196 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5198 log_error("Failed to write reboot param to "
5199 REBOOT_PARAM_FILE": %s", strerror(-r));
5202 } else if (optind < argc) {
5203 log_error("Too many arguments.");
5210 static int parse_time_spec(const char *t, usec_t *_u) {
5214 if (streq(t, "now"))
5216 else if (!strchr(t, ':')) {
5219 if (safe_atou64(t, &u) < 0)
5222 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5231 hour = strtol(t, &e, 10);
5232 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5235 minute = strtol(e+1, &e, 10);
5236 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5239 n = now(CLOCK_REALTIME);
5240 s = (time_t) (n / USEC_PER_SEC);
5242 assert_se(localtime_r(&s, &tm));
5244 tm.tm_hour = (int) hour;
5245 tm.tm_min = (int) minute;
5248 assert_se(s = mktime(&tm));
5250 *_u = (usec_t) s * USEC_PER_SEC;
5253 *_u += USEC_PER_DAY;
5259 static int shutdown_parse_argv(int argc, char *argv[]) {
5266 static const struct option options[] = {
5267 { "help", no_argument, NULL, ARG_HELP },
5268 { "halt", no_argument, NULL, 'H' },
5269 { "poweroff", no_argument, NULL, 'P' },
5270 { "reboot", no_argument, NULL, 'r' },
5271 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5272 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5281 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5285 return shutdown_help();
5288 arg_action = ACTION_HALT;
5292 arg_action = ACTION_POWEROFF;
5297 arg_action = ACTION_KEXEC;
5299 arg_action = ACTION_REBOOT;
5303 arg_action = ACTION_KEXEC;
5307 if (arg_action != ACTION_HALT)
5308 arg_action = ACTION_POWEROFF;
5321 /* Compatibility nops */
5325 arg_action = ACTION_CANCEL_SHUTDOWN;
5332 assert_not_reached("Unhandled option");
5336 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5337 r = parse_time_spec(argv[optind], &arg_when);
5339 log_error("Failed to parse time specification: %s", argv[optind]);
5343 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5345 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5346 /* No time argument for shutdown cancel */
5347 arg_wall = argv + optind;
5348 else if (argc > optind + 1)
5349 /* We skip the time argument */
5350 arg_wall = argv + optind + 1;
5357 static int telinit_parse_argv(int argc, char *argv[]) {
5364 static const struct option options[] = {
5365 { "help", no_argument, NULL, ARG_HELP },
5366 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5370 static const struct {
5374 { '0', ACTION_POWEROFF },
5375 { '6', ACTION_REBOOT },
5376 { '1', ACTION_RESCUE },
5377 { '2', ACTION_RUNLEVEL2 },
5378 { '3', ACTION_RUNLEVEL3 },
5379 { '4', ACTION_RUNLEVEL4 },
5380 { '5', ACTION_RUNLEVEL5 },
5381 { 's', ACTION_RESCUE },
5382 { 'S', ACTION_RESCUE },
5383 { 'q', ACTION_RELOAD },
5384 { 'Q', ACTION_RELOAD },
5385 { 'u', ACTION_REEXEC },
5386 { 'U', ACTION_REEXEC }
5395 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5399 return telinit_help();
5409 assert_not_reached("Unhandled option");
5413 if (optind >= argc) {
5418 if (optind + 1 < argc) {
5419 log_error("Too many arguments.");
5423 if (strlen(argv[optind]) != 1) {
5424 log_error("Expected single character argument.");
5428 for (i = 0; i < ELEMENTSOF(table); i++)
5429 if (table[i].from == argv[optind][0])
5432 if (i >= ELEMENTSOF(table)) {
5433 log_error("Unknown command '%s'.", argv[optind]);
5437 arg_action = table[i].to;
5444 static int runlevel_parse_argv(int argc, char *argv[]) {
5450 static const struct option options[] = {
5451 { "help", no_argument, NULL, ARG_HELP },
5460 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5464 return runlevel_help();
5471 assert_not_reached("Unhandled option");
5475 if (optind < argc) {
5476 log_error("Too many arguments.");
5483 static int parse_argv(int argc, char *argv[]) {
5487 if (program_invocation_short_name) {
5489 if (strstr(program_invocation_short_name, "halt")) {
5490 arg_action = ACTION_HALT;
5491 return halt_parse_argv(argc, argv);
5492 } else if (strstr(program_invocation_short_name, "poweroff")) {
5493 arg_action = ACTION_POWEROFF;
5494 return halt_parse_argv(argc, argv);
5495 } else if (strstr(program_invocation_short_name, "reboot")) {
5497 arg_action = ACTION_KEXEC;
5499 arg_action = ACTION_REBOOT;
5500 return halt_parse_argv(argc, argv);
5501 } else if (strstr(program_invocation_short_name, "shutdown")) {
5502 arg_action = ACTION_POWEROFF;
5503 return shutdown_parse_argv(argc, argv);
5504 } else if (strstr(program_invocation_short_name, "init")) {
5506 if (sd_booted() > 0) {
5507 arg_action = _ACTION_INVALID;
5508 return telinit_parse_argv(argc, argv);
5510 /* Hmm, so some other init system is
5511 * running, we need to forward this
5512 * request to it. For now we simply
5513 * guess that it is Upstart. */
5515 execv(TELINIT, argv);
5517 log_error("Couldn't find an alternative telinit implementation to spawn.");
5521 } else if (strstr(program_invocation_short_name, "runlevel")) {
5522 arg_action = ACTION_RUNLEVEL;
5523 return runlevel_parse_argv(argc, argv);
5527 arg_action = ACTION_SYSTEMCTL;
5528 return systemctl_parse_argv(argc, argv);
5531 _pure_ static int action_to_runlevel(void) {
5533 static const char table[_ACTION_MAX] = {
5534 [ACTION_HALT] = '0',
5535 [ACTION_POWEROFF] = '0',
5536 [ACTION_REBOOT] = '6',
5537 [ACTION_RUNLEVEL2] = '2',
5538 [ACTION_RUNLEVEL3] = '3',
5539 [ACTION_RUNLEVEL4] = '4',
5540 [ACTION_RUNLEVEL5] = '5',
5541 [ACTION_RESCUE] = '1'
5544 assert(arg_action < _ACTION_MAX);
5546 return table[arg_action];
5549 static int talk_initctl(void) {
5551 struct init_request request = {
5552 .magic = INIT_MAGIC,
5554 .cmd = INIT_CMD_RUNLVL
5557 _cleanup_close_ int fd = -1;
5561 rl = action_to_runlevel();
5565 request.runlevel = rl;
5567 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5569 if (errno == ENOENT)
5572 log_error("Failed to open "INIT_FIFO": %m");
5577 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5579 log_error("Failed to write to "INIT_FIFO": %m");
5580 return errno > 0 ? -errno : -EIO;
5586 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5588 static const struct {
5596 int (* const dispatch)(sd_bus *bus, char **args);
5598 { "list-units", LESS, 1, list_units },
5599 { "list-unit-files", EQUAL, 1, list_unit_files },
5600 { "list-sockets", LESS, 1, list_sockets },
5601 { "list-timers", LESS, 1, list_timers },
5602 { "list-jobs", EQUAL, 1, list_jobs },
5603 { "clear-jobs", EQUAL, 1, daemon_reload },
5604 { "cancel", MORE, 2, cancel_job },
5605 { "start", MORE, 2, start_unit },
5606 { "stop", MORE, 2, start_unit },
5607 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5608 { "reload", MORE, 2, start_unit },
5609 { "restart", MORE, 2, start_unit },
5610 { "try-restart", MORE, 2, start_unit },
5611 { "reload-or-restart", MORE, 2, start_unit },
5612 { "reload-or-try-restart", MORE, 2, start_unit },
5613 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5614 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5615 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5616 { "isolate", EQUAL, 2, start_unit },
5617 { "kill", MORE, 2, kill_unit },
5618 { "is-active", MORE, 2, check_unit_active },
5619 { "check", MORE, 2, check_unit_active },
5620 { "is-failed", MORE, 2, check_unit_failed },
5621 { "show", MORE, 1, show },
5622 { "status", MORE, 1, show },
5623 { "help", MORE, 2, show },
5624 { "snapshot", LESS, 2, snapshot },
5625 { "delete", MORE, 2, delete_snapshot },
5626 { "daemon-reload", EQUAL, 1, daemon_reload },
5627 { "daemon-reexec", EQUAL, 1, daemon_reload },
5628 { "show-environment", EQUAL, 1, show_environment },
5629 { "set-environment", MORE, 2, set_environment },
5630 { "unset-environment", MORE, 2, set_environment },
5631 { "halt", EQUAL, 1, start_special },
5632 { "poweroff", EQUAL, 1, start_special },
5633 { "reboot", EQUAL, 1, start_special },
5634 { "kexec", EQUAL, 1, start_special },
5635 { "suspend", EQUAL, 1, start_special },
5636 { "hibernate", EQUAL, 1, start_special },
5637 { "hybrid-sleep", EQUAL, 1, start_special },
5638 { "default", EQUAL, 1, start_special },
5639 { "rescue", EQUAL, 1, start_special },
5640 { "emergency", EQUAL, 1, start_special },
5641 { "exit", EQUAL, 1, start_special },
5642 { "reset-failed", MORE, 1, reset_failed },
5643 { "enable", MORE, 2, enable_unit },
5644 { "disable", MORE, 2, enable_unit },
5645 { "is-enabled", MORE, 2, unit_is_enabled },
5646 { "reenable", MORE, 2, enable_unit },
5647 { "preset", MORE, 2, enable_unit },
5648 { "mask", MORE, 2, enable_unit },
5649 { "unmask", MORE, 2, enable_unit },
5650 { "link", MORE, 2, enable_unit },
5651 { "switch-root", MORE, 2, switch_root },
5652 { "list-dependencies", LESS, 2, list_dependencies },
5653 { "set-default", EQUAL, 2, enable_unit },
5654 { "get-default", LESS, 1, get_default },
5655 { "set-property", MORE, 3, set_property },
5664 left = argc - optind;
5667 /* Special rule: no arguments means "list-units" */
5670 if (streq(argv[optind], "help") && !argv[optind+1]) {
5671 log_error("This command expects one or more "
5672 "unit names. Did you mean --help?");
5676 for (i = 0; i < ELEMENTSOF(verbs); i++)
5677 if (streq(argv[optind], verbs[i].verb))
5680 if (i >= ELEMENTSOF(verbs)) {
5681 log_error("Unknown operation '%s'.", argv[optind]);
5686 switch (verbs[i].argc_cmp) {
5689 if (left != verbs[i].argc) {
5690 log_error("Invalid number of arguments.");
5697 if (left < verbs[i].argc) {
5698 log_error("Too few arguments.");
5705 if (left > verbs[i].argc) {
5706 log_error("Too many arguments.");
5713 assert_not_reached("Unknown comparison operator.");
5716 /* Require a bus connection for all operations but
5718 if (!streq(verbs[i].verb, "enable") &&
5719 !streq(verbs[i].verb, "disable") &&
5720 !streq(verbs[i].verb, "is-enabled") &&
5721 !streq(verbs[i].verb, "list-unit-files") &&
5722 !streq(verbs[i].verb, "reenable") &&
5723 !streq(verbs[i].verb, "preset") &&
5724 !streq(verbs[i].verb, "mask") &&
5725 !streq(verbs[i].verb, "unmask") &&
5726 !streq(verbs[i].verb, "link") &&
5727 !streq(verbs[i].verb, "set-default") &&
5728 !streq(verbs[i].verb, "get-default")) {
5730 if (running_in_chroot() > 0) {
5731 log_info("Running in chroot, ignoring request.");
5735 if (((!streq(verbs[i].verb, "reboot") &&
5736 !streq(verbs[i].verb, "halt") &&
5737 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5738 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5744 if (!bus && !avoid_bus()) {
5745 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5750 return verbs[i].dispatch(bus, argv + optind);
5753 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5755 struct sd_shutdown_command c = {
5762 union sockaddr_union sockaddr = {
5763 .un.sun_family = AF_UNIX,
5764 .un.sun_path = "/run/systemd/shutdownd",
5767 struct iovec iovec[2] = {{
5768 .iov_base = (char*) &c,
5769 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5772 struct msghdr msghdr = {
5773 .msg_name = &sockaddr,
5774 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5775 + sizeof("/run/systemd/shutdownd") - 1,
5780 _cleanup_close_ int fd;
5782 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5786 if (!isempty(message)) {
5787 iovec[1].iov_base = (char*) message;
5788 iovec[1].iov_len = strlen(message);
5789 msghdr.msg_iovlen++;
5792 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5798 static int reload_with_fallback(sd_bus *bus) {
5801 /* First, try systemd via D-Bus. */
5802 if (daemon_reload(bus, NULL) >= 0)
5806 /* Nothing else worked, so let's try signals */
5807 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5809 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5810 log_error("kill() failed: %m");
5817 static int start_with_fallback(sd_bus *bus) {
5820 /* First, try systemd via D-Bus. */
5821 if (start_unit(bus, NULL) >= 0)
5825 /* Nothing else worked, so let's try
5827 if (talk_initctl() > 0)
5830 log_error("Failed to talk to init daemon.");
5834 warn_wall(arg_action);
5838 static int halt_now(enum action a) {
5840 /* Make sure C-A-D is handled by the kernel from this
5842 reboot(RB_ENABLE_CAD);
5847 log_info("Halting.");
5848 reboot(RB_HALT_SYSTEM);
5851 case ACTION_POWEROFF:
5852 log_info("Powering off.");
5853 reboot(RB_POWER_OFF);
5856 case ACTION_REBOOT: {
5857 _cleanup_free_ char *param = NULL;
5859 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
5860 log_info("Rebooting with argument '%s'.", param);
5861 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
5862 LINUX_REBOOT_CMD_RESTART2, param);
5865 log_info("Rebooting.");
5866 reboot(RB_AUTOBOOT);
5871 assert_not_reached("Unknown action.");
5875 static int halt_main(sd_bus *bus) {
5878 r = check_inhibitors(bus, arg_action);
5882 if (geteuid() != 0) {
5883 /* Try logind if we are a normal user and no special
5884 * mode applies. Maybe PolicyKit allows us to shutdown
5887 if (arg_when <= 0 &&
5890 (arg_action == ACTION_POWEROFF ||
5891 arg_action == ACTION_REBOOT)) {
5892 r = reboot_with_logind(bus, arg_action);
5897 log_error("Must be root.");
5902 _cleanup_free_ char *m;
5904 m = strv_join(arg_wall, " ");
5908 r = send_shutdownd(arg_when,
5909 arg_action == ACTION_HALT ? 'H' :
5910 arg_action == ACTION_POWEROFF ? 'P' :
5911 arg_action == ACTION_KEXEC ? 'K' :
5918 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
5920 char date[FORMAT_TIMESTAMP_MAX];
5922 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5923 format_timestamp(date, sizeof(date), arg_when));
5928 if (!arg_dry && !arg_force)
5929 return start_with_fallback(bus);
5932 if (sd_booted() > 0)
5933 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5935 r = utmp_put_shutdown();
5937 log_warning("Failed to write utmp record: %s", strerror(-r));
5944 r = halt_now(arg_action);
5945 log_error("Failed to reboot: %s", strerror(-r));
5950 static int runlevel_main(void) {
5951 int r, runlevel, previous;
5953 r = utmp_get_runlevel(&runlevel, &previous);
5960 previous <= 0 ? 'N' : previous,
5961 runlevel <= 0 ? 'N' : runlevel);
5966 int main(int argc, char*argv[]) {
5967 _cleanup_bus_unref_ sd_bus *bus = NULL;
5970 setlocale(LC_ALL, "");
5971 log_parse_environment();
5974 /* Explicitly not on_tty() to avoid setting cached value.
5975 * This becomes relevant for piping output which might be
5977 original_stdout_is_tty = isatty(STDOUT_FILENO);
5979 r = parse_argv(argc, argv);
5983 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5984 * let's shortcut this */
5985 if (arg_action == ACTION_RUNLEVEL) {
5986 r = runlevel_main();
5990 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
5991 log_info("Running in chroot, ignoring request.");
5997 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
5999 /* systemctl_main() will print an error message for the bus
6000 * connection, but only if it needs to */
6002 switch (arg_action) {
6004 case ACTION_SYSTEMCTL:
6005 r = systemctl_main(bus, argc, argv, r);
6009 case ACTION_POWEROFF:
6015 case ACTION_RUNLEVEL2:
6016 case ACTION_RUNLEVEL3:
6017 case ACTION_RUNLEVEL4:
6018 case ACTION_RUNLEVEL5:
6020 case ACTION_EMERGENCY:
6021 case ACTION_DEFAULT:
6022 r = start_with_fallback(bus);
6027 r = reload_with_fallback(bus);
6030 case ACTION_CANCEL_SHUTDOWN: {
6031 _cleanup_free_ char *m = NULL;
6034 m = strv_join(arg_wall, " ");
6041 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6043 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6047 case ACTION_RUNLEVEL:
6048 case _ACTION_INVALID:
6050 assert_not_reached("Unknown action");
6055 ask_password_agent_close();
6056 polkit_agent_close();
6058 strv_free(arg_types);
6059 strv_free(arg_states);
6060 strv_free(arg_properties);
6062 return r < 0 ? EXIT_FAILURE : r;