1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
41 #include "sd-daemon.h"
42 #include "sd-shutdown.h"
49 #include "utmp-wtmp.h"
52 #include "path-util.h"
54 #include "cgroup-show.h"
55 #include "cgroup-util.h"
57 #include "path-lookup.h"
58 #include "conf-parser.h"
59 #include "exit-status.h"
60 #include "bus-errors.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "socket-util.h"
71 #include "bus-message.h"
72 #include "bus-error.h"
74 static char **arg_types = NULL;
75 static char **arg_states = NULL;
76 static char **arg_properties = NULL;
77 static bool arg_all = false;
78 static bool original_stdout_is_tty;
79 static enum dependency {
84 } arg_dependency = DEPENDENCY_FORWARD;
85 static const char *arg_job_mode = "replace";
86 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
87 static bool arg_no_block = false;
88 static bool arg_no_legend = false;
89 static bool arg_no_pager = false;
90 static bool arg_no_wtmp = false;
91 static bool arg_no_wall = false;
92 static bool arg_no_reload = false;
93 static bool arg_show_types = false;
94 static bool arg_ignore_inhibitors = false;
95 static bool arg_dry = false;
96 static bool arg_quiet = false;
97 static bool arg_full = false;
98 static int arg_force = 0;
99 static bool arg_ask_password = true;
100 static bool arg_runtime = false;
101 static char **arg_wall = NULL;
102 static const char *arg_kill_who = NULL;
103 static int arg_signal = SIGTERM;
104 static const char *arg_root = NULL;
105 static usec_t arg_when = 0;
127 ACTION_CANCEL_SHUTDOWN,
129 } arg_action = ACTION_SYSTEMCTL;
130 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
131 static char *arg_host = NULL;
132 static unsigned arg_lines = 10;
133 static OutputMode arg_output = OUTPUT_SHORT;
134 static bool arg_plain = false;
136 static int daemon_reload(sd_bus *bus, char **args);
137 static int halt_now(enum action a);
139 static void pager_open_if_enabled(void) {
147 static void ask_password_agent_open_if_enabled(void) {
149 /* Open the password agent as a child process if necessary */
151 if (!arg_ask_password)
154 if (arg_scope != UNIT_FILE_SYSTEM)
157 if (arg_transport != BUS_TRANSPORT_LOCAL)
160 ask_password_agent_open();
164 static void polkit_agent_open_if_enabled(void) {
166 /* Open the polkit agent as a child process if necessary */
168 if (!arg_ask_password)
171 if (arg_scope != UNIT_FILE_SYSTEM)
174 if (arg_transport != BUS_TRANSPORT_LOCAL)
181 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
184 if (!sd_bus_error_is_set(error))
187 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
188 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
189 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
190 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
191 return EXIT_NOPERMISSION;
193 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
194 return EXIT_NOTINSTALLED;
196 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
197 sd_bus_error_has_name(error, BUS_ERROR_NOT_SUPPORTED))
198 return EXIT_NOTIMPLEMENTED;
200 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
201 return EXIT_NOTCONFIGURED;
209 static void warn_wall(enum action a) {
210 static const char *table[_ACTION_MAX] = {
211 [ACTION_HALT] = "The system is going down for system halt NOW!",
212 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
213 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
214 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
215 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
216 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
217 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
224 _cleanup_free_ char *p;
226 p = strv_join(arg_wall, " ");
241 utmp_wall(table[a], NULL);
244 static bool avoid_bus(void) {
246 if (running_in_chroot() > 0)
249 if (sd_booted() <= 0)
252 if (!isempty(arg_root))
255 if (arg_scope == UNIT_FILE_GLOBAL)
261 static int compare_unit_info(const void *a, const void *b) {
262 const UnitInfo *u = a, *v = b;
265 d1 = strrchr(u->id, '.');
266 d2 = strrchr(v->id, '.');
271 r = strcasecmp(d1, d2);
276 return strcasecmp(u->id, v->id);
279 static bool output_show_unit(const UnitInfo *u) {
282 if (!strv_isempty(arg_states))
284 strv_contains(arg_states, u->load_state) ||
285 strv_contains(arg_states, u->sub_state) ||
286 strv_contains(arg_states, u->active_state);
288 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
289 strv_find(arg_types, dot+1))) &&
290 (arg_all || !(streq(u->active_state, "inactive")
291 || u->following[0]) || u->job_id > 0);
294 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
295 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
297 unsigned n_shown = 0;
300 max_id_len = sizeof("UNIT")-1;
301 load_len = sizeof("LOAD")-1;
302 active_len = sizeof("ACTIVE")-1;
303 sub_len = sizeof("SUB")-1;
304 job_len = sizeof("JOB")-1;
307 for (u = unit_infos; u < unit_infos + c; u++) {
308 if (!output_show_unit(u))
311 max_id_len = MAX(max_id_len, strlen(u->id));
312 load_len = MAX(load_len, strlen(u->load_state));
313 active_len = MAX(active_len, strlen(u->active_state));
314 sub_len = MAX(sub_len, strlen(u->sub_state));
316 if (u->job_id != 0) {
317 job_len = MAX(job_len, strlen(u->job_type));
322 if (!arg_full && original_stdout_is_tty) {
325 id_len = MIN(max_id_len, 25u);
326 basic_len = 5 + id_len + 5 + active_len + sub_len;
329 basic_len += job_len + 1;
331 if (basic_len < (unsigned) columns()) {
332 unsigned extra_len, incr;
333 extra_len = columns() - basic_len;
335 /* Either UNIT already got 25, or is fully satisfied.
336 * Grant up to 25 to DESC now. */
337 incr = MIN(extra_len, 25u);
341 /* split the remaining space between UNIT and DESC,
342 * but do not give UNIT more than it needs. */
344 incr = MIN(extra_len / 2, max_id_len - id_len);
346 desc_len += extra_len - incr;
352 for (u = unit_infos; u < unit_infos + c; u++) {
353 _cleanup_free_ char *e = NULL;
354 const char *on_loaded, *off_loaded, *on = "";
355 const char *on_active, *off_active, *off = "";
357 if (!output_show_unit(u))
360 if (!n_shown && !arg_no_legend) {
361 printf("%-*s %-*s %-*s %-*s ",
364 active_len, "ACTIVE",
368 printf("%-*s ", job_len, "JOB");
370 if (!arg_full && arg_no_pager)
371 printf("%.*s\n", desc_len, "DESCRIPTION");
373 printf("%s\n", "DESCRIPTION");
378 if (streq(u->load_state, "error") ||
379 streq(u->load_state, "not-found")) {
380 on_loaded = on = ansi_highlight_red();
381 off_loaded = off = ansi_highlight_off();
383 on_loaded = off_loaded = "";
385 if (streq(u->active_state, "failed")) {
386 on_active = on = ansi_highlight_red();
387 off_active = off = ansi_highlight_off();
389 on_active = off_active = "";
391 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
393 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
394 on, id_len, e ? e : u->id, off,
395 on_loaded, load_len, u->load_state, off_loaded,
396 on_active, active_len, u->active_state,
397 sub_len, u->sub_state, off_active,
398 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
401 printf("%.*s\n", desc_len, u->description);
403 printf("%s\n", u->description);
406 if (!arg_no_legend) {
407 const char *on, *off;
410 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
411 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
412 "SUB = The low-level unit activation state, values depend on unit type.\n");
414 printf("JOB = Pending job for the unit.\n");
416 on = ansi_highlight();
417 off = ansi_highlight_off();
419 on = ansi_highlight_red();
420 off = ansi_highlight_off();
424 printf("%s%u loaded units listed.%s\n"
425 "To show all installed unit files use 'systemctl list-unit-files'.\n",
428 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
429 "To show all installed unit files use 'systemctl list-unit-files'.\n",
434 static int get_unit_list(
436 sd_bus_message **_reply,
437 UnitInfo **_unit_infos) {
439 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
440 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
441 _cleanup_free_ UnitInfo *unit_infos = NULL;
450 r = sd_bus_call_method(
452 "org.freedesktop.systemd1",
453 "/org/freedesktop/systemd1",
454 "org.freedesktop.systemd1.Manager",
460 log_error("Failed to list units: %s", bus_error_message(&error, r));
464 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
466 return bus_log_parse_error(r);
468 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
470 if (!GREEDY_REALLOC(unit_infos, size, c+1))
476 return bus_log_parse_error(r);
478 r = sd_bus_message_exit_container(reply);
480 return bus_log_parse_error(r);
485 *_unit_infos = unit_infos;
491 static int list_units(sd_bus *bus, char **args) {
492 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
493 _cleanup_free_ UnitInfo *unit_infos = NULL;
496 pager_open_if_enabled();
498 r = get_unit_list(bus, &reply, &unit_infos);
502 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
503 output_units_list(unit_infos, r);
508 static int get_triggered_units(
513 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
516 r = sd_bus_get_property_strv(
518 "org.freedesktop.systemd1",
520 "org.freedesktop.systemd1.Unit",
526 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
531 static int get_listening(
533 const char* unit_path,
536 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
537 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
538 const char *type, *path;
541 r = sd_bus_get_property(
543 "org.freedesktop.systemd1",
545 "org.freedesktop.systemd1.Socket",
551 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
555 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
557 return bus_log_parse_error(r);
559 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
561 r = strv_extend(listening, type);
565 r = strv_extend(listening, path);
572 return bus_log_parse_error(r);
574 r = sd_bus_message_exit_container(reply);
576 return bus_log_parse_error(r);
587 /* Note: triggered is a list here, although it almost certainly
588 * will always be one unit. Nevertheless, dbus API allows for multiple
589 * values, so let's follow that.*/
592 /* The strv above is shared. free is set only in the first one. */
596 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
602 o = strcmp(a->path, b->path);
604 o = strcmp(a->type, b->type);
609 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
610 struct socket_info *s;
611 unsigned pathlen = sizeof("LISTEN") - 1,
612 typelen = (sizeof("TYPE") - 1) * arg_show_types,
613 socklen = sizeof("UNIT") - 1,
614 servlen = sizeof("ACTIVATES") - 1;
615 const char *on, *off;
617 for (s = socket_infos; s < socket_infos + cs; s++) {
621 socklen = MAX(socklen, strlen(s->id));
623 typelen = MAX(typelen, strlen(s->type));
624 pathlen = MAX(pathlen, strlen(s->path));
626 STRV_FOREACH(a, s->triggered)
627 tmp += strlen(*a) + 2*(a != s->triggered);
628 servlen = MAX(servlen, tmp);
633 printf("%-*s %-*.*s%-*s %s\n",
635 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
639 for (s = socket_infos; s < socket_infos + cs; s++) {
643 printf("%-*s %-*s %-*s",
644 pathlen, s->path, typelen, s->type, socklen, s->id);
647 pathlen, s->path, socklen, s->id);
648 STRV_FOREACH(a, s->triggered)
650 a == s->triggered ? "" : ",", *a);
654 on = ansi_highlight();
655 off = ansi_highlight_off();
659 on = ansi_highlight_red();
660 off = ansi_highlight_off();
663 if (!arg_no_legend) {
664 printf("%s%u sockets listed.%s\n", on, cs, off);
666 printf("Pass --all to see loaded but inactive sockets, too.\n");
672 static int list_sockets(sd_bus *bus, char **args) {
673 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
674 _cleanup_free_ UnitInfo *unit_infos = NULL;
675 struct socket_info *socket_infos = NULL;
677 struct socket_info *s;
682 pager_open_if_enabled();
684 n = get_unit_list(bus, &reply, &unit_infos);
688 for (u = unit_infos; u < unit_infos + n; u++) {
689 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
692 if (!output_show_unit(u))
695 if (!endswith(u->id, ".socket"))
698 r = get_triggered_units(bus, u->unit_path, &triggered);
702 c = get_listening(bus, u->unit_path, &listening);
708 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
713 for (i = 0; i < c; i++)
714 socket_infos[cs + i] = (struct socket_info) {
716 .type = listening[i*2],
717 .path = listening[i*2 + 1],
718 .triggered = triggered,
719 .own_triggered = i==0,
722 /* from this point on we will cleanup those socket_infos */
725 listening = triggered = NULL; /* avoid cleanup */
728 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
729 (__compar_fn_t) socket_info_compare);
731 output_sockets_list(socket_infos, cs);
734 assert(cs == 0 || socket_infos);
735 for (s = socket_infos; s < socket_infos + cs; s++) {
738 if (s->own_triggered)
739 strv_free(s->triggered);
746 static int get_next_elapse(
749 dual_timestamp *next) {
751 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
759 r = sd_bus_get_property_trivial(
761 "org.freedesktop.systemd1",
763 "org.freedesktop.systemd1.Timer",
764 "NextElapseUSecMonotonic",
769 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
773 r = sd_bus_get_property_trivial(
775 "org.freedesktop.systemd1",
777 "org.freedesktop.systemd1.Timer",
778 "NextElapseUSecRealtime",
783 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
797 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
801 if (a->next_elapse < b->next_elapse)
803 if (a->next_elapse > b->next_elapse)
806 return strcmp(a->id, b->id);
809 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
810 struct timer_info *t;
812 nextlen = sizeof("NEXT") - 1,
813 leftlen = sizeof("LEFT") - 1,
814 unitlen = sizeof("UNIT") - 1,
815 activatelen = sizeof("ACTIVATES") - 1;
817 const char *on, *off;
819 assert(timer_infos || n == 0);
821 for (t = timer_infos; t < timer_infos + n; t++) {
825 if (t->next_elapse > 0) {
826 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
828 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
829 nextlen = MAX(nextlen, strlen(tstamp) + 1);
831 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
832 leftlen = MAX(leftlen, strlen(trel));
835 unitlen = MAX(unitlen, strlen(t->id));
837 STRV_FOREACH(a, t->triggered)
838 ul += strlen(*a) + 2*(a != t->triggered);
839 activatelen = MAX(activatelen, ul);
844 printf("%-*s %-*s %-*s %s\n",
850 for (t = timer_infos; t < timer_infos + n; t++) {
851 char tstamp[FORMAT_TIMESTAMP_MAX] = "n/a", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
854 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
855 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
857 printf("%-*s %-*s %-*s",
858 nextlen, tstamp, leftlen, trel, unitlen, t->id);
860 STRV_FOREACH(a, t->triggered)
862 a == t->triggered ? "" : ",", *a);
866 on = ansi_highlight();
867 off = ansi_highlight_off();
871 on = ansi_highlight_red();
872 off = ansi_highlight_off();
875 if (!arg_no_legend) {
876 printf("%s%u timers listed.%s\n", on, n, off);
878 printf("Pass --all to see loaded but inactive timers, too.\n");
884 static int list_timers(sd_bus *bus, char **args) {
886 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
887 _cleanup_free_ struct timer_info *timer_infos = NULL;
888 _cleanup_free_ UnitInfo *unit_infos = NULL;
889 struct timer_info *t;
896 pager_open_if_enabled();
898 n = get_unit_list(bus, &reply, &unit_infos);
902 dual_timestamp_get(&nw);
904 for (u = unit_infos; u < unit_infos + n; u++) {
905 _cleanup_strv_free_ char **triggered = NULL;
909 if (!output_show_unit(u))
912 if (!endswith(u->id, ".timer"))
915 r = get_triggered_units(bus, u->unit_path, &triggered);
919 r = get_next_elapse(bus, u->unit_path, &next);
923 if (next.monotonic != (usec_t) -1 && next.monotonic > 0) {
926 if (next.monotonic > nw.monotonic)
927 converted = nw.realtime + (next.monotonic - nw.monotonic);
929 converted = nw.realtime - (nw.monotonic - next.monotonic);
931 if (next.realtime != (usec_t) -1 && next.realtime > 0)
932 m = MIN(converted, next.realtime);
938 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
943 timer_infos[c++] = (struct timer_info) {
946 .triggered = triggered,
949 triggered = NULL; /* avoid cleanup */
952 qsort_safe(timer_infos, c, sizeof(struct timer_info),
953 (__compar_fn_t) timer_info_compare);
955 output_timers_list(timer_infos, c);
958 for (t = timer_infos; t < timer_infos + c; t++)
959 strv_free(t->triggered);
964 static int compare_unit_file_list(const void *a, const void *b) {
966 const UnitFileList *u = a, *v = b;
968 d1 = strrchr(u->path, '.');
969 d2 = strrchr(v->path, '.');
974 r = strcasecmp(d1, d2);
979 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
982 static bool output_show_unit_file(const UnitFileList *u) {
985 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
988 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
989 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
990 const UnitFileList *u;
992 max_id_len = sizeof("UNIT FILE")-1;
993 state_cols = sizeof("STATE")-1;
995 for (u = units; u < units + c; u++) {
996 if (!output_show_unit_file(u))
999 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
1000 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1004 unsigned basic_cols;
1006 id_cols = MIN(max_id_len, 25u);
1007 basic_cols = 1 + id_cols + state_cols;
1008 if (basic_cols < (unsigned) columns())
1009 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1011 id_cols = max_id_len;
1014 printf("%-*s %-*s\n",
1015 id_cols, "UNIT FILE",
1016 state_cols, "STATE");
1018 for (u = units; u < units + c; u++) {
1019 _cleanup_free_ char *e = NULL;
1020 const char *on, *off;
1023 if (!output_show_unit_file(u))
1028 if (u->state == UNIT_FILE_MASKED ||
1029 u->state == UNIT_FILE_MASKED_RUNTIME ||
1030 u->state == UNIT_FILE_DISABLED ||
1031 u->state == UNIT_FILE_INVALID) {
1032 on = ansi_highlight_red();
1033 off = ansi_highlight_off();
1034 } else if (u->state == UNIT_FILE_ENABLED) {
1035 on = ansi_highlight_green();
1036 off = ansi_highlight_off();
1040 id = path_get_file_name(u->path);
1042 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1044 printf("%-*s %s%-*s%s\n",
1045 id_cols, e ? e : id,
1046 on, state_cols, unit_file_state_to_string(u->state), off);
1050 printf("\n%u unit files listed.\n", n_shown);
1053 static int list_unit_files(sd_bus *bus, char **args) {
1054 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1055 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1056 _cleanup_free_ UnitFileList *units = NULL;
1062 pager_open_if_enabled();
1070 h = hashmap_new(string_hash_func, string_compare_func);
1074 r = unit_file_get_list(arg_scope, arg_root, h);
1076 unit_file_list_free(h);
1077 log_error("Failed to get unit file list: %s", strerror(-r));
1081 n_units = hashmap_size(h);
1082 units = new(UnitFileList, n_units);
1084 unit_file_list_free(h);
1088 HASHMAP_FOREACH(u, h, i) {
1089 memcpy(units + c++, u, sizeof(UnitFileList));
1093 assert(c == n_units);
1098 r = sd_bus_call_method(
1100 "org.freedesktop.systemd1",
1101 "/org/freedesktop/systemd1",
1102 "org.freedesktop.systemd1.Manager",
1108 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1112 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1114 return bus_log_parse_error(r);
1116 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1118 if (!GREEDY_REALLOC(units, size, c + 1))
1121 units[c++] = (struct UnitFileList) {
1123 unit_file_state_from_string(state)
1127 return bus_log_parse_error(r);
1129 r = sd_bus_message_exit_container(reply);
1131 return bus_log_parse_error(r);
1135 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
1136 output_unit_file_list(units, c);
1142 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1143 _cleanup_free_ char *n = NULL;
1144 size_t max_len = MAX(columns(),20u);
1150 for (i = level - 1; i >= 0; i--) {
1152 if(len > max_len - 3 && !arg_full) {
1153 printf("%s...\n",max_len % 2 ? "" : " ");
1156 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
1160 if(len > max_len - 3 && !arg_full) {
1161 printf("%s...\n",max_len % 2 ? "" : " ");
1165 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1169 printf("%s\n", name);
1173 n = ellipsize(name, max_len-len, 100);
1181 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1183 static const char *dependencies[] = {
1184 [DEPENDENCY_FORWARD] = "Requires\0"
1185 "RequiresOverridable\0"
1187 "RequisiteOverridable\0"
1189 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1190 "RequiredByOverridable\0"
1193 [DEPENDENCY_AFTER] = "After\0",
1194 [DEPENDENCY_BEFORE] = "Before\0",
1197 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1198 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1199 _cleanup_strv_free_ char **ret = NULL;
1200 _cleanup_free_ char *path = NULL;
1206 assert(arg_dependency < ELEMENTSOF(dependencies));
1208 path = unit_dbus_path_from_name(name);
1212 r = sd_bus_call_method(
1214 "org.freedesktop.systemd1",
1216 "org.freedesktop.DBus.Properties",
1220 "s", "org.freedesktop.systemd1.Unit");
1222 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1226 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1228 return bus_log_parse_error(r);
1230 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1233 r = sd_bus_message_read(reply, "s", &prop);
1235 return bus_log_parse_error(r);
1237 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1238 r = sd_bus_message_skip(reply, "v");
1240 return bus_log_parse_error(r);
1243 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1245 return bus_log_parse_error(r);
1247 r = bus_message_read_strv_extend(reply, &ret);
1249 return bus_log_parse_error(r);
1251 r = sd_bus_message_exit_container(reply);
1253 return bus_log_parse_error(r);
1256 r = sd_bus_message_exit_container(reply);
1258 return bus_log_parse_error(r);
1262 return bus_log_parse_error(r);
1264 r = sd_bus_message_exit_container(reply);
1266 return bus_log_parse_error(r);
1274 static int list_dependencies_compare(const void *_a, const void *_b) {
1275 const char **a = (const char**) _a, **b = (const char**) _b;
1277 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1279 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1282 return strcasecmp(*a, *b);
1285 static int list_dependencies_one(
1290 unsigned int branches) {
1292 _cleanup_strv_free_ char **deps = NULL, **u;
1300 u = strv_append(*units, name);
1304 r = list_dependencies_get_dependencies(bus, name, &deps);
1308 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1310 STRV_FOREACH(c, deps) {
1311 if (strv_contains(u, *c)) {
1313 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1320 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1324 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1325 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1340 static int list_dependencies(sd_bus *bus, char **args) {
1341 _cleanup_strv_free_ char **units = NULL;
1342 _cleanup_free_ char *unit = NULL;
1348 unit = unit_name_mangle(args[1]);
1353 u = SPECIAL_DEFAULT_TARGET;
1355 pager_open_if_enabled();
1359 return list_dependencies_one(bus, u, 0, &units, 0);
1362 static int get_default(sd_bus *bus, char **args) {
1363 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1364 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1365 _cleanup_free_ char *_path = NULL;
1369 if (!bus || avoid_bus()) {
1370 r = unit_file_get_default(arg_scope, arg_root, &_path);
1372 log_error("Failed to get default target: %s", strerror(-r));
1378 r = sd_bus_call_method(
1380 "org.freedesktop.systemd1",
1381 "/org/freedesktop/systemd1",
1382 "org.freedesktop.systemd1.Manager",
1388 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1392 r = sd_bus_message_read(reply, "s", &path);
1394 return bus_log_parse_error(r);
1398 printf("%s\n", path);
1405 const char *name, *type, *state;
1408 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1409 unsigned id_len, unit_len, type_len, state_len;
1410 const struct job_info *j;
1411 const char *on, *off;
1412 bool shorten = false;
1414 assert(n == 0 || jobs);
1417 on = ansi_highlight_green();
1418 off = ansi_highlight_off();
1420 printf("%sNo jobs running.%s\n", on, off);
1424 pager_open_if_enabled();
1426 id_len = sizeof("JOB")-1;
1427 unit_len = sizeof("UNIT")-1;
1428 type_len = sizeof("TYPE")-1;
1429 state_len = sizeof("STATE")-1;
1431 for (j = jobs; j < jobs + n; j++) {
1432 uint32_t id = j->id;
1433 assert(j->name && j->type && j->state);
1435 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1436 unit_len = MAX(unit_len, strlen(j->name));
1437 type_len = MAX(type_len, strlen(j->type));
1438 state_len = MAX(state_len, strlen(j->state));
1441 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1442 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 if (!arg_no_legend) {
1471 on = ansi_highlight();
1472 off = ansi_highlight_off();
1474 printf("\n%s%u jobs listed%s.\n", on, n, off);
1478 static int list_jobs(sd_bus *bus, char **args) {
1479 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1480 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1481 const char *name, *type, *state, *job_path, *unit_path;
1482 _cleanup_free_ struct job_info *jobs = NULL;
1488 r = sd_bus_call_method(
1490 "org.freedesktop.systemd1",
1491 "/org/freedesktop/systemd1",
1492 "org.freedesktop.systemd1.Manager",
1498 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1502 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1504 return bus_log_parse_error(r);
1506 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1508 if (!GREEDY_REALLOC(jobs, size, c + 1))
1511 jobs[c++] = (struct job_info) {
1519 return bus_log_parse_error(r);
1521 r = sd_bus_message_exit_container(reply);
1523 return bus_log_parse_error(r);
1525 output_jobs_list(jobs, c);
1529 static int cancel_job(sd_bus *bus, char **args) {
1530 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1535 if (strv_length(args) <= 1)
1536 return daemon_reload(bus, args);
1538 STRV_FOREACH(name, args+1) {
1542 r = safe_atou32(*name, &id);
1544 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1548 r = sd_bus_call_method(
1550 "org.freedesktop.systemd1",
1551 "/org/freedesktop/systemd1",
1552 "org.freedesktop.systemd1.Manager",
1558 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1566 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1567 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1568 _cleanup_free_ char *n = NULL;
1572 /* We ignore all errors here, since this is used to show a
1575 n = unit_name_mangle(unit);
1579 /* We don't use unit_dbus_path_from_name() directly since we
1580 * don't want to load the unit if it isn't loaded. */
1582 r = sd_bus_call_method(
1584 "org.freedesktop.systemd1",
1585 "/org/freedesktop/systemd1",
1586 "org.freedesktop.systemd1.Manager",
1594 r = sd_bus_message_read(reply, "o", &path);
1598 r = sd_bus_get_property_trivial(
1600 "org.freedesktop.systemd1",
1602 "org.freedesktop.systemd1.Unit",
1612 typedef struct WaitData {
1619 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1626 log_debug("Got D-Bus request: %s.%s() on %s",
1627 sd_bus_message_get_interface(m),
1628 sd_bus_message_get_member(m),
1629 sd_bus_message_get_path(m));
1631 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1632 log_error("Warning! D-Bus connection terminated.");
1634 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1636 const char *path, *result, *unit;
1640 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1642 ret = set_remove(d->set, (char*) path);
1648 if (!isempty(result))
1649 d->result = strdup(result);
1652 d->name = strdup(unit);
1657 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1659 ret = set_remove(d->set, (char*) path);
1666 d->result = strdup(result);
1672 log_error("Failed to parse message.");
1678 static int enable_wait_for_jobs(sd_bus *bus) {
1683 r = sd_bus_add_match(
1686 "sender='org.freedesktop.systemd1',"
1687 "interface='org.freedesktop.systemd1.Manager',"
1688 "member='JobRemoved',"
1689 "path='/org/freedesktop/systemd1'",
1692 log_error("Failed to add match");
1696 /* This is slightly dirty, since we don't undo the match registrations. */
1700 static int wait_for_jobs(sd_bus *bus, Set *s) {
1701 WaitData d = { .set = s };
1707 r = sd_bus_add_filter(bus, wait_filter, &d);
1711 while (!set_isempty(s)) {
1713 r = sd_bus_process(bus, NULL);
1718 r = sd_bus_wait(bus, (uint64_t) -1);
1727 if (streq(d.result, "timeout"))
1728 log_error("Job for %s timed out.", strna(d.name));
1729 else if (streq(d.result, "canceled"))
1730 log_error("Job for %s canceled.", strna(d.name));
1731 else if (streq(d.result, "dependency"))
1732 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1733 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1734 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1737 if (streq_ptr(d.result, "timeout"))
1739 else if (streq_ptr(d.result, "canceled"))
1741 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1752 return sd_bus_remove_filter(bus, wait_filter, &d);
1755 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1756 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1757 _cleanup_free_ char *n = NULL, *state = NULL;
1763 n = unit_name_mangle(name);
1767 /* We don't use unit_dbus_path_from_name() directly since we
1768 * don't want to load the unit if it isn't loaded. */
1770 r = sd_bus_call_method(
1772 "org.freedesktop.systemd1",
1773 "/org/freedesktop/systemd1",
1774 "org.freedesktop.systemd1.Manager",
1785 r = sd_bus_message_read(reply, "o", &path);
1787 return bus_log_parse_error(r);
1789 r = sd_bus_get_property_string(
1791 "org.freedesktop.systemd1",
1793 "org.freedesktop.systemd1.Unit",
1806 return nulstr_contains(good_states, state);
1809 static int check_triggering_units(
1813 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1814 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1815 _cleanup_strv_free_ char **triggered_by = NULL;
1816 bool print_warning_label = true;
1820 n = unit_name_mangle(name);
1824 path = unit_dbus_path_from_name(n);
1828 r = sd_bus_get_property_string(
1830 "org.freedesktop.systemd1",
1832 "org.freedesktop.systemd1.Unit",
1837 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1841 if (streq(state, "masked"))
1844 r = sd_bus_get_property_strv(
1846 "org.freedesktop.systemd1",
1848 "org.freedesktop.systemd1.Unit",
1853 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1857 STRV_FOREACH(i, triggered_by) {
1858 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1860 log_error("Failed to check unit: %s", strerror(-r));
1867 if (print_warning_label) {
1868 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1869 print_warning_label = false;
1872 log_warning(" %s", *i);
1878 static int start_unit_one(
1883 sd_bus_error *error,
1886 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1887 _cleanup_free_ char *n;
1896 n = unit_name_mangle(name);
1900 r = sd_bus_call_method(
1902 "org.freedesktop.systemd1",
1903 "/org/freedesktop/systemd1",
1904 "org.freedesktop.systemd1.Manager",
1910 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1911 /* There's always a fallback possible for
1912 * legacy actions. */
1913 return -EADDRNOTAVAIL;
1915 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1919 r = sd_bus_message_read(reply, "o", &path);
1921 return bus_log_parse_error(r);
1923 if (need_daemon_reload(bus, n) > 0)
1924 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1925 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1934 r = set_consume(s, p);
1942 static const struct {
1946 } action_table[_ACTION_MAX] = {
1947 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1948 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1949 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1950 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1951 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1952 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1953 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1954 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1955 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1956 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1957 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1958 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1959 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1960 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1961 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1964 static enum action verb_to_action(const char *verb) {
1967 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1968 if (streq_ptr(action_table[i].verb, verb))
1971 return _ACTION_INVALID;
1974 static int start_unit(sd_bus *bus, char **args) {
1975 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1976 _cleanup_set_free_free_ Set *s = NULL;
1977 const char *method, *mode, *one_name;
1983 ask_password_agent_open_if_enabled();
1985 if (arg_action == ACTION_SYSTEMCTL) {
1988 streq(args[0], "stop") ||
1989 streq(args[0], "condstop") ? "StopUnit" :
1990 streq(args[0], "reload") ? "ReloadUnit" :
1991 streq(args[0], "restart") ? "RestartUnit" :
1993 streq(args[0], "try-restart") ||
1994 streq(args[0], "condrestart") ? "TryRestartUnit" :
1996 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1998 streq(args[0], "reload-or-try-restart") ||
1999 streq(args[0], "condreload") ||
2000 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2002 action = verb_to_action(args[0]);
2004 mode = streq(args[0], "isolate") ? "isolate" :
2005 action_table[action].mode ?: arg_job_mode;
2007 one_name = action_table[action].target;
2009 assert(arg_action < ELEMENTSOF(action_table));
2010 assert(action_table[arg_action].target);
2012 method = "StartUnit";
2014 mode = action_table[arg_action].mode;
2015 one_name = action_table[arg_action].target;
2018 if (!arg_no_block) {
2019 r = enable_wait_for_jobs(bus);
2021 log_error("Could not watch jobs: %s", strerror(-r));
2025 s = set_new(string_hash_func, string_compare_func);
2031 r = start_unit_one(bus, method, one_name, mode, &error, s);
2033 r = translate_bus_error_to_exit_status(r, &error);
2037 STRV_FOREACH(name, args+1) {
2040 q = start_unit_one(bus, method, *name, mode, &error, s);
2042 r = translate_bus_error_to_exit_status(r, &error);
2043 sd_bus_error_free(&error);
2048 if (!arg_no_block) {
2051 q = wait_for_jobs(bus, s);
2055 /* When stopping units, warn if they can still be triggered by
2056 * another active unit (socket, path, timer) */
2057 if (!arg_quiet && streq(method, "StopUnit")) {
2059 check_triggering_units(bus, one_name);
2061 STRV_FOREACH(name, args+1)
2062 check_triggering_units(bus, *name);
2069 /* Ask systemd-logind, which might grant access to unprivileged users
2070 * through PolicyKit */
2071 static int reboot_with_logind(sd_bus *bus, enum action a) {
2073 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2080 polkit_agent_open_if_enabled();
2088 case ACTION_POWEROFF:
2089 method = "PowerOff";
2092 case ACTION_SUSPEND:
2096 case ACTION_HIBERNATE:
2097 method = "Hibernate";
2100 case ACTION_HYBRID_SLEEP:
2101 method = "HybridSleep";
2108 r = sd_bus_call_method(
2110 "org.freedesktop.login1",
2111 "/org/freedesktop/login1",
2112 "org.freedesktop.login1.Manager",
2118 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2126 static int check_inhibitors(sd_bus *bus, enum action a) {
2128 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2129 _cleanup_strv_free_ char **sessions = NULL;
2130 const char *what, *who, *why, *mode;
2139 if (arg_ignore_inhibitors || arg_force > 0)
2151 r = sd_bus_call_method(
2153 "org.freedesktop.login1",
2154 "/org/freedesktop/login1",
2155 "org.freedesktop.login1.Manager",
2161 /* If logind is not around, then there are no inhibitors... */
2164 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2166 return bus_log_parse_error(r);
2168 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2169 _cleanup_free_ char *comm = NULL, *user = NULL;
2170 _cleanup_strv_free_ char **sv = NULL;
2172 if (!streq(mode, "block"))
2175 sv = strv_split(what, ":");
2179 if (!strv_contains(sv,
2181 a == ACTION_POWEROFF ||
2182 a == ACTION_REBOOT ||
2183 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2186 get_process_comm(pid, &comm);
2187 user = uid_to_name(uid);
2189 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2190 who, (unsigned long) pid, strna(comm), strna(user), why);
2195 return bus_log_parse_error(r);
2197 r = sd_bus_message_exit_container(reply);
2199 return bus_log_parse_error(r);
2201 /* Check for current sessions */
2202 sd_get_sessions(&sessions);
2203 STRV_FOREACH(s, sessions) {
2204 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2206 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2209 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2212 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2215 sd_session_get_tty(*s, &tty);
2216 sd_session_get_seat(*s, &seat);
2217 sd_session_get_service(*s, &service);
2218 user = uid_to_name(uid);
2220 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2227 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2228 action_table[a].verb);
2236 static int start_special(sd_bus *bus, char **args) {
2242 a = verb_to_action(args[0]);
2244 r = check_inhibitors(bus, a);
2248 if (arg_force >= 2 && geteuid() != 0) {
2249 log_error("Must be root.");
2253 if (arg_force >= 2 &&
2254 (a == ACTION_HALT ||
2255 a == ACTION_POWEROFF ||
2256 a == ACTION_REBOOT))
2259 if (arg_force >= 1 &&
2260 (a == ACTION_HALT ||
2261 a == ACTION_POWEROFF ||
2262 a == ACTION_REBOOT ||
2263 a == ACTION_KEXEC ||
2265 return daemon_reload(bus, args);
2267 /* first try logind, to allow authentication with polkit */
2268 if (geteuid() != 0 &&
2269 (a == ACTION_POWEROFF ||
2270 a == ACTION_REBOOT ||
2271 a == ACTION_SUSPEND ||
2272 a == ACTION_HIBERNATE ||
2273 a == ACTION_HYBRID_SLEEP)) {
2274 r = reboot_with_logind(bus, a);
2279 r = start_unit(bus, args);
2280 if (r == EXIT_SUCCESS)
2286 static int check_unit_active(sd_bus *bus, char **args) {
2288 int r = 3; /* According to LSB: "program is not running" */
2293 STRV_FOREACH(name, args+1) {
2296 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2306 static int check_unit_failed(sd_bus *bus, char **args) {
2313 STRV_FOREACH(name, args+1) {
2316 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2326 static int kill_unit(sd_bus *bus, char **args) {
2327 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2335 arg_kill_who = "all";
2337 STRV_FOREACH(name, args+1) {
2338 _cleanup_free_ char *n = NULL;
2340 n = unit_name_mangle(*name);
2344 r = sd_bus_call_method(
2346 "org.freedesktop.systemd1",
2347 "/org/freedesktop/systemd1",
2348 "org.freedesktop.systemd1.Manager",
2352 "ssi", n, arg_kill_who, arg_signal);
2354 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2362 typedef struct ExecStatusInfo {
2370 usec_t start_timestamp;
2371 usec_t exit_timestamp;
2376 LIST_FIELDS(struct ExecStatusInfo, exec);
2379 static void exec_status_info_free(ExecStatusInfo *i) {
2388 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2389 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2392 int32_t code, status;
2398 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2400 return bus_log_parse_error(r);
2404 r = sd_bus_message_read(m, "s", &path);
2406 return bus_log_parse_error(r);
2408 i->path = strdup(path);
2412 r = sd_bus_message_read_strv(m, &i->argv);
2414 return bus_log_parse_error(r);
2416 r = sd_bus_message_read(m,
2419 &start_timestamp, &start_timestamp_monotonic,
2420 &exit_timestamp, &exit_timestamp_monotonic,
2424 return bus_log_parse_error(r);
2427 i->start_timestamp = (usec_t) start_timestamp;
2428 i->exit_timestamp = (usec_t) exit_timestamp;
2429 i->pid = (pid_t) pid;
2433 r = sd_bus_message_exit_container(m);
2435 return bus_log_parse_error(r);
2440 typedef struct UnitStatusInfo {
2442 const char *load_state;
2443 const char *active_state;
2444 const char *sub_state;
2445 const char *unit_file_state;
2447 const char *description;
2448 const char *following;
2450 char **documentation;
2452 const char *fragment_path;
2453 const char *source_path;
2454 const char *control_group;
2456 char **dropin_paths;
2458 const char *load_error;
2461 usec_t inactive_exit_timestamp;
2462 usec_t inactive_exit_timestamp_monotonic;
2463 usec_t active_enter_timestamp;
2464 usec_t active_exit_timestamp;
2465 usec_t inactive_enter_timestamp;
2467 bool need_daemon_reload;
2472 const char *status_text;
2473 const char *pid_file;
2476 usec_t start_timestamp;
2477 usec_t exit_timestamp;
2479 int exit_code, exit_status;
2481 usec_t condition_timestamp;
2482 bool condition_result;
2483 bool failed_condition_trigger;
2484 bool failed_condition_negate;
2485 const char *failed_condition;
2486 const char *failed_condition_param;
2489 unsigned n_accepted;
2490 unsigned n_connections;
2493 /* Pairs of type, path */
2497 const char *sysfs_path;
2499 /* Mount, Automount */
2505 LIST_HEAD(ExecStatusInfo, exec);
2508 static void print_status_info(
2513 const char *on, *off, *ss;
2515 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2516 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2519 arg_all * OUTPUT_SHOW_ALL |
2520 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2521 on_tty() * OUTPUT_COLOR |
2522 !arg_quiet * OUTPUT_WARN_CUTOFF |
2523 arg_full * OUTPUT_FULL_WIDTH;
2528 /* This shows pretty information about a unit. See
2529 * print_property() for a low-level property printer */
2531 printf("%s", strna(i->id));
2533 if (i->description && !streq_ptr(i->id, i->description))
2534 printf(" - %s", i->description);
2539 printf(" Follow: unit currently follows state of %s\n", i->following);
2541 if (streq_ptr(i->load_state, "error")) {
2542 on = ansi_highlight_red();
2543 off = ansi_highlight_off();
2547 path = i->source_path ? i->source_path : i->fragment_path;
2550 printf(" Loaded: %s%s%s (Reason: %s)\n",
2551 on, strna(i->load_state), off, i->load_error);
2552 else if (path && i->unit_file_state)
2553 printf(" Loaded: %s%s%s (%s; %s)\n",
2554 on, strna(i->load_state), off, path, i->unit_file_state);
2556 printf(" Loaded: %s%s%s (%s)\n",
2557 on, strna(i->load_state), off, path);
2559 printf(" Loaded: %s%s%s\n",
2560 on, strna(i->load_state), off);
2562 if (!strv_isempty(i->dropin_paths)) {
2563 _cleanup_free_ char *dir = NULL;
2567 STRV_FOREACH(dropin, i->dropin_paths) {
2568 if (! dir || last) {
2569 printf(dir ? " " : " Drop-In: ");
2574 if (path_get_parent(*dropin, &dir) < 0) {
2579 printf("%s\n %s", dir,
2580 draw_special_char(DRAW_TREE_RIGHT));
2583 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2585 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2589 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2591 if (streq_ptr(i->active_state, "failed")) {
2592 on = ansi_highlight_red();
2593 off = ansi_highlight_off();
2594 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2595 on = ansi_highlight_green();
2596 off = ansi_highlight_off();
2601 printf(" Active: %s%s (%s)%s",
2602 on, strna(i->active_state), ss, off);
2604 printf(" Active: %s%s%s",
2605 on, strna(i->active_state), off);
2607 if (!isempty(i->result) && !streq(i->result, "success"))
2608 printf(" (Result: %s)", i->result);
2610 timestamp = (streq_ptr(i->active_state, "active") ||
2611 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2612 (streq_ptr(i->active_state, "inactive") ||
2613 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2614 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2615 i->active_exit_timestamp;
2617 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2618 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2621 printf(" since %s; %s\n", s2, s1);
2623 printf(" since %s\n", s2);
2627 if (!i->condition_result && i->condition_timestamp > 0) {
2628 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2629 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2631 printf(" start condition failed at %s%s%s\n",
2632 s2, s1 ? "; " : "", s1 ? s1 : "");
2633 if (i->failed_condition_trigger)
2634 printf(" none of the trigger conditions were met\n");
2635 else if (i->failed_condition)
2636 printf(" %s=%s%s was not met\n",
2637 i->failed_condition,
2638 i->failed_condition_negate ? "!" : "",
2639 i->failed_condition_param);
2643 printf(" Device: %s\n", i->sysfs_path);
2645 printf(" Where: %s\n", i->where);
2647 printf(" What: %s\n", i->what);
2649 STRV_FOREACH(t, i->documentation)
2650 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2652 STRV_FOREACH_PAIR(t, t2, i->listen)
2653 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2656 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2658 LIST_FOREACH(exec, p, i->exec) {
2659 _cleanup_free_ char *argv = NULL;
2662 /* Only show exited processes here */
2666 argv = strv_join(p->argv, " ");
2667 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2669 good = is_clean_exit_lsb(p->code, p->status, NULL);
2671 on = ansi_highlight_red();
2672 off = ansi_highlight_off();
2676 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2678 if (p->code == CLD_EXITED) {
2681 printf("status=%i", p->status);
2683 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2688 printf("signal=%s", signal_to_string(p->status));
2690 printf(")%s\n", off);
2692 if (i->main_pid == p->pid &&
2693 i->start_timestamp == p->start_timestamp &&
2694 i->exit_timestamp == p->start_timestamp)
2695 /* Let's not show this twice */
2698 if (p->pid == i->control_pid)
2702 if (i->main_pid > 0 || i->control_pid > 0) {
2703 if (i->main_pid > 0) {
2704 printf(" Main PID: %u", (unsigned) i->main_pid);
2707 _cleanup_free_ char *comm = NULL;
2708 get_process_comm(i->main_pid, &comm);
2710 printf(" (%s)", comm);
2711 } else if (i->exit_code > 0) {
2712 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2714 if (i->exit_code == CLD_EXITED) {
2717 printf("status=%i", i->exit_status);
2719 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2724 printf("signal=%s", signal_to_string(i->exit_status));
2728 if (i->control_pid > 0)
2732 if (i->control_pid > 0) {
2733 _cleanup_free_ char *c = NULL;
2735 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2737 get_process_comm(i->control_pid, &c);
2746 printf(" Status: \"%s\"\n", i->status_text);
2748 if (i->control_group &&
2749 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2752 printf(" CGroup: %s\n", i->control_group);
2754 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2757 char prefix[] = " ";
2760 if (c > sizeof(prefix) - 1)
2761 c -= sizeof(prefix) - 1;
2765 if (i->main_pid > 0)
2766 extra[k++] = i->main_pid;
2768 if (i->control_pid > 0)
2769 extra[k++] = i->control_pid;
2771 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2772 c, false, extra, k, flags);
2776 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2778 show_journal_by_unit(stdout,
2782 i->inactive_exit_timestamp_monotonic,
2786 arg_scope == UNIT_FILE_SYSTEM,
2790 if (i->need_daemon_reload)
2791 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2792 ansi_highlight_red(),
2793 ansi_highlight_off(),
2794 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2797 static void show_unit_help(UnitStatusInfo *i) {
2802 if (!i->documentation) {
2803 log_info("Documentation for %s not known.", i->id);
2807 STRV_FOREACH(p, i->documentation) {
2809 if (startswith(*p, "man:")) {
2810 const char *args[4] = { "man", NULL, NULL, NULL };
2811 _cleanup_free_ char *page = NULL, *section = NULL;
2818 if ((*p)[k-1] == ')')
2819 e = strrchr(*p, '(');
2822 page = strndup((*p) + 4, e - *p - 4);
2823 section = strndup(e + 1, *p + k - e - 2);
2824 if (!page || !section) {
2836 log_error("Failed to fork: %m");
2842 execvp(args[0], (char**) args);
2843 log_error("Failed to execute man: %m");
2844 _exit(EXIT_FAILURE);
2847 wait_for_terminate(pid, NULL);
2849 log_info("Can't show: %s", *p);
2853 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2860 switch (contents[0]) {
2862 case SD_BUS_TYPE_STRING: {
2865 r = sd_bus_message_read(m, "s", &s);
2867 return bus_log_parse_error(r);
2870 if (streq(name, "Id"))
2872 else if (streq(name, "LoadState"))
2874 else if (streq(name, "ActiveState"))
2875 i->active_state = s;
2876 else if (streq(name, "SubState"))
2878 else if (streq(name, "Description"))
2880 else if (streq(name, "FragmentPath"))
2881 i->fragment_path = s;
2882 else if (streq(name, "SourcePath"))
2885 else if (streq(name, "DefaultControlGroup")) {
2887 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2889 i->control_group = e;
2892 else if (streq(name, "ControlGroup"))
2893 i->control_group = s;
2894 else if (streq(name, "StatusText"))
2896 else if (streq(name, "PIDFile"))
2898 else if (streq(name, "SysFSPath"))
2900 else if (streq(name, "Where"))
2902 else if (streq(name, "What"))
2904 else if (streq(name, "Following"))
2906 else if (streq(name, "UnitFileState"))
2907 i->unit_file_state = s;
2908 else if (streq(name, "Result"))
2915 case SD_BUS_TYPE_BOOLEAN: {
2918 r = sd_bus_message_read(m, "b", &b);
2920 return bus_log_parse_error(r);
2922 if (streq(name, "Accept"))
2924 else if (streq(name, "NeedDaemonReload"))
2925 i->need_daemon_reload = b;
2926 else if (streq(name, "ConditionResult"))
2927 i->condition_result = b;
2932 case SD_BUS_TYPE_UINT32: {
2935 r = sd_bus_message_read(m, "u", &u);
2937 return bus_log_parse_error(r);
2939 if (streq(name, "MainPID")) {
2941 i->main_pid = (pid_t) u;
2944 } else if (streq(name, "ControlPID"))
2945 i->control_pid = (pid_t) u;
2946 else if (streq(name, "ExecMainPID")) {
2948 i->main_pid = (pid_t) u;
2949 } else if (streq(name, "NAccepted"))
2951 else if (streq(name, "NConnections"))
2952 i->n_connections = u;
2957 case SD_BUS_TYPE_INT32: {
2960 r = sd_bus_message_read(m, "i", &j);
2962 return bus_log_parse_error(r);
2964 if (streq(name, "ExecMainCode"))
2965 i->exit_code = (int) j;
2966 else if (streq(name, "ExecMainStatus"))
2967 i->exit_status = (int) j;
2972 case SD_BUS_TYPE_UINT64: {
2975 r = sd_bus_message_read(m, "t", &u);
2977 return bus_log_parse_error(r);
2979 if (streq(name, "ExecMainStartTimestamp"))
2980 i->start_timestamp = (usec_t) u;
2981 else if (streq(name, "ExecMainExitTimestamp"))
2982 i->exit_timestamp = (usec_t) u;
2983 else if (streq(name, "ActiveEnterTimestamp"))
2984 i->active_enter_timestamp = (usec_t) u;
2985 else if (streq(name, "InactiveEnterTimestamp"))
2986 i->inactive_enter_timestamp = (usec_t) u;
2987 else if (streq(name, "InactiveExitTimestamp"))
2988 i->inactive_exit_timestamp = (usec_t) u;
2989 else if (streq(name, "InactiveExitTimestampMonotonic"))
2990 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2991 else if (streq(name, "ActiveExitTimestamp"))
2992 i->active_exit_timestamp = (usec_t) u;
2993 else if (streq(name, "ConditionTimestamp"))
2994 i->condition_timestamp = (usec_t) u;
2999 case SD_BUS_TYPE_ARRAY:
3001 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3002 _cleanup_free_ ExecStatusInfo *info = NULL;
3004 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3006 return bus_log_parse_error(r);
3008 info = new0(ExecStatusInfo, 1);
3012 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3014 info->name = strdup(name);
3018 LIST_PREPEND(exec, i->exec, info);
3020 info = new0(ExecStatusInfo, 1);
3026 return bus_log_parse_error(r);
3028 r = sd_bus_message_exit_container(m);
3030 return bus_log_parse_error(r);
3034 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3035 const char *type, *path;
3037 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3039 return bus_log_parse_error(r);
3041 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3043 r = strv_extend(&i->listen, type);
3047 r = strv_extend(&i->listen, path);
3052 return bus_log_parse_error(r);
3054 r = sd_bus_message_exit_container(m);
3056 return bus_log_parse_error(r);
3060 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3062 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3064 return bus_log_parse_error(r);
3066 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3068 r = sd_bus_message_read_strv(m, &i->documentation);
3070 return bus_log_parse_error(r);
3072 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3073 const char *cond, *param;
3074 int trigger, negate;
3077 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3079 return bus_log_parse_error(r);
3081 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3082 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3083 if (state < 0 && (!trigger || !i->failed_condition)) {
3084 i->failed_condition = cond;
3085 i->failed_condition_trigger = trigger;
3086 i->failed_condition_negate = negate;
3087 i->failed_condition_param = param;
3091 return bus_log_parse_error(r);
3093 r = sd_bus_message_exit_container(m);
3095 return bus_log_parse_error(r);
3102 case SD_BUS_TYPE_STRUCT_BEGIN:
3104 if (streq(name, "LoadError")) {
3105 const char *n, *message;
3107 r = sd_bus_message_read(m, "(ss)", &n, &message);
3109 return bus_log_parse_error(r);
3111 if (!isempty(message))
3112 i->load_error = message;
3125 r = sd_bus_message_skip(m, contents);
3127 return bus_log_parse_error(r);
3132 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3138 /* This is a low-level property printer, see
3139 * print_status_info() for the nicer output */
3141 if (arg_properties && !strv_find(arg_properties, name)) {
3142 /* skip what we didn't read */
3143 r = sd_bus_message_skip(m, contents);
3147 switch (contents[0]) {
3149 case SD_BUS_TYPE_STRUCT_BEGIN:
3151 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3154 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3156 return bus_log_parse_error(r);
3159 printf("%s=%u\n", name, (unsigned) u);
3161 printf("%s=\n", name);
3165 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3168 r = sd_bus_message_read(m, "(so)", &s, NULL);
3170 return bus_log_parse_error(r);
3172 if (arg_all || !isempty(s))
3173 printf("%s=%s\n", name, s);
3177 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3178 const char *a = NULL, *b = NULL;
3180 r = sd_bus_message_read(m, "(ss)", &a, &b);
3182 return bus_log_parse_error(r);
3184 if (arg_all || !isempty(a) || !isempty(b))
3185 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3192 case SD_BUS_TYPE_ARRAY:
3194 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3198 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3200 return bus_log_parse_error(r);
3202 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3203 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
3206 return bus_log_parse_error(r);
3208 r = sd_bus_message_exit_container(m);
3210 return bus_log_parse_error(r);
3214 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
3215 const char *type, *path;
3217 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3219 return bus_log_parse_error(r);
3221 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3222 printf("%s=%s\n", type, path);
3224 return bus_log_parse_error(r);
3226 r = sd_bus_message_exit_container(m);
3228 return bus_log_parse_error(r);
3232 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3233 const char *type, *path;
3235 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3237 return bus_log_parse_error(r);
3239 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3240 printf("Listen%s=%s\n", type, path);
3242 return bus_log_parse_error(r);
3244 r = sd_bus_message_exit_container(m);
3246 return bus_log_parse_error(r);
3250 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3252 uint64_t value, next_elapse;
3254 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3256 return bus_log_parse_error(r);
3258 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3259 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3261 printf("%s={ value=%s ; next_elapse=%s }\n",
3263 format_timespan(timespan1, sizeof(timespan1), value, 0),
3264 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3267 return bus_log_parse_error(r);
3269 r = sd_bus_message_exit_container(m);
3271 return bus_log_parse_error(r);
3275 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3276 ExecStatusInfo info = {};
3278 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3280 return bus_log_parse_error(r);
3282 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3283 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3284 _cleanup_free_ char *tt;
3286 tt = strv_join(info.argv, " ");
3288 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3292 yes_no(info.ignore),
3293 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3294 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3295 (unsigned) info. pid,
3296 sigchld_code_to_string(info.code),
3298 info.code == CLD_EXITED ? "" : "/",
3299 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3302 strv_free(info.argv);
3306 r = sd_bus_message_exit_container(m);
3308 return bus_log_parse_error(r);
3312 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3313 const char *path, *rwm;
3315 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3317 return bus_log_parse_error(r);
3319 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3320 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3322 return bus_log_parse_error(r);
3324 r = sd_bus_message_exit_container(m);
3326 return bus_log_parse_error(r);
3330 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3334 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3336 return bus_log_parse_error(r);
3338 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3339 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3341 return bus_log_parse_error(r);
3343 r = sd_bus_message_exit_container(m);
3345 return bus_log_parse_error(r);
3349 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3353 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3355 return bus_log_parse_error(r);
3357 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3358 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3360 return bus_log_parse_error(r);
3362 r = sd_bus_message_exit_container(m);
3364 return bus_log_parse_error(r);
3372 r = bus_print_property(name, m, arg_all);
3374 return bus_log_parse_error(r);
3377 r = sd_bus_message_skip(m, contents);
3379 return bus_log_parse_error(r);
3382 printf("%s=[unprintable]\n", name);
3388 static int show_one(
3392 bool show_properties,
3396 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3397 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3398 UnitStatusInfo info = {};
3405 r = sd_bus_call_method(
3407 "org.freedesktop.systemd1",
3409 "org.freedesktop.DBus.Properties",
3415 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3419 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3421 return bus_log_parse_error(r);
3428 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3429 const char *name, *contents;
3431 r = sd_bus_message_read(reply, "s", &name);
3433 return bus_log_parse_error(r);
3435 r = sd_bus_message_peek_type(reply, NULL, &contents);
3437 return bus_log_parse_error(r);
3439 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3441 return bus_log_parse_error(r);
3443 if (show_properties)
3444 r = print_property(name, reply, contents);
3446 r = status_property(name, reply, &info, contents);
3450 r = sd_bus_message_exit_container(reply);
3452 return bus_log_parse_error(r);
3454 r = sd_bus_message_exit_container(reply);
3456 return bus_log_parse_error(r);
3459 return bus_log_parse_error(r);
3461 r = sd_bus_message_exit_container(reply);
3463 return bus_log_parse_error(r);
3467 if (!show_properties) {
3468 if (streq(verb, "help"))
3469 show_unit_help(&info);
3471 print_status_info(&info, ellipsized);
3474 strv_free(info.documentation);
3475 strv_free(info.dropin_paths);
3476 strv_free(info.listen);
3478 if (!streq_ptr(info.active_state, "active") &&
3479 !streq_ptr(info.active_state, "reloading") &&
3480 streq(verb, "status")) {
3481 /* According to LSB: "program not running" */
3482 /* 0: program is running or service is OK
3483 * 1: program is dead and /var/run pid file exists
3484 * 2: program is dead and /var/lock lock file exists
3485 * 3: program is not running
3486 * 4: program or service status is unknown
3488 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3494 while ((p = info.exec)) {
3495 LIST_REMOVE(exec, info.exec, p);
3496 exec_status_info_free(p);
3502 static int show_one_by_pid(
3509 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3510 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3511 const char *path = NULL;
3514 r = sd_bus_call_method(
3516 "org.freedesktop.systemd1",
3517 "/org/freedesktop/systemd1",
3518 "org.freedesktop.systemd1.Manager",
3524 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3528 r = sd_bus_message_read(reply, "o", &path);
3530 return bus_log_parse_error(r);
3532 return show_one(verb, bus, path, false, new_line, ellipsized);
3535 static int show_all(
3538 bool show_properties,
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_call(bus, m, 0, &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_call(bus, m, 0, &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_call(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;