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;
897 pager_open_if_enabled();
899 n = get_unit_list(bus, &reply, &unit_infos);
903 dual_timestamp_get(&nw);
905 for (u = unit_infos; u < unit_infos + n; u++) {
906 _cleanup_strv_free_ char **triggered = NULL;
910 if (!output_show_unit(u))
913 if (!endswith(u->id, ".timer"))
916 r = get_triggered_units(bus, u->unit_path, &triggered);
920 r = get_next_elapse(bus, u->unit_path, &next);
924 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
927 if (next.monotonic > nw.monotonic)
928 converted = nw.realtime + (next.monotonic - nw.monotonic);
930 converted = nw.realtime - (nw.monotonic - next.monotonic);
932 if (next.realtime != (usec_t) -1 && next.realtime > 0)
933 m = MIN(converted, next.realtime);
939 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
944 timer_infos[c++] = (struct timer_info) {
947 .triggered = triggered,
950 triggered = NULL; /* avoid cleanup */
953 qsort_safe(timer_infos, c, sizeof(struct timer_info),
954 (__compar_fn_t) timer_info_compare);
956 output_timers_list(timer_infos, c);
959 for (t = timer_infos; t < timer_infos + c; t++)
960 strv_free(t->triggered);
965 static int compare_unit_file_list(const void *a, const void *b) {
967 const UnitFileList *u = a, *v = b;
969 d1 = strrchr(u->path, '.');
970 d2 = strrchr(v->path, '.');
975 r = strcasecmp(d1, d2);
980 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
983 static bool output_show_unit_file(const UnitFileList *u) {
986 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
989 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
990 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
991 const UnitFileList *u;
993 max_id_len = sizeof("UNIT FILE")-1;
994 state_cols = sizeof("STATE")-1;
996 for (u = units; u < units + c; u++) {
997 if (!output_show_unit_file(u))
1000 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
1001 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1005 unsigned basic_cols;
1007 id_cols = MIN(max_id_len, 25u);
1008 basic_cols = 1 + id_cols + state_cols;
1009 if (basic_cols < (unsigned) columns())
1010 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1012 id_cols = max_id_len;
1015 printf("%-*s %-*s\n",
1016 id_cols, "UNIT FILE",
1017 state_cols, "STATE");
1019 for (u = units; u < units + c; u++) {
1020 _cleanup_free_ char *e = NULL;
1021 const char *on, *off;
1024 if (!output_show_unit_file(u))
1029 if (u->state == UNIT_FILE_MASKED ||
1030 u->state == UNIT_FILE_MASKED_RUNTIME ||
1031 u->state == UNIT_FILE_DISABLED ||
1032 u->state == UNIT_FILE_INVALID) {
1033 on = ansi_highlight_red();
1034 off = ansi_highlight_off();
1035 } else if (u->state == UNIT_FILE_ENABLED) {
1036 on = ansi_highlight_green();
1037 off = ansi_highlight_off();
1041 id = path_get_file_name(u->path);
1043 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1045 printf("%-*s %s%-*s%s\n",
1046 id_cols, e ? e : id,
1047 on, state_cols, unit_file_state_to_string(u->state), off);
1051 printf("\n%u unit files listed.\n", n_shown);
1054 static int list_unit_files(sd_bus *bus, char **args) {
1055 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1056 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1057 _cleanup_free_ UnitFileList *units = NULL;
1063 pager_open_if_enabled();
1071 h = hashmap_new(string_hash_func, string_compare_func);
1075 r = unit_file_get_list(arg_scope, arg_root, h);
1077 unit_file_list_free(h);
1078 log_error("Failed to get unit file list: %s", strerror(-r));
1082 n_units = hashmap_size(h);
1083 units = new(UnitFileList, n_units);
1085 unit_file_list_free(h);
1089 HASHMAP_FOREACH(u, h, i) {
1090 memcpy(units + c++, u, sizeof(UnitFileList));
1094 assert(c == n_units);
1099 r = sd_bus_call_method(
1101 "org.freedesktop.systemd1",
1102 "/org/freedesktop/systemd1",
1103 "org.freedesktop.systemd1.Manager",
1109 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1113 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1115 return bus_log_parse_error(r);
1117 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1119 if (!GREEDY_REALLOC(units, size, c + 1))
1122 units[c++] = (struct UnitFileList) {
1124 unit_file_state_from_string(state)
1128 return bus_log_parse_error(r);
1130 r = sd_bus_message_exit_container(reply);
1132 return bus_log_parse_error(r);
1136 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1137 output_unit_file_list(units, c);
1143 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1144 _cleanup_free_ char *n = NULL;
1145 size_t max_len = MAX(columns(),20u);
1151 for (i = level - 1; i >= 0; i--) {
1153 if(len > max_len - 3 && !arg_full) {
1154 printf("%s...\n",max_len % 2 ? "" : " ");
1157 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1161 if(len > max_len - 3 && !arg_full) {
1162 printf("%s...\n",max_len % 2 ? "" : " ");
1166 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1170 printf("%s\n", name);
1174 n = ellipsize(name, max_len-len, 100);
1182 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1184 static const char *dependencies[] = {
1185 [DEPENDENCY_FORWARD] = "Requires\0"
1186 "RequiresOverridable\0"
1188 "RequisiteOverridable\0"
1190 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1191 "RequiredByOverridable\0"
1194 [DEPENDENCY_AFTER] = "After\0",
1195 [DEPENDENCY_BEFORE] = "Before\0",
1198 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1199 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1200 _cleanup_strv_free_ char **ret = NULL;
1201 _cleanup_free_ char *path = NULL;
1207 assert(arg_dependency < ELEMENTSOF(dependencies));
1209 path = unit_dbus_path_from_name(name);
1213 r = sd_bus_call_method(
1215 "org.freedesktop.systemd1",
1217 "org.freedesktop.DBus.Properties",
1221 "s", "org.freedesktop.systemd1.Unit");
1223 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1227 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1229 return bus_log_parse_error(r);
1231 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1234 r = sd_bus_message_read(reply, "s", &prop);
1236 return bus_log_parse_error(r);
1238 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1239 r = sd_bus_message_skip(reply, "v");
1241 return bus_log_parse_error(r);
1244 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1246 return bus_log_parse_error(r);
1248 r = bus_message_read_strv_extend(reply, &ret);
1250 return bus_log_parse_error(r);
1252 r = sd_bus_message_exit_container(reply);
1254 return bus_log_parse_error(r);
1257 r = sd_bus_message_exit_container(reply);
1259 return bus_log_parse_error(r);
1263 return bus_log_parse_error(r);
1265 r = sd_bus_message_exit_container(reply);
1267 return bus_log_parse_error(r);
1275 static int list_dependencies_compare(const void *_a, const void *_b) {
1276 const char **a = (const char**) _a, **b = (const char**) _b;
1278 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1280 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1283 return strcasecmp(*a, *b);
1286 static int list_dependencies_one(
1291 unsigned int branches) {
1293 _cleanup_strv_free_ char **deps = NULL, **u;
1301 u = strv_append(*units, name);
1305 r = list_dependencies_get_dependencies(bus, name, &deps);
1309 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1311 STRV_FOREACH(c, deps) {
1312 if (strv_contains(u, *c)) {
1314 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1321 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1325 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1326 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1341 static int list_dependencies(sd_bus *bus, char **args) {
1342 _cleanup_strv_free_ char **units = NULL;
1343 _cleanup_free_ char *unit = NULL;
1349 unit = unit_name_mangle(args[1]);
1354 u = SPECIAL_DEFAULT_TARGET;
1356 pager_open_if_enabled();
1360 return list_dependencies_one(bus, u, 0, &units, 0);
1363 static int get_default(sd_bus *bus, char **args) {
1364 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1365 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1366 _cleanup_free_ char *_path = NULL;
1370 if (!bus || avoid_bus()) {
1371 r = unit_file_get_default(arg_scope, arg_root, &_path);
1373 log_error("Failed to get default target: %s", strerror(-r));
1379 r = sd_bus_call_method(
1381 "org.freedesktop.systemd1",
1382 "/org/freedesktop/systemd1",
1383 "org.freedesktop.systemd1.Manager",
1389 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1393 r = sd_bus_message_read(reply, "s", &path);
1395 return bus_log_parse_error(r);
1399 printf("%s\n", path);
1406 const char *name, *type, *state;
1409 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1410 unsigned id_len, unit_len, type_len, state_len;
1411 const struct job_info *j;
1412 const char *on, *off;
1413 bool shorten = false;
1415 assert(n == 0 || jobs);
1418 on = ansi_highlight_green();
1419 off = ansi_highlight_off();
1421 printf("%sNo jobs running.%s\n", on, off);
1425 pager_open_if_enabled();
1427 id_len = sizeof("JOB")-1;
1428 unit_len = sizeof("UNIT")-1;
1429 type_len = sizeof("TYPE")-1;
1430 state_len = sizeof("STATE")-1;
1432 for (j = jobs; j < jobs + n; j++) {
1433 uint32_t id = j->id;
1434 assert(j->name && j->type && j->state);
1436 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1437 unit_len = MAX(unit_len, strlen(j->name));
1438 type_len = MAX(type_len, strlen(j->type));
1439 state_len = MAX(state_len, strlen(j->state));
1442 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1443 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1447 printf("%*s %-*s %-*s %-*s\n",
1451 state_len, "STATE");
1453 for (j = jobs; j < jobs + n; j++) {
1454 _cleanup_free_ char *e = NULL;
1456 if (streq(j->state, "running")) {
1457 on = ansi_highlight();
1458 off = ansi_highlight_off();
1462 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1463 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1465 on, unit_len, e ? e : j->name, off,
1467 on, state_len, j->state, off);
1470 on = ansi_highlight();
1471 off = ansi_highlight_off();
1473 printf("\n%s%u jobs listed%s.\n", on, n, off);
1476 static int list_jobs(sd_bus *bus, char **args) {
1477 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1478 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1479 const char *name, *type, *state, *job_path, *unit_path;
1480 _cleanup_free_ struct job_info *jobs = NULL;
1486 r = sd_bus_call_method(
1488 "org.freedesktop.systemd1",
1489 "/org/freedesktop/systemd1",
1490 "org.freedesktop.systemd1.Manager",
1496 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1500 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1502 return bus_log_parse_error(r);
1504 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1506 if (!GREEDY_REALLOC(jobs, size, c + 1))
1509 jobs[c++] = (struct job_info) {
1517 return bus_log_parse_error(r);
1519 r = sd_bus_message_exit_container(reply);
1521 return bus_log_parse_error(r);
1523 output_jobs_list(jobs, c);
1527 static int cancel_job(sd_bus *bus, char **args) {
1528 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1533 if (strv_length(args) <= 1)
1534 return daemon_reload(bus, args);
1536 STRV_FOREACH(name, args+1) {
1540 r = safe_atou32(*name, &id);
1542 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1546 r = sd_bus_call_method(
1548 "org.freedesktop.systemd1",
1549 "/org/freedesktop/systemd1",
1550 "org.freedesktop.systemd1.Manager",
1556 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1564 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1565 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1566 _cleanup_free_ char *n = NULL;
1570 /* We ignore all errors here, since this is used to show a
1573 n = unit_name_mangle(unit);
1577 /* We don't use unit_dbus_path_from_name() directly since we
1578 * don't want to load the unit if it isn't loaded. */
1580 r = sd_bus_call_method(
1582 "org.freedesktop.systemd1",
1583 "/org/freedesktop/systemd1",
1584 "org.freedesktop.systemd1.Manager",
1592 r = sd_bus_message_read(reply, "o", &path);
1596 r = sd_bus_get_property_trivial(
1598 "org.freedesktop.systemd1",
1600 "org.freedesktop.systemd1.Unit",
1610 typedef struct WaitData {
1617 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1624 log_debug("Got D-Bus request: %s.%s() on %s",
1625 sd_bus_message_get_interface(m),
1626 sd_bus_message_get_member(m),
1627 sd_bus_message_get_path(m));
1629 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1630 log_error("Warning! D-Bus connection terminated.");
1632 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1634 const char *path, *result, *unit;
1638 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1640 ret = set_remove(d->set, (char*) path);
1646 if (!isempty(result))
1647 d->result = strdup(result);
1650 d->name = strdup(unit);
1655 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1657 ret = set_remove(d->set, (char*) path);
1664 d->result = strdup(result);
1670 log_error("Failed to parse message.");
1676 static int enable_wait_for_jobs(sd_bus *bus) {
1681 r = sd_bus_add_match(
1684 "sender='org.freedesktop.systemd1',"
1685 "interface='org.freedesktop.systemd1.Manager',"
1686 "member='JobRemoved',"
1687 "path='/org/freedesktop/systemd1'",
1690 log_error("Failed to add match");
1694 /* This is slightly dirty, since we don't undo the match registrations. */
1698 static int wait_for_jobs(sd_bus *bus, Set *s) {
1699 WaitData d = { .set = s };
1705 r = sd_bus_add_filter(bus, wait_filter, &d);
1709 while (!set_isempty(s)) {
1711 r = sd_bus_process(bus, NULL);
1716 r = sd_bus_wait(bus, (uint64_t) -1);
1725 if (streq(d.result, "timeout"))
1726 log_error("Job for %s timed out.", strna(d.name));
1727 else if (streq(d.result, "canceled"))
1728 log_error("Job for %s canceled.", strna(d.name));
1729 else if (streq(d.result, "dependency"))
1730 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1731 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1732 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1735 if (streq_ptr(d.result, "timeout"))
1737 else if (streq_ptr(d.result, "canceled"))
1739 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1750 return sd_bus_remove_filter(bus, wait_filter, &d);
1753 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1754 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1755 _cleanup_free_ char *n = NULL, *state = NULL;
1761 n = unit_name_mangle(name);
1765 /* We don't use unit_dbus_path_from_name() directly since we
1766 * don't want to load the unit if it isn't loaded. */
1768 r = sd_bus_call_method(
1770 "org.freedesktop.systemd1",
1771 "/org/freedesktop/systemd1",
1772 "org.freedesktop.systemd1.Manager",
1783 r = sd_bus_message_read(reply, "o", &path);
1785 return bus_log_parse_error(r);
1787 r = sd_bus_get_property_string(
1789 "org.freedesktop.systemd1",
1791 "org.freedesktop.systemd1.Unit",
1804 return nulstr_contains(good_states, state);
1807 static int check_triggering_units(
1811 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1812 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1813 _cleanup_strv_free_ char **triggered_by = NULL;
1814 bool print_warning_label = true;
1818 n = unit_name_mangle(name);
1822 path = unit_dbus_path_from_name(n);
1826 r = sd_bus_get_property_string(
1828 "org.freedesktop.systemd1",
1830 "org.freedesktop.systemd1.Unit",
1835 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1839 if (streq(state, "masked"))
1842 r = sd_bus_get_property_strv(
1844 "org.freedesktop.systemd1",
1846 "org.freedesktop.systemd1.Unit",
1851 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1855 STRV_FOREACH(i, triggered_by) {
1856 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1858 log_error("Failed to check unit: %s", strerror(-r));
1865 if (print_warning_label) {
1866 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1867 print_warning_label = false;
1870 log_warning(" %s", *i);
1876 static int start_unit_one(
1881 sd_bus_error *error,
1884 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1885 _cleanup_free_ char *n;
1894 n = unit_name_mangle(name);
1898 r = sd_bus_call_method(
1900 "org.freedesktop.systemd1",
1901 "/org/freedesktop/systemd1",
1902 "org.freedesktop.systemd1.Manager",
1908 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1909 /* There's always a fallback possible for
1910 * legacy actions. */
1911 return -EADDRNOTAVAIL;
1913 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1917 r = sd_bus_message_read(reply, "o", &path);
1919 return bus_log_parse_error(r);
1921 if (need_daemon_reload(bus, n) > 0)
1922 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1923 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1932 r = set_consume(s, p);
1940 static const struct {
1944 } action_table[_ACTION_MAX] = {
1945 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1946 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1947 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1948 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1949 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1950 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1951 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1952 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1953 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1954 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1955 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1956 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1957 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1958 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1959 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1962 static enum action verb_to_action(const char *verb) {
1965 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1966 if (streq_ptr(action_table[i].verb, verb))
1969 return _ACTION_INVALID;
1972 static int start_unit(sd_bus *bus, char **args) {
1973 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1974 _cleanup_set_free_free_ Set *s = NULL;
1975 const char *method, *mode, *one_name;
1981 ask_password_agent_open_if_enabled();
1983 if (arg_action == ACTION_SYSTEMCTL) {
1986 streq(args[0], "stop") ||
1987 streq(args[0], "condstop") ? "StopUnit" :
1988 streq(args[0], "reload") ? "ReloadUnit" :
1989 streq(args[0], "restart") ? "RestartUnit" :
1991 streq(args[0], "try-restart") ||
1992 streq(args[0], "condrestart") ? "TryRestartUnit" :
1994 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1996 streq(args[0], "reload-or-try-restart") ||
1997 streq(args[0], "condreload") ||
1998 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2000 action = verb_to_action(args[0]);
2002 mode = streq(args[0], "isolate") ? "isolate" :
2003 action_table[action].mode ?: arg_job_mode;
2005 one_name = action_table[action].target;
2007 assert(arg_action < ELEMENTSOF(action_table));
2008 assert(action_table[arg_action].target);
2010 method = "StartUnit";
2012 mode = action_table[arg_action].mode;
2013 one_name = action_table[arg_action].target;
2016 if (!arg_no_block) {
2017 r = enable_wait_for_jobs(bus);
2019 log_error("Could not watch jobs: %s", strerror(-r));
2023 s = set_new(string_hash_func, string_compare_func);
2029 r = start_unit_one(bus, method, one_name, mode, &error, s);
2031 r = translate_bus_error_to_exit_status(r, &error);
2035 STRV_FOREACH(name, args+1) {
2038 q = start_unit_one(bus, method, *name, mode, &error, s);
2040 r = translate_bus_error_to_exit_status(r, &error);
2041 sd_bus_error_free(&error);
2046 if (!arg_no_block) {
2049 q = wait_for_jobs(bus, s);
2053 /* When stopping units, warn if they can still be triggered by
2054 * another active unit (socket, path, timer) */
2055 if (!arg_quiet && streq(method, "StopUnit")) {
2057 check_triggering_units(bus, one_name);
2059 STRV_FOREACH(name, args+1)
2060 check_triggering_units(bus, *name);
2067 /* Ask systemd-logind, which might grant access to unprivileged users
2068 * through PolicyKit */
2069 static int reboot_with_logind(sd_bus *bus, enum action a) {
2071 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2078 polkit_agent_open_if_enabled();
2086 case ACTION_POWEROFF:
2087 method = "PowerOff";
2090 case ACTION_SUSPEND:
2094 case ACTION_HIBERNATE:
2095 method = "Hibernate";
2098 case ACTION_HYBRID_SLEEP:
2099 method = "HybridSleep";
2106 r = sd_bus_call_method(
2108 "org.freedesktop.login1",
2109 "/org/freedesktop/login1",
2110 "org.freedesktop.login1.Manager",
2116 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2124 static int check_inhibitors(sd_bus *bus, enum action a) {
2126 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2127 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2128 _cleanup_strv_free_ char **sessions = NULL;
2129 const char *what, *who, *why, *mode;
2138 if (arg_ignore_inhibitors || arg_force > 0)
2150 r = sd_bus_call_method(
2152 "org.freedesktop.login1",
2153 "/org/freedesktop/login1",
2154 "org.freedesktop.login1.Manager",
2160 /* If logind is not around, then there are no inhibitors... */
2163 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2165 return bus_log_parse_error(r);
2167 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2168 _cleanup_free_ char *comm = NULL, *user = NULL;
2169 _cleanup_strv_free_ char **sv = NULL;
2171 if (!streq(mode, "block"))
2174 sv = strv_split(what, ":");
2178 if (!strv_contains(sv,
2180 a == ACTION_POWEROFF ||
2181 a == ACTION_REBOOT ||
2182 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2185 get_process_comm(pid, &comm);
2186 user = uid_to_name(uid);
2188 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2189 who, (unsigned long) pid, strna(comm), strna(user), why);
2194 return bus_log_parse_error(r);
2196 r = sd_bus_message_exit_container(reply);
2198 return bus_log_parse_error(r);
2200 /* Check for current sessions */
2201 sd_get_sessions(&sessions);
2202 STRV_FOREACH(s, sessions) {
2203 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2205 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2208 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2211 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2214 sd_session_get_tty(*s, &tty);
2215 sd_session_get_seat(*s, &seat);
2216 sd_session_get_service(*s, &service);
2217 user = uid_to_name(uid);
2219 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2226 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2227 action_table[a].verb);
2235 static int start_special(sd_bus *bus, char **args) {
2241 a = verb_to_action(args[0]);
2243 r = check_inhibitors(bus, a);
2247 if (arg_force >= 2 && geteuid() != 0) {
2248 log_error("Must be root.");
2252 if (arg_force >= 2 &&
2253 (a == ACTION_HALT ||
2254 a == ACTION_POWEROFF ||
2255 a == ACTION_REBOOT))
2258 if (arg_force >= 1 &&
2259 (a == ACTION_HALT ||
2260 a == ACTION_POWEROFF ||
2261 a == ACTION_REBOOT ||
2262 a == ACTION_KEXEC ||
2264 return daemon_reload(bus, args);
2266 /* first try logind, to allow authentication with polkit */
2267 if (geteuid() != 0 &&
2268 (a == ACTION_POWEROFF ||
2269 a == ACTION_REBOOT ||
2270 a == ACTION_SUSPEND ||
2271 a == ACTION_HIBERNATE ||
2272 a == ACTION_HYBRID_SLEEP)) {
2273 r = reboot_with_logind(bus, a);
2278 r = start_unit(bus, args);
2279 if (r == EXIT_SUCCESS)
2285 static int check_unit_active(sd_bus *bus, char **args) {
2287 int r = 3; /* According to LSB: "program is not running" */
2292 STRV_FOREACH(name, args+1) {
2295 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2305 static int check_unit_failed(sd_bus *bus, char **args) {
2312 STRV_FOREACH(name, args+1) {
2315 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2325 static int kill_unit(sd_bus *bus, char **args) {
2326 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2334 arg_kill_who = "all";
2336 STRV_FOREACH(name, args+1) {
2337 _cleanup_free_ char *n = NULL;
2339 n = unit_name_mangle(*name);
2343 r = sd_bus_call_method(
2345 "org.freedesktop.systemd1",
2346 "/org/freedesktop/systemd1",
2347 "org.freedesktop.systemd1.Manager",
2351 "ssi", n, arg_kill_who, arg_signal);
2353 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2361 typedef struct ExecStatusInfo {
2369 usec_t start_timestamp;
2370 usec_t exit_timestamp;
2375 LIST_FIELDS(struct ExecStatusInfo, exec);
2378 static void exec_status_info_free(ExecStatusInfo *i) {
2387 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2388 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2391 int32_t code, status;
2397 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2399 return bus_log_parse_error(r);
2403 r = sd_bus_message_read(m, "s", &path);
2405 return bus_log_parse_error(r);
2407 i->path = strdup(path);
2411 r = sd_bus_message_read_strv(m, &i->argv);
2413 return bus_log_parse_error(r);
2415 r = sd_bus_message_read(m,
2418 &start_timestamp, &start_timestamp_monotonic,
2419 &exit_timestamp, &exit_timestamp_monotonic,
2423 return bus_log_parse_error(r);
2426 i->start_timestamp = (usec_t) start_timestamp;
2427 i->exit_timestamp = (usec_t) exit_timestamp;
2428 i->pid = (pid_t) pid;
2432 r = sd_bus_message_exit_container(m);
2434 return bus_log_parse_error(r);
2439 typedef struct UnitStatusInfo {
2441 const char *load_state;
2442 const char *active_state;
2443 const char *sub_state;
2444 const char *unit_file_state;
2446 const char *description;
2447 const char *following;
2449 char **documentation;
2451 const char *fragment_path;
2452 const char *source_path;
2453 const char *control_group;
2455 char **dropin_paths;
2457 const char *load_error;
2460 usec_t inactive_exit_timestamp;
2461 usec_t inactive_exit_timestamp_monotonic;
2462 usec_t active_enter_timestamp;
2463 usec_t active_exit_timestamp;
2464 usec_t inactive_enter_timestamp;
2466 bool need_daemon_reload;
2471 const char *status_text;
2472 const char *pid_file;
2475 usec_t start_timestamp;
2476 usec_t exit_timestamp;
2478 int exit_code, exit_status;
2480 usec_t condition_timestamp;
2481 bool condition_result;
2482 bool failed_condition_trigger;
2483 bool failed_condition_negate;
2484 const char *failed_condition;
2485 const char *failed_condition_param;
2488 unsigned n_accepted;
2489 unsigned n_connections;
2492 /* Pairs of type, path */
2496 const char *sysfs_path;
2498 /* Mount, Automount */
2504 LIST_HEAD(ExecStatusInfo, exec);
2507 static void print_status_info(
2512 const char *on, *off, *ss;
2514 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2515 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2518 arg_all * OUTPUT_SHOW_ALL |
2519 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2520 on_tty() * OUTPUT_COLOR |
2521 !arg_quiet * OUTPUT_WARN_CUTOFF |
2522 arg_full * OUTPUT_FULL_WIDTH;
2527 /* This shows pretty information about a unit. See
2528 * print_property() for a low-level property printer */
2530 printf("%s", strna(i->id));
2532 if (i->description && !streq_ptr(i->id, i->description))
2533 printf(" - %s", i->description);
2538 printf(" Follow: unit currently follows state of %s\n", i->following);
2540 if (streq_ptr(i->load_state, "error")) {
2541 on = ansi_highlight_red();
2542 off = ansi_highlight_off();
2546 path = i->source_path ? i->source_path : i->fragment_path;
2549 printf(" Loaded: %s%s%s (Reason: %s)\n",
2550 on, strna(i->load_state), off, i->load_error);
2551 else if (path && i->unit_file_state)
2552 printf(" Loaded: %s%s%s (%s; %s)\n",
2553 on, strna(i->load_state), off, path, i->unit_file_state);
2555 printf(" Loaded: %s%s%s (%s)\n",
2556 on, strna(i->load_state), off, path);
2558 printf(" Loaded: %s%s%s\n",
2559 on, strna(i->load_state), off);
2561 if (!strv_isempty(i->dropin_paths)) {
2562 _cleanup_free_ char *dir = NULL;
2566 STRV_FOREACH(dropin, i->dropin_paths) {
2567 if (! dir || last) {
2568 printf(dir ? " " : " Drop-In: ");
2573 if (path_get_parent(*dropin, &dir) < 0) {
2578 printf("%s\n %s", dir,
2579 draw_special_char(DRAW_TREE_RIGHT));
2582 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2584 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2588 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2590 if (streq_ptr(i->active_state, "failed")) {
2591 on = ansi_highlight_red();
2592 off = ansi_highlight_off();
2593 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2594 on = ansi_highlight_green();
2595 off = ansi_highlight_off();
2600 printf(" Active: %s%s (%s)%s",
2601 on, strna(i->active_state), ss, off);
2603 printf(" Active: %s%s%s",
2604 on, strna(i->active_state), off);
2606 if (!isempty(i->result) && !streq(i->result, "success"))
2607 printf(" (Result: %s)", i->result);
2609 timestamp = (streq_ptr(i->active_state, "active") ||
2610 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2611 (streq_ptr(i->active_state, "inactive") ||
2612 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2613 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2614 i->active_exit_timestamp;
2616 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2617 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2620 printf(" since %s; %s\n", s2, s1);
2622 printf(" since %s\n", s2);
2626 if (!i->condition_result && i->condition_timestamp > 0) {
2627 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2628 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2630 printf(" start condition failed at %s%s%s\n",
2631 s2, s1 ? "; " : "", s1 ? s1 : "");
2632 if (i->failed_condition_trigger)
2633 printf(" none of the trigger conditions were met\n");
2634 else if (i->failed_condition)
2635 printf(" %s=%s%s was not met\n",
2636 i->failed_condition,
2637 i->failed_condition_negate ? "!" : "",
2638 i->failed_condition_param);
2642 printf(" Device: %s\n", i->sysfs_path);
2644 printf(" Where: %s\n", i->where);
2646 printf(" What: %s\n", i->what);
2648 STRV_FOREACH(t, i->documentation)
2649 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2651 STRV_FOREACH_PAIR(t, t2, i->listen)
2652 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2655 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2657 LIST_FOREACH(exec, p, i->exec) {
2658 _cleanup_free_ char *argv = NULL;
2661 /* Only show exited processes here */
2665 argv = strv_join(p->argv, " ");
2666 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2668 good = is_clean_exit_lsb(p->code, p->status, NULL);
2670 on = ansi_highlight_red();
2671 off = ansi_highlight_off();
2675 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2677 if (p->code == CLD_EXITED) {
2680 printf("status=%i", p->status);
2682 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2687 printf("signal=%s", signal_to_string(p->status));
2689 printf(")%s\n", off);
2691 if (i->main_pid == p->pid &&
2692 i->start_timestamp == p->start_timestamp &&
2693 i->exit_timestamp == p->start_timestamp)
2694 /* Let's not show this twice */
2697 if (p->pid == i->control_pid)
2701 if (i->main_pid > 0 || i->control_pid > 0) {
2702 if (i->main_pid > 0) {
2703 printf(" Main PID: %u", (unsigned) i->main_pid);
2706 _cleanup_free_ char *comm = NULL;
2707 get_process_comm(i->main_pid, &comm);
2709 printf(" (%s)", comm);
2710 } else if (i->exit_code > 0) {
2711 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2713 if (i->exit_code == CLD_EXITED) {
2716 printf("status=%i", i->exit_status);
2718 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2723 printf("signal=%s", signal_to_string(i->exit_status));
2727 if (i->control_pid > 0)
2731 if (i->control_pid > 0) {
2732 _cleanup_free_ char *c = NULL;
2734 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2736 get_process_comm(i->control_pid, &c);
2745 printf(" Status: \"%s\"\n", i->status_text);
2747 if (i->control_group &&
2748 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2751 printf(" CGroup: %s\n", i->control_group);
2753 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2756 char prefix[] = " ";
2759 if (c > sizeof(prefix) - 1)
2760 c -= sizeof(prefix) - 1;
2764 if (i->main_pid > 0)
2765 extra[k++] = i->main_pid;
2767 if (i->control_pid > 0)
2768 extra[k++] = i->control_pid;
2770 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2771 c, false, extra, k, flags);
2775 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2777 show_journal_by_unit(stdout,
2781 i->inactive_exit_timestamp_monotonic,
2785 arg_scope == UNIT_FILE_SYSTEM,
2789 if (i->need_daemon_reload)
2790 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2791 ansi_highlight_red(),
2792 ansi_highlight_off(),
2793 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2796 static void show_unit_help(UnitStatusInfo *i) {
2801 if (!i->documentation) {
2802 log_info("Documentation for %s not known.", i->id);
2806 STRV_FOREACH(p, i->documentation) {
2808 if (startswith(*p, "man:")) {
2809 const char *args[4] = { "man", NULL, NULL, NULL };
2810 _cleanup_free_ char *page = NULL, *section = NULL;
2817 if ((*p)[k-1] == ')')
2818 e = strrchr(*p, '(');
2821 page = strndup((*p) + 4, e - *p - 4);
2822 section = strndup(e + 1, *p + k - e - 2);
2823 if (!page || !section) {
2835 log_error("Failed to fork: %m");
2841 execvp(args[0], (char**) args);
2842 log_error("Failed to execute man: %m");
2843 _exit(EXIT_FAILURE);
2846 wait_for_terminate(pid, NULL);
2848 log_info("Can't show: %s", *p);
2852 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2859 switch (contents[0]) {
2861 case SD_BUS_TYPE_STRING: {
2864 r = sd_bus_message_read(m, "s", &s);
2866 return bus_log_parse_error(r);
2869 if (streq(name, "Id"))
2871 else if (streq(name, "LoadState"))
2873 else if (streq(name, "ActiveState"))
2874 i->active_state = s;
2875 else if (streq(name, "SubState"))
2877 else if (streq(name, "Description"))
2879 else if (streq(name, "FragmentPath"))
2880 i->fragment_path = s;
2881 else if (streq(name, "SourcePath"))
2884 else if (streq(name, "DefaultControlGroup")) {
2886 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2888 i->control_group = e;
2891 else if (streq(name, "ControlGroup"))
2892 i->control_group = s;
2893 else if (streq(name, "StatusText"))
2895 else if (streq(name, "PIDFile"))
2897 else if (streq(name, "SysFSPath"))
2899 else if (streq(name, "Where"))
2901 else if (streq(name, "What"))
2903 else if (streq(name, "Following"))
2905 else if (streq(name, "UnitFileState"))
2906 i->unit_file_state = s;
2907 else if (streq(name, "Result"))
2914 case SD_BUS_TYPE_BOOLEAN: {
2917 r = sd_bus_message_read(m, "b", &b);
2919 return bus_log_parse_error(r);
2921 if (streq(name, "Accept"))
2923 else if (streq(name, "NeedDaemonReload"))
2924 i->need_daemon_reload = b;
2925 else if (streq(name, "ConditionResult"))
2926 i->condition_result = b;
2931 case SD_BUS_TYPE_UINT32: {
2934 r = sd_bus_message_read(m, "u", &u);
2936 return bus_log_parse_error(r);
2938 if (streq(name, "MainPID")) {
2940 i->main_pid = (pid_t) u;
2943 } else if (streq(name, "ControlPID"))
2944 i->control_pid = (pid_t) u;
2945 else if (streq(name, "ExecMainPID")) {
2947 i->main_pid = (pid_t) u;
2948 } else if (streq(name, "NAccepted"))
2950 else if (streq(name, "NConnections"))
2951 i->n_connections = u;
2956 case SD_BUS_TYPE_INT32: {
2959 r = sd_bus_message_read(m, "i", &j);
2961 return bus_log_parse_error(r);
2963 if (streq(name, "ExecMainCode"))
2964 i->exit_code = (int) j;
2965 else if (streq(name, "ExecMainStatus"))
2966 i->exit_status = (int) j;
2971 case SD_BUS_TYPE_UINT64: {
2974 r = sd_bus_message_read(m, "t", &u);
2976 return bus_log_parse_error(r);
2978 if (streq(name, "ExecMainStartTimestamp"))
2979 i->start_timestamp = (usec_t) u;
2980 else if (streq(name, "ExecMainExitTimestamp"))
2981 i->exit_timestamp = (usec_t) u;
2982 else if (streq(name, "ActiveEnterTimestamp"))
2983 i->active_enter_timestamp = (usec_t) u;
2984 else if (streq(name, "InactiveEnterTimestamp"))
2985 i->inactive_enter_timestamp = (usec_t) u;
2986 else if (streq(name, "InactiveExitTimestamp"))
2987 i->inactive_exit_timestamp = (usec_t) u;
2988 else if (streq(name, "InactiveExitTimestampMonotonic"))
2989 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2990 else if (streq(name, "ActiveExitTimestamp"))
2991 i->active_exit_timestamp = (usec_t) u;
2992 else if (streq(name, "ConditionTimestamp"))
2993 i->condition_timestamp = (usec_t) u;
2998 case SD_BUS_TYPE_ARRAY:
3000 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3001 _cleanup_free_ ExecStatusInfo *info = NULL;
3003 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3005 return bus_log_parse_error(r);
3007 info = new0(ExecStatusInfo, 1);
3011 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3013 info->name = strdup(name);
3017 LIST_PREPEND(exec, i->exec, info);
3019 info = new0(ExecStatusInfo, 1);
3025 return bus_log_parse_error(r);
3027 r = sd_bus_message_exit_container(m);
3029 return bus_log_parse_error(r);
3033 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3034 const char *type, *path;
3036 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3038 return bus_log_parse_error(r);
3040 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3042 r = strv_extend(&i->listen, type);
3046 r = strv_extend(&i->listen, path);
3051 return bus_log_parse_error(r);
3053 r = sd_bus_message_exit_container(m);
3055 return bus_log_parse_error(r);
3059 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3061 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3063 return bus_log_parse_error(r);
3065 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3067 r = sd_bus_message_read_strv(m, &i->documentation);
3069 return bus_log_parse_error(r);
3071 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3072 const char *cond, *param;
3073 int trigger, negate;
3076 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3078 return bus_log_parse_error(r);
3080 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3081 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3082 if (state < 0 && (!trigger || !i->failed_condition)) {
3083 i->failed_condition = cond;
3084 i->failed_condition_trigger = trigger;
3085 i->failed_condition_negate = negate;
3086 i->failed_condition_param = param;
3090 return bus_log_parse_error(r);
3092 r = sd_bus_message_exit_container(m);
3094 return bus_log_parse_error(r);
3101 case SD_BUS_TYPE_STRUCT_BEGIN:
3103 if (streq(name, "LoadError")) {
3104 const char *n, *message;
3106 r = sd_bus_message_read(m, "(ss)", &n, &message);
3108 return bus_log_parse_error(r);
3110 if (!isempty(message))
3111 i->load_error = message;
3124 r = sd_bus_message_skip(m, contents);
3126 return bus_log_parse_error(r);
3131 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3137 /* This is a low-level property printer, see
3138 * print_status_info() for the nicer output */
3140 if (arg_properties && !strv_find(arg_properties, name)) {
3141 /* skip what we didn't read */
3142 r = sd_bus_message_skip(m, contents);
3146 switch (contents[0]) {
3148 case SD_BUS_TYPE_STRUCT_BEGIN:
3150 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3153 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3155 return bus_log_parse_error(r);
3158 printf("%s=%u\n", name, (unsigned) u);
3160 printf("%s=\n", name);
3164 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3167 r = sd_bus_message_read(m, "(so)", &s, NULL);
3169 return bus_log_parse_error(r);
3171 if (arg_all || !isempty(s))
3172 printf("%s=%s\n", name, s);
3176 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3177 const char *a = NULL, *b = NULL;
3179 r = sd_bus_message_read(m, "(ss)", &a, &b);
3181 return bus_log_parse_error(r);
3183 if (arg_all || !isempty(a) || !isempty(b))
3184 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3191 case SD_BUS_TYPE_ARRAY:
3193 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3197 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3199 return bus_log_parse_error(r);
3201 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3202 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3205 return bus_log_parse_error(r);
3207 r = sd_bus_message_exit_container(m);
3209 return bus_log_parse_error(r);
3213 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3214 const char *type, *path;
3216 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3218 return bus_log_parse_error(r);
3220 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3221 printf("%s=%s\n", type, path);
3223 return bus_log_parse_error(r);
3225 r = sd_bus_message_exit_container(m);
3227 return bus_log_parse_error(r);
3231 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3232 const char *type, *path;
3234 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3236 return bus_log_parse_error(r);
3238 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3239 printf("Listen%s=%s\n", type, path);
3241 return bus_log_parse_error(r);
3243 r = sd_bus_message_exit_container(m);
3245 return bus_log_parse_error(r);
3249 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3251 uint64_t value, next_elapse;
3253 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3255 return bus_log_parse_error(r);
3257 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3258 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3260 printf("%s={ value=%s ; next_elapse=%s }\n",
3262 format_timespan(timespan1, sizeof(timespan1), value, 0),
3263 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3266 return bus_log_parse_error(r);
3268 r = sd_bus_message_exit_container(m);
3270 return bus_log_parse_error(r);
3274 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3275 ExecStatusInfo info = {};
3277 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3279 return bus_log_parse_error(r);
3281 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3282 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3283 _cleanup_free_ char *tt;
3285 tt = strv_join(info.argv, " ");
3287 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3291 yes_no(info.ignore),
3292 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3293 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3294 (unsigned) info. pid,
3295 sigchld_code_to_string(info.code),
3297 info.code == CLD_EXITED ? "" : "/",
3298 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3301 strv_free(info.argv);
3305 r = sd_bus_message_exit_container(m);
3307 return bus_log_parse_error(r);
3311 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3312 const char *path, *rwm;
3314 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3316 return bus_log_parse_error(r);
3318 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3319 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3321 return bus_log_parse_error(r);
3323 r = sd_bus_message_exit_container(m);
3325 return bus_log_parse_error(r);
3329 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3333 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3335 return bus_log_parse_error(r);
3337 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3338 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3340 return bus_log_parse_error(r);
3342 r = sd_bus_message_exit_container(m);
3344 return bus_log_parse_error(r);
3348 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3352 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3354 return bus_log_parse_error(r);
3356 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3357 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3359 return bus_log_parse_error(r);
3361 r = sd_bus_message_exit_container(m);
3363 return bus_log_parse_error(r);
3371 r = bus_print_property(name, m, arg_all);
3373 return bus_log_parse_error(r);
3376 r = sd_bus_message_skip(m, contents);
3378 return bus_log_parse_error(r);
3381 printf("%s=[unprintable]\n", name);
3387 static int show_one(
3391 bool show_properties,
3395 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3396 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3397 UnitStatusInfo info = {};
3404 r = sd_bus_call_method(
3406 "org.freedesktop.systemd1",
3408 "org.freedesktop.DBus.Properties",
3414 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3418 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3420 return bus_log_parse_error(r);
3427 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3428 const char *name, *contents;
3430 r = sd_bus_message_read(reply, "s", &name);
3432 return bus_log_parse_error(r);
3434 r = sd_bus_message_peek_type(reply, NULL, &contents);
3436 return bus_log_parse_error(r);
3438 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3440 return bus_log_parse_error(r);
3442 if (show_properties)
3443 r = print_property(name, reply, contents);
3445 r = status_property(name, reply, &info, contents);
3449 r = sd_bus_message_exit_container(reply);
3451 return bus_log_parse_error(r);
3453 r = sd_bus_message_exit_container(reply);
3455 return bus_log_parse_error(r);
3458 return bus_log_parse_error(r);
3460 r = sd_bus_message_exit_container(reply);
3462 return bus_log_parse_error(r);
3466 if (!show_properties) {
3467 if (streq(verb, "help"))
3468 show_unit_help(&info);
3470 print_status_info(&info, ellipsized);
3473 strv_free(info.documentation);
3474 strv_free(info.dropin_paths);
3475 strv_free(info.listen);
3477 if (!streq_ptr(info.active_state, "active") &&
3478 !streq_ptr(info.active_state, "reloading") &&
3479 streq(verb, "status")) {
3480 /* According to LSB: "program not running" */
3481 /* 0: program is running or service is OK
3482 * 1: program is dead and /var/run pid file exists
3483 * 2: program is dead and /var/lock lock file exists
3484 * 3: program is not running
3485 * 4: program or service status is unknown
3487 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3493 while ((p = info.exec)) {
3494 LIST_REMOVE(exec, info.exec, p);
3495 exec_status_info_free(p);
3501 static int show_one_by_pid(
3508 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3509 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3510 const char *path = NULL;
3513 r = sd_bus_call_method(
3515 "org.freedesktop.systemd1",
3516 "/org/freedesktop/systemd1",
3517 "org.freedesktop.systemd1.Manager",
3523 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3527 r = sd_bus_message_read(reply, "o", &path);
3529 return bus_log_parse_error(r);
3531 return show_one(verb, bus, path, false, new_line, ellipsized);
3534 static int show_all(
3537 bool show_properties,
3541 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3542 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3543 _cleanup_free_ UnitInfo *unit_infos = NULL;
3548 r = get_unit_list(bus, &reply, &unit_infos);
3554 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3556 for (u = unit_infos; u < unit_infos + c; u++) {
3557 _cleanup_free_ char *p = NULL;
3559 if (!output_show_unit(u))
3562 p = unit_dbus_path_from_name(u->id);
3566 printf("%s -> '%s'\n", u->id, p);
3568 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3576 static int show(sd_bus *bus, char **args) {
3578 bool show_properties, show_status, new_line = false;
3580 bool ellipsized = false;
3585 show_properties = streq(args[0], "show");
3586 show_status = streq(args[0], "status");
3588 if (show_properties)
3589 pager_open_if_enabled();
3591 /* If no argument is specified inspect the manager itself */
3593 if (show_properties && strv_length(args) <= 1)
3594 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3596 if (show_status && strv_length(args) <= 1)
3597 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3599 STRV_FOREACH(name, args+1) {
3602 if (safe_atou32(*name, &id) < 0) {
3603 _cleanup_free_ char *p = NULL, *n = NULL;
3604 /* Interpret as unit name */
3606 n = unit_name_mangle(*name);
3610 p = unit_dbus_path_from_name(n);
3614 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3618 } else if (show_properties) {
3619 _cleanup_free_ char *p = NULL;
3621 /* Interpret as job id */
3622 if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
3625 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3630 /* Interpret as PID */
3631 r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized);
3637 if (ellipsized && !arg_quiet)
3638 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3643 static int append_assignment(sd_bus_message *m, const char *assignment) {
3651 eq = strchr(assignment, '=');
3653 log_error("Not an assignment: %s", assignment);
3657 field = strndupa(assignment, eq - assignment);
3660 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3662 return bus_log_create_error(r);
3664 if (streq(field, "CPUAccounting") ||
3665 streq(field, "MemoryAccounting") ||
3666 streq(field, "BlockIOAccounting")) {
3668 r = parse_boolean(eq);
3670 log_error("Failed to parse boolean assignment %s.", assignment);
3674 r = sd_bus_message_append(m, "v", "b", r);
3676 } else if (streq(field, "MemoryLimit")) {
3679 r = parse_bytes(eq, &bytes);
3681 log_error("Failed to parse bytes specification %s", assignment);
3685 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3687 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3690 r = safe_atou64(eq, &u);
3692 log_error("Failed to parse %s value %s.", field, eq);
3696 r = sd_bus_message_append(m, "v", "t", u);
3698 } else if (streq(field, "DevicePolicy"))
3699 r = sd_bus_message_append(m, "v", "s", eq);
3701 else if (streq(field, "DeviceAllow")) {
3704 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3706 const char *path, *rwm;
3709 e = strchr(eq, ' ');
3711 path = strndupa(eq, e - eq);
3718 if (!path_startswith(path, "/dev")) {
3719 log_error("%s is not a device file in /dev.", path);
3723 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3726 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3729 r = sd_bus_message_append(m, "v", "a(st)", 0);
3731 const char *path, *bandwidth;
3735 e = strchr(eq, ' ');
3737 path = strndupa(eq, e - eq);
3740 log_error("Failed to parse %s value %s.", field, eq);
3744 if (!path_startswith(path, "/dev")) {
3745 log_error("%s is not a device file in /dev.", path);
3749 r = parse_bytes(bandwidth, &bytes);
3751 log_error("Failed to parse byte value %s.", bandwidth);
3755 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3758 } else if (streq(field, "BlockIODeviceWeight")) {
3761 r = sd_bus_message_append(m, "v", "a(st)", 0);
3763 const char *path, *weight;
3767 e = strchr(eq, ' ');
3769 path = strndupa(eq, e - eq);
3772 log_error("Failed to parse %s value %s.", field, eq);
3776 if (!path_startswith(path, "/dev")) {
3777 log_error("%s is not a device file in /dev.", path);
3781 r = safe_atou64(weight, &u);
3783 log_error("Failed to parse %s value %s.", field, weight);
3786 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3790 log_error("Unknown assignment %s.", assignment);
3795 return bus_log_create_error(r);
3800 static int set_property(sd_bus *bus, char **args) {
3801 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3802 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3803 _cleanup_free_ char *n = NULL;
3807 r = sd_bus_message_new_method_call(
3809 "org.freedesktop.systemd1",
3810 "/org/freedesktop/systemd1",
3811 "org.freedesktop.systemd1.Manager",
3812 "SetUnitProperties",
3815 return bus_log_create_error(r);
3817 n = unit_name_mangle(args[1]);
3821 r = sd_bus_message_append(m, "sb", n, arg_runtime);
3823 return bus_log_create_error(r);
3825 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
3827 return bus_log_create_error(r);
3829 STRV_FOREACH(i, args + 2) {
3830 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
3832 return bus_log_create_error(r);
3834 r = append_assignment(m, *i);
3838 r = sd_bus_message_close_container(m);
3840 return bus_log_create_error(r);
3843 r = sd_bus_message_close_container(m);
3845 return bus_log_create_error(r);
3847 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
3849 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
3856 static int snapshot(sd_bus *bus, char **args) {
3857 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3858 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3859 _cleanup_free_ char *n = NULL, *id = NULL;
3863 if (strv_length(args) > 1)
3864 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
3870 r = sd_bus_call_method(
3872 "org.freedesktop.systemd1",
3873 "/org/freedesktop/systemd1",
3874 "org.freedesktop.systemd1.Manager",
3880 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
3884 r = sd_bus_message_read(reply, "o", &path);
3886 return bus_log_parse_error(r);
3888 r = sd_bus_get_property_string(
3890 "org.freedesktop.systemd1",
3892 "org.freedesktop.systemd1.Unit",
3897 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
3907 static int delete_snapshot(sd_bus *bus, char **args) {
3908 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3914 STRV_FOREACH(name, args+1) {
3915 _cleanup_free_ char *n = NULL;
3917 n = unit_name_mangle_with_suffix(*name, ".snapshot");
3921 r = sd_bus_call_method(
3923 "org.freedesktop.systemd1",
3924 "/org/freedesktop/systemd1",
3925 "org.freedesktop.systemd1.Manager",
3931 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
3939 static int daemon_reload(sd_bus *bus, char **args) {
3940 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3944 if (arg_action == ACTION_RELOAD)
3946 else if (arg_action == ACTION_REEXEC)
3947 method = "Reexecute";
3949 assert(arg_action == ACTION_SYSTEMCTL);
3952 streq(args[0], "clear-jobs") ||
3953 streq(args[0], "cancel") ? "ClearJobs" :
3954 streq(args[0], "daemon-reexec") ? "Reexecute" :
3955 streq(args[0], "reset-failed") ? "ResetFailed" :
3956 streq(args[0], "halt") ? "Halt" :
3957 streq(args[0], "poweroff") ? "PowerOff" :
3958 streq(args[0], "reboot") ? "Reboot" :
3959 streq(args[0], "kexec") ? "KExec" :
3960 streq(args[0], "exit") ? "Exit" :
3961 /* "daemon-reload" */ "Reload";
3964 r = sd_bus_call_method(
3966 "org.freedesktop.systemd1",
3967 "/org/freedesktop/systemd1",
3968 "org.freedesktop.systemd1.Manager",
3974 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
3975 /* There's always a fallback possible for
3976 * legacy actions. */
3978 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
3979 /* On reexecution, we expect a disconnect, not a
3983 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3985 return r < 0 ? r : 0;
3988 static int reset_failed(sd_bus *bus, char **args) {
3989 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3993 if (strv_length(args) <= 1)
3994 return daemon_reload(bus, args);
3996 STRV_FOREACH(name, args+1) {
3997 _cleanup_free_ char *n;
3999 n = unit_name_mangle(*name);
4003 r = sd_bus_call_method(
4005 "org.freedesktop.systemd1",
4006 "/org/freedesktop/systemd1",
4007 "org.freedesktop.systemd1.Manager",
4013 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
4021 static int show_environment(sd_bus *bus, char **args) {
4022 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4023 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4027 pager_open_if_enabled();
4029 r = sd_bus_get_property(
4031 "org.freedesktop.systemd1",
4032 "/org/freedesktop/systemd1",
4033 "org.freedesktop.systemd1.Manager",
4039 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4043 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4045 return bus_log_parse_error(r);
4047 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4050 return bus_log_parse_error(r);
4052 r = sd_bus_message_exit_container(reply);
4054 return bus_log_parse_error(r);
4059 static int switch_root(sd_bus *bus, char **args) {
4060 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4061 _cleanup_free_ char *init = NULL;
4066 l = strv_length(args);
4067 if (l < 2 || l > 3) {
4068 log_error("Wrong number of arguments.");
4075 init = strdup(args[2]);
4077 parse_env_file("/proc/cmdline", WHITESPACE,
4088 log_debug("switching root - root: %s; init: %s", root, init);
4090 r = sd_bus_call_method(
4092 "org.freedesktop.systemd1",
4093 "/org/freedesktop/systemd1",
4094 "org.freedesktop.systemd1.Manager",
4100 log_error("Failed to switch root: %s", bus_error_message(&error, r));
4107 static int set_environment(sd_bus *bus, char **args) {
4108 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4109 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4116 method = streq(args[0], "set-environment")
4118 : "UnsetEnvironment";
4120 r = sd_bus_message_new_method_call(
4122 "org.freedesktop.systemd1",
4123 "/org/freedesktop/systemd1",
4124 "org.freedesktop.systemd1.Manager",
4128 return bus_log_create_error(r);
4130 r = sd_bus_message_append_strv(m, args + 1);
4132 return bus_log_create_error(r);
4134 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
4136 log_error("Failed to set environment: %s", bus_error_message(&error, r));
4143 static int enable_sysv_units(const char *verb, char **args) {
4146 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4147 unsigned f = 1, t = 1;
4148 _cleanup_lookup_paths_free_ LookupPaths paths = {};
4150 if (arg_scope != UNIT_FILE_SYSTEM)
4153 if (!streq(verb, "enable") &&
4154 !streq(verb, "disable") &&
4155 !streq(verb, "is-enabled"))
4158 /* Processes all SysV units, and reshuffles the array so that
4159 * afterwards only the native units remain */
4161 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
4166 for (f = 0; args[f]; f++) {
4168 _cleanup_free_ char *p = NULL, *q = NULL;
4169 bool found_native = false, found_sysv;
4171 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
4179 if (!endswith(name, ".service"))
4182 if (path_is_absolute(name))
4185 STRV_FOREACH(k, paths.unit_path) {
4186 if (!isempty(arg_root))
4187 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
4189 asprintf(&p, "%s/%s", *k, name);
4196 found_native = access(p, F_OK) >= 0;
4207 if (!isempty(arg_root))
4208 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
4210 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
4216 p[strlen(p) - sizeof(".service") + 1] = 0;
4217 found_sysv = access(p, F_OK) >= 0;
4222 /* Mark this entry, so that we don't try enabling it as native unit */
4223 args[f] = (char*) "";
4225 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4227 if (!isempty(arg_root))
4228 argv[c++] = q = strappend("--root=", arg_root);
4230 argv[c++] = path_get_file_name(p);
4232 streq(verb, "enable") ? "on" :
4233 streq(verb, "disable") ? "off" : "--level=5";
4236 l = strv_join((char**)argv, " ");
4242 log_info("Executing %s", l);
4247 log_error("Failed to fork: %m");
4250 } else if (pid == 0) {
4253 execv(argv[0], (char**) argv);
4254 _exit(EXIT_FAILURE);
4257 j = wait_for_terminate(pid, &status);
4259 log_error("Failed to wait for child: %s", strerror(-r));
4264 if (status.si_code == CLD_EXITED) {
4265 if (streq(verb, "is-enabled")) {
4266 if (status.si_status == 0) {
4275 } else if (status.si_status != 0) {
4286 /* Drop all SysV units */
4287 for (f = 0, t = 0; args[f]; f++) {
4289 if (isempty(args[f]))
4292 args[t++] = args[f];
4301 static int mangle_names(char **original_names, char ***mangled_names) {
4302 char **i, **l, **name;
4304 l = new(char*, strv_length(original_names) + 1);
4309 STRV_FOREACH(name, original_names) {
4311 /* When enabling units qualified path names are OK,
4312 * too, hence allow them explicitly. */
4317 *i = unit_name_mangle(*name);
4333 static int enable_unit(sd_bus *bus, char **args) {
4334 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4335 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4336 _cleanup_strv_free_ char **mangled_names = NULL;
4337 const char *verb = args[0];
4338 UnitFileChange *changes = NULL;
4339 unsigned n_changes = 0, i;
4340 int carries_install_info = -1;
4346 r = mangle_names(args+1, &mangled_names);
4350 r = enable_sysv_units(verb, mangled_names);
4354 if (!bus || avoid_bus()) {
4355 if (streq(verb, "enable")) {
4356 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4357 carries_install_info = r;
4358 } else if (streq(verb, "disable"))
4359 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4360 else if (streq(verb, "reenable")) {
4361 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4362 carries_install_info = r;
4363 } else if (streq(verb, "link"))
4364 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4365 else if (streq(verb, "preset")) {
4366 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4367 carries_install_info = r;
4368 } else if (streq(verb, "mask"))
4369 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4370 else if (streq(verb, "unmask"))
4371 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4372 else if (streq(verb, "set-default"))
4373 r = unit_file_set_default(arg_scope, arg_root, args[1], &changes, &n_changes);
4375 assert_not_reached("Unknown verb");
4378 log_error("Operation failed: %s", strerror(-r));
4383 for (i = 0; i < n_changes; i++) {
4384 if (changes[i].type == UNIT_FILE_SYMLINK)
4385 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
4387 log_info("rm '%s'", changes[i].path);
4393 const char *method, *type, *path, *source;
4394 int expect_carries_install_info = false;
4395 bool send_force = true;
4397 if (streq(verb, "enable")) {
4398 method = "EnableUnitFiles";
4399 expect_carries_install_info = true;
4400 } else if (streq(verb, "disable")) {
4401 method = "DisableUnitFiles";
4403 } else if (streq(verb, "reenable")) {
4404 method = "ReenableUnitFiles";
4405 expect_carries_install_info = true;
4406 } else if (streq(verb, "link"))
4407 method = "LinkUnitFiles";
4408 else if (streq(verb, "preset")) {
4409 method = "PresetUnitFiles";
4410 expect_carries_install_info = true;
4411 } else if (streq(verb, "mask"))
4412 method = "MaskUnitFiles";
4413 else if (streq(verb, "unmask")) {
4414 method = "UnmaskUnitFiles";
4416 } else if (streq(verb, "set-default")) {
4417 method = "SetDefaultTarget";
4419 assert_not_reached("Unknown verb");
4421 r = sd_bus_message_new_method_call(
4423 "org.freedesktop.systemd1",
4424 "/org/freedesktop/systemd1",
4425 "org.freedesktop.systemd1.Manager",
4429 return bus_log_create_error(r);
4431 r = sd_bus_message_append_strv(m, mangled_names);
4433 return bus_log_create_error(r);
4435 r = sd_bus_message_append(m, "b", arg_runtime);
4437 return bus_log_create_error(r);
4440 r = sd_bus_message_append(m, "b", arg_force);
4442 return bus_log_create_error(r);
4445 r = sd_bus_send_with_reply_and_block(bus, m, -0, &error, &reply);
4447 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4451 if (expect_carries_install_info) {
4452 r = sd_bus_message_read(reply, "b", &carries_install_info);
4454 return bus_log_parse_error(r);
4457 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(sss)");
4459 return bus_log_parse_error(r);
4461 while ((r = sd_bus_message_read(reply, "(sss)", &type, &path, &source)) > 0) {
4463 if (streq(type, "symlink"))
4464 log_info("ln -s '%s' '%s'", source, path);
4466 log_info("rm '%s'", path);
4470 return bus_log_parse_error(r);
4472 r = sd_bus_message_exit_container(reply);
4474 return bus_log_parse_error(r);
4476 /* Try to reload if enabeld */
4478 r = daemon_reload(bus, args);
4483 if (carries_install_info == 0)
4484 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4485 "using systemctl.\n"
4486 "Possible reasons for having this kind of units are:\n"
4487 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4488 " .wants/ or .requires/ directory.\n"
4489 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4490 " a requirement dependency on it.\n"
4491 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4492 " D-Bus, udev, scripted systemctl call, ...).\n");
4495 unit_file_changes_free(changes, n_changes);
4500 static int unit_is_enabled(sd_bus *bus, char **args) {
4502 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4503 _cleanup_strv_free_ char **mangled_names = NULL;
4508 r = mangle_names(args+1, &mangled_names);
4512 r = enable_sysv_units(args[0], mangled_names);
4518 if (!bus || avoid_bus()) {
4520 STRV_FOREACH(name, mangled_names) {
4521 UnitFileState state;
4523 state = unit_file_get_state(arg_scope, arg_root, *name);
4525 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4529 if (state == UNIT_FILE_ENABLED ||
4530 state == UNIT_FILE_ENABLED_RUNTIME ||
4531 state == UNIT_FILE_STATIC)
4535 puts(unit_file_state_to_string(state));
4539 STRV_FOREACH(name, mangled_names) {
4540 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4543 r = sd_bus_call_method(
4545 "org.freedesktop.systemd1",
4546 "/org/freedesktop/systemd1",
4547 "org.freedesktop.systemd1.Manager",
4553 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4557 r = sd_bus_message_read(reply, "s", &s);
4559 return bus_log_parse_error(r);
4561 if (streq(s, "enabled") ||
4562 streq(s, "enabled-runtime") ||
4574 static int systemctl_help(void) {
4576 pager_open_if_enabled();
4578 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4579 "Query or send control commands to the systemd manager.\n\n"
4580 " -h --help Show this help\n"
4581 " --version Show package version\n"
4582 " --system Connect to system manager\n"
4583 " --user Connect to user service manager\n"
4584 " -H --host=[USER@]HOST\n"
4585 " Operate on remote host\n"
4586 " -M --machine=CONTAINER\n"
4587 " Operate on local container\n"
4588 " -t --type=TYPE List only units of a particular type\n"
4589 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4590 " -p --property=NAME Show only properties by this name\n"
4591 " -a --all Show all loaded units/properties, including dead/empty\n"
4592 " ones. To list all units installed on the system, use\n"
4593 " the 'list-unit-files' command instead.\n"
4594 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4595 " -l --full Don't ellipsize unit names on output\n"
4596 " --fail When queueing a new job, fail if conflicting jobs are\n"
4598 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4600 " --ignore-dependencies\n"
4601 " When queueing a new job, ignore all its dependencies\n"
4602 " --show-types When showing sockets, explicitly show their type\n"
4603 " -i --ignore-inhibitors\n"
4604 " When shutting down or sleeping, ignore inhibitors\n"
4605 " --kill-who=WHO Who to send signal to\n"
4606 " -s --signal=SIGNAL Which signal to send\n"
4607 " -q --quiet Suppress output\n"
4608 " --no-block Do not wait until operation finished\n"
4609 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4610 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4612 " --no-legend Do not print a legend (column headers and hints)\n"
4613 " --no-pager Do not pipe output into a pager\n"
4614 " --no-ask-password\n"
4615 " Do not ask for system passwords\n"
4616 " --global Enable/disable unit files globally\n"
4617 " --runtime Enable unit files only temporarily until next reboot\n"
4618 " -f --force When enabling unit files, override existing symlinks\n"
4619 " When shutting down, execute action immediately\n"
4620 " --root=PATH Enable unit files in the specified root directory\n"
4621 " -n --lines=INTEGER Number of journal entries to show\n"
4622 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4623 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4625 " list-units List loaded units\n"
4626 " list-sockets List loaded sockets ordered by address\n"
4627 " list-timers List loaded timers ordered by next elapse\n"
4628 " start [NAME...] Start (activate) one or more units\n"
4629 " stop [NAME...] Stop (deactivate) one or more units\n"
4630 " reload [NAME...] Reload one or more units\n"
4631 " restart [NAME...] Start or restart one or more units\n"
4632 " try-restart [NAME...] Restart one or more units if active\n"
4633 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4634 " otherwise start or restart\n"
4635 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4636 " otherwise restart if active\n"
4637 " isolate [NAME] Start one unit and stop all others\n"
4638 " kill [NAME...] Send signal to processes of a unit\n"
4639 " is-active [NAME...] Check whether units are active\n"
4640 " is-failed [NAME...] Check whether units are failed\n"
4641 " status [NAME...|PID...] Show runtime status of one or more units\n"
4642 " show [NAME...|JOB...] Show properties of one or more\n"
4643 " units/jobs or the manager\n"
4644 " set-property [NAME] [ASSIGNMENT...]\n"
4645 " Sets one or more properties of a unit\n"
4646 " help [NAME...|PID...] Show manual for one or more units\n"
4647 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4649 " list-dependencies [NAME] Recursively show units which are required\n"
4650 " or wanted by this unit or by which this\n"
4651 " unit is required or wanted\n\n"
4652 "Unit File Commands:\n"
4653 " list-unit-files List installed unit files\n"
4654 " enable [NAME...] Enable one or more unit files\n"
4655 " disable [NAME...] Disable one or more unit files\n"
4656 " reenable [NAME...] Reenable one or more unit files\n"
4657 " preset [NAME...] Enable/disable one or more unit files\n"
4658 " based on preset configuration\n"
4659 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4660 " mask [NAME...] Mask one or more units\n"
4661 " unmask [NAME...] Unmask one or more units\n"
4662 " link [PATH...] Link one or more units files into\n"
4663 " the search path\n"
4664 " get-default Get the name of the default target\n"
4665 " set-default NAME Set the default target\n\n"
4667 " list-jobs List jobs\n"
4668 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4669 "Snapshot Commands:\n"
4670 " snapshot [NAME] Create a snapshot\n"
4671 " delete [NAME...] Remove one or more snapshots\n\n"
4672 "Environment Commands:\n"
4673 " show-environment Dump environment\n"
4674 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4675 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4676 "Manager Lifecycle Commands:\n"
4677 " daemon-reload Reload systemd manager configuration\n"
4678 " daemon-reexec Reexecute systemd manager\n\n"
4679 "System Commands:\n"
4680 " default Enter system default mode\n"
4681 " rescue Enter system rescue mode\n"
4682 " emergency Enter system emergency mode\n"
4683 " halt Shut down and halt the system\n"
4684 " poweroff Shut down and power-off the system\n"
4685 " reboot [ARG] Shut down and reboot the system\n"
4686 " kexec Shut down and reboot the system with kexec\n"
4687 " exit Request user instance exit\n"
4688 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4689 " suspend Suspend the system\n"
4690 " hibernate Hibernate the system\n"
4691 " hybrid-sleep Hibernate and suspend the system\n",
4692 program_invocation_short_name);
4697 static int halt_help(void) {
4699 printf("%s [OPTIONS...]%s\n\n"
4700 "%s the system.\n\n"
4701 " --help Show this help\n"
4702 " --halt Halt the machine\n"
4703 " -p --poweroff Switch off the machine\n"
4704 " --reboot Reboot the machine\n"
4705 " -f --force Force immediate halt/power-off/reboot\n"
4706 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4707 " -d --no-wtmp Don't write wtmp record\n"
4708 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4709 program_invocation_short_name,
4710 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4711 arg_action == ACTION_REBOOT ? "Reboot" :
4712 arg_action == ACTION_POWEROFF ? "Power off" :
4718 static int shutdown_help(void) {
4720 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4721 "Shut down the system.\n\n"
4722 " --help Show this help\n"
4723 " -H --halt Halt the machine\n"
4724 " -P --poweroff Power-off the machine\n"
4725 " -r --reboot Reboot the machine\n"
4726 " -h Equivalent to --poweroff, overridden by --halt\n"
4727 " -k Don't halt/power-off/reboot, just send warnings\n"
4728 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4729 " -c Cancel a pending shutdown\n",
4730 program_invocation_short_name);
4735 static int telinit_help(void) {
4737 printf("%s [OPTIONS...] {COMMAND}\n\n"
4738 "Send control commands to the init daemon.\n\n"
4739 " --help Show this help\n"
4740 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4742 " 0 Power-off the machine\n"
4743 " 6 Reboot the machine\n"
4744 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4745 " 1, s, S Enter rescue mode\n"
4746 " q, Q Reload init daemon configuration\n"
4747 " u, U Reexecute init daemon\n",
4748 program_invocation_short_name);
4753 static int runlevel_help(void) {
4755 printf("%s [OPTIONS...]\n\n"
4756 "Prints the previous and current runlevel of the init system.\n\n"
4757 " --help Show this help\n",
4758 program_invocation_short_name);
4763 static int help_types(void) {
4767 puts("Available unit types:");
4768 for(i = 0; i < _UNIT_TYPE_MAX; i++) {
4769 t = unit_type_to_string(i);
4777 static int systemctl_parse_argv(int argc, char *argv[]) {
4786 ARG_IGNORE_DEPENDENCIES,
4798 ARG_NO_ASK_PASSWORD,
4806 static const struct option options[] = {
4807 { "help", no_argument, NULL, 'h' },
4808 { "version", no_argument, NULL, ARG_VERSION },
4809 { "type", required_argument, NULL, 't' },
4810 { "property", required_argument, NULL, 'p' },
4811 { "all", no_argument, NULL, 'a' },
4812 { "reverse", no_argument, NULL, ARG_REVERSE },
4813 { "after", no_argument, NULL, ARG_AFTER },
4814 { "before", no_argument, NULL, ARG_BEFORE },
4815 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4816 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4817 { "full", no_argument, NULL, 'l' },
4818 { "fail", no_argument, NULL, ARG_FAIL },
4819 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
4820 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
4821 { "ignore-inhibitors", no_argument, NULL, 'i' },
4822 { "user", no_argument, NULL, ARG_USER },
4823 { "system", no_argument, NULL, ARG_SYSTEM },
4824 { "global", no_argument, NULL, ARG_GLOBAL },
4825 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4826 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4827 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4828 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4829 { "quiet", no_argument, NULL, 'q' },
4830 { "root", required_argument, NULL, ARG_ROOT },
4831 { "force", no_argument, NULL, ARG_FORCE },
4832 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4833 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4834 { "signal", required_argument, NULL, 's' },
4835 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4836 { "host", required_argument, NULL, 'H' },
4837 { "machine", required_argument, NULL, 'M' },
4838 { "runtime", no_argument, NULL, ARG_RUNTIME },
4839 { "lines", required_argument, NULL, 'n' },
4840 { "output", required_argument, NULL, 'o' },
4841 { "plain", no_argument, NULL, ARG_PLAIN },
4842 { "state", required_argument, NULL, ARG_STATE },
4851 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
4856 return systemctl_help();
4859 puts(PACKAGE_STRING);
4860 puts(SYSTEMD_FEATURES);
4867 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4868 _cleanup_free_ char *type;
4870 type = strndup(word, size);
4874 if (streq(type, "help")) {
4879 if (unit_type_from_string(type) >= 0) {
4880 if (strv_push(&arg_types, type))
4886 /* It's much nicer to use --state= for
4887 * load states, but let's support this
4888 * in --types= too for compatibility
4889 * with old versions */
4890 if (unit_load_state_from_string(optarg) >= 0) {
4891 if (strv_push(&arg_states, type) < 0)
4897 log_error("Unknown unit type or load state '%s'.", type);
4898 log_info("Use -t help to see a list of allowed values.");
4906 /* Make sure that if the empty property list
4907 was specified, we won't show any properties. */
4908 if (isempty(optarg) && !arg_properties) {
4909 arg_properties = new0(char*, 1);
4910 if (!arg_properties)
4916 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4919 prop = strndup(word, size);
4923 if (strv_push(&arg_properties, prop) < 0) {
4930 /* If the user asked for a particular
4931 * property, show it to him, even if it is
4943 arg_dependency = DEPENDENCY_REVERSE;
4947 arg_dependency = DEPENDENCY_AFTER;
4951 arg_dependency = DEPENDENCY_BEFORE;
4954 case ARG_SHOW_TYPES:
4955 arg_show_types = true;
4959 arg_job_mode = "fail";
4962 case ARG_IRREVERSIBLE:
4963 arg_job_mode = "replace-irreversibly";
4966 case ARG_IGNORE_DEPENDENCIES:
4967 arg_job_mode = "ignore-dependencies";
4971 arg_scope = UNIT_FILE_USER;
4975 arg_scope = UNIT_FILE_SYSTEM;
4979 arg_scope = UNIT_FILE_GLOBAL;
4983 arg_no_block = true;
4987 arg_no_legend = true;
4991 arg_no_pager = true;
5007 if (strv_extend(&arg_states, "failed") < 0)
5025 arg_no_reload = true;
5029 arg_kill_who = optarg;
5033 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
5034 log_error("Failed to parse signal string %s.", optarg);
5039 case ARG_NO_ASK_PASSWORD:
5040 arg_ask_password = false;
5044 arg_transport = BUS_TRANSPORT_REMOTE;
5049 arg_transport = BUS_TRANSPORT_CONTAINER;
5058 if (safe_atou(optarg, &arg_lines) < 0) {
5059 log_error("Failed to parse lines '%s'", optarg);
5065 arg_output = output_mode_from_string(optarg);
5066 if (arg_output < 0) {
5067 log_error("Unknown output '%s'.", optarg);
5073 arg_ignore_inhibitors = true;
5084 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
5087 s = strndup(word, size);
5091 if (strv_push(&arg_states, s) < 0) {
5103 assert_not_reached("Unhandled option");
5107 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
5108 log_error("Cannot access user instance remotely.");
5115 static int halt_parse_argv(int argc, char *argv[]) {
5124 static const struct option options[] = {
5125 { "help", no_argument, NULL, ARG_HELP },
5126 { "halt", no_argument, NULL, ARG_HALT },
5127 { "poweroff", no_argument, NULL, 'p' },
5128 { "reboot", no_argument, NULL, ARG_REBOOT },
5129 { "force", no_argument, NULL, 'f' },
5130 { "wtmp-only", no_argument, NULL, 'w' },
5131 { "no-wtmp", no_argument, NULL, 'd' },
5132 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5141 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
5142 if (runlevel == '0' || runlevel == '6')
5145 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
5152 arg_action = ACTION_HALT;
5156 if (arg_action != ACTION_REBOOT)
5157 arg_action = ACTION_POWEROFF;
5161 arg_action = ACTION_REBOOT;
5183 /* Compatibility nops */
5190 assert_not_reached("Unhandled option");
5194 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
5195 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
5197 log_error("Failed to write reboot param to "
5198 REBOOT_PARAM_FILE": %s", strerror(-r));
5201 } else if (optind < argc) {
5202 log_error("Too many arguments.");
5209 static int parse_time_spec(const char *t, usec_t *_u) {
5213 if (streq(t, "now"))
5215 else if (!strchr(t, ':')) {
5218 if (safe_atou64(t, &u) < 0)
5221 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5230 hour = strtol(t, &e, 10);
5231 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5234 minute = strtol(e+1, &e, 10);
5235 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5238 n = now(CLOCK_REALTIME);
5239 s = (time_t) (n / USEC_PER_SEC);
5241 assert_se(localtime_r(&s, &tm));
5243 tm.tm_hour = (int) hour;
5244 tm.tm_min = (int) minute;
5247 assert_se(s = mktime(&tm));
5249 *_u = (usec_t) s * USEC_PER_SEC;
5252 *_u += USEC_PER_DAY;
5258 static int shutdown_parse_argv(int argc, char *argv[]) {
5265 static const struct option options[] = {
5266 { "help", no_argument, NULL, ARG_HELP },
5267 { "halt", no_argument, NULL, 'H' },
5268 { "poweroff", no_argument, NULL, 'P' },
5269 { "reboot", no_argument, NULL, 'r' },
5270 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5271 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5280 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5284 return shutdown_help();
5287 arg_action = ACTION_HALT;
5291 arg_action = ACTION_POWEROFF;
5296 arg_action = ACTION_KEXEC;
5298 arg_action = ACTION_REBOOT;
5302 arg_action = ACTION_KEXEC;
5306 if (arg_action != ACTION_HALT)
5307 arg_action = ACTION_POWEROFF;
5320 /* Compatibility nops */
5324 arg_action = ACTION_CANCEL_SHUTDOWN;
5331 assert_not_reached("Unhandled option");
5335 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5336 r = parse_time_spec(argv[optind], &arg_when);
5338 log_error("Failed to parse time specification: %s", argv[optind]);
5342 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5344 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5345 /* No time argument for shutdown cancel */
5346 arg_wall = argv + optind;
5347 else if (argc > optind + 1)
5348 /* We skip the time argument */
5349 arg_wall = argv + optind + 1;
5356 static int telinit_parse_argv(int argc, char *argv[]) {
5363 static const struct option options[] = {
5364 { "help", no_argument, NULL, ARG_HELP },
5365 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5369 static const struct {
5373 { '0', ACTION_POWEROFF },
5374 { '6', ACTION_REBOOT },
5375 { '1', ACTION_RESCUE },
5376 { '2', ACTION_RUNLEVEL2 },
5377 { '3', ACTION_RUNLEVEL3 },
5378 { '4', ACTION_RUNLEVEL4 },
5379 { '5', ACTION_RUNLEVEL5 },
5380 { 's', ACTION_RESCUE },
5381 { 'S', ACTION_RESCUE },
5382 { 'q', ACTION_RELOAD },
5383 { 'Q', ACTION_RELOAD },
5384 { 'u', ACTION_REEXEC },
5385 { 'U', ACTION_REEXEC }
5394 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5398 return telinit_help();
5408 assert_not_reached("Unhandled option");
5412 if (optind >= argc) {
5417 if (optind + 1 < argc) {
5418 log_error("Too many arguments.");
5422 if (strlen(argv[optind]) != 1) {
5423 log_error("Expected single character argument.");
5427 for (i = 0; i < ELEMENTSOF(table); i++)
5428 if (table[i].from == argv[optind][0])
5431 if (i >= ELEMENTSOF(table)) {
5432 log_error("Unknown command '%s'.", argv[optind]);
5436 arg_action = table[i].to;
5443 static int runlevel_parse_argv(int argc, char *argv[]) {
5449 static const struct option options[] = {
5450 { "help", no_argument, NULL, ARG_HELP },
5459 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5463 return runlevel_help();
5470 assert_not_reached("Unhandled option");
5474 if (optind < argc) {
5475 log_error("Too many arguments.");
5482 static int parse_argv(int argc, char *argv[]) {
5486 if (program_invocation_short_name) {
5488 if (strstr(program_invocation_short_name, "halt")) {
5489 arg_action = ACTION_HALT;
5490 return halt_parse_argv(argc, argv);
5491 } else if (strstr(program_invocation_short_name, "poweroff")) {
5492 arg_action = ACTION_POWEROFF;
5493 return halt_parse_argv(argc, argv);
5494 } else if (strstr(program_invocation_short_name, "reboot")) {
5496 arg_action = ACTION_KEXEC;
5498 arg_action = ACTION_REBOOT;
5499 return halt_parse_argv(argc, argv);
5500 } else if (strstr(program_invocation_short_name, "shutdown")) {
5501 arg_action = ACTION_POWEROFF;
5502 return shutdown_parse_argv(argc, argv);
5503 } else if (strstr(program_invocation_short_name, "init")) {
5505 if (sd_booted() > 0) {
5506 arg_action = _ACTION_INVALID;
5507 return telinit_parse_argv(argc, argv);
5509 /* Hmm, so some other init system is
5510 * running, we need to forward this
5511 * request to it. For now we simply
5512 * guess that it is Upstart. */
5514 execv(TELINIT, argv);
5516 log_error("Couldn't find an alternative telinit implementation to spawn.");
5520 } else if (strstr(program_invocation_short_name, "runlevel")) {
5521 arg_action = ACTION_RUNLEVEL;
5522 return runlevel_parse_argv(argc, argv);
5526 arg_action = ACTION_SYSTEMCTL;
5527 return systemctl_parse_argv(argc, argv);
5530 _pure_ static int action_to_runlevel(void) {
5532 static const char table[_ACTION_MAX] = {
5533 [ACTION_HALT] = '0',
5534 [ACTION_POWEROFF] = '0',
5535 [ACTION_REBOOT] = '6',
5536 [ACTION_RUNLEVEL2] = '2',
5537 [ACTION_RUNLEVEL3] = '3',
5538 [ACTION_RUNLEVEL4] = '4',
5539 [ACTION_RUNLEVEL5] = '5',
5540 [ACTION_RESCUE] = '1'
5543 assert(arg_action < _ACTION_MAX);
5545 return table[arg_action];
5548 static int talk_initctl(void) {
5550 struct init_request request = {
5551 .magic = INIT_MAGIC,
5553 .cmd = INIT_CMD_RUNLVL
5556 _cleanup_close_ int fd = -1;
5560 rl = action_to_runlevel();
5564 request.runlevel = rl;
5566 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5568 if (errno == ENOENT)
5571 log_error("Failed to open "INIT_FIFO": %m");
5576 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5578 log_error("Failed to write to "INIT_FIFO": %m");
5579 return errno > 0 ? -errno : -EIO;
5585 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5587 static const struct {
5595 int (* const dispatch)(sd_bus *bus, char **args);
5597 { "list-units", LESS, 1, list_units },
5598 { "list-unit-files", EQUAL, 1, list_unit_files },
5599 { "list-sockets", LESS, 1, list_sockets },
5600 { "list-timers", LESS, 1, list_timers },
5601 { "list-jobs", EQUAL, 1, list_jobs },
5602 { "clear-jobs", EQUAL, 1, daemon_reload },
5603 { "cancel", MORE, 2, cancel_job },
5604 { "start", MORE, 2, start_unit },
5605 { "stop", MORE, 2, start_unit },
5606 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5607 { "reload", MORE, 2, start_unit },
5608 { "restart", MORE, 2, start_unit },
5609 { "try-restart", MORE, 2, start_unit },
5610 { "reload-or-restart", MORE, 2, start_unit },
5611 { "reload-or-try-restart", MORE, 2, start_unit },
5612 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5613 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5614 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5615 { "isolate", EQUAL, 2, start_unit },
5616 { "kill", MORE, 2, kill_unit },
5617 { "is-active", MORE, 2, check_unit_active },
5618 { "check", MORE, 2, check_unit_active },
5619 { "is-failed", MORE, 2, check_unit_failed },
5620 { "show", MORE, 1, show },
5621 { "status", MORE, 1, show },
5622 { "help", MORE, 2, show },
5623 { "snapshot", LESS, 2, snapshot },
5624 { "delete", MORE, 2, delete_snapshot },
5625 { "daemon-reload", EQUAL, 1, daemon_reload },
5626 { "daemon-reexec", EQUAL, 1, daemon_reload },
5627 { "show-environment", EQUAL, 1, show_environment },
5628 { "set-environment", MORE, 2, set_environment },
5629 { "unset-environment", MORE, 2, set_environment },
5630 { "halt", EQUAL, 1, start_special },
5631 { "poweroff", EQUAL, 1, start_special },
5632 { "reboot", EQUAL, 1, start_special },
5633 { "kexec", EQUAL, 1, start_special },
5634 { "suspend", EQUAL, 1, start_special },
5635 { "hibernate", EQUAL, 1, start_special },
5636 { "hybrid-sleep", EQUAL, 1, start_special },
5637 { "default", EQUAL, 1, start_special },
5638 { "rescue", EQUAL, 1, start_special },
5639 { "emergency", EQUAL, 1, start_special },
5640 { "exit", EQUAL, 1, start_special },
5641 { "reset-failed", MORE, 1, reset_failed },
5642 { "enable", MORE, 2, enable_unit },
5643 { "disable", MORE, 2, enable_unit },
5644 { "is-enabled", MORE, 2, unit_is_enabled },
5645 { "reenable", MORE, 2, enable_unit },
5646 { "preset", MORE, 2, enable_unit },
5647 { "mask", MORE, 2, enable_unit },
5648 { "unmask", MORE, 2, enable_unit },
5649 { "link", MORE, 2, enable_unit },
5650 { "switch-root", MORE, 2, switch_root },
5651 { "list-dependencies", LESS, 2, list_dependencies },
5652 { "set-default", EQUAL, 2, enable_unit },
5653 { "get-default", LESS, 1, get_default },
5654 { "set-property", MORE, 3, set_property },
5663 left = argc - optind;
5666 /* Special rule: no arguments means "list-units" */
5669 if (streq(argv[optind], "help") && !argv[optind+1]) {
5670 log_error("This command expects one or more "
5671 "unit names. Did you mean --help?");
5675 for (i = 0; i < ELEMENTSOF(verbs); i++)
5676 if (streq(argv[optind], verbs[i].verb))
5679 if (i >= ELEMENTSOF(verbs)) {
5680 log_error("Unknown operation '%s'.", argv[optind]);
5685 switch (verbs[i].argc_cmp) {
5688 if (left != verbs[i].argc) {
5689 log_error("Invalid number of arguments.");
5696 if (left < verbs[i].argc) {
5697 log_error("Too few arguments.");
5704 if (left > verbs[i].argc) {
5705 log_error("Too many arguments.");
5712 assert_not_reached("Unknown comparison operator.");
5715 /* Require a bus connection for all operations but
5717 if (!streq(verbs[i].verb, "enable") &&
5718 !streq(verbs[i].verb, "disable") &&
5719 !streq(verbs[i].verb, "is-enabled") &&
5720 !streq(verbs[i].verb, "list-unit-files") &&
5721 !streq(verbs[i].verb, "reenable") &&
5722 !streq(verbs[i].verb, "preset") &&
5723 !streq(verbs[i].verb, "mask") &&
5724 !streq(verbs[i].verb, "unmask") &&
5725 !streq(verbs[i].verb, "link") &&
5726 !streq(verbs[i].verb, "set-default") &&
5727 !streq(verbs[i].verb, "get-default")) {
5729 if (running_in_chroot() > 0) {
5730 log_info("Running in chroot, ignoring request.");
5734 if (((!streq(verbs[i].verb, "reboot") &&
5735 !streq(verbs[i].verb, "halt") &&
5736 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5737 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5743 if (!bus && !avoid_bus()) {
5744 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5749 return verbs[i].dispatch(bus, argv + optind);
5752 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5754 struct sd_shutdown_command c = {
5761 union sockaddr_union sockaddr = {
5762 .un.sun_family = AF_UNIX,
5763 .un.sun_path = "/run/systemd/shutdownd",
5766 struct iovec iovec[2] = {{
5767 .iov_base = (char*) &c,
5768 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5771 struct msghdr msghdr = {
5772 .msg_name = &sockaddr,
5773 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5774 + sizeof("/run/systemd/shutdownd") - 1,
5779 _cleanup_close_ int fd;
5781 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5785 if (!isempty(message)) {
5786 iovec[1].iov_base = (char*) message;
5787 iovec[1].iov_len = strlen(message);
5788 msghdr.msg_iovlen++;
5791 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5797 static int reload_with_fallback(sd_bus *bus) {
5800 /* First, try systemd via D-Bus. */
5801 if (daemon_reload(bus, NULL) >= 0)
5805 /* Nothing else worked, so let's try signals */
5806 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5808 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5809 log_error("kill() failed: %m");
5816 static int start_with_fallback(sd_bus *bus) {
5819 /* First, try systemd via D-Bus. */
5820 if (start_unit(bus, NULL) >= 0)
5824 /* Nothing else worked, so let's try
5826 if (talk_initctl() > 0)
5829 log_error("Failed to talk to init daemon.");
5833 warn_wall(arg_action);
5837 static int halt_now(enum action a) {
5839 /* Make sure C-A-D is handled by the kernel from this
5841 reboot(RB_ENABLE_CAD);
5846 log_info("Halting.");
5847 reboot(RB_HALT_SYSTEM);
5850 case ACTION_POWEROFF:
5851 log_info("Powering off.");
5852 reboot(RB_POWER_OFF);
5855 case ACTION_REBOOT: {
5856 _cleanup_free_ char *param = NULL;
5858 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
5859 log_info("Rebooting with argument '%s'.", param);
5860 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
5861 LINUX_REBOOT_CMD_RESTART2, param);
5864 log_info("Rebooting.");
5865 reboot(RB_AUTOBOOT);
5870 assert_not_reached("Unknown action.");
5874 static int halt_main(sd_bus *bus) {
5877 r = check_inhibitors(bus, arg_action);
5881 if (geteuid() != 0) {
5882 /* Try logind if we are a normal user and no special
5883 * mode applies. Maybe PolicyKit allows us to shutdown
5886 if (arg_when <= 0 &&
5889 (arg_action == ACTION_POWEROFF ||
5890 arg_action == ACTION_REBOOT)) {
5891 r = reboot_with_logind(bus, arg_action);
5896 log_error("Must be root.");
5901 _cleanup_free_ char *m;
5903 m = strv_join(arg_wall, " ");
5907 r = send_shutdownd(arg_when,
5908 arg_action == ACTION_HALT ? 'H' :
5909 arg_action == ACTION_POWEROFF ? 'P' :
5910 arg_action == ACTION_KEXEC ? 'K' :
5917 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
5919 char date[FORMAT_TIMESTAMP_MAX];
5921 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5922 format_timestamp(date, sizeof(date), arg_when));
5927 if (!arg_dry && !arg_force)
5928 return start_with_fallback(bus);
5931 if (sd_booted() > 0)
5932 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5934 r = utmp_put_shutdown();
5936 log_warning("Failed to write utmp record: %s", strerror(-r));
5943 r = halt_now(arg_action);
5944 log_error("Failed to reboot: %s", strerror(-r));
5949 static int runlevel_main(void) {
5950 int r, runlevel, previous;
5952 r = utmp_get_runlevel(&runlevel, &previous);
5959 previous <= 0 ? 'N' : previous,
5960 runlevel <= 0 ? 'N' : runlevel);
5965 int main(int argc, char*argv[]) {
5966 _cleanup_bus_unref_ sd_bus *bus = NULL;
5969 setlocale(LC_ALL, "");
5970 log_parse_environment();
5973 /* Explicitly not on_tty() to avoid setting cached value.
5974 * This becomes relevant for piping output which might be
5976 original_stdout_is_tty = isatty(STDOUT_FILENO);
5978 r = parse_argv(argc, argv);
5982 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5983 * let's shortcut this */
5984 if (arg_action == ACTION_RUNLEVEL) {
5985 r = runlevel_main();
5989 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
5990 log_info("Running in chroot, ignoring request.");
5996 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
5998 /* systemctl_main() will print an error message for the bus
5999 * connection, but only if it needs to */
6001 switch (arg_action) {
6003 case ACTION_SYSTEMCTL:
6004 r = systemctl_main(bus, argc, argv, r);
6008 case ACTION_POWEROFF:
6014 case ACTION_RUNLEVEL2:
6015 case ACTION_RUNLEVEL3:
6016 case ACTION_RUNLEVEL4:
6017 case ACTION_RUNLEVEL5:
6019 case ACTION_EMERGENCY:
6020 case ACTION_DEFAULT:
6021 r = start_with_fallback(bus);
6026 r = reload_with_fallback(bus);
6029 case ACTION_CANCEL_SHUTDOWN: {
6030 _cleanup_free_ char *m = NULL;
6033 m = strv_join(arg_wall, " ");
6040 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
6042 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
6046 case ACTION_RUNLEVEL:
6047 case _ACTION_INVALID:
6049 assert_not_reached("Unknown action");
6054 ask_password_agent_close();
6055 polkit_agent_close();
6057 strv_free(arg_types);
6058 strv_free(arg_states);
6059 strv_free(arg_properties);
6061 return r < 0 ? EXIT_FAILURE : r;