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;
753 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
761 r = sd_bus_get_property_trivial(
763 "org.freedesktop.systemd1",
765 "org.freedesktop.systemd1.Timer",
766 "NextElapseUSecMonotonic",
771 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
775 r = sd_bus_get_property_trivial(
777 "org.freedesktop.systemd1",
779 "org.freedesktop.systemd1.Timer",
780 "NextElapseUSecRealtime",
785 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
799 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
803 if (a->next_elapse < b->next_elapse)
805 if (a->next_elapse > b->next_elapse)
808 return strcmp(a->id, b->id);
811 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
812 struct timer_info *t;
814 nextlen = sizeof("NEXT") - 1,
815 leftlen = sizeof("LEFT") - 1,
816 unitlen = sizeof("UNIT") - 1,
817 activatelen = sizeof("ACTIVATES") - 1;
819 const char *on, *off;
821 assert(timer_infos || n == 0);
823 for (t = timer_infos; t < timer_infos + n; t++) {
827 if (t->next_elapse > 0) {
828 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
830 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
831 nextlen = MAX(nextlen, strlen(tstamp) + 1);
833 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
834 leftlen = MAX(leftlen, strlen(trel));
837 unitlen = MAX(unitlen, strlen(t->id));
839 STRV_FOREACH(a, t->triggered)
840 ul += strlen(*a) + 2*(a != t->triggered);
841 activatelen = MAX(activatelen, ul);
846 printf("%-*s %-*s %-*s %s\n",
852 for (t = timer_infos; t < timer_infos + n; t++) {
853 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
856 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
857 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
859 printf("%-*s %-*s %-*s",
860 nextlen, tstamp, leftlen, trel, unitlen, t->id);
862 STRV_FOREACH(a, t->triggered)
864 a == t->triggered ? "" : ",", *a);
868 on = ansi_highlight();
869 off = ansi_highlight_off();
873 on = ansi_highlight_red();
874 off = ansi_highlight_off();
877 if (!arg_no_legend) {
878 printf("%s%u timers listed.%s\n", on, n, off);
880 printf("Pass --all to see loaded but inactive timers, too.\n");
886 static int list_timers(sd_bus *bus, char **args) {
888 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
889 _cleanup_free_ struct timer_info *timer_infos = NULL;
890 _cleanup_free_ UnitInfo *unit_infos = NULL;
891 struct timer_info *t;
898 pager_open_if_enabled();
900 n = get_unit_list(bus, &reply, &unit_infos);
904 dual_timestamp_get(&nw);
906 for (u = unit_infos; u < unit_infos + n; u++) {
907 _cleanup_strv_free_ char **triggered = NULL;
911 if (!output_show_unit(u))
914 if (!endswith(u->id, ".timer"))
917 r = get_triggered_units(bus, u->unit_path, &triggered);
921 r = get_next_elapse(bus, u->unit_path, &next);
925 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
928 if (next.monotonic > nw.monotonic)
929 converted = nw.realtime + (next.monotonic - nw.monotonic);
931 converted = nw.realtime - (nw.monotonic - next.monotonic);
933 if (next.realtime != (usec_t) -1 && next.realtime > 0)
934 m = MIN(converted, next.realtime);
940 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
945 timer_infos[c++] = (struct timer_info) {
948 .triggered = triggered,
951 triggered = NULL; /* avoid cleanup */
954 qsort_safe(timer_infos, c, sizeof(struct timer_info),
955 (__compar_fn_t) timer_info_compare);
957 output_timers_list(timer_infos, c);
960 for (t = timer_infos; t < timer_infos + c; t++)
961 strv_free(t->triggered);
966 static int compare_unit_file_list(const void *a, const void *b) {
968 const UnitFileList *u = a, *v = b;
970 d1 = strrchr(u->path, '.');
971 d2 = strrchr(v->path, '.');
976 r = strcasecmp(d1, d2);
981 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
984 static bool output_show_unit_file(const UnitFileList *u) {
987 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
990 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
991 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
992 const UnitFileList *u;
994 max_id_len = sizeof("UNIT FILE")-1;
995 state_cols = sizeof("STATE")-1;
997 for (u = units; u < units + c; u++) {
998 if (!output_show_unit_file(u))
1001 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
1002 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1006 unsigned basic_cols;
1008 id_cols = MIN(max_id_len, 25u);
1009 basic_cols = 1 + id_cols + state_cols;
1010 if (basic_cols < (unsigned) columns())
1011 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1013 id_cols = max_id_len;
1016 printf("%-*s %-*s\n",
1017 id_cols, "UNIT FILE",
1018 state_cols, "STATE");
1020 for (u = units; u < units + c; u++) {
1021 _cleanup_free_ char *e = NULL;
1022 const char *on, *off;
1025 if (!output_show_unit_file(u))
1030 if (u->state == UNIT_FILE_MASKED ||
1031 u->state == UNIT_FILE_MASKED_RUNTIME ||
1032 u->state == UNIT_FILE_DISABLED ||
1033 u->state == UNIT_FILE_INVALID) {
1034 on = ansi_highlight_red();
1035 off = ansi_highlight_off();
1036 } else if (u->state == UNIT_FILE_ENABLED) {
1037 on = ansi_highlight_green();
1038 off = ansi_highlight_off();
1042 id = path_get_file_name(u->path);
1044 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1046 printf("%-*s %s%-*s%s\n",
1047 id_cols, e ? e : id,
1048 on, state_cols, unit_file_state_to_string(u->state), off);
1052 printf("\n%u unit files listed.\n", n_shown);
1055 static int list_unit_files(sd_bus *bus, char **args) {
1056 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1057 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1058 _cleanup_free_ UnitFileList *units = NULL;
1064 pager_open_if_enabled();
1072 h = hashmap_new(string_hash_func, string_compare_func);
1076 r = unit_file_get_list(arg_scope, arg_root, h);
1078 unit_file_list_free(h);
1079 log_error("Failed to get unit file list: %s", strerror(-r));
1083 n_units = hashmap_size(h);
1084 units = new(UnitFileList, n_units);
1086 unit_file_list_free(h);
1090 HASHMAP_FOREACH(u, h, i) {
1091 memcpy(units + c++, u, sizeof(UnitFileList));
1095 assert(c == n_units);
1100 r = sd_bus_call_method(
1102 "org.freedesktop.systemd1",
1103 "/org/freedesktop/systemd1",
1104 "org.freedesktop.systemd1.Manager",
1110 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1114 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1116 return bus_log_parse_error(r);
1118 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1120 if (!GREEDY_REALLOC(units, size, c + 1))
1123 units[c++] = (struct UnitFileList) {
1125 unit_file_state_from_string(state)
1129 return bus_log_parse_error(r);
1131 r = sd_bus_message_exit_container(reply);
1133 return bus_log_parse_error(r);
1137 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1138 output_unit_file_list(units, c);
1144 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1145 _cleanup_free_ char *n = NULL;
1146 size_t max_len = MAX(columns(),20u);
1152 for (i = level - 1; i >= 0; i--) {
1154 if(len > max_len - 3 && !arg_full) {
1155 printf("%s...\n",max_len % 2 ? "" : " ");
1158 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1162 if(len > max_len - 3 && !arg_full) {
1163 printf("%s...\n",max_len % 2 ? "" : " ");
1167 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1171 printf("%s\n", name);
1175 n = ellipsize(name, max_len-len, 100);
1183 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1185 static const char *dependencies[] = {
1186 [DEPENDENCY_FORWARD] = "Requires\0"
1187 "RequiresOverridable\0"
1189 "RequisiteOverridable\0"
1191 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1192 "RequiredByOverridable\0"
1195 [DEPENDENCY_AFTER] = "After\0",
1196 [DEPENDENCY_BEFORE] = "Before\0",
1199 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1200 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1201 _cleanup_strv_free_ char **ret = NULL;
1202 _cleanup_free_ char *path = NULL;
1208 assert(arg_dependency < ELEMENTSOF(dependencies));
1210 path = unit_dbus_path_from_name(name);
1214 r = sd_bus_call_method(
1216 "org.freedesktop.systemd1",
1218 "org.freedesktop.DBus.Properties",
1222 "s", "org.freedesktop.systemd1.Unit");
1224 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1228 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1230 return bus_log_parse_error(r);
1232 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1235 r = sd_bus_message_read(reply, "s", &prop);
1237 return bus_log_parse_error(r);
1239 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1240 r = sd_bus_message_skip(reply, "v");
1242 return bus_log_parse_error(r);
1245 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1247 return bus_log_parse_error(r);
1249 r = bus_message_read_strv_extend(reply, &ret);
1251 return bus_log_parse_error(r);
1253 r = sd_bus_message_exit_container(reply);
1255 return bus_log_parse_error(r);
1258 r = sd_bus_message_exit_container(reply);
1260 return bus_log_parse_error(r);
1264 return bus_log_parse_error(r);
1266 r = sd_bus_message_exit_container(reply);
1268 return bus_log_parse_error(r);
1276 static int list_dependencies_compare(const void *_a, const void *_b) {
1277 const char **a = (const char**) _a, **b = (const char**) _b;
1279 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1281 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1284 return strcasecmp(*a, *b);
1287 static int list_dependencies_one(
1292 unsigned int branches) {
1294 _cleanup_strv_free_ char **deps = NULL, **u;
1302 u = strv_append(*units, name);
1306 r = list_dependencies_get_dependencies(bus, name, &deps);
1310 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1312 STRV_FOREACH(c, deps) {
1313 if (strv_contains(u, *c)) {
1315 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1322 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1326 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1327 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1342 static int list_dependencies(sd_bus *bus, char **args) {
1343 _cleanup_strv_free_ char **units = NULL;
1344 _cleanup_free_ char *unit = NULL;
1350 unit = unit_name_mangle(args[1]);
1355 u = SPECIAL_DEFAULT_TARGET;
1357 pager_open_if_enabled();
1361 return list_dependencies_one(bus, u, 0, &units, 0);
1364 static int get_default(sd_bus *bus, char **args) {
1365 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1366 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1367 _cleanup_free_ char *_path = NULL;
1371 if (!bus || avoid_bus()) {
1372 r = unit_file_get_default(arg_scope, arg_root, &_path);
1374 log_error("Failed to get default target: %s", strerror(-r));
1380 r = sd_bus_call_method(
1382 "org.freedesktop.systemd1",
1383 "/org/freedesktop/systemd1",
1384 "org.freedesktop.systemd1.Manager",
1390 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1394 r = sd_bus_message_read(reply, "s", &path);
1396 return bus_log_parse_error(r);
1400 printf("%s\n", path);
1407 const char *name, *type, *state;
1410 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1411 unsigned id_len, unit_len, type_len, state_len;
1412 const struct job_info *j;
1413 const char *on, *off;
1414 bool shorten = false;
1416 assert(n == 0 || jobs);
1419 on = ansi_highlight_green();
1420 off = ansi_highlight_off();
1422 printf("%sNo jobs running.%s\n", on, off);
1426 pager_open_if_enabled();
1428 id_len = sizeof("JOB")-1;
1429 unit_len = sizeof("UNIT")-1;
1430 type_len = sizeof("TYPE")-1;
1431 state_len = sizeof("STATE")-1;
1433 for (j = jobs; j < jobs + n; j++) {
1434 uint32_t id = j->id;
1435 assert(j->name && j->type && j->state);
1437 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1438 unit_len = MAX(unit_len, strlen(j->name));
1439 type_len = MAX(type_len, strlen(j->type));
1440 state_len = MAX(state_len, strlen(j->state));
1443 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1444 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1449 printf("%*s %-*s %-*s %-*s\n",
1453 state_len, "STATE");
1455 for (j = jobs; j < jobs + n; j++) {
1456 _cleanup_free_ char *e = NULL;
1458 if (streq(j->state, "running")) {
1459 on = ansi_highlight();
1460 off = ansi_highlight_off();
1464 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1465 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1467 on, unit_len, e ? e : j->name, off,
1469 on, state_len, j->state, off);
1472 if (!arg_no_legend) {
1473 on = ansi_highlight();
1474 off = ansi_highlight_off();
1476 printf("\n%s%u jobs listed%s.\n", on, n, off);
1480 static int list_jobs(sd_bus *bus, char **args) {
1481 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1482 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1483 const char *name, *type, *state, *job_path, *unit_path;
1484 _cleanup_free_ struct job_info *jobs = NULL;
1490 r = sd_bus_call_method(
1492 "org.freedesktop.systemd1",
1493 "/org/freedesktop/systemd1",
1494 "org.freedesktop.systemd1.Manager",
1500 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1504 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1506 return bus_log_parse_error(r);
1508 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1510 if (!GREEDY_REALLOC(jobs, size, c + 1))
1513 jobs[c++] = (struct job_info) {
1521 return bus_log_parse_error(r);
1523 r = sd_bus_message_exit_container(reply);
1525 return bus_log_parse_error(r);
1527 output_jobs_list(jobs, c);
1531 static int cancel_job(sd_bus *bus, char **args) {
1532 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1537 if (strv_length(args) <= 1)
1538 return daemon_reload(bus, args);
1540 STRV_FOREACH(name, args+1) {
1544 r = safe_atou32(*name, &id);
1546 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1550 r = sd_bus_call_method(
1552 "org.freedesktop.systemd1",
1553 "/org/freedesktop/systemd1",
1554 "org.freedesktop.systemd1.Manager",
1560 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1568 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1569 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1570 _cleanup_free_ char *n = NULL;
1574 /* We ignore all errors here, since this is used to show a
1577 n = unit_name_mangle(unit);
1581 /* We don't use unit_dbus_path_from_name() directly since we
1582 * don't want to load the unit if it isn't loaded. */
1584 r = sd_bus_call_method(
1586 "org.freedesktop.systemd1",
1587 "/org/freedesktop/systemd1",
1588 "org.freedesktop.systemd1.Manager",
1596 r = sd_bus_message_read(reply, "o", &path);
1600 r = sd_bus_get_property_trivial(
1602 "org.freedesktop.systemd1",
1604 "org.freedesktop.systemd1.Unit",
1614 typedef struct WaitData {
1621 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1628 log_debug("Got D-Bus request: %s.%s() on %s",
1629 sd_bus_message_get_interface(m),
1630 sd_bus_message_get_member(m),
1631 sd_bus_message_get_path(m));
1633 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1634 log_error("Warning! D-Bus connection terminated.");
1636 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1638 const char *path, *result, *unit;
1642 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1644 ret = set_remove(d->set, (char*) path);
1650 if (!isempty(result))
1651 d->result = strdup(result);
1654 d->name = strdup(unit);
1659 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1661 ret = set_remove(d->set, (char*) path);
1668 d->result = strdup(result);
1674 log_error("Failed to parse message.");
1680 static int enable_wait_for_jobs(sd_bus *bus) {
1685 r = sd_bus_add_match(
1688 "sender='org.freedesktop.systemd1',"
1689 "interface='org.freedesktop.systemd1.Manager',"
1690 "member='JobRemoved',"
1691 "path='/org/freedesktop/systemd1'",
1694 log_error("Failed to add match");
1698 /* This is slightly dirty, since we don't undo the match registrations. */
1702 static int wait_for_jobs(sd_bus *bus, Set *s) {
1703 WaitData d = { .set = s };
1709 r = sd_bus_add_filter(bus, wait_filter, &d);
1713 while (!set_isempty(s)) {
1715 r = sd_bus_process(bus, NULL);
1720 r = sd_bus_wait(bus, (uint64_t) -1);
1729 if (streq(d.result, "timeout"))
1730 log_error("Job for %s timed out.", strna(d.name));
1731 else if (streq(d.result, "canceled"))
1732 log_error("Job for %s canceled.", strna(d.name));
1733 else if (streq(d.result, "dependency"))
1734 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1735 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1736 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1739 if (streq_ptr(d.result, "timeout"))
1741 else if (streq_ptr(d.result, "canceled"))
1743 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1754 return sd_bus_remove_filter(bus, wait_filter, &d);
1757 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1758 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1759 _cleanup_free_ char *n = NULL, *state = NULL;
1765 n = unit_name_mangle(name);
1769 /* We don't use unit_dbus_path_from_name() directly since we
1770 * don't want to load the unit if it isn't loaded. */
1772 r = sd_bus_call_method(
1774 "org.freedesktop.systemd1",
1775 "/org/freedesktop/systemd1",
1776 "org.freedesktop.systemd1.Manager",
1787 r = sd_bus_message_read(reply, "o", &path);
1789 return bus_log_parse_error(r);
1791 r = sd_bus_get_property_string(
1793 "org.freedesktop.systemd1",
1795 "org.freedesktop.systemd1.Unit",
1808 return nulstr_contains(good_states, state);
1811 static int check_triggering_units(
1815 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1816 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1817 _cleanup_strv_free_ char **triggered_by = NULL;
1818 bool print_warning_label = true;
1822 n = unit_name_mangle(name);
1826 path = unit_dbus_path_from_name(n);
1830 r = sd_bus_get_property_string(
1832 "org.freedesktop.systemd1",
1834 "org.freedesktop.systemd1.Unit",
1839 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1843 if (streq(state, "masked"))
1846 r = sd_bus_get_property_strv(
1848 "org.freedesktop.systemd1",
1850 "org.freedesktop.systemd1.Unit",
1855 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1859 STRV_FOREACH(i, triggered_by) {
1860 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1862 log_error("Failed to check unit: %s", strerror(-r));
1869 if (print_warning_label) {
1870 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1871 print_warning_label = false;
1874 log_warning(" %s", *i);
1880 static int start_unit_one(
1885 sd_bus_error *error,
1888 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1889 _cleanup_free_ char *n;
1898 n = unit_name_mangle(name);
1902 r = sd_bus_call_method(
1904 "org.freedesktop.systemd1",
1905 "/org/freedesktop/systemd1",
1906 "org.freedesktop.systemd1.Manager",
1912 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1913 /* There's always a fallback possible for
1914 * legacy actions. */
1915 return -EADDRNOTAVAIL;
1917 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1921 r = sd_bus_message_read(reply, "o", &path);
1923 return bus_log_parse_error(r);
1925 if (need_daemon_reload(bus, n) > 0)
1926 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1927 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1936 r = set_consume(s, p);
1944 static const struct {
1948 } action_table[_ACTION_MAX] = {
1949 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1950 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1951 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1952 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1953 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1954 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1955 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1956 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1957 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1958 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1959 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1960 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1961 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1962 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1963 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1966 static enum action verb_to_action(const char *verb) {
1969 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1970 if (streq_ptr(action_table[i].verb, verb))
1973 return _ACTION_INVALID;
1976 static int start_unit(sd_bus *bus, char **args) {
1977 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1978 _cleanup_set_free_free_ Set *s = NULL;
1979 const char *method, *mode, *one_name;
1985 ask_password_agent_open_if_enabled();
1987 if (arg_action == ACTION_SYSTEMCTL) {
1990 streq(args[0], "stop") ||
1991 streq(args[0], "condstop") ? "StopUnit" :
1992 streq(args[0], "reload") ? "ReloadUnit" :
1993 streq(args[0], "restart") ? "RestartUnit" :
1995 streq(args[0], "try-restart") ||
1996 streq(args[0], "condrestart") ? "TryRestartUnit" :
1998 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2000 streq(args[0], "reload-or-try-restart") ||
2001 streq(args[0], "condreload") ||
2002 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2004 action = verb_to_action(args[0]);
2006 mode = streq(args[0], "isolate") ? "isolate" :
2007 action_table[action].mode ?: arg_job_mode;
2009 one_name = action_table[action].target;
2011 assert(arg_action < ELEMENTSOF(action_table));
2012 assert(action_table[arg_action].target);
2014 method = "StartUnit";
2016 mode = action_table[arg_action].mode;
2017 one_name = action_table[arg_action].target;
2020 if (!arg_no_block) {
2021 r = enable_wait_for_jobs(bus);
2023 log_error("Could not watch jobs: %s", strerror(-r));
2027 s = set_new(string_hash_func, string_compare_func);
2033 r = start_unit_one(bus, method, one_name, mode, &error, s);
2035 r = translate_bus_error_to_exit_status(r, &error);
2039 STRV_FOREACH(name, args+1) {
2042 q = start_unit_one(bus, method, *name, mode, &error, s);
2044 r = translate_bus_error_to_exit_status(r, &error);
2045 sd_bus_error_free(&error);
2050 if (!arg_no_block) {
2053 q = wait_for_jobs(bus, s);
2057 /* When stopping units, warn if they can still be triggered by
2058 * another active unit (socket, path, timer) */
2059 if (!arg_quiet && streq(method, "StopUnit")) {
2061 check_triggering_units(bus, one_name);
2063 STRV_FOREACH(name, args+1)
2064 check_triggering_units(bus, *name);
2071 /* Ask systemd-logind, which might grant access to unprivileged users
2072 * through PolicyKit */
2073 static int reboot_with_logind(sd_bus *bus, enum action a) {
2075 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2082 polkit_agent_open_if_enabled();
2090 case ACTION_POWEROFF:
2091 method = "PowerOff";
2094 case ACTION_SUSPEND:
2098 case ACTION_HIBERNATE:
2099 method = "Hibernate";
2102 case ACTION_HYBRID_SLEEP:
2103 method = "HybridSleep";
2110 r = sd_bus_call_method(
2112 "org.freedesktop.login1",
2113 "/org/freedesktop/login1",
2114 "org.freedesktop.login1.Manager",
2120 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2128 static int check_inhibitors(sd_bus *bus, enum action a) {
2130 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2131 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2132 _cleanup_strv_free_ char **sessions = NULL;
2133 const char *what, *who, *why, *mode;
2142 if (arg_ignore_inhibitors || arg_force > 0)
2154 r = sd_bus_call_method(
2156 "org.freedesktop.login1",
2157 "/org/freedesktop/login1",
2158 "org.freedesktop.login1.Manager",
2164 /* If logind is not around, then there are no inhibitors... */
2167 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2169 return bus_log_parse_error(r);
2171 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2172 _cleanup_free_ char *comm = NULL, *user = NULL;
2173 _cleanup_strv_free_ char **sv = NULL;
2175 if (!streq(mode, "block"))
2178 sv = strv_split(what, ":");
2182 if (!strv_contains(sv,
2184 a == ACTION_POWEROFF ||
2185 a == ACTION_REBOOT ||
2186 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2189 get_process_comm(pid, &comm);
2190 user = uid_to_name(uid);
2192 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2193 who, (unsigned long) pid, strna(comm), strna(user), why);
2198 return bus_log_parse_error(r);
2200 r = sd_bus_message_exit_container(reply);
2202 return bus_log_parse_error(r);
2204 /* Check for current sessions */
2205 sd_get_sessions(&sessions);
2206 STRV_FOREACH(s, sessions) {
2207 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2209 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2212 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2215 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2218 sd_session_get_tty(*s, &tty);
2219 sd_session_get_seat(*s, &seat);
2220 sd_session_get_service(*s, &service);
2221 user = uid_to_name(uid);
2223 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2230 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2231 action_table[a].verb);
2239 static int start_special(sd_bus *bus, char **args) {
2245 a = verb_to_action(args[0]);
2247 r = check_inhibitors(bus, a);
2251 if (arg_force >= 2 && geteuid() != 0) {
2252 log_error("Must be root.");
2256 if (arg_force >= 2 &&
2257 (a == ACTION_HALT ||
2258 a == ACTION_POWEROFF ||
2259 a == ACTION_REBOOT))
2262 if (arg_force >= 1 &&
2263 (a == ACTION_HALT ||
2264 a == ACTION_POWEROFF ||
2265 a == ACTION_REBOOT ||
2266 a == ACTION_KEXEC ||
2268 return daemon_reload(bus, args);
2270 /* first try logind, to allow authentication with polkit */
2271 if (geteuid() != 0 &&
2272 (a == ACTION_POWEROFF ||
2273 a == ACTION_REBOOT ||
2274 a == ACTION_SUSPEND ||
2275 a == ACTION_HIBERNATE ||
2276 a == ACTION_HYBRID_SLEEP)) {
2277 r = reboot_with_logind(bus, a);
2282 r = start_unit(bus, args);
2283 if (r == EXIT_SUCCESS)
2289 static int check_unit_active(sd_bus *bus, char **args) {
2291 int r = 3; /* According to LSB: "program is not running" */
2296 STRV_FOREACH(name, args+1) {
2299 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2309 static int check_unit_failed(sd_bus *bus, char **args) {
2316 STRV_FOREACH(name, args+1) {
2319 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2329 static int kill_unit(sd_bus *bus, char **args) {
2330 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2338 arg_kill_who = "all";
2340 STRV_FOREACH(name, args+1) {
2341 _cleanup_free_ char *n = NULL;
2343 n = unit_name_mangle(*name);
2347 r = sd_bus_call_method(
2349 "org.freedesktop.systemd1",
2350 "/org/freedesktop/systemd1",
2351 "org.freedesktop.systemd1.Manager",
2355 "ssi", n, arg_kill_who, arg_signal);
2357 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2365 typedef struct ExecStatusInfo {
2373 usec_t start_timestamp;
2374 usec_t exit_timestamp;
2379 LIST_FIELDS(struct ExecStatusInfo, exec);
2382 static void exec_status_info_free(ExecStatusInfo *i) {
2391 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2392 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2395 int32_t code, status;
2401 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2403 return bus_log_parse_error(r);
2407 r = sd_bus_message_read(m, "s", &path);
2409 return bus_log_parse_error(r);
2411 i->path = strdup(path);
2415 r = sd_bus_message_read_strv(m, &i->argv);
2417 return bus_log_parse_error(r);
2419 r = sd_bus_message_read(m,
2422 &start_timestamp, &start_timestamp_monotonic,
2423 &exit_timestamp, &exit_timestamp_monotonic,
2427 return bus_log_parse_error(r);
2430 i->start_timestamp = (usec_t) start_timestamp;
2431 i->exit_timestamp = (usec_t) exit_timestamp;
2432 i->pid = (pid_t) pid;
2436 r = sd_bus_message_exit_container(m);
2438 return bus_log_parse_error(r);
2443 typedef struct UnitStatusInfo {
2445 const char *load_state;
2446 const char *active_state;
2447 const char *sub_state;
2448 const char *unit_file_state;
2450 const char *description;
2451 const char *following;
2453 char **documentation;
2455 const char *fragment_path;
2456 const char *source_path;
2457 const char *control_group;
2459 char **dropin_paths;
2461 const char *load_error;
2464 usec_t inactive_exit_timestamp;
2465 usec_t inactive_exit_timestamp_monotonic;
2466 usec_t active_enter_timestamp;
2467 usec_t active_exit_timestamp;
2468 usec_t inactive_enter_timestamp;
2470 bool need_daemon_reload;
2475 const char *status_text;
2476 const char *pid_file;
2479 usec_t start_timestamp;
2480 usec_t exit_timestamp;
2482 int exit_code, exit_status;
2484 usec_t condition_timestamp;
2485 bool condition_result;
2486 bool failed_condition_trigger;
2487 bool failed_condition_negate;
2488 const char *failed_condition;
2489 const char *failed_condition_param;
2492 unsigned n_accepted;
2493 unsigned n_connections;
2496 /* Pairs of type, path */
2500 const char *sysfs_path;
2502 /* Mount, Automount */
2508 LIST_HEAD(ExecStatusInfo, exec);
2511 static void print_status_info(
2516 const char *on, *off, *ss;
2518 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2519 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2522 arg_all * OUTPUT_SHOW_ALL |
2523 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2524 on_tty() * OUTPUT_COLOR |
2525 !arg_quiet * OUTPUT_WARN_CUTOFF |
2526 arg_full * OUTPUT_FULL_WIDTH;
2531 /* This shows pretty information about a unit. See
2532 * print_property() for a low-level property printer */
2534 printf("%s", strna(i->id));
2536 if (i->description && !streq_ptr(i->id, i->description))
2537 printf(" - %s", i->description);
2542 printf(" Follow: unit currently follows state of %s\n", i->following);
2544 if (streq_ptr(i->load_state, "error")) {
2545 on = ansi_highlight_red();
2546 off = ansi_highlight_off();
2550 path = i->source_path ? i->source_path : i->fragment_path;
2553 printf(" Loaded: %s%s%s (Reason: %s)\n",
2554 on, strna(i->load_state), off, i->load_error);
2555 else if (path && i->unit_file_state)
2556 printf(" Loaded: %s%s%s (%s; %s)\n",
2557 on, strna(i->load_state), off, path, i->unit_file_state);
2559 printf(" Loaded: %s%s%s (%s)\n",
2560 on, strna(i->load_state), off, path);
2562 printf(" Loaded: %s%s%s\n",
2563 on, strna(i->load_state), off);
2565 if (!strv_isempty(i->dropin_paths)) {
2566 _cleanup_free_ char *dir = NULL;
2570 STRV_FOREACH(dropin, i->dropin_paths) {
2571 if (! dir || last) {
2572 printf(dir ? " " : " Drop-In: ");
2577 if (path_get_parent(*dropin, &dir) < 0) {
2582 printf("%s\n %s", dir,
2583 draw_special_char(DRAW_TREE_RIGHT));
2586 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2588 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2592 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2594 if (streq_ptr(i->active_state, "failed")) {
2595 on = ansi_highlight_red();
2596 off = ansi_highlight_off();
2597 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2598 on = ansi_highlight_green();
2599 off = ansi_highlight_off();
2604 printf(" Active: %s%s (%s)%s",
2605 on, strna(i->active_state), ss, off);
2607 printf(" Active: %s%s%s",
2608 on, strna(i->active_state), off);
2610 if (!isempty(i->result) && !streq(i->result, "success"))
2611 printf(" (Result: %s)", i->result);
2613 timestamp = (streq_ptr(i->active_state, "active") ||
2614 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2615 (streq_ptr(i->active_state, "inactive") ||
2616 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2617 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2618 i->active_exit_timestamp;
2620 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2621 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2624 printf(" since %s; %s\n", s2, s1);
2626 printf(" since %s\n", s2);
2630 if (!i->condition_result && i->condition_timestamp > 0) {
2631 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2632 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2634 printf(" start condition failed at %s%s%s\n",
2635 s2, s1 ? "; " : "", s1 ? s1 : "");
2636 if (i->failed_condition_trigger)
2637 printf(" none of the trigger conditions were met\n");
2638 else if (i->failed_condition)
2639 printf(" %s=%s%s was not met\n",
2640 i->failed_condition,
2641 i->failed_condition_negate ? "!" : "",
2642 i->failed_condition_param);
2646 printf(" Device: %s\n", i->sysfs_path);
2648 printf(" Where: %s\n", i->where);
2650 printf(" What: %s\n", i->what);
2652 STRV_FOREACH(t, i->documentation)
2653 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2655 STRV_FOREACH_PAIR(t, t2, i->listen)
2656 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2659 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2661 LIST_FOREACH(exec, p, i->exec) {
2662 _cleanup_free_ char *argv = NULL;
2665 /* Only show exited processes here */
2669 argv = strv_join(p->argv, " ");
2670 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2672 good = is_clean_exit_lsb(p->code, p->status, NULL);
2674 on = ansi_highlight_red();
2675 off = ansi_highlight_off();
2679 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2681 if (p->code == CLD_EXITED) {
2684 printf("status=%i", p->status);
2686 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2691 printf("signal=%s", signal_to_string(p->status));
2693 printf(")%s\n", off);
2695 if (i->main_pid == p->pid &&
2696 i->start_timestamp == p->start_timestamp &&
2697 i->exit_timestamp == p->start_timestamp)
2698 /* Let's not show this twice */
2701 if (p->pid == i->control_pid)
2705 if (i->main_pid > 0 || i->control_pid > 0) {
2706 if (i->main_pid > 0) {
2707 printf(" Main PID: %u", (unsigned) i->main_pid);
2710 _cleanup_free_ char *comm = NULL;
2711 get_process_comm(i->main_pid, &comm);
2713 printf(" (%s)", comm);
2714 } else if (i->exit_code > 0) {
2715 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2717 if (i->exit_code == CLD_EXITED) {
2720 printf("status=%i", i->exit_status);
2722 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2727 printf("signal=%s", signal_to_string(i->exit_status));
2731 if (i->control_pid > 0)
2735 if (i->control_pid > 0) {
2736 _cleanup_free_ char *c = NULL;
2738 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2740 get_process_comm(i->control_pid, &c);
2749 printf(" Status: \"%s\"\n", i->status_text);
2751 if (i->control_group &&
2752 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2755 printf(" CGroup: %s\n", i->control_group);
2757 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2760 char prefix[] = " ";
2763 if (c > sizeof(prefix) - 1)
2764 c -= sizeof(prefix) - 1;
2768 if (i->main_pid > 0)
2769 extra[k++] = i->main_pid;
2771 if (i->control_pid > 0)
2772 extra[k++] = i->control_pid;
2774 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2775 c, false, extra, k, flags);
2779 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2781 show_journal_by_unit(stdout,
2785 i->inactive_exit_timestamp_monotonic,
2789 arg_scope == UNIT_FILE_SYSTEM,
2793 if (i->need_daemon_reload)
2794 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2795 ansi_highlight_red(),
2796 ansi_highlight_off(),
2797 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2800 static void show_unit_help(UnitStatusInfo *i) {
2805 if (!i->documentation) {
2806 log_info("Documentation for %s not known.", i->id);
2810 STRV_FOREACH(p, i->documentation) {
2812 if (startswith(*p, "man:")) {
2813 const char *args[4] = { "man", NULL, NULL, NULL };
2814 _cleanup_free_ char *page = NULL, *section = NULL;
2821 if ((*p)[k-1] == ')')
2822 e = strrchr(*p, '(');
2825 page = strndup((*p) + 4, e - *p - 4);
2826 section = strndup(e + 1, *p + k - e - 2);
2827 if (!page || !section) {
2839 log_error("Failed to fork: %m");
2845 execvp(args[0], (char**) args);
2846 log_error("Failed to execute man: %m");
2847 _exit(EXIT_FAILURE);
2850 wait_for_terminate(pid, NULL);
2852 log_info("Can't show: %s", *p);
2856 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2863 switch (contents[0]) {
2865 case SD_BUS_TYPE_STRING: {
2868 r = sd_bus_message_read(m, "s", &s);
2870 return bus_log_parse_error(r);
2873 if (streq(name, "Id"))
2875 else if (streq(name, "LoadState"))
2877 else if (streq(name, "ActiveState"))
2878 i->active_state = s;
2879 else if (streq(name, "SubState"))
2881 else if (streq(name, "Description"))
2883 else if (streq(name, "FragmentPath"))
2884 i->fragment_path = s;
2885 else if (streq(name, "SourcePath"))
2888 else if (streq(name, "DefaultControlGroup")) {
2890 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2892 i->control_group = e;
2895 else if (streq(name, "ControlGroup"))
2896 i->control_group = s;
2897 else if (streq(name, "StatusText"))
2899 else if (streq(name, "PIDFile"))
2901 else if (streq(name, "SysFSPath"))
2903 else if (streq(name, "Where"))
2905 else if (streq(name, "What"))
2907 else if (streq(name, "Following"))
2909 else if (streq(name, "UnitFileState"))
2910 i->unit_file_state = s;
2911 else if (streq(name, "Result"))
2918 case SD_BUS_TYPE_BOOLEAN: {
2921 r = sd_bus_message_read(m, "b", &b);
2923 return bus_log_parse_error(r);
2925 if (streq(name, "Accept"))
2927 else if (streq(name, "NeedDaemonReload"))
2928 i->need_daemon_reload = b;
2929 else if (streq(name, "ConditionResult"))
2930 i->condition_result = b;
2935 case SD_BUS_TYPE_UINT32: {
2938 r = sd_bus_message_read(m, "u", &u);
2940 return bus_log_parse_error(r);
2942 if (streq(name, "MainPID")) {
2944 i->main_pid = (pid_t) u;
2947 } else if (streq(name, "ControlPID"))
2948 i->control_pid = (pid_t) u;
2949 else if (streq(name, "ExecMainPID")) {
2951 i->main_pid = (pid_t) u;
2952 } else if (streq(name, "NAccepted"))
2954 else if (streq(name, "NConnections"))
2955 i->n_connections = u;
2960 case SD_BUS_TYPE_INT32: {
2963 r = sd_bus_message_read(m, "i", &j);
2965 return bus_log_parse_error(r);
2967 if (streq(name, "ExecMainCode"))
2968 i->exit_code = (int) j;
2969 else if (streq(name, "ExecMainStatus"))
2970 i->exit_status = (int) j;
2975 case SD_BUS_TYPE_UINT64: {
2978 r = sd_bus_message_read(m, "t", &u);
2980 return bus_log_parse_error(r);
2982 if (streq(name, "ExecMainStartTimestamp"))
2983 i->start_timestamp = (usec_t) u;
2984 else if (streq(name, "ExecMainExitTimestamp"))
2985 i->exit_timestamp = (usec_t) u;
2986 else if (streq(name, "ActiveEnterTimestamp"))
2987 i->active_enter_timestamp = (usec_t) u;
2988 else if (streq(name, "InactiveEnterTimestamp"))
2989 i->inactive_enter_timestamp = (usec_t) u;
2990 else if (streq(name, "InactiveExitTimestamp"))
2991 i->inactive_exit_timestamp = (usec_t) u;
2992 else if (streq(name, "InactiveExitTimestampMonotonic"))
2993 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2994 else if (streq(name, "ActiveExitTimestamp"))
2995 i->active_exit_timestamp = (usec_t) u;
2996 else if (streq(name, "ConditionTimestamp"))
2997 i->condition_timestamp = (usec_t) u;
3002 case SD_BUS_TYPE_ARRAY:
3004 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3005 _cleanup_free_ ExecStatusInfo *info = NULL;
3007 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3009 return bus_log_parse_error(r);
3011 info = new0(ExecStatusInfo, 1);
3015 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3017 info->name = strdup(name);
3021 LIST_PREPEND(exec, i->exec, info);
3023 info = new0(ExecStatusInfo, 1);
3029 return bus_log_parse_error(r);
3031 r = sd_bus_message_exit_container(m);
3033 return bus_log_parse_error(r);
3037 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3038 const char *type, *path;
3040 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3042 return bus_log_parse_error(r);
3044 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3046 r = strv_extend(&i->listen, type);
3050 r = strv_extend(&i->listen, path);
3055 return bus_log_parse_error(r);
3057 r = sd_bus_message_exit_container(m);
3059 return bus_log_parse_error(r);
3063 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3065 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3067 return bus_log_parse_error(r);
3069 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3071 r = sd_bus_message_read_strv(m, &i->documentation);
3073 return bus_log_parse_error(r);
3075 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3076 const char *cond, *param;
3077 int trigger, negate;
3080 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3082 return bus_log_parse_error(r);
3084 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3085 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3086 if (state < 0 && (!trigger || !i->failed_condition)) {
3087 i->failed_condition = cond;
3088 i->failed_condition_trigger = trigger;
3089 i->failed_condition_negate = negate;
3090 i->failed_condition_param = param;
3094 return bus_log_parse_error(r);
3096 r = sd_bus_message_exit_container(m);
3098 return bus_log_parse_error(r);
3105 case SD_BUS_TYPE_STRUCT_BEGIN:
3107 if (streq(name, "LoadError")) {
3108 const char *n, *message;
3110 r = sd_bus_message_read(m, "(ss)", &n, &message);
3112 return bus_log_parse_error(r);
3114 if (!isempty(message))
3115 i->load_error = message;
3128 r = sd_bus_message_skip(m, contents);
3130 return bus_log_parse_error(r);
3135 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3141 /* This is a low-level property printer, see
3142 * print_status_info() for the nicer output */
3144 if (arg_properties && !strv_find(arg_properties, name)) {
3145 /* skip what we didn't read */
3146 r = sd_bus_message_skip(m, contents);
3150 switch (contents[0]) {
3152 case SD_BUS_TYPE_STRUCT_BEGIN:
3154 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3157 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3159 return bus_log_parse_error(r);
3162 printf("%s=%u\n", name, (unsigned) u);
3164 printf("%s=\n", name);
3168 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3171 r = sd_bus_message_read(m, "(so)", &s, NULL);
3173 return bus_log_parse_error(r);
3175 if (arg_all || !isempty(s))
3176 printf("%s=%s\n", name, s);
3180 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3181 const char *a = NULL, *b = NULL;
3183 r = sd_bus_message_read(m, "(ss)", &a, &b);
3185 return bus_log_parse_error(r);
3187 if (arg_all || !isempty(a) || !isempty(b))
3188 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3195 case SD_BUS_TYPE_ARRAY:
3197 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3201 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3203 return bus_log_parse_error(r);
3205 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3206 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3209 return bus_log_parse_error(r);
3211 r = sd_bus_message_exit_container(m);
3213 return bus_log_parse_error(r);
3217 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3218 const char *type, *path;
3220 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3222 return bus_log_parse_error(r);
3224 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3225 printf("%s=%s\n", type, path);
3227 return bus_log_parse_error(r);
3229 r = sd_bus_message_exit_container(m);
3231 return bus_log_parse_error(r);
3235 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3236 const char *type, *path;
3238 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3240 return bus_log_parse_error(r);
3242 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3243 printf("Listen%s=%s\n", type, path);
3245 return bus_log_parse_error(r);
3247 r = sd_bus_message_exit_container(m);
3249 return bus_log_parse_error(r);
3253 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3255 uint64_t value, next_elapse;
3257 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3259 return bus_log_parse_error(r);
3261 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3262 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3264 printf("%s={ value=%s ; next_elapse=%s }\n",
3266 format_timespan(timespan1, sizeof(timespan1), value, 0),
3267 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3270 return bus_log_parse_error(r);
3272 r = sd_bus_message_exit_container(m);
3274 return bus_log_parse_error(r);
3278 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3279 ExecStatusInfo info = {};
3281 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3283 return bus_log_parse_error(r);
3285 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3286 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3287 _cleanup_free_ char *tt;
3289 tt = strv_join(info.argv, " ");
3291 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3295 yes_no(info.ignore),
3296 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3297 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3298 (unsigned) info. pid,
3299 sigchld_code_to_string(info.code),
3301 info.code == CLD_EXITED ? "" : "/",
3302 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3305 strv_free(info.argv);
3309 r = sd_bus_message_exit_container(m);
3311 return bus_log_parse_error(r);
3315 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3316 const char *path, *rwm;
3318 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3320 return bus_log_parse_error(r);
3322 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3323 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3325 return bus_log_parse_error(r);
3327 r = sd_bus_message_exit_container(m);
3329 return bus_log_parse_error(r);
3333 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3337 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3339 return bus_log_parse_error(r);
3341 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3342 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3344 return bus_log_parse_error(r);
3346 r = sd_bus_message_exit_container(m);
3348 return bus_log_parse_error(r);
3352 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3356 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3358 return bus_log_parse_error(r);
3360 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3361 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3363 return bus_log_parse_error(r);
3365 r = sd_bus_message_exit_container(m);
3367 return bus_log_parse_error(r);
3375 r = bus_print_property(name, m, arg_all);
3377 return bus_log_parse_error(r);
3380 r = sd_bus_message_skip(m, contents);
3382 return bus_log_parse_error(r);
3385 printf("%s=[unprintable]\n", name);
3391 static int show_one(
3395 bool show_properties,
3399 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3400 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3401 UnitStatusInfo info = {};
3408 r = sd_bus_call_method(
3410 "org.freedesktop.systemd1",
3412 "org.freedesktop.DBus.Properties",
3418 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3422 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3424 return bus_log_parse_error(r);
3431 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3432 const char *name, *contents;
3434 r = sd_bus_message_read(reply, "s", &name);
3436 return bus_log_parse_error(r);
3438 r = sd_bus_message_peek_type(reply, NULL, &contents);
3440 return bus_log_parse_error(r);
3442 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3444 return bus_log_parse_error(r);
3446 if (show_properties)
3447 r = print_property(name, reply, contents);
3449 r = status_property(name, reply, &info, contents);
3453 r = sd_bus_message_exit_container(reply);
3455 return bus_log_parse_error(r);
3457 r = sd_bus_message_exit_container(reply);
3459 return bus_log_parse_error(r);
3462 return bus_log_parse_error(r);
3464 r = sd_bus_message_exit_container(reply);
3466 return bus_log_parse_error(r);
3470 if (!show_properties) {
3471 if (streq(verb, "help"))
3472 show_unit_help(&info);
3474 print_status_info(&info, ellipsized);
3477 strv_free(info.documentation);
3478 strv_free(info.dropin_paths);
3479 strv_free(info.listen);
3481 if (!streq_ptr(info.active_state, "active") &&
3482 !streq_ptr(info.active_state, "reloading") &&
3483 streq(verb, "status")) {
3484 /* According to LSB: "program not running" */
3485 /* 0: program is running or service is OK
3486 * 1: program is dead and /var/run pid file exists
3487 * 2: program is dead and /var/lock lock file exists
3488 * 3: program is not running
3489 * 4: program or service status is unknown
3491 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3497 while ((p = info.exec)) {
3498 LIST_REMOVE(exec, info.exec, p);
3499 exec_status_info_free(p);
3505 static int show_one_by_pid(
3512 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3513 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3514 const char *path = NULL;
3517 r = sd_bus_call_method(
3519 "org.freedesktop.systemd1",
3520 "/org/freedesktop/systemd1",
3521 "org.freedesktop.systemd1.Manager",
3527 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3531 r = sd_bus_message_read(reply, "o", &path);
3533 return bus_log_parse_error(r);
3535 return show_one(verb, bus, path, false, new_line, ellipsized);
3538 static int show_all(
3541 bool show_properties,
3545 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3546 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3547 _cleanup_free_ UnitInfo *unit_infos = NULL;
3552 r = get_unit_list(bus, &reply, &unit_infos);
3558 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3560 for (u = unit_infos; u < unit_infos + c; u++) {
3561 _cleanup_free_ char *p = NULL;
3563 if (!output_show_unit(u))
3566 p = unit_dbus_path_from_name(u->id);
3570 printf("%s -> '%s'\n", u->id, p);
3572 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3580 static int show(sd_bus *bus, char **args) {
3582 bool show_properties, show_status, new_line = false;
3584 bool ellipsized = false;
3589 show_properties = streq(args[0], "show");
3590 show_status = streq(args[0], "status");
3592 if (show_properties)
3593 pager_open_if_enabled();
3595 /* If no argument is specified inspect the manager itself */
3597 if (show_properties && strv_length(args) <= 1)
3598 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3600 if (show_status && strv_length(args) <= 1)
3601 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3603 STRV_FOREACH(name, args+1) {
3606 if (safe_atou32(*name, &id) < 0) {
3607 _cleanup_free_ char *p = NULL, *n = NULL;
3608 /* Interpret as unit name */
3610 n = unit_name_mangle(*name);
3614 p = unit_dbus_path_from_name(n);
3618 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3622 } else if (show_properties) {
3623 _cleanup_free_ char *p = NULL;
3625 /* Interpret as job id */
3626 if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
3629 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3634 /* Interpret as PID */
3635 r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized);
3641 if (ellipsized && !arg_quiet)
3642 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3647 static int append_assignment(sd_bus_message *m, const char *assignment) {
3655 eq = strchr(assignment, '=');
3657 log_error("Not an assignment: %s", assignment);
3661 field = strndupa(assignment, eq - assignment);
3664 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3666 return bus_log_create_error(r);
3668 if (streq(field, "CPUAccounting") ||
3669 streq(field, "MemoryAccounting") ||
3670 streq(field, "BlockIOAccounting")) {
3672 r = parse_boolean(eq);
3674 log_error("Failed to parse boolean assignment %s.", assignment);
3678 r = sd_bus_message_append(m, "v", "b", r);
3680 } else if (streq(field, "MemoryLimit")) {
3683 r = parse_bytes(eq, &bytes);
3685 log_error("Failed to parse bytes specification %s", assignment);
3689 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3691 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3694 r = safe_atou64(eq, &u);
3696 log_error("Failed to parse %s value %s.", field, eq);
3700 r = sd_bus_message_append(m, "v", "t", u);
3702 } else if (streq(field, "DevicePolicy"))
3703 r = sd_bus_message_append(m, "v", "s", eq);
3705 else if (streq(field, "DeviceAllow")) {
3708 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3710 const char *path, *rwm;
3713 e = strchr(eq, ' ');
3715 path = strndupa(eq, e - eq);
3722 if (!path_startswith(path, "/dev")) {
3723 log_error("%s is not a device file in /dev.", path);
3727 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3730 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3733 r = sd_bus_message_append(m, "v", "a(st)", 0);
3735 const char *path, *bandwidth;
3739 e = strchr(eq, ' ');
3741 path = strndupa(eq, e - eq);
3744 log_error("Failed to parse %s value %s.", field, eq);
3748 if (!path_startswith(path, "/dev")) {
3749 log_error("%s is not a device file in /dev.", path);
3753 r = parse_bytes(bandwidth, &bytes);
3755 log_error("Failed to parse byte value %s.", bandwidth);
3759 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3762 } else if (streq(field, "BlockIODeviceWeight")) {
3765 r = sd_bus_message_append(m, "v", "a(st)", 0);
3767 const char *path, *weight;
3771 e = strchr(eq, ' ');
3773 path = strndupa(eq, e - eq);
3776 log_error("Failed to parse %s value %s.", field, eq);
3780 if (!path_startswith(path, "/dev")) {
3781 log_error("%s is not a device file in /dev.", path);
3785 r = safe_atou64(weight, &u);
3787 log_error("Failed to parse %s value %s.", field, weight);
3790 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3794 log_error("Unknown assignment %s.", assignment);
3799 return bus_log_create_error(r);
3804 static int set_property(sd_bus *bus, char **args) {
3805 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3806 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3807 _cleanup_free_ char *n = NULL;
3811 r = sd_bus_message_new_method_call(
3813 "org.freedesktop.systemd1",
3814 "/org/freedesktop/systemd1",
3815 "org.freedesktop.systemd1.Manager",
3816 "SetUnitProperties",
3819 return bus_log_create_error(r);
3821 n = unit_name_mangle(args[1]);
3825 r = sd_bus_message_append(m, "sb", n, arg_runtime);
3827 return bus_log_create_error(r);
3829 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
3831 return bus_log_create_error(r);
3833 STRV_FOREACH(i, args + 2) {
3834 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
3836 return bus_log_create_error(r);
3838 r = append_assignment(m, *i);
3842 r = sd_bus_message_close_container(m);
3844 return bus_log_create_error(r);
3847 r = sd_bus_message_close_container(m);
3849 return bus_log_create_error(r);
3851 r = sd_bus_call(bus, m, 0, &error, NULL);
3853 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
3860 static int snapshot(sd_bus *bus, char **args) {
3861 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3862 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3863 _cleanup_free_ char *n = NULL, *id = NULL;
3867 if (strv_length(args) > 1)
3868 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
3874 r = sd_bus_call_method(
3876 "org.freedesktop.systemd1",
3877 "/org/freedesktop/systemd1",
3878 "org.freedesktop.systemd1.Manager",
3884 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
3888 r = sd_bus_message_read(reply, "o", &path);
3890 return bus_log_parse_error(r);
3892 r = sd_bus_get_property_string(
3894 "org.freedesktop.systemd1",
3896 "org.freedesktop.systemd1.Unit",
3901 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
3911 static int delete_snapshot(sd_bus *bus, char **args) {
3912 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3918 STRV_FOREACH(name, args+1) {
3919 _cleanup_free_ char *n = NULL;
3921 n = unit_name_mangle_with_suffix(*name, ".snapshot");
3925 r = sd_bus_call_method(
3927 "org.freedesktop.systemd1",
3928 "/org/freedesktop/systemd1",
3929 "org.freedesktop.systemd1.Manager",
3935 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
3943 static int daemon_reload(sd_bus *bus, char **args) {
3944 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3948 if (arg_action == ACTION_RELOAD)
3950 else if (arg_action == ACTION_REEXEC)
3951 method = "Reexecute";
3953 assert(arg_action == ACTION_SYSTEMCTL);
3956 streq(args[0], "clear-jobs") ||
3957 streq(args[0], "cancel") ? "ClearJobs" :
3958 streq(args[0], "daemon-reexec") ? "Reexecute" :
3959 streq(args[0], "reset-failed") ? "ResetFailed" :
3960 streq(args[0], "halt") ? "Halt" :
3961 streq(args[0], "poweroff") ? "PowerOff" :
3962 streq(args[0], "reboot") ? "Reboot" :
3963 streq(args[0], "kexec") ? "KExec" :
3964 streq(args[0], "exit") ? "Exit" :
3965 /* "daemon-reload" */ "Reload";
3968 r = sd_bus_call_method(
3970 "org.freedesktop.systemd1",
3971 "/org/freedesktop/systemd1",
3972 "org.freedesktop.systemd1.Manager",
3978 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
3979 /* There's always a fallback possible for
3980 * legacy actions. */
3982 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
3983 /* On reexecution, we expect a disconnect, not a
3987 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3989 return r < 0 ? r : 0;
3992 static int reset_failed(sd_bus *bus, char **args) {
3993 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3997 if (strv_length(args) <= 1)
3998 return daemon_reload(bus, args);
4000 STRV_FOREACH(name, args+1) {
4001 _cleanup_free_ char *n;
4003 n = unit_name_mangle(*name);
4007 r = sd_bus_call_method(
4009 "org.freedesktop.systemd1",
4010 "/org/freedesktop/systemd1",
4011 "org.freedesktop.systemd1.Manager",
4017 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4025 static int show_environment(sd_bus *bus, char **args) {
4026 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4027 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4031 pager_open_if_enabled();
4033 r = sd_bus_get_property(
4035 "org.freedesktop.systemd1",
4036 "/org/freedesktop/systemd1",
4037 "org.freedesktop.systemd1.Manager",
4043 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4047 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4049 return bus_log_parse_error(r);
4051 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4054 return bus_log_parse_error(r);
4056 r = sd_bus_message_exit_container(reply);
4058 return bus_log_parse_error(r);
4063 static int switch_root(sd_bus *bus, char **args) {
4064 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4065 _cleanup_free_ char *init = NULL;
4070 l = strv_length(args);
4071 if (l < 2 || l > 3) {
4072 log_error("Wrong number of arguments.");
4079 init = strdup(args[2]);
4081 parse_env_file("/proc/cmdline", WHITESPACE,
4092 log_debug("switching root - root: %s; init: %s", root, init);
4094 r = sd_bus_call_method(
4096 "org.freedesktop.systemd1",
4097 "/org/freedesktop/systemd1",
4098 "org.freedesktop.systemd1.Manager",
4104 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4111 static int set_environment(sd_bus *bus, char **args) {
4112 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4113 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4120 method = streq(args[0], "set-environment")
4122 : "UnsetEnvironment";
4124 r = sd_bus_message_new_method_call(
4126 "org.freedesktop.systemd1",
4127 "/org/freedesktop/systemd1",
4128 "org.freedesktop.systemd1.Manager",
4132 return bus_log_create_error(r);
4134 r = sd_bus_message_append_strv(m, args + 1);
4136 return bus_log_create_error(r);
4138 r = sd_bus_call(bus, m, 0, &error, NULL);
4140 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4147 static int enable_sysv_units(const char *verb, char **args) {
4150 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4151 unsigned f = 1, t = 1;
4152 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4154 if (arg_scope != UNIT_FILE_SYSTEM)
4157 if (!streq(verb, "enable") &&
4158 !streq(verb, "disable") &&
4159 !streq(verb, "is-enabled"))
4162 /* Processes all SysV units, and reshuffles the array so that
4163 * afterwards only the native units remain */
4165 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4170 for (f = 0; args[f]; f++) {
4172 _cleanup_free_ char *p = NULL, *q = NULL;
4173 bool found_native = false, found_sysv;
4175 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4183 if (!endswith(name, ".service"))
4186 if (path_is_absolute(name))
4189 STRV_FOREACH(k, paths.unit_path) {
4190 if (!isempty(arg_root))
4191 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4193 asprintf(&p, "%s/%s", *k, name);
4200 found_native = access(p, F_OK) >= 0;
4211 if (!isempty(arg_root))
4212 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4214 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4220 p[strlen(p) - sizeof(".service") + 1] = 0;
4221 found_sysv = access(p, F_OK) >= 0;
4226 /* Mark this entry, so that we don't try enabling it as native unit */
4227 args[f] = (char*) "";
4229 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4231 if (!isempty(arg_root))
4232 argv[c++] = q = strappend("--root=", arg_root);
4234 argv[c++] = path_get_file_name(p);
4236 streq(verb, "enable") ? "on" :
4237 streq(verb, "disable") ? "off" : "--level=5";
4240 l = strv_join((char**)argv, " ");
4246 log_info("Executing %s", l);
4251 log_error("Failed to fork: %m");
4254 } else if (pid == 0) {
4257 execv(argv[0], (char**) argv);
4258 _exit(EXIT_FAILURE);
4261 j = wait_for_terminate(pid, &status);
4263 log_error("Failed to wait for child: %s", strerror(-r));
4268 if (status.si_code == CLD_EXITED) {
4269 if (streq(verb, "is-enabled")) {
4270 if (status.si_status == 0) {
4279 } else if (status.si_status != 0) {
4290 /* Drop all SysV units */
4291 for (f = 0, t = 0; args[f]; f++) {
4293 if (isempty(args[f]))
4296 args[t++] = args[f];
4305 static int mangle_names(char **original_names, char ***mangled_names) {
4306 char **i, **l, **name;
4308 l = new(char*, strv_length(original_names) + 1);
4313 STRV_FOREACH(name, original_names) {
4315 /* When enabling units qualified path names are OK,
4316 * too, hence allow them explicitly. */
4321 *i = unit_name_mangle(*name);
4337 static int enable_unit(sd_bus *bus, char **args) {
4338 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4339 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4340 _cleanup_strv_free_ char **mangled_names = NULL;
4341 const char *verb = args[0];
4342 UnitFileChange *changes = NULL;
4343 unsigned n_changes = 0, i;
4344 int carries_install_info = -1;
4350 r = mangle_names(args+1, &mangled_names);
4354 r = enable_sysv_units(verb, mangled_names);
4358 if (!bus || avoid_bus()) {
4359 if (streq(verb, "enable")) {
4360 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4361 carries_install_info = r;
4362 } else if (streq(verb, "disable"))
4363 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4364 else if (streq(verb, "reenable")) {
4365 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4366 carries_install_info = r;
4367 } else if (streq(verb, "link"))
4368 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4369 else if (streq(verb, "preset")) {
4370 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4371 carries_install_info = r;
4372 } else if (streq(verb, "mask"))
4373 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4374 else if (streq(verb, "unmask"))
4375 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4376 else if (streq(verb, "set-default"))
4377 r = unit_file_set_default(arg_scope, arg_root, args[1], &changes, &n_changes);
4379 assert_not_reached("Unknown verb");
4382 log_error("Operation failed: %s", strerror(-r));
4387 for (i = 0; i < n_changes; i++) {
4388 if (changes[i].type == UNIT_FILE_SYMLINK)
4389 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
4391 log_info("rm '%s'", changes[i].path);
4397 const char *method, *type, *path, *source;
4398 int expect_carries_install_info = false;
4399 bool send_force = true;
4401 if (streq(verb, "enable")) {
4402 method = "EnableUnitFiles";
4403 expect_carries_install_info = true;
4404 } else if (streq(verb, "disable")) {
4405 method = "DisableUnitFiles";
4407 } else if (streq(verb, "reenable")) {
4408 method = "ReenableUnitFiles";
4409 expect_carries_install_info = true;
4410 } else if (streq(verb, "link"))
4411 method = "LinkUnitFiles";
4412 else if (streq(verb, "preset")) {
4413 method = "PresetUnitFiles";
4414 expect_carries_install_info = true;
4415 } else if (streq(verb, "mask"))
4416 method = "MaskUnitFiles";
4417 else if (streq(verb, "unmask")) {
4418 method = "UnmaskUnitFiles";
4420 } else if (streq(verb, "set-default")) {
4421 method = "SetDefaultTarget";
4423 assert_not_reached("Unknown verb");
4425 r = sd_bus_message_new_method_call(
4427 "org.freedesktop.systemd1",
4428 "/org/freedesktop/systemd1",
4429 "org.freedesktop.systemd1.Manager",
4433 return bus_log_create_error(r);
4435 r = sd_bus_message_append_strv(m, mangled_names);
4437 return bus_log_create_error(r);
4439 r = sd_bus_message_append(m, "b", arg_runtime);
4441 return bus_log_create_error(r);
4444 r = sd_bus_message_append(m, "b", arg_force);
4446 return bus_log_create_error(r);
4449 r = sd_bus_call(bus, m, 0, &error, &reply);
4451 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4455 if (expect_carries_install_info) {
4456 r = sd_bus_message_read(reply, "b", &carries_install_info);
4458 return bus_log_parse_error(r);
4461 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(sss)");
4463 return bus_log_parse_error(r);
4465 while ((r = sd_bus_message_read(reply, "(sss)", &type, &path, &source)) > 0) {
4467 if (streq(type, "symlink"))
4468 log_info("ln -s '%s' '%s'", source, path);
4470 log_info("rm '%s'", path);
4474 return bus_log_parse_error(r);
4476 r = sd_bus_message_exit_container(reply);
4478 return bus_log_parse_error(r);
4480 /* Try to reload if enabeld */
4482 r = daemon_reload(bus, args);
4487 if (carries_install_info == 0)
4488 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4489 "using systemctl.\n"
4490 "Possible reasons for having this kind of units are:\n"
4491 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4492 " .wants/ or .requires/ directory.\n"
4493 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4494 " a requirement dependency on it.\n"
4495 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4496 " D-Bus, udev, scripted systemctl call, ...).\n");
4499 unit_file_changes_free(changes, n_changes);
4504 static int unit_is_enabled(sd_bus *bus, char **args) {
4506 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4507 _cleanup_strv_free_ char **mangled_names = NULL;
4512 r = mangle_names(args+1, &mangled_names);
4516 r = enable_sysv_units(args[0], mangled_names);
4522 if (!bus || avoid_bus()) {
4524 STRV_FOREACH(name, mangled_names) {
4525 UnitFileState state;
4527 state = unit_file_get_state(arg_scope, arg_root, *name);
4529 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4533 if (state == UNIT_FILE_ENABLED ||
4534 state == UNIT_FILE_ENABLED_RUNTIME ||
4535 state == UNIT_FILE_STATIC)
4539 puts(unit_file_state_to_string(state));
4543 STRV_FOREACH(name, mangled_names) {
4544 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4547 r = sd_bus_call_method(
4549 "org.freedesktop.systemd1",
4550 "/org/freedesktop/systemd1",
4551 "org.freedesktop.systemd1.Manager",
4557 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4561 r = sd_bus_message_read(reply, "s", &s);
4563 return bus_log_parse_error(r);
4565 if (streq(s, "enabled") ||
4566 streq(s, "enabled-runtime") ||
4578 static int systemctl_help(void) {
4580 pager_open_if_enabled();
4582 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4583 "Query or send control commands to the systemd manager.\n\n"
4584 " -h --help Show this help\n"
4585 " --version Show package version\n"
4586 " --system Connect to system manager\n"
4587 " --user Connect to user service manager\n"
4588 " -H --host=[USER@]HOST\n"
4589 " Operate on remote host\n"
4590 " -M --machine=CONTAINER\n"
4591 " Operate on local container\n"
4592 " -t --type=TYPE List only units of a particular type\n"
4593 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4594 " -p --property=NAME Show only properties by this name\n"
4595 " -a --all Show all loaded units/properties, including dead/empty\n"
4596 " ones. To list all units installed on the system, use\n"
4597 " the 'list-unit-files' command instead.\n"
4598 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4599 " -l --full Don't ellipsize unit names on output\n"
4600 " --fail When queueing a new job, fail if conflicting jobs are\n"
4602 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4604 " --ignore-dependencies\n"
4605 " When queueing a new job, ignore all its dependencies\n"
4606 " --show-types When showing sockets, explicitly show their type\n"
4607 " -i --ignore-inhibitors\n"
4608 " When shutting down or sleeping, ignore inhibitors\n"
4609 " --kill-who=WHO Who to send signal to\n"
4610 " -s --signal=SIGNAL Which signal to send\n"
4611 " -q --quiet Suppress output\n"
4612 " --no-block Do not wait until operation finished\n"
4613 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4614 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4616 " --no-legend Do not print a legend (column headers and hints)\n"
4617 " --no-pager Do not pipe output into a pager\n"
4618 " --no-ask-password\n"
4619 " Do not ask for system passwords\n"
4620 " --global Enable/disable unit files globally\n"
4621 " --runtime Enable unit files only temporarily until next reboot\n"
4622 " -f --force When enabling unit files, override existing symlinks\n"
4623 " When shutting down, execute action immediately\n"
4624 " --root=PATH Enable unit files in the specified root directory\n"
4625 " -n --lines=INTEGER Number of journal entries to show\n"
4626 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4627 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4629 " list-units List loaded units\n"
4630 " list-sockets List loaded sockets ordered by address\n"
4631 " list-timers List loaded timers ordered by next elapse\n"
4632 " start [NAME...] Start (activate) one or more units\n"
4633 " stop [NAME...] Stop (deactivate) one or more units\n"
4634 " reload [NAME...] Reload one or more units\n"
4635 " restart [NAME...] Start or restart one or more units\n"
4636 " try-restart [NAME...] Restart one or more units if active\n"
4637 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4638 " otherwise start or restart\n"
4639 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4640 " otherwise restart if active\n"
4641 " isolate [NAME] Start one unit and stop all others\n"
4642 " kill [NAME...] Send signal to processes of a unit\n"
4643 " is-active [NAME...] Check whether units are active\n"
4644 " is-failed [NAME...] Check whether units are failed\n"
4645 " status [NAME...|PID...] Show runtime status of one or more units\n"
4646 " show [NAME...|JOB...] Show properties of one or more\n"
4647 " units/jobs or the manager\n"
4648 " set-property [NAME] [ASSIGNMENT...]\n"
4649 " Sets one or more properties of a unit\n"
4650 " help [NAME...|PID...] Show manual for one or more units\n"
4651 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4653 " list-dependencies [NAME] Recursively show units which are required\n"
4654 " or wanted by this unit or by which this\n"
4655 " unit is required or wanted\n\n"
4656 "Unit File Commands:\n"
4657 " list-unit-files List installed unit files\n"
4658 " enable [NAME...] Enable one or more unit files\n"
4659 " disable [NAME...] Disable one or more unit files\n"
4660 " reenable [NAME...] Reenable one or more unit files\n"
4661 " preset [NAME...] Enable/disable one or more unit files\n"
4662 " based on preset configuration\n"
4663 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4664 " mask [NAME...] Mask one or more units\n"
4665 " unmask [NAME...] Unmask one or more units\n"
4666 " link [PATH...] Link one or more units files into\n"
4667 " the search path\n"
4668 " get-default Get the name of the default target\n"
4669 " set-default NAME Set the default target\n\n"
4671 " list-jobs List jobs\n"
4672 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4673 "Snapshot Commands:\n"
4674 " snapshot [NAME] Create a snapshot\n"
4675 " delete [NAME...] Remove one or more snapshots\n\n"
4676 "Environment Commands:\n"
4677 " show-environment Dump environment\n"
4678 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4679 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4680 "Manager Lifecycle Commands:\n"
4681 " daemon-reload Reload systemd manager configuration\n"
4682 " daemon-reexec Reexecute systemd manager\n\n"
4683 "System Commands:\n"
4684 " default Enter system default mode\n"
4685 " rescue Enter system rescue mode\n"
4686 " emergency Enter system emergency mode\n"
4687 " halt Shut down and halt the system\n"
4688 " poweroff Shut down and power-off the system\n"
4689 " reboot [ARG] Shut down and reboot the system\n"
4690 " kexec Shut down and reboot the system with kexec\n"
4691 " exit Request user instance exit\n"
4692 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4693 " suspend Suspend the system\n"
4694 " hibernate Hibernate the system\n"
4695 " hybrid-sleep Hibernate and suspend the system\n",
4696 program_invocation_short_name);
4701 static int halt_help(void) {
4703 printf("%s [OPTIONS...]%s\n\n"
4704 "%s the system.\n\n"
4705 " --help Show this help\n"
4706 " --halt Halt the machine\n"
4707 " -p --poweroff Switch off the machine\n"
4708 " --reboot Reboot the machine\n"
4709 " -f --force Force immediate halt/power-off/reboot\n"
4710 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4711 " -d --no-wtmp Don't write wtmp record\n"
4712 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4713 program_invocation_short_name,
4714 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4715 arg_action == ACTION_REBOOT ? "Reboot" :
4716 arg_action == ACTION_POWEROFF ? "Power off" :
4722 static int shutdown_help(void) {
4724 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4725 "Shut down the system.\n\n"
4726 " --help Show this help\n"
4727 " -H --halt Halt the machine\n"
4728 " -P --poweroff Power-off the machine\n"
4729 " -r --reboot Reboot the machine\n"
4730 " -h Equivalent to --poweroff, overridden by --halt\n"
4731 " -k Don't halt/power-off/reboot, just send warnings\n"
4732 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4733 " -c Cancel a pending shutdown\n",
4734 program_invocation_short_name);
4739 static int telinit_help(void) {
4741 printf("%s [OPTIONS...] {COMMAND}\n\n"
4742 "Send control commands to the init daemon.\n\n"
4743 " --help Show this help\n"
4744 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4746 " 0 Power-off the machine\n"
4747 " 6 Reboot the machine\n"
4748 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4749 " 1, s, S Enter rescue mode\n"
4750 " q, Q Reload init daemon configuration\n"
4751 " u, U Reexecute init daemon\n",
4752 program_invocation_short_name);
4757 static int runlevel_help(void) {
4759 printf("%s [OPTIONS...]\n\n"
4760 "Prints the previous and current runlevel of the init system.\n\n"
4761 " --help Show this help\n",
4762 program_invocation_short_name);
4767 static int help_types(void) {
4771 puts("Available unit types:");
4772 for(i = 0; i < _UNIT_TYPE_MAX; i++) {
4773 t = unit_type_to_string(i);
4781 static int systemctl_parse_argv(int argc, char *argv[]) {
4790 ARG_IGNORE_DEPENDENCIES,
4802 ARG_NO_ASK_PASSWORD,
4810 static const struct option options[] = {
4811 { "help", no_argument, NULL, 'h' },
4812 { "version", no_argument, NULL, ARG_VERSION },
4813 { "type", required_argument, NULL, 't' },
4814 { "property", required_argument, NULL, 'p' },
4815 { "all", no_argument, NULL, 'a' },
4816 { "reverse", no_argument, NULL, ARG_REVERSE },
4817 { "after", no_argument, NULL, ARG_AFTER },
4818 { "before", no_argument, NULL, ARG_BEFORE },
4819 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4820 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4821 { "full", no_argument, NULL, 'l' },
4822 { "fail", no_argument, NULL, ARG_FAIL },
4823 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
4824 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
4825 { "ignore-inhibitors", no_argument, NULL, 'i' },
4826 { "user", no_argument, NULL, ARG_USER },
4827 { "system", no_argument, NULL, ARG_SYSTEM },
4828 { "global", no_argument, NULL, ARG_GLOBAL },
4829 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4830 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4831 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4832 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4833 { "quiet", no_argument, NULL, 'q' },
4834 { "root", required_argument, NULL, ARG_ROOT },
4835 { "force", no_argument, NULL, ARG_FORCE },
4836 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4837 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4838 { "signal", required_argument, NULL, 's' },
4839 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4840 { "host", required_argument, NULL, 'H' },
4841 { "machine", required_argument, NULL, 'M' },
4842 { "runtime", no_argument, NULL, ARG_RUNTIME },
4843 { "lines", required_argument, NULL, 'n' },
4844 { "output", required_argument, NULL, 'o' },
4845 { "plain", no_argument, NULL, ARG_PLAIN },
4846 { "state", required_argument, NULL, ARG_STATE },
4855 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
4860 return systemctl_help();
4863 puts(PACKAGE_STRING);
4864 puts(SYSTEMD_FEATURES);
4871 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4872 _cleanup_free_ char *type;
4874 type = strndup(word, size);
4878 if (streq(type, "help")) {
4883 if (unit_type_from_string(type) >= 0) {
4884 if (strv_push(&arg_types, type))
4890 /* It's much nicer to use --state= for
4891 * load states, but let's support this
4892 * in --types= too for compatibility
4893 * with old versions */
4894 if (unit_load_state_from_string(optarg) >= 0) {
4895 if (strv_push(&arg_states, type) < 0)
4901 log_error("Unknown unit type or load state '%s'.", type);
4902 log_info("Use -t help to see a list of allowed values.");
4910 /* Make sure that if the empty property list
4911 was specified, we won't show any properties. */
4912 if (isempty(optarg) && !arg_properties) {
4913 arg_properties = new0(char*, 1);
4914 if (!arg_properties)
4920 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4923 prop = strndup(word, size);
4927 if (strv_push(&arg_properties, prop) < 0) {
4934 /* If the user asked for a particular
4935 * property, show it to him, even if it is
4947 arg_dependency = DEPENDENCY_REVERSE;
4951 arg_dependency = DEPENDENCY_AFTER;
4955 arg_dependency = DEPENDENCY_BEFORE;
4958 case ARG_SHOW_TYPES:
4959 arg_show_types = true;
4963 arg_job_mode = "fail";
4966 case ARG_IRREVERSIBLE:
4967 arg_job_mode = "replace-irreversibly";
4970 case ARG_IGNORE_DEPENDENCIES:
4971 arg_job_mode = "ignore-dependencies";
4975 arg_scope = UNIT_FILE_USER;
4979 arg_scope = UNIT_FILE_SYSTEM;
4983 arg_scope = UNIT_FILE_GLOBAL;
4987 arg_no_block = true;
4991 arg_no_legend = true;
4995 arg_no_pager = true;
5011 if (strv_extend(&arg_states, "failed") < 0)
5029 arg_no_reload = true;
5033 arg_kill_who = optarg;
5037 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5038 log_error("Failed to parse signal string %s.", optarg);
5043 case ARG_NO_ASK_PASSWORD:
5044 arg_ask_password = false;
5048 arg_transport = BUS_TRANSPORT_REMOTE;
5053 arg_transport = BUS_TRANSPORT_CONTAINER;
5062 if (safe_atou(optarg, &arg_lines) < 0) {
5063 log_error("Failed to parse lines '%s'", optarg);
5069 arg_output = output_mode_from_string(optarg);
5070 if (arg_output < 0) {
5071 log_error("Unknown output '%s'.", optarg);
5077 arg_ignore_inhibitors = true;
5088 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5091 s = strndup(word, size);
5095 if (strv_push(&arg_states, s) < 0) {
5107 assert_not_reached("Unhandled option");
5111 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5112 log_error("Cannot access user instance remotely.");
5119 static int halt_parse_argv(int argc, char *argv[]) {
5128 static const struct option options[] = {
5129 { "help", no_argument, NULL, ARG_HELP },
5130 { "halt", no_argument, NULL, ARG_HALT },
5131 { "poweroff", no_argument, NULL, 'p' },
5132 { "reboot", no_argument, NULL, ARG_REBOOT },
5133 { "force", no_argument, NULL, 'f' },
5134 { "wtmp-only", no_argument, NULL, 'w' },
5135 { "no-wtmp", no_argument, NULL, 'd' },
5136 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5145 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5146 if (runlevel == '0' || runlevel == '6')
5149 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5156 arg_action = ACTION_HALT;
5160 if (arg_action != ACTION_REBOOT)
5161 arg_action = ACTION_POWEROFF;
5165 arg_action = ACTION_REBOOT;
5187 /* Compatibility nops */
5194 assert_not_reached("Unhandled option");
5198 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5199 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5201 log_error("Failed to write reboot param to "
5202 REBOOT_PARAM_FILE": %s", strerror(-r));
5205 } else if (optind < argc) {
5206 log_error("Too many arguments.");
5213 static int parse_time_spec(const char *t, usec_t *_u) {
5217 if (streq(t, "now"))
5219 else if (!strchr(t, ':')) {
5222 if (safe_atou64(t, &u) < 0)
5225 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5234 hour = strtol(t, &e, 10);
5235 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5238 minute = strtol(e+1, &e, 10);
5239 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5242 n = now(CLOCK_REALTIME);
5243 s = (time_t) (n / USEC_PER_SEC);
5245 assert_se(localtime_r(&s, &tm));
5247 tm.tm_hour = (int) hour;
5248 tm.tm_min = (int) minute;
5251 assert_se(s = mktime(&tm));
5253 *_u = (usec_t) s * USEC_PER_SEC;
5256 *_u += USEC_PER_DAY;
5262 static int shutdown_parse_argv(int argc, char *argv[]) {
5269 static const struct option options[] = {
5270 { "help", no_argument, NULL, ARG_HELP },
5271 { "halt", no_argument, NULL, 'H' },
5272 { "poweroff", no_argument, NULL, 'P' },
5273 { "reboot", no_argument, NULL, 'r' },
5274 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5275 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5284 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5288 return shutdown_help();
5291 arg_action = ACTION_HALT;
5295 arg_action = ACTION_POWEROFF;
5300 arg_action = ACTION_KEXEC;
5302 arg_action = ACTION_REBOOT;
5306 arg_action = ACTION_KEXEC;
5310 if (arg_action != ACTION_HALT)
5311 arg_action = ACTION_POWEROFF;
5324 /* Compatibility nops */
5328 arg_action = ACTION_CANCEL_SHUTDOWN;
5335 assert_not_reached("Unhandled option");
5339 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5340 r = parse_time_spec(argv[optind], &arg_when);
5342 log_error("Failed to parse time specification: %s", argv[optind]);
5346 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5348 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5349 /* No time argument for shutdown cancel */
5350 arg_wall = argv + optind;
5351 else if (argc > optind + 1)
5352 /* We skip the time argument */
5353 arg_wall = argv + optind + 1;
5360 static int telinit_parse_argv(int argc, char *argv[]) {
5367 static const struct option options[] = {
5368 { "help", no_argument, NULL, ARG_HELP },
5369 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5373 static const struct {
5377 { '0', ACTION_POWEROFF },
5378 { '6', ACTION_REBOOT },
5379 { '1', ACTION_RESCUE },
5380 { '2', ACTION_RUNLEVEL2 },
5381 { '3', ACTION_RUNLEVEL3 },
5382 { '4', ACTION_RUNLEVEL4 },
5383 { '5', ACTION_RUNLEVEL5 },
5384 { 's', ACTION_RESCUE },
5385 { 'S', ACTION_RESCUE },
5386 { 'q', ACTION_RELOAD },
5387 { 'Q', ACTION_RELOAD },
5388 { 'u', ACTION_REEXEC },
5389 { 'U', ACTION_REEXEC }
5398 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5402 return telinit_help();
5412 assert_not_reached("Unhandled option");
5416 if (optind >= argc) {
5421 if (optind + 1 < argc) {
5422 log_error("Too many arguments.");
5426 if (strlen(argv[optind]) != 1) {
5427 log_error("Expected single character argument.");
5431 for (i = 0; i < ELEMENTSOF(table); i++)
5432 if (table[i].from == argv[optind][0])
5435 if (i >= ELEMENTSOF(table)) {
5436 log_error("Unknown command '%s'.", argv[optind]);
5440 arg_action = table[i].to;
5447 static int runlevel_parse_argv(int argc, char *argv[]) {
5453 static const struct option options[] = {
5454 { "help", no_argument, NULL, ARG_HELP },
5463 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5467 return runlevel_help();
5474 assert_not_reached("Unhandled option");
5478 if (optind < argc) {
5479 log_error("Too many arguments.");
5486 static int parse_argv(int argc, char *argv[]) {
5490 if (program_invocation_short_name) {
5492 if (strstr(program_invocation_short_name, "halt")) {
5493 arg_action = ACTION_HALT;
5494 return halt_parse_argv(argc, argv);
5495 } else if (strstr(program_invocation_short_name, "poweroff")) {
5496 arg_action = ACTION_POWEROFF;
5497 return halt_parse_argv(argc, argv);
5498 } else if (strstr(program_invocation_short_name, "reboot")) {
5500 arg_action = ACTION_KEXEC;
5502 arg_action = ACTION_REBOOT;
5503 return halt_parse_argv(argc, argv);
5504 } else if (strstr(program_invocation_short_name, "shutdown")) {
5505 arg_action = ACTION_POWEROFF;
5506 return shutdown_parse_argv(argc, argv);
5507 } else if (strstr(program_invocation_short_name, "init")) {
5509 if (sd_booted() > 0) {
5510 arg_action = _ACTION_INVALID;
5511 return telinit_parse_argv(argc, argv);
5513 /* Hmm, so some other init system is
5514 * running, we need to forward this
5515 * request to it. For now we simply
5516 * guess that it is Upstart. */
5518 execv(TELINIT, argv);
5520 log_error("Couldn't find an alternative telinit implementation to spawn.");
5524 } else if (strstr(program_invocation_short_name, "runlevel")) {
5525 arg_action = ACTION_RUNLEVEL;
5526 return runlevel_parse_argv(argc, argv);
5530 arg_action = ACTION_SYSTEMCTL;
5531 return systemctl_parse_argv(argc, argv);
5534 _pure_ static int action_to_runlevel(void) {
5536 static const char table[_ACTION_MAX] = {
5537 [ACTION_HALT] = '0',
5538 [ACTION_POWEROFF] = '0',
5539 [ACTION_REBOOT] = '6',
5540 [ACTION_RUNLEVEL2] = '2',
5541 [ACTION_RUNLEVEL3] = '3',
5542 [ACTION_RUNLEVEL4] = '4',
5543 [ACTION_RUNLEVEL5] = '5',
5544 [ACTION_RESCUE] = '1'
5547 assert(arg_action < _ACTION_MAX);
5549 return table[arg_action];
5552 static int talk_initctl(void) {
5554 struct init_request request = {
5555 .magic = INIT_MAGIC,
5557 .cmd = INIT_CMD_RUNLVL
5560 _cleanup_close_ int fd = -1;
5564 rl = action_to_runlevel();
5568 request.runlevel = rl;
5570 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5572 if (errno == ENOENT)
5575 log_error("Failed to open "INIT_FIFO": %m");
5580 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5582 log_error("Failed to write to "INIT_FIFO": %m");
5583 return errno > 0 ? -errno : -EIO;
5589 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5591 static const struct {
5599 int (* const dispatch)(sd_bus *bus, char **args);
5601 { "list-units", LESS, 1, list_units },
5602 { "list-unit-files", EQUAL, 1, list_unit_files },
5603 { "list-sockets", LESS, 1, list_sockets },
5604 { "list-timers", LESS, 1, list_timers },
5605 { "list-jobs", EQUAL, 1, list_jobs },
5606 { "clear-jobs", EQUAL, 1, daemon_reload },
5607 { "cancel", MORE, 2, cancel_job },
5608 { "start", MORE, 2, start_unit },
5609 { "stop", MORE, 2, start_unit },
5610 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5611 { "reload", MORE, 2, start_unit },
5612 { "restart", MORE, 2, start_unit },
5613 { "try-restart", MORE, 2, start_unit },
5614 { "reload-or-restart", MORE, 2, start_unit },
5615 { "reload-or-try-restart", MORE, 2, start_unit },
5616 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5617 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5618 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5619 { "isolate", EQUAL, 2, start_unit },
5620 { "kill", MORE, 2, kill_unit },
5621 { "is-active", MORE, 2, check_unit_active },
5622 { "check", MORE, 2, check_unit_active },
5623 { "is-failed", MORE, 2, check_unit_failed },
5624 { "show", MORE, 1, show },
5625 { "status", MORE, 1, show },
5626 { "help", MORE, 2, show },
5627 { "snapshot", LESS, 2, snapshot },
5628 { "delete", MORE, 2, delete_snapshot },
5629 { "daemon-reload", EQUAL, 1, daemon_reload },
5630 { "daemon-reexec", EQUAL, 1, daemon_reload },
5631 { "show-environment", EQUAL, 1, show_environment },
5632 { "set-environment", MORE, 2, set_environment },
5633 { "unset-environment", MORE, 2, set_environment },
5634 { "halt", EQUAL, 1, start_special },
5635 { "poweroff", EQUAL, 1, start_special },
5636 { "reboot", EQUAL, 1, start_special },
5637 { "kexec", EQUAL, 1, start_special },
5638 { "suspend", EQUAL, 1, start_special },
5639 { "hibernate", EQUAL, 1, start_special },
5640 { "hybrid-sleep", EQUAL, 1, start_special },
5641 { "default", EQUAL, 1, start_special },
5642 { "rescue", EQUAL, 1, start_special },
5643 { "emergency", EQUAL, 1, start_special },
5644 { "exit", EQUAL, 1, start_special },
5645 { "reset-failed", MORE, 1, reset_failed },
5646 { "enable", MORE, 2, enable_unit },
5647 { "disable", MORE, 2, enable_unit },
5648 { "is-enabled", MORE, 2, unit_is_enabled },
5649 { "reenable", MORE, 2, enable_unit },
5650 { "preset", MORE, 2, enable_unit },
5651 { "mask", MORE, 2, enable_unit },
5652 { "unmask", MORE, 2, enable_unit },
5653 { "link", MORE, 2, enable_unit },
5654 { "switch-root", MORE, 2, switch_root },
5655 { "list-dependencies", LESS, 2, list_dependencies },
5656 { "set-default", EQUAL, 2, enable_unit },
5657 { "get-default", LESS, 1, get_default },
5658 { "set-property", MORE, 3, set_property },
5667 left = argc - optind;
5670 /* Special rule: no arguments means "list-units" */
5673 if (streq(argv[optind], "help") && !argv[optind+1]) {
5674 log_error("This command expects one or more "
5675 "unit names. Did you mean --help?");
5679 for (i = 0; i < ELEMENTSOF(verbs); i++)
5680 if (streq(argv[optind], verbs[i].verb))
5683 if (i >= ELEMENTSOF(verbs)) {
5684 log_error("Unknown operation '%s'.", argv[optind]);
5689 switch (verbs[i].argc_cmp) {
5692 if (left != verbs[i].argc) {
5693 log_error("Invalid number of arguments.");
5700 if (left < verbs[i].argc) {
5701 log_error("Too few arguments.");
5708 if (left > verbs[i].argc) {
5709 log_error("Too many arguments.");
5716 assert_not_reached("Unknown comparison operator.");
5719 /* Require a bus connection for all operations but
5721 if (!streq(verbs[i].verb, "enable") &&
5722 !streq(verbs[i].verb, "disable") &&
5723 !streq(verbs[i].verb, "is-enabled") &&
5724 !streq(verbs[i].verb, "list-unit-files") &&
5725 !streq(verbs[i].verb, "reenable") &&
5726 !streq(verbs[i].verb, "preset") &&
5727 !streq(verbs[i].verb, "mask") &&
5728 !streq(verbs[i].verb, "unmask") &&
5729 !streq(verbs[i].verb, "link") &&
5730 !streq(verbs[i].verb, "set-default") &&
5731 !streq(verbs[i].verb, "get-default")) {
5733 if (running_in_chroot() > 0) {
5734 log_info("Running in chroot, ignoring request.");
5738 if (((!streq(verbs[i].verb, "reboot") &&
5739 !streq(verbs[i].verb, "halt") &&
5740 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5741 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5747 if (!bus && !avoid_bus()) {
5748 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5753 return verbs[i].dispatch(bus, argv + optind);
5756 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5758 struct sd_shutdown_command c = {
5765 union sockaddr_union sockaddr = {
5766 .un.sun_family = AF_UNIX,
5767 .un.sun_path = "/run/systemd/shutdownd",
5770 struct iovec iovec[2] = {{
5771 .iov_base = (char*) &c,
5772 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5775 struct msghdr msghdr = {
5776 .msg_name = &sockaddr,
5777 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5778 + sizeof("/run/systemd/shutdownd") - 1,
5783 _cleanup_close_ int fd;
5785 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5789 if (!isempty(message)) {
5790 iovec[1].iov_base = (char*) message;
5791 iovec[1].iov_len = strlen(message);
5792 msghdr.msg_iovlen++;
5795 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5801 static int reload_with_fallback(sd_bus *bus) {
5804 /* First, try systemd via D-Bus. */
5805 if (daemon_reload(bus, NULL) >= 0)
5809 /* Nothing else worked, so let's try signals */
5810 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5812 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5813 log_error("kill() failed: %m");
5820 static int start_with_fallback(sd_bus *bus) {
5823 /* First, try systemd via D-Bus. */
5824 if (start_unit(bus, NULL) >= 0)
5828 /* Nothing else worked, so let's try
5830 if (talk_initctl() > 0)
5833 log_error("Failed to talk to init daemon.");
5837 warn_wall(arg_action);
5841 static int halt_now(enum action a) {
5843 /* Make sure C-A-D is handled by the kernel from this
5845 reboot(RB_ENABLE_CAD);
5850 log_info("Halting.");
5851 reboot(RB_HALT_SYSTEM);
5854 case ACTION_POWEROFF:
5855 log_info("Powering off.");
5856 reboot(RB_POWER_OFF);
5859 case ACTION_REBOOT: {
5860 _cleanup_free_ char *param = NULL;
5862 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
5863 log_info("Rebooting with argument '%s'.", param);
5864 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
5865 LINUX_REBOOT_CMD_RESTART2, param);
5868 log_info("Rebooting.");
5869 reboot(RB_AUTOBOOT);
5874 assert_not_reached("Unknown action.");
5878 static int halt_main(sd_bus *bus) {
5881 r = check_inhibitors(bus, arg_action);
5885 if (geteuid() != 0) {
5886 /* Try logind if we are a normal user and no special
5887 * mode applies. Maybe PolicyKit allows us to shutdown
5890 if (arg_when <= 0 &&
5893 (arg_action == ACTION_POWEROFF ||
5894 arg_action == ACTION_REBOOT)) {
5895 r = reboot_with_logind(bus, arg_action);
5900 log_error("Must be root.");
5905 _cleanup_free_ char *m;
5907 m = strv_join(arg_wall, " ");
5911 r = send_shutdownd(arg_when,
5912 arg_action == ACTION_HALT ? 'H' :
5913 arg_action == ACTION_POWEROFF ? 'P' :
5914 arg_action == ACTION_KEXEC ? 'K' :
5921 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
5923 char date[FORMAT_TIMESTAMP_MAX];
5925 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5926 format_timestamp(date, sizeof(date), arg_when));
5931 if (!arg_dry && !arg_force)
5932 return start_with_fallback(bus);
5935 if (sd_booted() > 0)
5936 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5938 r = utmp_put_shutdown();
5940 log_warning("Failed to write utmp record: %s", strerror(-r));
5947 r = halt_now(arg_action);
5948 log_error("Failed to reboot: %s", strerror(-r));
5953 static int runlevel_main(void) {
5954 int r, runlevel, previous;
5956 r = utmp_get_runlevel(&runlevel, &previous);
5963 previous <= 0 ? 'N' : previous,
5964 runlevel <= 0 ? 'N' : runlevel);
5969 int main(int argc, char*argv[]) {
5970 _cleanup_bus_unref_ sd_bus *bus = NULL;
5973 setlocale(LC_ALL, "");
5974 log_parse_environment();
5977 /* Explicitly not on_tty() to avoid setting cached value.
5978 * This becomes relevant for piping output which might be
5980 original_stdout_is_tty = isatty(STDOUT_FILENO);
5982 r = parse_argv(argc, argv);
5986 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5987 * let's shortcut this */
5988 if (arg_action == ACTION_RUNLEVEL) {
5989 r = runlevel_main();
5993 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
5994 log_info("Running in chroot, ignoring request.");
6000 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
6002 /* systemctl_main() will print an error message for the bus
6003 * connection, but only if it needs to */
6005 switch (arg_action) {
6007 case ACTION_SYSTEMCTL:
6008 r = systemctl_main(bus, argc, argv, r);
6012 case ACTION_POWEROFF:
6018 case ACTION_RUNLEVEL2:
6019 case ACTION_RUNLEVEL3:
6020 case ACTION_RUNLEVEL4:
6021 case ACTION_RUNLEVEL5:
6023 case ACTION_EMERGENCY:
6024 case ACTION_DEFAULT:
6025 r = start_with_fallback(bus);
6030 r = reload_with_fallback(bus);
6033 case ACTION_CANCEL_SHUTDOWN: {
6034 _cleanup_free_ char *m = NULL;
6037 m = strv_join(arg_wall, " ");
6044 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6046 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6050 case ACTION_RUNLEVEL:
6051 case _ACTION_INVALID:
6053 assert_not_reached("Unknown action");
6058 ask_password_agent_close();
6059 polkit_agent_close();
6061 strv_free(arg_types);
6062 strv_free(arg_states);
6063 strv_free(arg_properties);
6065 return r < 0 ? EXIT_FAILURE : r;