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"
61 #include "unit-name.h"
63 #include "spawn-ask-password-agent.h"
64 #include "spawn-polkit-agent.h"
66 #include "logs-show.h"
67 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-common-errors.h"
78 static char **arg_types = NULL;
79 static char **arg_states = NULL;
80 static char **arg_properties = NULL;
81 static bool arg_all = false;
82 static enum dependency {
88 } arg_dependency = DEPENDENCY_FORWARD;
89 static const char *arg_job_mode = "replace";
90 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
91 static bool arg_no_block = false;
92 static bool arg_no_legend = false;
93 static bool arg_no_pager = false;
94 static bool arg_no_wtmp = false;
95 static bool arg_no_wall = false;
96 static bool arg_no_reload = false;
97 static bool arg_show_types = false;
98 static bool arg_ignore_inhibitors = false;
99 static bool arg_dry = false;
100 static bool arg_quiet = false;
101 static bool arg_full = false;
102 static bool arg_recursive = false;
103 static int arg_force = 0;
104 static bool arg_ask_password = true;
105 static bool arg_runtime = false;
106 static UnitFilePresetMode arg_preset_mode = UNIT_FILE_PRESET_FULL;
107 static char **arg_wall = NULL;
108 static const char *arg_kill_who = NULL;
109 static int arg_signal = SIGTERM;
110 static const char *arg_root = NULL;
111 static usec_t arg_when = 0;
133 ACTION_CANCEL_SHUTDOWN,
135 } arg_action = ACTION_SYSTEMCTL;
136 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
137 static char *arg_host = NULL;
138 static unsigned arg_lines = 10;
139 static OutputMode arg_output = OUTPUT_SHORT;
140 static bool arg_plain = false;
142 static bool original_stdout_is_tty;
144 static int daemon_reload(sd_bus *bus, char **args);
145 static int halt_now(enum action a);
146 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet);
148 static char** strv_skip_first(char **strv) {
149 if (strv_length(strv) > 0)
154 static void pager_open_if_enabled(void) {
162 static void ask_password_agent_open_if_enabled(void) {
164 /* Open the password agent as a child process if necessary */
166 if (!arg_ask_password)
169 if (arg_scope != UNIT_FILE_SYSTEM)
172 if (arg_transport != BUS_TRANSPORT_LOCAL)
175 ask_password_agent_open();
178 static void polkit_agent_open_if_enabled(void) {
180 /* Open the polkit agent as a child process if necessary */
182 if (!arg_ask_password)
185 if (arg_scope != UNIT_FILE_SYSTEM)
188 if (arg_transport != BUS_TRANSPORT_LOCAL)
194 static OutputFlags get_output_flags(void) {
196 arg_all * OUTPUT_SHOW_ALL |
197 arg_full * OUTPUT_FULL_WIDTH |
198 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
199 on_tty() * OUTPUT_COLOR |
200 !arg_quiet * OUTPUT_WARN_CUTOFF;
203 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
206 if (!sd_bus_error_is_set(error))
209 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
210 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
211 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
212 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
213 return EXIT_NOPERMISSION;
215 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
216 return EXIT_NOTINSTALLED;
218 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
219 sd_bus_error_has_name(error, SD_BUS_ERROR_NOT_SUPPORTED))
220 return EXIT_NOTIMPLEMENTED;
222 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
223 return EXIT_NOTCONFIGURED;
231 static void warn_wall(enum action a) {
232 static const char *table[_ACTION_MAX] = {
233 [ACTION_HALT] = "The system is going down for system halt NOW!",
234 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
235 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
236 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
237 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
238 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
239 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
246 _cleanup_free_ char *p;
248 p = strv_join(arg_wall, " ");
255 utmp_wall(p, NULL, NULL);
263 utmp_wall(table[a], NULL, NULL);
266 static bool avoid_bus(void) {
268 if (running_in_chroot() > 0)
271 if (sd_booted() <= 0)
274 if (!isempty(arg_root))
277 if (arg_scope == UNIT_FILE_GLOBAL)
283 static int compare_unit_info(const void *a, const void *b) {
284 const UnitInfo *u = a, *v = b;
288 /* First, order by machine */
289 if (!u->machine && v->machine)
291 if (u->machine && !v->machine)
293 if (u->machine && v->machine) {
294 r = strcasecmp(u->machine, v->machine);
299 /* Second, order by unit type */
300 d1 = strrchr(u->id, '.');
301 d2 = strrchr(v->id, '.');
303 r = strcasecmp(d1, d2);
308 /* Third, order by name */
309 return strcasecmp(u->id, v->id);
312 static bool output_show_unit(const UnitInfo *u, char **patterns) {
313 if (!strv_fnmatch_or_empty(u->id, patterns, FNM_NOESCAPE))
319 dot = strrchr(u->id, '.');
323 if (!strv_find(arg_types, dot+1))
333 if (streq(u->active_state, "inactive") || u->following[0])
339 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
340 unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
342 unsigned n_shown = 0;
345 max_id_len = strlen("UNIT");
346 load_len = strlen("LOAD");
347 active_len = strlen("ACTIVE");
348 sub_len = strlen("SUB");
349 job_len = strlen("JOB");
352 for (u = unit_infos; u < unit_infos + c; u++) {
353 max_id_len = MAX(max_id_len, strlen(u->id) + (u->machine ? strlen(u->machine)+1 : 0));
354 load_len = MAX(load_len, strlen(u->load_state));
355 active_len = MAX(active_len, strlen(u->active_state));
356 sub_len = MAX(sub_len, strlen(u->sub_state));
358 if (u->job_id != 0) {
359 job_len = MAX(job_len, strlen(u->job_type));
363 if (!arg_no_legend &&
364 (streq(u->active_state, "failed") ||
365 STR_IN_SET(u->load_state, "error", "not-found", "masked")))
369 if (!arg_full && original_stdout_is_tty) {
372 id_len = MIN(max_id_len, 25u);
373 basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
376 basic_len += job_len + 1;
378 if (basic_len < (unsigned) columns()) {
379 unsigned extra_len, incr;
380 extra_len = columns() - basic_len;
382 /* Either UNIT already got 25, or is fully satisfied.
383 * Grant up to 25 to DESC now. */
384 incr = MIN(extra_len, 25u);
388 /* split the remaining space between UNIT and DESC,
389 * but do not give UNIT more than it needs. */
391 incr = MIN(extra_len / 2, max_id_len - id_len);
393 desc_len += extra_len - incr;
399 for (u = unit_infos; u < unit_infos + c; u++) {
400 _cleanup_free_ char *e = NULL, *j = NULL;
401 const char *on_loaded = "", *off_loaded = "";
402 const char *on_active = "", *off_active = "";
403 const char *on_circle = "", *off_circle = "";
407 if (!n_shown && !arg_no_legend) {
412 printf("%-*s %-*s %-*s %-*s ",
415 active_len, "ACTIVE",
419 printf("%-*s ", job_len, "JOB");
421 if (!arg_full && arg_no_pager)
422 printf("%.*s\n", desc_len, "DESCRIPTION");
424 printf("%s\n", "DESCRIPTION");
429 if (STR_IN_SET(u->load_state, "error", "not-found", "masked") && !arg_plain) {
430 on_loaded = ansi_highlight_red();
431 on_circle = ansi_highlight_yellow();
432 off_loaded = off_circle = ansi_highlight_off();
434 } else if (streq(u->active_state, "failed") && !arg_plain) {
435 on_circle = on_active = ansi_highlight_red();
436 off_circle = off_active = ansi_highlight_off();
441 j = strjoin(u->machine, ":", u->id, NULL);
450 e = ellipsize(id, id_len, 33);
458 printf("%s%s%s ", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_circle);
460 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
461 on_active, id_len, id, off_active,
462 on_loaded, load_len, u->load_state, off_loaded,
463 on_active, active_len, u->active_state,
464 sub_len, u->sub_state, off_active,
465 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
468 printf("%.*s\n", desc_len, u->description);
470 printf("%s\n", u->description);
473 if (!arg_no_legend) {
474 const char *on, *off;
478 "LOAD = Reflects whether the unit definition was properly loaded.\n"
479 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
480 "SUB = The low-level unit activation state, values depend on unit type.");
481 puts(job_count ? "JOB = Pending job for the unit.\n" : "");
482 on = ansi_highlight();
483 off = ansi_highlight_off();
485 on = ansi_highlight_red();
486 off = ansi_highlight_off();
490 printf("%s%u loaded units listed.%s\n"
491 "To show all installed unit files use 'systemctl list-unit-files'.\n",
494 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
495 "To show all installed unit files use 'systemctl list-unit-files'.\n",
502 static int get_unit_list(
506 UnitInfo **unit_infos,
508 sd_bus_message **_reply) {
510 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
511 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
512 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
521 r = sd_bus_message_new_method_call(
524 "org.freedesktop.systemd1",
525 "/org/freedesktop/systemd1",
526 "org.freedesktop.systemd1.Manager",
527 "ListUnitsFiltered");
530 return bus_log_create_error(r);
532 r = sd_bus_message_append_strv(m, arg_states);
534 return bus_log_create_error(r);
536 r = sd_bus_call(bus, m, 0, &error, &reply);
538 log_error("Failed to list units: %s", bus_error_message(&error, r));
542 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
544 return bus_log_parse_error(r);
546 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
549 if (!output_show_unit(&u, patterns))
552 if (!GREEDY_REALLOC(*unit_infos, size, c+1))
555 (*unit_infos)[c++] = u;
558 return bus_log_parse_error(r);
560 r = sd_bus_message_exit_container(reply);
562 return bus_log_parse_error(r);
570 static void message_set_freep(Set **set) {
573 while ((m = set_steal_first(*set)))
574 sd_bus_message_unref(m);
579 static int get_unit_list_recursive(
582 UnitInfo **_unit_infos,
586 _cleanup_free_ UnitInfo *unit_infos = NULL;
587 _cleanup_(message_set_freep) Set *replies;
588 sd_bus_message *reply;
596 replies = set_new(NULL);
600 c = get_unit_list(bus, NULL, patterns, &unit_infos, 0, &reply);
604 r = set_put(replies, reply);
606 sd_bus_message_unref(reply);
611 _cleanup_strv_free_ char **machines = NULL;
614 r = sd_get_machine_names(&machines);
618 STRV_FOREACH(i, machines) {
619 _cleanup_bus_close_unref_ sd_bus *container = NULL;
622 r = sd_bus_open_system_machine(&container, *i);
624 log_error_errno(r, "Failed to connect to container %s: %m", *i);
628 k = get_unit_list(container, *i, patterns, &unit_infos, c, &reply);
634 r = set_put(replies, reply);
636 sd_bus_message_unref(reply);
641 *_machines = machines;
646 *_unit_infos = unit_infos;
655 static int list_units(sd_bus *bus, char **args) {
656 _cleanup_free_ UnitInfo *unit_infos = NULL;
657 _cleanup_(message_set_freep) Set *replies = NULL;
658 _cleanup_strv_free_ char **machines = NULL;
661 pager_open_if_enabled();
663 r = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
667 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
668 return output_units_list(unit_infos, r);
671 static int get_triggered_units(
676 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
679 r = sd_bus_get_property_strv(
681 "org.freedesktop.systemd1",
683 "org.freedesktop.systemd1.Unit",
689 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
694 static int get_listening(
696 const char* unit_path,
699 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
700 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
701 const char *type, *path;
704 r = sd_bus_get_property(
706 "org.freedesktop.systemd1",
708 "org.freedesktop.systemd1.Socket",
714 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
718 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
720 return bus_log_parse_error(r);
722 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
724 r = strv_extend(listening, type);
728 r = strv_extend(listening, path);
735 return bus_log_parse_error(r);
737 r = sd_bus_message_exit_container(reply);
739 return bus_log_parse_error(r);
751 /* Note: triggered is a list here, although it almost certainly
752 * will always be one unit. Nevertheless, dbus API allows for multiple
753 * values, so let's follow that. */
756 /* The strv above is shared. free is set only in the first one. */
760 static int socket_info_compare(const struct socket_info *a, const struct socket_info *b) {
766 if (!a->machine && b->machine)
768 if (a->machine && !b->machine)
770 if (a->machine && b->machine) {
771 o = strcasecmp(a->machine, b->machine);
776 o = strcmp(a->path, b->path);
778 o = strcmp(a->type, b->type);
783 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
784 struct socket_info *s;
785 unsigned pathlen = strlen("LISTEN"),
786 typelen = strlen("TYPE") * arg_show_types,
787 socklen = strlen("UNIT"),
788 servlen = strlen("ACTIVATES");
789 const char *on, *off;
791 for (s = socket_infos; s < socket_infos + cs; s++) {
795 socklen = MAX(socklen, strlen(s->id));
797 typelen = MAX(typelen, strlen(s->type));
798 pathlen = MAX(pathlen, strlen(s->path) + (s->machine ? strlen(s->machine)+1 : 0));
800 STRV_FOREACH(a, s->triggered)
801 tmp += strlen(*a) + 2*(a != s->triggered);
802 servlen = MAX(servlen, tmp);
807 printf("%-*s %-*.*s%-*s %s\n",
809 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
813 for (s = socket_infos; s < socket_infos + cs; s++) {
814 _cleanup_free_ char *j = NULL;
819 j = strjoin(s->machine, ":", s->path, NULL);
827 printf("%-*s %-*s %-*s",
828 pathlen, path, typelen, s->type, socklen, s->id);
831 pathlen, path, socklen, s->id);
832 STRV_FOREACH(a, s->triggered)
834 a == s->triggered ? "" : ",", *a);
838 on = ansi_highlight();
839 off = ansi_highlight_off();
843 on = ansi_highlight_red();
844 off = ansi_highlight_off();
847 if (!arg_no_legend) {
848 printf("%s%u sockets listed.%s\n", on, cs, off);
850 printf("Pass --all to see loaded but inactive sockets, too.\n");
856 static int list_sockets(sd_bus *bus, char **args) {
857 _cleanup_(message_set_freep) Set *replies = NULL;
858 _cleanup_strv_free_ char **machines = NULL;
859 _cleanup_free_ UnitInfo *unit_infos = NULL;
860 _cleanup_free_ struct socket_info *socket_infos = NULL;
862 struct socket_info *s;
867 pager_open_if_enabled();
869 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
873 for (u = unit_infos; u < unit_infos + n; u++) {
874 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
877 if (!endswith(u->id, ".socket"))
880 r = get_triggered_units(bus, u->unit_path, &triggered);
884 c = get_listening(bus, u->unit_path, &listening);
890 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
895 for (i = 0; i < c; i++)
896 socket_infos[cs + i] = (struct socket_info) {
897 .machine = u->machine,
899 .type = listening[i*2],
900 .path = listening[i*2 + 1],
901 .triggered = triggered,
902 .own_triggered = i==0,
905 /* from this point on we will cleanup those socket_infos */
908 listening = triggered = NULL; /* avoid cleanup */
911 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
912 (__compar_fn_t) socket_info_compare);
914 output_sockets_list(socket_infos, cs);
917 assert(cs == 0 || socket_infos);
918 for (s = socket_infos; s < socket_infos + cs; s++) {
921 if (s->own_triggered)
922 strv_free(s->triggered);
928 static int get_next_elapse(
931 dual_timestamp *next) {
933 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
941 r = sd_bus_get_property_trivial(
943 "org.freedesktop.systemd1",
945 "org.freedesktop.systemd1.Timer",
946 "NextElapseUSecMonotonic",
951 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
955 r = sd_bus_get_property_trivial(
957 "org.freedesktop.systemd1",
959 "org.freedesktop.systemd1.Timer",
960 "NextElapseUSecRealtime",
965 log_error("Failed to get next elapsation time: %s", bus_error_message(&error, r));
973 static int get_last_trigger(
978 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
985 r = sd_bus_get_property_trivial(
987 "org.freedesktop.systemd1",
989 "org.freedesktop.systemd1.Timer",
995 log_error("Failed to get last trigger time: %s", bus_error_message(&error, r));
1003 const char* machine;
1006 usec_t last_trigger;
1010 static int timer_info_compare(const struct timer_info *a, const struct timer_info *b) {
1016 if (!a->machine && b->machine)
1018 if (a->machine && !b->machine)
1020 if (a->machine && b->machine) {
1021 o = strcasecmp(a->machine, b->machine);
1026 if (a->next_elapse < b->next_elapse)
1028 if (a->next_elapse > b->next_elapse)
1031 return strcmp(a->id, b->id);
1034 static int output_timers_list(struct timer_info *timer_infos, unsigned n) {
1035 struct timer_info *t;
1037 nextlen = strlen("NEXT"),
1038 leftlen = strlen("LEFT"),
1039 lastlen = strlen("LAST"),
1040 passedlen = strlen("PASSED"),
1041 unitlen = strlen("UNIT"),
1042 activatelen = strlen("ACTIVATES");
1044 const char *on, *off;
1046 assert(timer_infos || n == 0);
1048 for (t = timer_infos; t < timer_infos + n; t++) {
1052 if (t->next_elapse > 0) {
1053 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1055 format_timestamp(tstamp, sizeof(tstamp), t->next_elapse);
1056 nextlen = MAX(nextlen, strlen(tstamp) + 1);
1058 format_timestamp_relative(trel, sizeof(trel), t->next_elapse);
1059 leftlen = MAX(leftlen, strlen(trel));
1062 if (t->last_trigger > 0) {
1063 char tstamp[FORMAT_TIMESTAMP_MAX] = "", trel[FORMAT_TIMESTAMP_RELATIVE_MAX] = "";
1065 format_timestamp(tstamp, sizeof(tstamp), t->last_trigger);
1066 lastlen = MAX(lastlen, strlen(tstamp) + 1);
1068 format_timestamp_relative(trel, sizeof(trel), t->last_trigger);
1069 passedlen = MAX(passedlen, strlen(trel));
1072 unitlen = MAX(unitlen, strlen(t->id) + (t->machine ? strlen(t->machine)+1 : 0));
1074 STRV_FOREACH(a, t->triggered)
1075 ul += strlen(*a) + 2*(a != t->triggered);
1077 activatelen = MAX(activatelen, ul);
1082 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1086 passedlen, "PASSED",
1090 for (t = timer_infos; t < timer_infos + n; t++) {
1091 _cleanup_free_ char *j = NULL;
1093 char tstamp1[FORMAT_TIMESTAMP_MAX] = "n/a", trel1[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1094 char tstamp2[FORMAT_TIMESTAMP_MAX] = "n/a", trel2[FORMAT_TIMESTAMP_RELATIVE_MAX] = "n/a";
1097 format_timestamp(tstamp1, sizeof(tstamp1), t->next_elapse);
1098 format_timestamp_relative(trel1, sizeof(trel1), t->next_elapse);
1100 format_timestamp(tstamp2, sizeof(tstamp2), t->last_trigger);
1101 format_timestamp_relative(trel2, sizeof(trel2), t->last_trigger);
1104 j = strjoin(t->machine, ":", t->id, NULL);
1111 printf("%-*s %-*s %-*s %-*s %-*s",
1112 nextlen, tstamp1, leftlen, trel1, lastlen, tstamp2, passedlen, trel2, unitlen, unit);
1114 STRV_FOREACH(a, t->triggered)
1116 a == t->triggered ? "" : ",", *a);
1120 on = ansi_highlight();
1121 off = ansi_highlight_off();
1125 on = ansi_highlight_red();
1126 off = ansi_highlight_off();
1129 if (!arg_no_legend) {
1130 printf("%s%u timers listed.%s\n", on, n, off);
1132 printf("Pass --all to see loaded but inactive timers, too.\n");
1138 static usec_t calc_next_elapse(dual_timestamp *nw, dual_timestamp *next) {
1144 if (next->monotonic != USEC_INFINITY && next->monotonic > 0) {
1147 if (next->monotonic > nw->monotonic)
1148 converted = nw->realtime + (next->monotonic - nw->monotonic);
1150 converted = nw->realtime - (nw->monotonic - next->monotonic);
1152 if (next->realtime != USEC_INFINITY && next->realtime > 0)
1153 next_elapse = MIN(converted, next->realtime);
1155 next_elapse = converted;
1158 next_elapse = next->realtime;
1163 static int list_timers(sd_bus *bus, char **args) {
1164 _cleanup_(message_set_freep) Set *replies = NULL;
1165 _cleanup_strv_free_ char **machines = NULL;
1166 _cleanup_free_ struct timer_info *timer_infos = NULL;
1167 _cleanup_free_ UnitInfo *unit_infos = NULL;
1168 struct timer_info *t;
1175 pager_open_if_enabled();
1177 n = get_unit_list_recursive(bus, strv_skip_first(args), &unit_infos, &replies, &machines);
1181 dual_timestamp_get(&nw);
1183 for (u = unit_infos; u < unit_infos + n; u++) {
1184 _cleanup_strv_free_ char **triggered = NULL;
1185 dual_timestamp next = {};
1188 if (!endswith(u->id, ".timer"))
1191 r = get_triggered_units(bus, u->unit_path, &triggered);
1195 r = get_next_elapse(bus, u->unit_path, &next);
1199 get_last_trigger(bus, u->unit_path, &last);
1201 if (!GREEDY_REALLOC(timer_infos, size, c+1)) {
1206 m = calc_next_elapse(&nw, &next);
1208 timer_infos[c++] = (struct timer_info) {
1209 .machine = u->machine,
1212 .last_trigger = last,
1213 .triggered = triggered,
1216 triggered = NULL; /* avoid cleanup */
1219 qsort_safe(timer_infos, c, sizeof(struct timer_info),
1220 (__compar_fn_t) timer_info_compare);
1222 output_timers_list(timer_infos, c);
1225 for (t = timer_infos; t < timer_infos + c; t++)
1226 strv_free(t->triggered);
1231 static int compare_unit_file_list(const void *a, const void *b) {
1232 const char *d1, *d2;
1233 const UnitFileList *u = a, *v = b;
1235 d1 = strrchr(u->path, '.');
1236 d2 = strrchr(v->path, '.');
1241 r = strcasecmp(d1, d2);
1246 return strcasecmp(basename(u->path), basename(v->path));
1249 static bool output_show_unit_file(const UnitFileList *u, char **patterns) {
1250 if (!strv_fnmatch_or_empty(basename(u->path), patterns, FNM_NOESCAPE))
1253 if (!strv_isempty(arg_types)) {
1256 dot = strrchr(u->path, '.');
1260 if (!strv_find(arg_types, dot+1))
1264 if (!strv_isempty(arg_states) &&
1265 !strv_find(arg_states, unit_file_state_to_string(u->state)))
1271 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
1272 unsigned max_id_len, id_cols, state_cols;
1273 const UnitFileList *u;
1275 max_id_len = strlen("UNIT FILE");
1276 state_cols = strlen("STATE");
1278 for (u = units; u < units + c; u++) {
1279 max_id_len = MAX(max_id_len, strlen(basename(u->path)));
1280 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
1284 unsigned basic_cols;
1286 id_cols = MIN(max_id_len, 25u);
1287 basic_cols = 1 + id_cols + state_cols;
1288 if (basic_cols < (unsigned) columns())
1289 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
1291 id_cols = max_id_len;
1294 printf("%-*s %-*s\n",
1295 id_cols, "UNIT FILE",
1296 state_cols, "STATE");
1298 for (u = units; u < units + c; u++) {
1299 _cleanup_free_ char *e = NULL;
1300 const char *on, *off;
1303 if (u->state == UNIT_FILE_MASKED ||
1304 u->state == UNIT_FILE_MASKED_RUNTIME ||
1305 u->state == UNIT_FILE_DISABLED ||
1306 u->state == UNIT_FILE_INVALID) {
1307 on = ansi_highlight_red();
1308 off = ansi_highlight_off();
1309 } else if (u->state == UNIT_FILE_ENABLED) {
1310 on = ansi_highlight_green();
1311 off = ansi_highlight_off();
1315 id = basename(u->path);
1317 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
1319 printf("%-*s %s%-*s%s\n",
1320 id_cols, e ? e : id,
1321 on, state_cols, unit_file_state_to_string(u->state), off);
1325 printf("\n%u unit files listed.\n", c);
1328 static int list_unit_files(sd_bus *bus, char **args) {
1329 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1330 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1331 _cleanup_free_ UnitFileList *units = NULL;
1339 pager_open_if_enabled();
1347 h = hashmap_new(&string_hash_ops);
1351 r = unit_file_get_list(arg_scope, arg_root, h);
1353 unit_file_list_free(h);
1354 log_error_errno(r, "Failed to get unit file list: %m");
1358 n_units = hashmap_size(h);
1360 units = new(UnitFileList, n_units);
1361 if (!units && n_units > 0) {
1362 unit_file_list_free(h);
1366 HASHMAP_FOREACH(u, h, i) {
1367 if (!output_show_unit_file(u, strv_skip_first(args)))
1374 assert(c <= n_units);
1377 r = sd_bus_call_method(
1379 "org.freedesktop.systemd1",
1380 "/org/freedesktop/systemd1",
1381 "org.freedesktop.systemd1.Manager",
1387 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
1391 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
1393 return bus_log_parse_error(r);
1395 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
1397 if (!GREEDY_REALLOC(units, size, c + 1))
1400 units[c] = (struct UnitFileList) {
1402 unit_file_state_from_string(state)
1405 if (output_show_unit_file(&units[c], strv_skip_first(args)))
1410 return bus_log_parse_error(r);
1412 r = sd_bus_message_exit_container(reply);
1414 return bus_log_parse_error(r);
1417 qsort_safe(units, c, sizeof(UnitFileList), compare_unit_file_list);
1418 output_unit_file_list(units, c);
1421 for (unit = units; unit < units + c; unit++)
1428 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
1429 _cleanup_free_ char *n = NULL;
1430 size_t max_len = MAX(columns(),20u);
1436 for (i = level - 1; i >= 0; i--) {
1438 if (len > max_len - 3 && !arg_full) {
1439 printf("%s...\n",max_len % 2 ? "" : " ");
1442 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERTICAL : DRAW_TREE_SPACE));
1446 if (len > max_len - 3 && !arg_full) {
1447 printf("%s...\n",max_len % 2 ? "" : " ");
1451 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
1455 printf("%s\n", name);
1459 n = ellipsize(name, max_len-len, 100);
1467 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
1469 static const char *dependencies[_DEPENDENCY_MAX] = {
1470 [DEPENDENCY_FORWARD] = "Requires\0"
1471 "RequiresOverridable\0"
1473 "RequisiteOverridable\0"
1476 [DEPENDENCY_REVERSE] = "RequiredBy\0"
1477 "RequiredByOverridable\0"
1481 [DEPENDENCY_AFTER] = "After\0",
1482 [DEPENDENCY_BEFORE] = "Before\0",
1485 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1486 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1487 _cleanup_strv_free_ char **ret = NULL;
1488 _cleanup_free_ char *path = NULL;
1494 assert_cc(ELEMENTSOF(dependencies) == _DEPENDENCY_MAX);
1496 path = unit_dbus_path_from_name(name);
1500 r = sd_bus_call_method(
1502 "org.freedesktop.systemd1",
1504 "org.freedesktop.DBus.Properties",
1508 "s", "org.freedesktop.systemd1.Unit");
1510 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1514 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1516 return bus_log_parse_error(r);
1518 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1521 r = sd_bus_message_read(reply, "s", &prop);
1523 return bus_log_parse_error(r);
1525 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1526 r = sd_bus_message_skip(reply, "v");
1528 return bus_log_parse_error(r);
1531 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1533 return bus_log_parse_error(r);
1535 r = bus_message_read_strv_extend(reply, &ret);
1537 return bus_log_parse_error(r);
1539 r = sd_bus_message_exit_container(reply);
1541 return bus_log_parse_error(r);
1544 r = sd_bus_message_exit_container(reply);
1546 return bus_log_parse_error(r);
1550 return bus_log_parse_error(r);
1552 r = sd_bus_message_exit_container(reply);
1554 return bus_log_parse_error(r);
1562 static int list_dependencies_compare(const void *_a, const void *_b) {
1563 const char **a = (const char**) _a, **b = (const char**) _b;
1565 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1567 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1570 return strcasecmp(*a, *b);
1573 static int list_dependencies_one(
1578 unsigned int branches) {
1580 _cleanup_strv_free_ char **deps = NULL;
1588 r = strv_extend(units, name);
1592 r = list_dependencies_get_dependencies(bus, name, &deps);
1596 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1598 STRV_FOREACH(c, deps) {
1599 if (strv_contains(*units, *c)) {
1601 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1614 state = check_one_unit(bus, *c, "activating\0active\0reloading\0", true);
1615 on = state > 0 ? ansi_highlight_green() : ansi_highlight_red();
1616 printf("%s%s%s ", on, draw_special_char(DRAW_BLACK_CIRCLE), ansi_highlight_off());
1619 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1623 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1624 r = list_dependencies_one(bus, *c, level + 1, units, (branches << 1) | (c[1] == NULL ? 0 : 1));
1631 strv_remove(*units, name);
1636 static int list_dependencies(sd_bus *bus, char **args) {
1637 _cleanup_strv_free_ char **units = NULL;
1638 _cleanup_free_ char *unit = NULL;
1644 unit = unit_name_mangle(args[1], MANGLE_NOGLOB);
1649 u = SPECIAL_DEFAULT_TARGET;
1651 pager_open_if_enabled();
1655 return list_dependencies_one(bus, u, 0, &units, 0);
1658 struct machine_info {
1662 char *control_group;
1663 uint32_t n_failed_units;
1668 static const struct bus_properties_map machine_info_property_map[] = {
1669 { "SystemState", "s", NULL, offsetof(struct machine_info, state) },
1670 { "NJobs", "u", NULL, offsetof(struct machine_info, n_jobs) },
1671 { "NFailedUnits", "u", NULL, offsetof(struct machine_info, n_failed_units) },
1672 { "ControlGroup", "s", NULL, offsetof(struct machine_info, control_group) },
1673 { "UserspaceTimestamp", "t", NULL, offsetof(struct machine_info, timestamp) },
1677 static void free_machines_list(struct machine_info *machine_infos, int n) {
1683 for (i = 0; i < n; i++) {
1684 free(machine_infos[i].name);
1685 free(machine_infos[i].state);
1686 free(machine_infos[i].control_group);
1689 free(machine_infos);
1692 static int compare_machine_info(const void *a, const void *b) {
1693 const struct machine_info *u = a, *v = b;
1695 if (u->is_host != v->is_host)
1696 return u->is_host > v->is_host ? -1 : 1;
1698 return strcasecmp(u->name, v->name);
1701 static int get_machine_properties(sd_bus *bus, struct machine_info *mi) {
1702 _cleanup_bus_close_unref_ sd_bus *container = NULL;
1708 r = sd_bus_open_system_machine(&container, mi->name);
1715 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, mi);
1722 static bool output_show_machine(const char *name, char **patterns) {
1723 return strv_fnmatch_or_empty(name, patterns, FNM_NOESCAPE);
1726 static int get_machine_list(
1728 struct machine_info **_machine_infos,
1731 struct machine_info *machine_infos = NULL;
1732 _cleanup_strv_free_ char **m = NULL;
1733 _cleanup_free_ char *hn = NULL;
1738 hn = gethostname_malloc();
1742 if (output_show_machine(hn, patterns)) {
1743 if (!GREEDY_REALLOC0(machine_infos, sz, c+1))
1746 machine_infos[c].is_host = true;
1747 machine_infos[c].name = hn;
1750 get_machine_properties(bus, &machine_infos[c]);
1754 sd_get_machine_names(&m);
1755 STRV_FOREACH(i, m) {
1756 _cleanup_free_ char *class = NULL;
1758 if (!output_show_machine(*i, patterns))
1761 sd_machine_get_class(*i, &class);
1762 if (!streq_ptr(class, "container"))
1765 if (!GREEDY_REALLOC0(machine_infos, sz, c+1)) {
1766 free_machines_list(machine_infos, c);
1770 machine_infos[c].is_host = false;
1771 machine_infos[c].name = strdup(*i);
1772 if (!machine_infos[c].name) {
1773 free_machines_list(machine_infos, c);
1777 get_machine_properties(NULL, &machine_infos[c]);
1781 *_machine_infos = machine_infos;
1785 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
1786 struct machine_info *m;
1789 namelen = sizeof("NAME") - 1,
1790 statelen = sizeof("STATE") - 1,
1791 failedlen = sizeof("FAILED") - 1,
1792 jobslen = sizeof("JOBS") - 1;
1794 assert(machine_infos || n == 0);
1796 for (m = machine_infos; m < machine_infos + n; m++) {
1797 namelen = MAX(namelen, strlen(m->name) + (m->is_host ? sizeof(" (host)") - 1 : 0));
1798 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
1799 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
1800 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
1802 if (!arg_plain && !streq_ptr(m->state, "running"))
1806 if (!arg_no_legend) {
1810 printf("%-*s %-*s %-*s %-*s\n",
1813 failedlen, "FAILED",
1817 for (m = machine_infos; m < machine_infos + n; m++) {
1818 const char *on_state = "", *off_state = "";
1819 const char *on_failed = "", *off_failed = "";
1820 bool circle = false;
1822 if (streq_ptr(m->state, "degraded")) {
1823 on_state = ansi_highlight_red();
1824 off_state = ansi_highlight_off();
1826 } else if (!streq_ptr(m->state, "running")) {
1827 on_state = ansi_highlight_yellow();
1828 off_state = ansi_highlight_off();
1832 if (m->n_failed_units > 0) {
1833 on_failed = ansi_highlight_red();
1834 off_failed = ansi_highlight_off();
1836 on_failed = off_failed = "";
1839 printf("%s%s%s ", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : " ", off_state);
1842 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1843 (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),
1844 on_state, statelen, strna(m->state), off_state,
1845 on_failed, failedlen, m->n_failed_units, off_failed,
1846 jobslen, m->n_jobs);
1848 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1849 namelen, strna(m->name),
1850 on_state, statelen, strna(m->state), off_state,
1851 on_failed, failedlen, m->n_failed_units, off_failed,
1852 jobslen, m->n_jobs);
1856 printf("\n%u machines listed.\n", n);
1859 static int list_machines(sd_bus *bus, char **args) {
1860 struct machine_info *machine_infos = NULL;
1865 if (geteuid() != 0) {
1866 log_error("Must be root.");
1870 pager_open_if_enabled();
1872 r = get_machine_list(bus, &machine_infos, strv_skip_first(args));
1876 qsort_safe(machine_infos, r, sizeof(struct machine_info), compare_machine_info);
1877 output_machines_list(machine_infos, r);
1878 free_machines_list(machine_infos, r);
1883 static int get_default(sd_bus *bus, char **args) {
1884 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1885 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1886 _cleanup_free_ char *_path = NULL;
1890 if (!bus || avoid_bus()) {
1891 r = unit_file_get_default(arg_scope, arg_root, &_path);
1893 return log_error_errno(r, "Failed to get default target: %m");
1897 r = sd_bus_call_method(
1899 "org.freedesktop.systemd1",
1900 "/org/freedesktop/systemd1",
1901 "org.freedesktop.systemd1.Manager",
1907 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1911 r = sd_bus_message_read(reply, "s", &path);
1913 return bus_log_parse_error(r);
1917 printf("%s\n", path);
1922 static void dump_unit_file_changes(const UnitFileChange *changes, unsigned n_changes) {
1925 assert(changes || n_changes == 0);
1927 for (i = 0; i < n_changes; i++) {
1928 if (changes[i].type == UNIT_FILE_SYMLINK)
1929 log_info("Created symlink from %s to %s.", changes[i].path, changes[i].source);
1931 log_info("Removed symlink %s.", changes[i].path);
1935 static int set_default(sd_bus *bus, char **args) {
1936 _cleanup_free_ char *unit = NULL;
1937 UnitFileChange *changes = NULL;
1938 unsigned n_changes = 0;
1941 unit = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
1945 if (!bus || avoid_bus()) {
1946 r = unit_file_set_default(arg_scope, arg_root, unit, true, &changes, &n_changes);
1948 return log_error_errno(r, "Failed to set default target: %m");
1951 dump_unit_file_changes(changes, n_changes);
1955 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
1956 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1958 r = sd_bus_message_new_method_call(
1961 "org.freedesktop.systemd1",
1962 "/org/freedesktop/systemd1",
1963 "org.freedesktop.systemd1.Manager",
1964 "SetDefaultTarget");
1966 return bus_log_create_error(r);
1968 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
1970 return bus_log_create_error(r);
1972 r = sd_bus_message_append(m, "sb", unit, 1);
1974 return bus_log_create_error(r);
1976 r = sd_bus_call(bus, m, 0, &error, &reply);
1978 log_error("Failed to set default target: %s", bus_error_message(&error, -r));
1982 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
1986 /* Try to reload if enabled */
1988 r = daemon_reload(bus, args);
1993 unit_file_changes_free(changes, n_changes);
2000 const char *name, *type, *state;
2003 static void output_jobs_list(const struct job_info* jobs, unsigned n, bool skipped) {
2004 unsigned id_len, unit_len, type_len, state_len;
2005 const struct job_info *j;
2006 const char *on, *off;
2007 bool shorten = false;
2009 assert(n == 0 || jobs);
2012 if (!arg_no_legend) {
2013 on = ansi_highlight_green();
2014 off = ansi_highlight_off();
2016 printf("%sNo jobs %s.%s\n", on, skipped ? "listed" : "running", off);
2021 pager_open_if_enabled();
2023 id_len = strlen("JOB");
2024 unit_len = strlen("UNIT");
2025 type_len = strlen("TYPE");
2026 state_len = strlen("STATE");
2028 for (j = jobs; j < jobs + n; j++) {
2029 uint32_t id = j->id;
2030 assert(j->name && j->type && j->state);
2032 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
2033 unit_len = MAX(unit_len, strlen(j->name));
2034 type_len = MAX(type_len, strlen(j->type));
2035 state_len = MAX(state_len, strlen(j->state));
2038 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
2039 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
2044 printf("%*s %-*s %-*s %-*s\n",
2048 state_len, "STATE");
2050 for (j = jobs; j < jobs + n; j++) {
2051 _cleanup_free_ char *e = NULL;
2053 if (streq(j->state, "running")) {
2054 on = ansi_highlight();
2055 off = ansi_highlight_off();
2059 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
2060 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2062 on, unit_len, e ? e : j->name, off,
2064 on, state_len, j->state, off);
2067 if (!arg_no_legend) {
2068 on = ansi_highlight();
2069 off = ansi_highlight_off();
2071 printf("\n%s%u jobs listed%s.\n", on, n, off);
2075 static bool output_show_job(struct job_info *job, char **patterns) {
2076 return strv_fnmatch_or_empty(job->name, patterns, FNM_NOESCAPE);
2079 static int list_jobs(sd_bus *bus, char **args) {
2080 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2081 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2082 const char *name, *type, *state, *job_path, *unit_path;
2083 _cleanup_free_ struct job_info *jobs = NULL;
2088 bool skipped = false;
2090 r = sd_bus_call_method(
2092 "org.freedesktop.systemd1",
2093 "/org/freedesktop/systemd1",
2094 "org.freedesktop.systemd1.Manager",
2100 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
2104 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
2106 return bus_log_parse_error(r);
2108 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
2109 struct job_info job = { id, name, type, state };
2111 if (!output_show_job(&job, strv_skip_first(args))) {
2116 if (!GREEDY_REALLOC(jobs, size, c + 1))
2122 return bus_log_parse_error(r);
2124 r = sd_bus_message_exit_container(reply);
2126 return bus_log_parse_error(r);
2128 output_jobs_list(jobs, c, skipped);
2132 static int cancel_job(sd_bus *bus, char **args) {
2133 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2139 if (strv_length(args) <= 1)
2140 return daemon_reload(bus, args);
2142 STRV_FOREACH(name, args+1) {
2143 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
2147 q = safe_atou32(*name, &id);
2149 return log_error_errno(q, "Failed to parse job id \"%s\": %m", *name);
2151 q = sd_bus_message_new_method_call(
2154 "org.freedesktop.systemd1",
2155 "/org/freedesktop/systemd1",
2156 "org.freedesktop.systemd1.Manager",
2159 return bus_log_create_error(q);
2161 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2163 return bus_log_create_error(1);
2165 q = sd_bus_message_append(m, "u", id);
2167 return bus_log_create_error(q);
2169 q = sd_bus_call(bus, m, 0, &error, NULL);
2171 log_error("Failed to cancel job %"PRIu32": %s", id, bus_error_message(&error, q));
2180 static int need_daemon_reload(sd_bus *bus, const char *unit) {
2181 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2185 /* We ignore all errors here, since this is used to show a
2188 /* We don't use unit_dbus_path_from_name() directly since we
2189 * don't want to load the unit if it isn't loaded. */
2191 r = sd_bus_call_method(
2193 "org.freedesktop.systemd1",
2194 "/org/freedesktop/systemd1",
2195 "org.freedesktop.systemd1.Manager",
2203 r = sd_bus_message_read(reply, "o", &path);
2207 r = sd_bus_get_property_trivial(
2209 "org.freedesktop.systemd1",
2211 "org.freedesktop.systemd1.Unit",
2221 static void warn_unit_file_changed(const char *name) {
2222 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2223 ansi_highlight_red(),
2224 ansi_highlight_off(),
2226 arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
2229 static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **unit_path) {
2236 STRV_FOREACH(p, lp->unit_path) {
2237 _cleanup_free_ char *path;
2239 path = path_join(arg_root, *p, unit_name);
2243 if (access(path, F_OK) == 0) {
2253 static int unit_find_paths(sd_bus *bus,
2254 const char *unit_name,
2255 bool avoid_bus_cache,
2257 char **fragment_path,
2258 char ***dropin_paths) {
2260 _cleanup_free_ char *path = NULL;
2261 _cleanup_strv_free_ char **dropins = NULL;
2265 * Finds where the unit is defined on disk. Returns 0 if the unit
2266 * is not found. Returns 1 if it is found, and sets
2267 * - the path to the unit in *path, if it exists on disk,
2268 * - and a strv of existing drop-ins in *dropins,
2269 * if the arg is not NULL and any dropins were found.
2273 assert(fragment_path);
2276 if (!avoid_bus_cache && !unit_name_is_template(unit_name)) {
2277 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2278 _cleanup_bus_message_unref_ sd_bus_message *unit_load_error = NULL;
2279 _cleanup_free_ char *unit = NULL;
2280 char *unit_load_error_name, *unit_load_error_message;
2282 unit = unit_dbus_path_from_name(unit_name);
2286 if (need_daemon_reload(bus, unit_name) > 0)
2287 warn_unit_file_changed(unit_name);
2289 r = sd_bus_get_property(
2291 "org.freedesktop.systemd1",
2293 "org.freedesktop.systemd1.Unit",
2299 return log_error_errno(r, "Failed to get LoadError: %s", bus_error_message(&error, r));
2301 r = sd_bus_message_read(
2304 &unit_load_error_name,
2305 &unit_load_error_message);
2307 return bus_log_parse_error(r);
2309 if (!isempty(unit_load_error_name)) {
2310 log_error("Unit %s is not loaded: %s", unit_name, unit_load_error_message);
2314 r = sd_bus_get_property_string(
2316 "org.freedesktop.systemd1",
2318 "org.freedesktop.systemd1.Unit",
2323 return log_error_errno(r, "Failed to get FragmentPath: %s", bus_error_message(&error, r));
2326 r = sd_bus_get_property_strv(
2328 "org.freedesktop.systemd1",
2330 "org.freedesktop.systemd1.Unit",
2335 return log_error_errno(r, "Failed to get DropInPaths: %s", bus_error_message(&error, r));
2338 _cleanup_set_free_ Set *names;
2340 names = set_new(NULL);
2344 r = set_put(names, unit_name);
2348 r = unit_file_find_path(lp, unit_name, &path);
2353 _cleanup_free_ char *template;
2355 template = unit_name_template(unit_name);
2359 if (!streq(template, unit_name)) {
2360 r = unit_file_find_path(lp, template, &path);
2367 r = unit_file_find_dropin_paths(lp->unit_path, NULL, names, &dropins);
2375 if (!isempty(path)) {
2376 *fragment_path = path;
2381 if (dropin_paths && !strv_isempty(dropins)) {
2382 *dropin_paths = dropins;
2388 log_error("No files found for %s.", unit_name);
2393 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
2394 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2395 _cleanup_free_ char *n = NULL, *state = NULL;
2401 n = unit_name_mangle(name, MANGLE_NOGLOB);
2405 /* We don't use unit_dbus_path_from_name() directly since we
2406 * don't want to load the unit if it isn't loaded. */
2408 r = sd_bus_call_method(
2410 "org.freedesktop.systemd1",
2411 "/org/freedesktop/systemd1",
2412 "org.freedesktop.systemd1.Manager",
2423 r = sd_bus_message_read(reply, "o", &path);
2425 return bus_log_parse_error(r);
2427 r = sd_bus_get_property_string(
2429 "org.freedesktop.systemd1",
2431 "org.freedesktop.systemd1.Unit",
2444 return nulstr_contains(good_states, state);
2447 static int check_triggering_units(
2451 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2452 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
2453 _cleanup_strv_free_ char **triggered_by = NULL;
2454 bool print_warning_label = true;
2458 n = unit_name_mangle(name, MANGLE_NOGLOB);
2462 path = unit_dbus_path_from_name(n);
2466 r = sd_bus_get_property_string(
2468 "org.freedesktop.systemd1",
2470 "org.freedesktop.systemd1.Unit",
2475 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
2479 if (streq(state, "masked"))
2482 r = sd_bus_get_property_strv(
2484 "org.freedesktop.systemd1",
2486 "org.freedesktop.systemd1.Unit",
2491 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
2495 STRV_FOREACH(i, triggered_by) {
2496 r = check_one_unit(bus, *i, "active\0reloading\0", true);
2498 return log_error_errno(r, "Failed to check unit: %m");
2503 if (print_warning_label) {
2504 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
2505 print_warning_label = false;
2508 log_warning(" %s", *i);
2514 static const struct {
2517 } unit_actions[] = {
2518 { "start", "StartUnit" },
2519 { "stop", "StopUnit" },
2520 { "condstop", "StopUnit" },
2521 { "reload", "ReloadUnit" },
2522 { "restart", "RestartUnit" },
2523 { "try-restart", "TryRestartUnit" },
2524 { "condrestart", "TryRestartUnit" },
2525 { "reload-or-restart", "ReloadOrRestartUnit" },
2526 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2527 { "condreload", "ReloadOrTryRestartUnit" },
2528 { "force-reload", "ReloadOrTryRestartUnit" }
2531 static const char *verb_to_method(const char *verb) {
2534 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2535 if (streq_ptr(unit_actions[i].verb, verb))
2536 return unit_actions[i].method;
2541 static const char *method_to_verb(const char *method) {
2544 for (i = 0; i < ELEMENTSOF(unit_actions); i++)
2545 if (streq_ptr(unit_actions[i].method, method))
2546 return unit_actions[i].verb;
2551 static int start_unit_one(
2556 sd_bus_error *error,
2557 BusWaitForJobs *w) {
2559 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
2568 log_debug("Calling manager for %s on %s, %s", method, name, mode);
2570 r = sd_bus_message_new_method_call(
2573 "org.freedesktop.systemd1",
2574 "/org/freedesktop/systemd1",
2575 "org.freedesktop.systemd1.Manager",
2578 return bus_log_create_error(r);
2580 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
2582 return bus_log_create_error(r);
2584 r = sd_bus_message_append(m, "ss", name, mode);
2586 return bus_log_create_error(r);
2588 r = sd_bus_call(bus, m, 0, error, &reply);
2592 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
2593 /* There's always a fallback possible for
2594 * legacy actions. */
2595 return -EADDRNOTAVAIL;
2597 verb = method_to_verb(method);
2599 log_error("Failed to %s %s: %s", verb, name, bus_error_message(error, r));
2603 r = sd_bus_message_read(reply, "o", &path);
2605 return bus_log_parse_error(r);
2607 if (need_daemon_reload(bus, name) > 0)
2608 warn_unit_file_changed(name);
2611 log_debug("Adding %s to the set", path);
2612 r = bus_wait_for_jobs_add(w, path);
2620 static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***ret) {
2622 _cleanup_strv_free_ char **mangled = NULL, **globs = NULL;
2626 STRV_FOREACH(name, names) {
2630 t = unit_name_mangle_with_suffix(*name, MANGLE_GLOB, suffix);
2632 t = unit_name_mangle(*name, MANGLE_GLOB);
2636 if (string_is_glob(t))
2637 r = strv_consume(&globs, t);
2639 r = strv_consume(&mangled, t);
2644 /* Query the manager only if any of the names are a glob, since
2645 * this is fairly expensive */
2646 if (!strv_isempty(globs)) {
2647 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2648 _cleanup_free_ UnitInfo *unit_infos = NULL;
2651 return log_error_errno(ENOTSUP, "Unit name globbing without bus is not implemented.");
2653 r = get_unit_list(bus, NULL, globs, &unit_infos, 0, &reply);
2657 for (i = 0; i < r; i++)
2658 if (strv_extend(&mangled, unit_infos[i].id) < 0)
2663 mangled = NULL; /* do not free */
2668 static const struct {
2672 } action_table[_ACTION_MAX] = {
2673 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
2674 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
2675 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
2676 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
2677 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
2678 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
2679 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
2680 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
2681 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
2682 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
2683 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
2684 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
2685 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
2686 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
2687 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
2690 static enum action verb_to_action(const char *verb) {
2693 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
2694 if (streq_ptr(action_table[i].verb, verb))
2697 return _ACTION_INVALID;
2700 static int start_unit(sd_bus *bus, char **args) {
2701 _cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
2702 const char *method, *mode, *one_name, *suffix = NULL;
2703 _cleanup_strv_free_ char **names = NULL;
2709 ask_password_agent_open_if_enabled();
2710 polkit_agent_open_if_enabled();
2712 if (arg_action == ACTION_SYSTEMCTL) {
2714 method = verb_to_method(args[0]);
2715 action = verb_to_action(args[0]);
2717 if (streq(args[0], "isolate")) {
2721 mode = action_table[action].mode ?: arg_job_mode;
2723 one_name = action_table[action].target;
2725 assert(arg_action < ELEMENTSOF(action_table));
2726 assert(action_table[arg_action].target);
2728 method = "StartUnit";
2730 mode = action_table[arg_action].mode;
2731 one_name = action_table[arg_action].target;
2735 names = strv_new(one_name, NULL);
2737 r = expand_names(bus, args + 1, suffix, &names);
2739 log_error_errno(r, "Failed to expand names: %m");
2742 if (!arg_no_block) {
2743 r = bus_wait_for_jobs_new(bus, &w);
2745 return log_error_errno(r, "Could not watch jobs: %m");
2748 STRV_FOREACH(name, names) {
2749 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2752 q = start_unit_one(bus, method, *name, mode, &error, w);
2753 if (r >= 0 && q < 0)
2754 r = translate_bus_error_to_exit_status(q, &error);
2757 if (!arg_no_block) {
2760 q = bus_wait_for_jobs(w, arg_quiet);
2764 /* When stopping units, warn if they can still be triggered by
2765 * another active unit (socket, path, timer) */
2766 if (!arg_quiet && streq(method, "StopUnit"))
2767 STRV_FOREACH(name, names)
2768 check_triggering_units(bus, *name);
2774 /* Ask systemd-logind, which might grant access to unprivileged users
2775 * through PolicyKit */
2776 static int reboot_with_logind(sd_bus *bus, enum action a) {
2778 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2785 polkit_agent_open_if_enabled();
2793 case ACTION_POWEROFF:
2794 method = "PowerOff";
2797 case ACTION_SUSPEND:
2801 case ACTION_HIBERNATE:
2802 method = "Hibernate";
2805 case ACTION_HYBRID_SLEEP:
2806 method = "HybridSleep";
2813 r = sd_bus_call_method(
2815 "org.freedesktop.login1",
2816 "/org/freedesktop/login1",
2817 "org.freedesktop.login1.Manager",
2821 "b", arg_ask_password);
2823 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
2831 static int check_inhibitors(sd_bus *bus, enum action a) {
2833 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
2834 _cleanup_strv_free_ char **sessions = NULL;
2835 const char *what, *who, *why, *mode;
2844 if (arg_ignore_inhibitors || arg_force > 0)
2856 r = sd_bus_call_method(
2858 "org.freedesktop.login1",
2859 "/org/freedesktop/login1",
2860 "org.freedesktop.login1.Manager",
2866 /* If logind is not around, then there are no inhibitors... */
2869 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
2871 return bus_log_parse_error(r);
2873 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
2874 _cleanup_free_ char *comm = NULL, *user = NULL;
2875 _cleanup_strv_free_ char **sv = NULL;
2877 if (!streq(mode, "block"))
2880 sv = strv_split(what, ":");
2884 if (!strv_contains(sv,
2886 a == ACTION_POWEROFF ||
2887 a == ACTION_REBOOT ||
2888 a == ACTION_KEXEC ? "shutdown" : "sleep"))
2891 get_process_comm(pid, &comm);
2892 user = uid_to_name(uid);
2894 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT" \"%s\", user %s), reason is \"%s\".",
2895 who, pid, strna(comm), strna(user), why);
2900 return bus_log_parse_error(r);
2902 r = sd_bus_message_exit_container(reply);
2904 return bus_log_parse_error(r);
2906 /* Check for current sessions */
2907 sd_get_sessions(&sessions);
2908 STRV_FOREACH(s, sessions) {
2909 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
2911 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
2914 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
2917 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
2920 sd_session_get_tty(*s, &tty);
2921 sd_session_get_seat(*s, &seat);
2922 sd_session_get_service(*s, &service);
2923 user = uid_to_name(uid);
2925 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2932 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2933 action_table[a].verb);
2941 static int start_special(sd_bus *bus, char **args) {
2947 a = verb_to_action(args[0]);
2949 r = check_inhibitors(bus, a);
2953 if (arg_force >= 2 && geteuid() != 0) {
2954 log_error("Must be root.");
2958 if (a == ACTION_REBOOT && args[1]) {
2959 r = update_reboot_param_file(args[1]);
2964 if (arg_force >= 2 &&
2965 (a == ACTION_HALT ||
2966 a == ACTION_POWEROFF ||
2967 a == ACTION_REBOOT))
2970 if (arg_force >= 1 &&
2971 (a == ACTION_HALT ||
2972 a == ACTION_POWEROFF ||
2973 a == ACTION_REBOOT ||
2974 a == ACTION_KEXEC ||
2976 return daemon_reload(bus, args);
2978 /* first try logind, to allow authentication with polkit */
2979 if (geteuid() != 0 &&
2980 (a == ACTION_POWEROFF ||
2981 a == ACTION_REBOOT ||
2982 a == ACTION_SUSPEND ||
2983 a == ACTION_HIBERNATE ||
2984 a == ACTION_HYBRID_SLEEP)) {
2985 r = reboot_with_logind(bus, a);
2986 if (r >= 0 || IN_SET(r, -ENOTSUP, -EINPROGRESS))
2990 r = start_unit(bus, args);
2991 if (r == EXIT_SUCCESS)
2997 static int check_unit_generic(sd_bus *bus, int code, const char *good_states, char **args) {
2998 _cleanup_strv_free_ char **names = NULL;
3005 r = expand_names(bus, args, NULL, &names);
3007 return log_error_errno(r, "Failed to expand names: %m");
3009 STRV_FOREACH(name, names) {
3012 state = check_one_unit(bus, *name, good_states, arg_quiet);
3022 static int check_unit_active(sd_bus *bus, char **args) {
3023 /* According to LSB: 3, "program is not running" */
3024 return check_unit_generic(bus, 3, "active\0reloading\0", args + 1);
3027 static int check_unit_failed(sd_bus *bus, char **args) {
3028 return check_unit_generic(bus, 1, "failed\0", args + 1);
3031 static int kill_unit(sd_bus *bus, char **args) {
3032 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3033 _cleanup_strv_free_ char **names = NULL;
3040 polkit_agent_open_if_enabled();
3043 arg_kill_who = "all";
3045 r = expand_names(bus, args + 1, NULL, &names);
3047 log_error_errno(r, "Failed to expand names: %m");
3049 STRV_FOREACH(name, names) {
3050 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3052 q = sd_bus_message_new_method_call(
3055 "org.freedesktop.systemd1",
3056 "/org/freedesktop/systemd1",
3057 "org.freedesktop.systemd1.Manager",
3060 return bus_log_create_error(q);
3062 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
3064 return bus_log_create_error(q);
3066 q = sd_bus_message_append(m, "ssi", *names, arg_kill_who, arg_signal);
3068 return bus_log_create_error(q);
3070 q = sd_bus_call(bus, m, 0, &error, NULL);
3072 log_error("Failed to kill unit %s: %s", *names, bus_error_message(&error, q));
3081 typedef struct ExecStatusInfo {
3089 usec_t start_timestamp;
3090 usec_t exit_timestamp;
3095 LIST_FIELDS(struct ExecStatusInfo, exec);
3098 static void exec_status_info_free(ExecStatusInfo *i) {
3107 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
3108 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
3111 int32_t code, status;
3117 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
3119 return bus_log_parse_error(r);
3123 r = sd_bus_message_read(m, "s", &path);
3125 return bus_log_parse_error(r);
3127 i->path = strdup(path);
3131 r = sd_bus_message_read_strv(m, &i->argv);
3133 return bus_log_parse_error(r);
3135 r = sd_bus_message_read(m,
3138 &start_timestamp, &start_timestamp_monotonic,
3139 &exit_timestamp, &exit_timestamp_monotonic,
3143 return bus_log_parse_error(r);
3146 i->start_timestamp = (usec_t) start_timestamp;
3147 i->exit_timestamp = (usec_t) exit_timestamp;
3148 i->pid = (pid_t) pid;
3152 r = sd_bus_message_exit_container(m);
3154 return bus_log_parse_error(r);
3159 typedef struct UnitStatusInfo {
3161 const char *load_state;
3162 const char *active_state;
3163 const char *sub_state;
3164 const char *unit_file_state;
3165 const char *unit_file_preset;
3167 const char *description;
3168 const char *following;
3170 char **documentation;
3172 const char *fragment_path;
3173 const char *source_path;
3174 const char *control_group;
3176 char **dropin_paths;
3178 const char *load_error;
3181 usec_t inactive_exit_timestamp;
3182 usec_t inactive_exit_timestamp_monotonic;
3183 usec_t active_enter_timestamp;
3184 usec_t active_exit_timestamp;
3185 usec_t inactive_enter_timestamp;
3187 bool need_daemon_reload;
3192 const char *status_text;
3193 const char *pid_file;
3197 usec_t start_timestamp;
3198 usec_t exit_timestamp;
3200 int exit_code, exit_status;
3202 usec_t condition_timestamp;
3203 bool condition_result;
3204 bool failed_condition_trigger;
3205 bool failed_condition_negate;
3206 const char *failed_condition;
3207 const char *failed_condition_parameter;
3209 usec_t assert_timestamp;
3211 bool failed_assert_trigger;
3212 bool failed_assert_negate;
3213 const char *failed_assert;
3214 const char *failed_assert_parameter;
3217 unsigned n_accepted;
3218 unsigned n_connections;
3221 /* Pairs of type, path */
3225 const char *sysfs_path;
3227 /* Mount, Automount */
3234 uint64_t memory_current;
3235 uint64_t memory_limit;
3237 LIST_HEAD(ExecStatusInfo, exec);
3240 static void print_status_info(
3245 const char *active_on, *active_off, *on, *off, *ss;
3247 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
3248 char since2[FORMAT_TIMESTAMP_MAX], *s2;
3254 /* This shows pretty information about a unit. See
3255 * print_property() for a low-level property printer */
3257 if (streq_ptr(i->active_state, "failed")) {
3258 active_on = ansi_highlight_red();
3259 active_off = ansi_highlight_off();
3260 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
3261 active_on = ansi_highlight_green();
3262 active_off = ansi_highlight_off();
3264 active_on = active_off = "";
3266 printf("%s%s%s %s", active_on, draw_special_char(DRAW_BLACK_CIRCLE), active_off, strna(i->id));
3268 if (i->description && !streq_ptr(i->id, i->description))
3269 printf(" - %s", i->description);
3274 printf(" Follow: unit currently follows state of %s\n", i->following);
3276 if (streq_ptr(i->load_state, "error")) {
3277 on = ansi_highlight_red();
3278 off = ansi_highlight_off();
3282 path = i->source_path ? i->source_path : i->fragment_path;
3285 printf(" Loaded: %s%s%s (Reason: %s)\n",
3286 on, strna(i->load_state), off, i->load_error);
3287 else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset))
3288 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3289 on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
3290 else if (path && !isempty(i->unit_file_state))
3291 printf(" Loaded: %s%s%s (%s; %s)\n",
3292 on, strna(i->load_state), off, path, i->unit_file_state);
3294 printf(" Loaded: %s%s%s (%s)\n",
3295 on, strna(i->load_state), off, path);
3297 printf(" Loaded: %s%s%s\n",
3298 on, strna(i->load_state), off);
3300 if (!strv_isempty(i->dropin_paths)) {
3301 _cleanup_free_ char *dir = NULL;
3305 STRV_FOREACH(dropin, i->dropin_paths) {
3306 if (! dir || last) {
3307 printf(dir ? " " : " Drop-In: ");
3312 if (path_get_parent(*dropin, &dir) < 0) {
3317 printf("%s\n %s", dir,
3318 draw_special_char(DRAW_TREE_RIGHT));
3321 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
3323 printf("%s%s", basename(*dropin), last ? "\n" : ", ");
3327 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
3329 printf(" Active: %s%s (%s)%s",
3330 active_on, strna(i->active_state), ss, active_off);
3332 printf(" Active: %s%s%s",
3333 active_on, strna(i->active_state), active_off);
3335 if (!isempty(i->result) && !streq(i->result, "success"))
3336 printf(" (Result: %s)", i->result);
3338 timestamp = (streq_ptr(i->active_state, "active") ||
3339 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
3340 (streq_ptr(i->active_state, "inactive") ||
3341 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
3342 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
3343 i->active_exit_timestamp;
3345 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
3346 s2 = format_timestamp(since2, sizeof(since2), timestamp);
3349 printf(" since %s; %s\n", s2, s1);
3351 printf(" since %s\n", s2);
3355 if (!i->condition_result && i->condition_timestamp > 0) {
3356 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
3357 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
3359 printf("Condition: start %scondition failed%s at %s%s%s\n",
3360 ansi_highlight_yellow(), ansi_highlight_off(),
3361 s2, s1 ? "; " : "", s1 ? s1 : "");
3362 if (i->failed_condition_trigger)
3363 printf(" none of the trigger conditions were met\n");
3364 else if (i->failed_condition)
3365 printf(" %s=%s%s was not met\n",
3366 i->failed_condition,
3367 i->failed_condition_negate ? "!" : "",
3368 i->failed_condition_parameter);
3371 if (!i->assert_result && i->assert_timestamp > 0) {
3372 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
3373 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
3375 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3376 ansi_highlight_red(), ansi_highlight_off(),
3377 s2, s1 ? "; " : "", s1 ? s1 : "");
3378 if (i->failed_assert_trigger)
3379 printf(" none of the trigger assertions were met\n");
3380 else if (i->failed_assert)
3381 printf(" %s=%s%s was not met\n",
3383 i->failed_assert_negate ? "!" : "",
3384 i->failed_assert_parameter);
3388 printf(" Device: %s\n", i->sysfs_path);
3390 printf(" Where: %s\n", i->where);
3392 printf(" What: %s\n", i->what);
3394 STRV_FOREACH(t, i->documentation)
3395 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
3397 STRV_FOREACH_PAIR(t, t2, i->listen)
3398 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
3401 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
3403 LIST_FOREACH(exec, p, i->exec) {
3404 _cleanup_free_ char *argv = NULL;
3407 /* Only show exited processes here */
3411 argv = strv_join(p->argv, " ");
3412 printf(" Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
3414 good = is_clean_exit_lsb(p->code, p->status, NULL);
3416 on = ansi_highlight_red();
3417 off = ansi_highlight_off();
3421 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
3423 if (p->code == CLD_EXITED) {
3426 printf("status=%i", p->status);
3428 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
3433 printf("signal=%s", signal_to_string(p->status));
3435 printf(")%s\n", off);
3437 if (i->main_pid == p->pid &&
3438 i->start_timestamp == p->start_timestamp &&
3439 i->exit_timestamp == p->start_timestamp)
3440 /* Let's not show this twice */
3443 if (p->pid == i->control_pid)
3447 if (i->main_pid > 0 || i->control_pid > 0) {
3448 if (i->main_pid > 0) {
3449 printf(" Main PID: "PID_FMT, i->main_pid);
3452 _cleanup_free_ char *comm = NULL;
3453 get_process_comm(i->main_pid, &comm);
3455 printf(" (%s)", comm);
3456 } else if (i->exit_code > 0) {
3457 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
3459 if (i->exit_code == CLD_EXITED) {
3462 printf("status=%i", i->exit_status);
3464 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
3469 printf("signal=%s", signal_to_string(i->exit_status));
3473 if (i->control_pid > 0)
3477 if (i->control_pid > 0) {
3478 _cleanup_free_ char *c = NULL;
3480 printf(" %8s: "PID_FMT, i->main_pid ? "" : " Control", i->control_pid);
3482 get_process_comm(i->control_pid, &c);
3491 printf(" Status: \"%s\"\n", i->status_text);
3492 if (i->status_errno > 0)
3493 printf(" Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
3495 if (i->memory_current != (uint64_t) -1) {
3496 char buf[FORMAT_BYTES_MAX];
3498 printf(" Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
3500 if (i->memory_limit != (uint64_t) -1)
3501 printf(" (limit: %s)\n", format_bytes(buf, sizeof(buf), i->memory_limit));
3506 if (i->control_group &&
3507 (i->main_pid > 0 || i->control_pid > 0 ||
3508 ((arg_transport != BUS_TRANSPORT_LOCAL && arg_transport != BUS_TRANSPORT_MACHINE) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0))) {
3511 printf(" CGroup: %s\n", i->control_group);
3513 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
3516 static const char prefix[] = " ";
3519 if (c > sizeof(prefix) - 1)
3520 c -= sizeof(prefix) - 1;
3524 if (i->main_pid > 0)
3525 extra[k++] = i->main_pid;
3527 if (i->control_pid > 0)
3528 extra[k++] = i->control_pid;
3530 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix, c, false, extra, k, get_output_flags());
3534 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
3535 show_journal_by_unit(
3540 i->inactive_exit_timestamp_monotonic,
3543 get_output_flags() | OUTPUT_BEGIN_NEWLINE,
3544 SD_JOURNAL_LOCAL_ONLY,
3545 arg_scope == UNIT_FILE_SYSTEM,
3549 if (i->need_daemon_reload)
3550 warn_unit_file_changed(i->id);
3553 static void show_unit_help(UnitStatusInfo *i) {
3558 if (!i->documentation) {
3559 log_info("Documentation for %s not known.", i->id);
3563 STRV_FOREACH(p, i->documentation)
3564 if (startswith(*p, "man:"))
3565 show_man_page(*p + 4, false);
3567 log_info("Can't show: %s", *p);
3570 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
3577 switch (contents[0]) {
3579 case SD_BUS_TYPE_STRING: {
3582 r = sd_bus_message_read(m, "s", &s);
3584 return bus_log_parse_error(r);
3587 if (streq(name, "Id"))
3589 else if (streq(name, "LoadState"))
3591 else if (streq(name, "ActiveState"))
3592 i->active_state = s;
3593 else if (streq(name, "SubState"))
3595 else if (streq(name, "Description"))
3597 else if (streq(name, "FragmentPath"))
3598 i->fragment_path = s;
3599 else if (streq(name, "SourcePath"))
3602 else if (streq(name, "DefaultControlGroup")) {
3604 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
3606 i->control_group = e;
3609 else if (streq(name, "ControlGroup"))
3610 i->control_group = s;
3611 else if (streq(name, "StatusText"))
3613 else if (streq(name, "PIDFile"))
3615 else if (streq(name, "SysFSPath"))
3617 else if (streq(name, "Where"))
3619 else if (streq(name, "What"))
3621 else if (streq(name, "Following"))
3623 else if (streq(name, "UnitFileState"))
3624 i->unit_file_state = s;
3625 else if (streq(name, "UnitFilePreset"))
3626 i->unit_file_preset = s;
3627 else if (streq(name, "Result"))
3634 case SD_BUS_TYPE_BOOLEAN: {
3637 r = sd_bus_message_read(m, "b", &b);
3639 return bus_log_parse_error(r);
3641 if (streq(name, "Accept"))
3643 else if (streq(name, "NeedDaemonReload"))
3644 i->need_daemon_reload = b;
3645 else if (streq(name, "ConditionResult"))
3646 i->condition_result = b;
3647 else if (streq(name, "AssertResult"))
3648 i->assert_result = b;
3653 case SD_BUS_TYPE_UINT32: {
3656 r = sd_bus_message_read(m, "u", &u);
3658 return bus_log_parse_error(r);
3660 if (streq(name, "MainPID")) {
3662 i->main_pid = (pid_t) u;
3665 } else if (streq(name, "ControlPID"))
3666 i->control_pid = (pid_t) u;
3667 else if (streq(name, "ExecMainPID")) {
3669 i->main_pid = (pid_t) u;
3670 } else if (streq(name, "NAccepted"))
3672 else if (streq(name, "NConnections"))
3673 i->n_connections = u;
3678 case SD_BUS_TYPE_INT32: {
3681 r = sd_bus_message_read(m, "i", &j);
3683 return bus_log_parse_error(r);
3685 if (streq(name, "ExecMainCode"))
3686 i->exit_code = (int) j;
3687 else if (streq(name, "ExecMainStatus"))
3688 i->exit_status = (int) j;
3689 else if (streq(name, "StatusErrno"))
3690 i->status_errno = (int) j;
3695 case SD_BUS_TYPE_UINT64: {
3698 r = sd_bus_message_read(m, "t", &u);
3700 return bus_log_parse_error(r);
3702 if (streq(name, "ExecMainStartTimestamp"))
3703 i->start_timestamp = (usec_t) u;
3704 else if (streq(name, "ExecMainExitTimestamp"))
3705 i->exit_timestamp = (usec_t) u;
3706 else if (streq(name, "ActiveEnterTimestamp"))
3707 i->active_enter_timestamp = (usec_t) u;
3708 else if (streq(name, "InactiveEnterTimestamp"))
3709 i->inactive_enter_timestamp = (usec_t) u;
3710 else if (streq(name, "InactiveExitTimestamp"))
3711 i->inactive_exit_timestamp = (usec_t) u;
3712 else if (streq(name, "InactiveExitTimestampMonotonic"))
3713 i->inactive_exit_timestamp_monotonic = (usec_t) u;
3714 else if (streq(name, "ActiveExitTimestamp"))
3715 i->active_exit_timestamp = (usec_t) u;
3716 else if (streq(name, "ConditionTimestamp"))
3717 i->condition_timestamp = (usec_t) u;
3718 else if (streq(name, "AssertTimestamp"))
3719 i->assert_timestamp = (usec_t) u;
3720 else if (streq(name, "MemoryCurrent"))
3721 i->memory_current = u;
3722 else if (streq(name, "MemoryLimit"))
3723 i->memory_limit = u;
3728 case SD_BUS_TYPE_ARRAY:
3730 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3731 _cleanup_free_ ExecStatusInfo *info = NULL;
3733 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3735 return bus_log_parse_error(r);
3737 info = new0(ExecStatusInfo, 1);
3741 while ((r = exec_status_info_deserialize(m, info)) > 0) {
3743 info->name = strdup(name);
3747 LIST_PREPEND(exec, i->exec, info);
3749 info = new0(ExecStatusInfo, 1);
3755 return bus_log_parse_error(r);
3757 r = sd_bus_message_exit_container(m);
3759 return bus_log_parse_error(r);
3763 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3764 const char *type, *path;
3766 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3768 return bus_log_parse_error(r);
3770 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
3772 r = strv_extend(&i->listen, type);
3776 r = strv_extend(&i->listen, path);
3781 return bus_log_parse_error(r);
3783 r = sd_bus_message_exit_container(m);
3785 return bus_log_parse_error(r);
3789 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
3791 r = sd_bus_message_read_strv(m, &i->dropin_paths);
3793 return bus_log_parse_error(r);
3795 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
3797 r = sd_bus_message_read_strv(m, &i->documentation);
3799 return bus_log_parse_error(r);
3801 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
3802 const char *cond, *param;
3803 int trigger, negate;
3806 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3808 return bus_log_parse_error(r);
3810 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3811 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3812 if (state < 0 && (!trigger || !i->failed_condition)) {
3813 i->failed_condition = cond;
3814 i->failed_condition_trigger = trigger;
3815 i->failed_condition_negate = negate;
3816 i->failed_condition_parameter = param;
3820 return bus_log_parse_error(r);
3822 r = sd_bus_message_exit_container(m);
3824 return bus_log_parse_error(r);
3826 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Asserts")) {
3827 const char *cond, *param;
3828 int trigger, negate;
3831 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
3833 return bus_log_parse_error(r);
3835 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
3836 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
3837 if (state < 0 && (!trigger || !i->failed_assert)) {
3838 i->failed_assert = cond;
3839 i->failed_assert_trigger = trigger;
3840 i->failed_assert_negate = negate;
3841 i->failed_assert_parameter = param;
3845 return bus_log_parse_error(r);
3847 r = sd_bus_message_exit_container(m);
3849 return bus_log_parse_error(r);
3856 case SD_BUS_TYPE_STRUCT_BEGIN:
3858 if (streq(name, "LoadError")) {
3859 const char *n, *message;
3861 r = sd_bus_message_read(m, "(ss)", &n, &message);
3863 return bus_log_parse_error(r);
3865 if (!isempty(message))
3866 i->load_error = message;
3879 r = sd_bus_message_skip(m, contents);
3881 return bus_log_parse_error(r);
3886 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
3892 /* This is a low-level property printer, see
3893 * print_status_info() for the nicer output */
3895 if (arg_properties && !strv_find(arg_properties, name)) {
3896 /* skip what we didn't read */
3897 r = sd_bus_message_skip(m, contents);
3901 switch (contents[0]) {
3903 case SD_BUS_TYPE_STRUCT_BEGIN:
3905 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
3908 r = sd_bus_message_read(m, "(uo)", &u, NULL);
3910 return bus_log_parse_error(r);
3913 printf("%s=%"PRIu32"\n", name, u);
3915 printf("%s=\n", name);
3919 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
3922 r = sd_bus_message_read(m, "(so)", &s, NULL);
3924 return bus_log_parse_error(r);
3926 if (arg_all || !isempty(s))
3927 printf("%s=%s\n", name, s);
3931 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
3932 const char *a = NULL, *b = NULL;
3934 r = sd_bus_message_read(m, "(ss)", &a, &b);
3936 return bus_log_parse_error(r);
3938 if (arg_all || !isempty(a) || !isempty(b))
3939 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
3942 } else if (streq_ptr(name, "SystemCallFilter")) {
3943 _cleanup_strv_free_ char **l = NULL;
3946 r = sd_bus_message_enter_container(m, 'r', "bas");
3948 return bus_log_parse_error(r);
3950 r = sd_bus_message_read(m, "b", &whitelist);
3952 return bus_log_parse_error(r);
3954 r = sd_bus_message_read_strv(m, &l);
3956 return bus_log_parse_error(r);
3958 r = sd_bus_message_exit_container(m);
3960 return bus_log_parse_error(r);
3962 if (arg_all || whitelist || !strv_isempty(l)) {
3966 fputs(name, stdout);
3972 STRV_FOREACH(i, l) {
3980 fputc('\n', stdout);
3988 case SD_BUS_TYPE_ARRAY:
3990 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
3994 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
3996 return bus_log_parse_error(r);
3998 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
3999 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
4002 return bus_log_parse_error(r);
4004 r = sd_bus_message_exit_container(m);
4006 return bus_log_parse_error(r);
4010 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
4011 const char *type, *path;
4013 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4015 return bus_log_parse_error(r);
4017 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4018 printf("%s=%s\n", type, path);
4020 return bus_log_parse_error(r);
4022 r = sd_bus_message_exit_container(m);
4024 return bus_log_parse_error(r);
4028 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
4029 const char *type, *path;
4031 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4033 return bus_log_parse_error(r);
4035 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
4036 printf("Listen%s=%s\n", type, path);
4038 return bus_log_parse_error(r);
4040 r = sd_bus_message_exit_container(m);
4042 return bus_log_parse_error(r);
4046 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
4048 uint64_t value, next_elapse;
4050 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
4052 return bus_log_parse_error(r);
4054 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
4055 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
4057 printf("%s={ value=%s ; next_elapse=%s }\n",
4059 format_timespan(timespan1, sizeof(timespan1), value, 0),
4060 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
4063 return bus_log_parse_error(r);
4065 r = sd_bus_message_exit_container(m);
4067 return bus_log_parse_error(r);
4071 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
4072 ExecStatusInfo info = {};
4074 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
4076 return bus_log_parse_error(r);
4078 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
4079 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
4080 _cleanup_free_ char *tt;
4082 tt = strv_join(info.argv, " ");
4084 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT" ; code=%s ; status=%i%s%s }\n",
4088 yes_no(info.ignore),
4089 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
4090 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
4092 sigchld_code_to_string(info.code),
4094 info.code == CLD_EXITED ? "" : "/",
4095 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
4098 strv_free(info.argv);
4102 r = sd_bus_message_exit_container(m);
4104 return bus_log_parse_error(r);
4108 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
4109 const char *path, *rwm;
4111 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
4113 return bus_log_parse_error(r);
4115 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
4116 printf("%s=%s %s\n", name, strna(path), strna(rwm));
4118 return bus_log_parse_error(r);
4120 r = sd_bus_message_exit_container(m);
4122 return bus_log_parse_error(r);
4126 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
4130 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4132 return bus_log_parse_error(r);
4134 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
4135 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
4137 return bus_log_parse_error(r);
4139 r = sd_bus_message_exit_container(m);
4141 return bus_log_parse_error(r);
4145 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
4149 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
4151 return bus_log_parse_error(r);
4153 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
4154 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
4156 return bus_log_parse_error(r);
4158 r = sd_bus_message_exit_container(m);
4160 return bus_log_parse_error(r);
4168 r = bus_print_property(name, m, arg_all);
4170 return bus_log_parse_error(r);
4173 r = sd_bus_message_skip(m, contents);
4175 return bus_log_parse_error(r);
4178 printf("%s=[unprintable]\n", name);
4184 static int show_one(
4188 bool show_properties,
4192 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4193 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4194 UnitStatusInfo info = {
4195 .memory_current = (uint64_t) -1,
4196 .memory_limit = (uint64_t) -1,
4204 log_debug("Showing one %s", path);
4206 r = sd_bus_call_method(
4208 "org.freedesktop.systemd1",
4210 "org.freedesktop.DBus.Properties",
4216 log_error("Failed to get properties: %s", bus_error_message(&error, r));
4220 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
4222 return bus_log_parse_error(r);
4229 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
4230 const char *name, *contents;
4232 r = sd_bus_message_read(reply, "s", &name);
4234 return bus_log_parse_error(r);
4236 r = sd_bus_message_peek_type(reply, NULL, &contents);
4238 return bus_log_parse_error(r);
4240 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
4242 return bus_log_parse_error(r);
4244 if (show_properties)
4245 r = print_property(name, reply, contents);
4247 r = status_property(name, reply, &info, contents);
4251 r = sd_bus_message_exit_container(reply);
4253 return bus_log_parse_error(r);
4255 r = sd_bus_message_exit_container(reply);
4257 return bus_log_parse_error(r);
4260 return bus_log_parse_error(r);
4262 r = sd_bus_message_exit_container(reply);
4264 return bus_log_parse_error(r);
4268 if (!show_properties) {
4269 if (streq(verb, "help"))
4270 show_unit_help(&info);
4272 print_status_info(&info, ellipsized);
4275 strv_free(info.documentation);
4276 strv_free(info.dropin_paths);
4277 strv_free(info.listen);
4279 if (!streq_ptr(info.active_state, "active") &&
4280 !streq_ptr(info.active_state, "reloading") &&
4281 streq(verb, "status")) {
4282 /* According to LSB: "program not running" */
4283 /* 0: program is running or service is OK
4284 * 1: program is dead and /run PID file exists
4285 * 2: program is dead and /run/lock lock file exists
4286 * 3: program is not running
4287 * 4: program or service status is unknown
4289 if (info.pid_file && access(info.pid_file, F_OK) == 0)
4295 while ((p = info.exec)) {
4296 LIST_REMOVE(exec, info.exec, p);
4297 exec_status_info_free(p);
4303 static int get_unit_dbus_path_by_pid(
4308 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4309 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4313 r = sd_bus_call_method(
4315 "org.freedesktop.systemd1",
4316 "/org/freedesktop/systemd1",
4317 "org.freedesktop.systemd1.Manager",
4323 log_error("Failed to get unit for PID %"PRIu32": %s", pid, bus_error_message(&error, r));
4327 r = sd_bus_message_read(reply, "o", &u);
4329 return bus_log_parse_error(r);
4339 static int show_all(
4342 bool show_properties,
4346 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4347 _cleanup_free_ UnitInfo *unit_infos = NULL;
4352 r = get_unit_list(bus, NULL, NULL, &unit_infos, 0, &reply);
4356 pager_open_if_enabled();
4360 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
4362 for (u = unit_infos; u < unit_infos + c; u++) {
4363 _cleanup_free_ char *p = NULL;
4365 p = unit_dbus_path_from_name(u->id);
4369 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
4372 else if (r > 0 && ret == 0)
4379 static int show_system_status(sd_bus *bus) {
4380 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], since2[FORMAT_TIMESTAMP_MAX];
4381 _cleanup_free_ char *hn = NULL;
4382 struct machine_info mi = {};
4383 const char *on, *off;
4386 hn = gethostname_malloc();
4390 r = bus_map_all_properties(bus, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map, &mi);
4392 return log_error_errno(r, "Failed to read server status: %m");
4394 if (streq_ptr(mi.state, "degraded")) {
4395 on = ansi_highlight_red();
4396 off = ansi_highlight_off();
4397 } else if (!streq_ptr(mi.state, "running")) {
4398 on = ansi_highlight_yellow();
4399 off = ansi_highlight_off();
4403 printf("%s%s%s %s\n", on, draw_special_char(DRAW_BLACK_CIRCLE), off, arg_host ? arg_host : hn);
4405 printf(" State: %s%s%s\n",
4406 on, strna(mi.state), off);
4408 printf(" Jobs: %u queued\n", mi.n_jobs);
4409 printf(" Failed: %u units\n", mi.n_failed_units);
4411 printf(" Since: %s; %s\n",
4412 format_timestamp(since2, sizeof(since2), mi.timestamp),
4413 format_timestamp_relative(since1, sizeof(since1), mi.timestamp));
4415 printf(" CGroup: %s\n", mi.control_group ?: "/");
4416 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_MACHINE) {
4417 static const char prefix[] = " ";
4421 if (c > sizeof(prefix) - 1)
4422 c -= sizeof(prefix) - 1;
4426 show_cgroup(SYSTEMD_CGROUP_CONTROLLER, strempty(mi.control_group), prefix, c, false, get_output_flags());
4430 free(mi.control_group);
4435 static int show(sd_bus *bus, char **args) {
4436 bool show_properties, show_status, new_line = false;
4437 bool ellipsized = false;
4443 show_properties = streq(args[0], "show");
4444 show_status = streq(args[0], "status");
4446 if (show_properties)
4447 pager_open_if_enabled();
4449 /* If no argument is specified inspect the manager itself */
4451 if (show_properties && strv_length(args) <= 1)
4452 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
4454 if (show_status && strv_length(args) <= 1) {
4456 pager_open_if_enabled();
4457 show_system_status(bus);
4461 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
4463 _cleanup_free_ char **patterns = NULL;
4466 STRV_FOREACH(name, args + 1) {
4467 _cleanup_free_ char *unit = NULL;
4470 if (safe_atou32(*name, &id) < 0) {
4471 if (strv_push(&patterns, *name) < 0)
4475 } else if (show_properties) {
4476 /* Interpret as job id */
4477 if (asprintf(&unit, "/org/freedesktop/systemd1/job/%u", id) < 0)
4481 /* Interpret as PID */
4482 r = get_unit_dbus_path_by_pid(bus, id, &unit);
4489 r = show_one(args[0], bus, unit, show_properties,
4490 &new_line, &ellipsized);
4493 else if (r > 0 && ret == 0)
4497 if (!strv_isempty(patterns)) {
4498 _cleanup_strv_free_ char **names = NULL;
4500 r = expand_names(bus, patterns, NULL, &names);
4502 log_error_errno(r, "Failed to expand names: %m");
4504 STRV_FOREACH(name, names) {
4505 _cleanup_free_ char *unit;
4507 unit = unit_dbus_path_from_name(*name);
4511 r = show_one(args[0], bus, unit, show_properties,
4512 &new_line, &ellipsized);
4515 else if (r > 0 && ret == 0)
4521 if (ellipsized && !arg_quiet)
4522 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4527 static int init_home_and_lookup_paths(char **user_home, char **user_runtime, LookupPaths *lp) {
4531 assert(user_runtime);
4534 if (arg_scope == UNIT_FILE_USER) {
4535 r = user_config_home(user_home);
4537 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4539 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4541 r = user_runtime_dir(user_runtime);
4543 return log_error_errno(r, "Failed to query XDG_CONFIG_HOME: %m");
4545 return log_error_errno(ENOTDIR, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4548 r = lookup_paths_init_from_scope(lp, arg_scope, arg_root);
4550 return log_error_errno(r, "Failed to query unit lookup paths: %m");
4555 static int cat(sd_bus *bus, char **args) {
4556 _cleanup_free_ char *user_home = NULL;
4557 _cleanup_free_ char *user_runtime = NULL;
4558 _cleanup_lookup_paths_free_ LookupPaths lp = {};
4559 _cleanup_strv_free_ char **names = NULL;
4561 bool first = true, avoid_bus_cache;
4566 if (arg_transport != BUS_TRANSPORT_LOCAL) {
4567 log_error("Cannot remotely cat units");
4571 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
4575 r = expand_names(bus, args + 1, NULL, &names);
4577 return log_error_errno(r, "Failed to expand names: %m");
4579 avoid_bus_cache = !bus || avoid_bus();
4581 pager_open_if_enabled();
4583 STRV_FOREACH(name, names) {
4584 _cleanup_free_ char *fragment_path = NULL;
4585 _cleanup_strv_free_ char **dropin_paths = NULL;
4588 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &fragment_path, &dropin_paths);
4599 if (fragment_path) {
4600 printf("%s# %s%s\n",
4601 ansi_highlight_blue(),
4603 ansi_highlight_off());
4606 r = copy_file_fd(fragment_path, STDOUT_FILENO, false);
4608 log_warning_errno(r, "Failed to cat %s: %m", fragment_path);
4613 STRV_FOREACH(path, dropin_paths) {
4614 printf("%s%s# %s%s\n",
4615 isempty(fragment_path) && path == dropin_paths ? "" : "\n",
4616 ansi_highlight_blue(),
4618 ansi_highlight_off());
4621 r = copy_file_fd(*path, STDOUT_FILENO, false);
4623 log_warning_errno(r, "Failed to cat %s: %m", *path);
4629 return r < 0 ? r : 0;
4632 static int set_property(sd_bus *bus, char **args) {
4633 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4634 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4635 _cleanup_free_ char *n = NULL;
4639 polkit_agent_open_if_enabled();
4641 r = sd_bus_message_new_method_call(
4644 "org.freedesktop.systemd1",
4645 "/org/freedesktop/systemd1",
4646 "org.freedesktop.systemd1.Manager",
4647 "SetUnitProperties");
4649 return bus_log_create_error(r);
4651 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4653 return bus_log_create_error(r);
4655 n = unit_name_mangle(args[1], MANGLE_NOGLOB);
4659 r = sd_bus_message_append(m, "sb", n, arg_runtime);
4661 return bus_log_create_error(r);
4663 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
4665 return bus_log_create_error(r);
4667 STRV_FOREACH(i, args + 2) {
4668 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
4670 return bus_log_create_error(r);
4672 r = bus_append_unit_property_assignment(m, *i);
4676 r = sd_bus_message_close_container(m);
4678 return bus_log_create_error(r);
4681 r = sd_bus_message_close_container(m);
4683 return bus_log_create_error(r);
4685 r = sd_bus_call(bus, m, 0, &error, NULL);
4687 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
4694 static int snapshot(sd_bus *bus, char **args) {
4695 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4696 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
4697 _cleanup_free_ char *n = NULL, *id = NULL;
4701 polkit_agent_open_if_enabled();
4703 if (strv_length(args) > 1)
4704 n = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".snapshot");
4710 r = sd_bus_message_new_method_call(
4713 "org.freedesktop.systemd1",
4714 "/org/freedesktop/systemd1",
4715 "org.freedesktop.systemd1.Manager",
4718 return bus_log_create_error(r);
4720 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4722 return bus_log_create_error(r);
4724 r = sd_bus_message_append(m, "sb", n, false);
4726 return bus_log_create_error(r);
4728 r = sd_bus_call(bus, m, 0, &error, &reply);
4730 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
4734 r = sd_bus_message_read(reply, "o", &path);
4736 return bus_log_parse_error(r);
4738 r = sd_bus_get_property_string(
4740 "org.freedesktop.systemd1",
4742 "org.freedesktop.systemd1.Unit",
4747 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
4757 static int delete_snapshot(sd_bus *bus, char **args) {
4758 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4759 _cleanup_strv_free_ char **names = NULL;
4765 polkit_agent_open_if_enabled();
4767 r = expand_names(bus, args + 1, ".snapshot", &names);
4769 log_error_errno(r, "Failed to expand names: %m");
4771 STRV_FOREACH(name, names) {
4772 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4775 q = sd_bus_message_new_method_call(
4778 "org.freedesktop.systemd1",
4779 "/org/freedesktop/systemd1",
4780 "org.freedesktop.systemd1.Manager",
4783 return bus_log_create_error(q);
4785 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4787 return bus_log_create_error(q);
4789 q = sd_bus_message_append(m, "s", *name);
4791 return bus_log_create_error(q);
4793 q = sd_bus_call(bus, m, 0, &error, NULL);
4795 log_error("Failed to remove snapshot %s: %s", *name, bus_error_message(&error, q));
4804 static int daemon_reload(sd_bus *bus, char **args) {
4805 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4806 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4810 polkit_agent_open_if_enabled();
4812 if (arg_action == ACTION_RELOAD)
4814 else if (arg_action == ACTION_REEXEC)
4815 method = "Reexecute";
4817 assert(arg_action == ACTION_SYSTEMCTL);
4820 streq(args[0], "clear-jobs") ||
4821 streq(args[0], "cancel") ? "ClearJobs" :
4822 streq(args[0], "daemon-reexec") ? "Reexecute" :
4823 streq(args[0], "reset-failed") ? "ResetFailed" :
4824 streq(args[0], "halt") ? "Halt" :
4825 streq(args[0], "poweroff") ? "PowerOff" :
4826 streq(args[0], "reboot") ? "Reboot" :
4827 streq(args[0], "kexec") ? "KExec" :
4828 streq(args[0], "exit") ? "Exit" :
4829 /* "daemon-reload" */ "Reload";
4832 r = sd_bus_message_new_method_call(
4835 "org.freedesktop.systemd1",
4836 "/org/freedesktop/systemd1",
4837 "org.freedesktop.systemd1.Manager",
4840 return bus_log_create_error(r);
4842 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4844 return bus_log_create_error(r);
4846 r = sd_bus_call(bus, m, 0, &error, NULL);
4847 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
4848 /* There's always a fallback possible for
4849 * legacy actions. */
4851 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
4852 /* On reexecution, we expect a disconnect, not a
4856 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4858 return r < 0 ? r : 0;
4861 static int reset_failed(sd_bus *bus, char **args) {
4862 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4863 _cleanup_strv_free_ char **names = NULL;
4867 if (strv_length(args) <= 1)
4868 return daemon_reload(bus, args);
4870 polkit_agent_open_if_enabled();
4872 r = expand_names(bus, args + 1, NULL, &names);
4874 log_error_errno(r, "Failed to expand names: %m");
4876 STRV_FOREACH(name, names) {
4877 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
4879 q = sd_bus_message_new_method_call(
4882 "org.freedesktop.systemd1",
4883 "/org/freedesktop/systemd1",
4884 "org.freedesktop.systemd1.Manager",
4887 return bus_log_create_error(q);
4889 q = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
4891 return bus_log_create_error(q);
4893 q = sd_bus_message_append(m, "s", *name);
4895 return bus_log_create_error(q);
4897 q = sd_bus_call(bus, m, 0, &error, NULL);
4899 log_error("Failed to reset failed state of unit %s: %s", *name, bus_error_message(&error, q));
4908 static int show_environment(sd_bus *bus, char **args) {
4909 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4910 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4914 pager_open_if_enabled();
4916 r = sd_bus_get_property(
4918 "org.freedesktop.systemd1",
4919 "/org/freedesktop/systemd1",
4920 "org.freedesktop.systemd1.Manager",
4926 log_error("Failed to get environment: %s", bus_error_message(&error, r));
4930 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
4932 return bus_log_parse_error(r);
4934 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
4937 return bus_log_parse_error(r);
4939 r = sd_bus_message_exit_container(reply);
4941 return bus_log_parse_error(r);
4946 static int switch_root(sd_bus *bus, char **args) {
4947 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4948 _cleanup_free_ char *cmdline_init = NULL;
4949 const char *root, *init;
4953 l = strv_length(args);
4954 if (l < 2 || l > 3) {
4955 log_error("Wrong number of arguments.");
4964 r = parse_env_file("/proc/cmdline", WHITESPACE,
4965 "init", &cmdline_init,
4968 log_debug_errno(r, "Failed to parse /proc/cmdline: %m");
4970 init = cmdline_init;
4977 const char *root_systemd_path = NULL, *root_init_path = NULL;
4979 root_systemd_path = strjoina(root, "/" SYSTEMD_BINARY_PATH);
4980 root_init_path = strjoina(root, "/", init);
4982 /* If the passed init is actually the same as the
4983 * systemd binary, then let's suppress it. */
4984 if (files_same(root_init_path, root_systemd_path) > 0)
4988 log_debug("Switching root - root: %s; init: %s", root, strna(init));
4990 r = sd_bus_call_method(
4992 "org.freedesktop.systemd1",
4993 "/org/freedesktop/systemd1",
4994 "org.freedesktop.systemd1.Manager",
5000 log_error("Failed to switch root: %s", bus_error_message(&error, r));
5007 static int set_environment(sd_bus *bus, char **args) {
5008 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5009 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5016 method = streq(args[0], "set-environment")
5018 : "UnsetEnvironment";
5020 r = sd_bus_message_new_method_call(
5023 "org.freedesktop.systemd1",
5024 "/org/freedesktop/systemd1",
5025 "org.freedesktop.systemd1.Manager",
5028 return bus_log_create_error(r);
5030 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5032 return bus_log_create_error(r);
5034 r = sd_bus_message_append_strv(m, args + 1);
5036 return bus_log_create_error(r);
5038 r = sd_bus_call(bus, m, 0, &error, NULL);
5040 log_error("Failed to set environment: %s", bus_error_message(&error, r));
5047 static int import_environment(sd_bus *bus, char **args) {
5048 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5049 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
5055 r = sd_bus_message_new_method_call(
5058 "org.freedesktop.systemd1",
5059 "/org/freedesktop/systemd1",
5060 "org.freedesktop.systemd1.Manager",
5063 return bus_log_create_error(r);
5065 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5067 return bus_log_create_error(r);
5069 if (strv_isempty(args + 1))
5070 r = sd_bus_message_append_strv(m, environ);
5074 r = sd_bus_message_open_container(m, 'a', "s");
5076 return bus_log_create_error(r);
5078 STRV_FOREACH(a, args + 1) {
5080 if (!env_name_is_valid(*a)) {
5081 log_error("Not a valid environment variable name: %s", *a);
5085 STRV_FOREACH(b, environ) {
5088 eq = startswith(*b, *a);
5089 if (eq && *eq == '=') {
5091 r = sd_bus_message_append(m, "s", *b);
5093 return bus_log_create_error(r);
5100 r = sd_bus_message_close_container(m);
5103 return bus_log_create_error(r);
5105 r = sd_bus_call(bus, m, 0, &error, NULL);
5107 log_error("Failed to import environment: %s", bus_error_message(&error, r));
5114 static int enable_sysv_units(const char *verb, char **args) {
5117 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
5119 _cleanup_lookup_paths_free_ LookupPaths paths = {};
5121 if (arg_scope != UNIT_FILE_SYSTEM)
5124 if (!streq(verb, "enable") &&
5125 !streq(verb, "disable") &&
5126 !streq(verb, "is-enabled"))
5129 /* Processes all SysV units, and reshuffles the array so that
5130 * afterwards only the native units remain */
5132 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, arg_root, NULL, NULL, NULL);
5139 _cleanup_free_ char *p = NULL, *q = NULL, *l = NULL;
5140 bool found_native = false, found_sysv;
5142 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
5150 if (!endswith(name, ".service"))
5153 if (path_is_absolute(name))
5156 STRV_FOREACH(k, paths.unit_path) {
5157 _cleanup_free_ char *path = NULL;
5159 path = path_join(arg_root, *k, name);
5163 found_native = access(path, F_OK) >= 0;
5171 p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
5175 p[strlen(p) - strlen(".service")] = 0;
5176 found_sysv = access(p, F_OK) >= 0;
5180 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
5182 if (!isempty(arg_root))
5183 argv[c++] = q = strappend("--root=", arg_root);
5185 argv[c++] = basename(p);
5187 streq(verb, "enable") ? "on" :
5188 streq(verb, "disable") ? "off" : "--level=5";
5191 l = strv_join((char**)argv, " ");
5195 log_info("Executing %s", l);
5199 return log_error_errno(errno, "Failed to fork: %m");
5200 else if (pid == 0) {
5203 execv(argv[0], (char**) argv);
5204 _exit(EXIT_FAILURE);
5207 j = wait_for_terminate(pid, &status);
5209 log_error_errno(r, "Failed to wait for child: %m");
5213 if (status.si_code == CLD_EXITED) {
5214 if (streq(verb, "is-enabled")) {
5215 if (status.si_status == 0) {
5224 } else if (status.si_status != 0)
5229 /* Remove this entry, so that we don't try enabling it as native unit */
5232 assert(args[f] == name);
5233 strv_remove(args, name);
5240 static int mangle_names(char **original_names, char ***mangled_names) {
5241 char **i, **l, **name;
5243 l = new(char*, strv_length(original_names) + 1);
5248 STRV_FOREACH(name, original_names) {
5250 /* When enabling units qualified path names are OK,
5251 * too, hence allow them explicitly. */
5256 *i = unit_name_mangle(*name, MANGLE_NOGLOB);
5272 static int enable_unit(sd_bus *bus, char **args) {
5273 _cleanup_strv_free_ char **names = NULL;
5274 const char *verb = args[0];
5275 UnitFileChange *changes = NULL;
5276 unsigned n_changes = 0;
5277 int carries_install_info = -1;
5283 r = mangle_names(args+1, &names);
5287 r = enable_sysv_units(verb, names);
5291 /* If the operation was fully executed by the SysV compat,
5292 * let's finish early */
5293 if (strv_isempty(names))
5296 if (!bus || avoid_bus()) {
5297 if (streq(verb, "enable")) {
5298 r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5299 carries_install_info = r;
5300 } else if (streq(verb, "disable"))
5301 r = unit_file_disable(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5302 else if (streq(verb, "reenable")) {
5303 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5304 carries_install_info = r;
5305 } else if (streq(verb, "link"))
5306 r = unit_file_link(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5307 else if (streq(verb, "preset")) {
5308 r = unit_file_preset(arg_scope, arg_runtime, arg_root, names, arg_preset_mode, arg_force, &changes, &n_changes);
5309 carries_install_info = r;
5310 } else if (streq(verb, "mask"))
5311 r = unit_file_mask(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);
5312 else if (streq(verb, "unmask"))
5313 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, names, &changes, &n_changes);
5315 assert_not_reached("Unknown verb");
5318 log_error_errno(r, "Operation failed: %m");
5323 dump_unit_file_changes(changes, n_changes);
5327 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5328 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5329 int expect_carries_install_info = false;
5330 bool send_force = true, send_preset_mode = false;
5333 polkit_agent_open_if_enabled();
5335 if (streq(verb, "enable")) {
5336 method = "EnableUnitFiles";
5337 expect_carries_install_info = true;
5338 } else if (streq(verb, "disable")) {
5339 method = "DisableUnitFiles";
5341 } else if (streq(verb, "reenable")) {
5342 method = "ReenableUnitFiles";
5343 expect_carries_install_info = true;
5344 } else if (streq(verb, "link"))
5345 method = "LinkUnitFiles";
5346 else if (streq(verb, "preset")) {
5348 if (arg_preset_mode != UNIT_FILE_PRESET_FULL) {
5349 method = "PresetUnitFilesWithMode";
5350 send_preset_mode = true;
5352 method = "PresetUnitFiles";
5354 expect_carries_install_info = true;
5355 } else if (streq(verb, "mask"))
5356 method = "MaskUnitFiles";
5357 else if (streq(verb, "unmask")) {
5358 method = "UnmaskUnitFiles";
5361 assert_not_reached("Unknown verb");
5363 r = sd_bus_message_new_method_call(
5366 "org.freedesktop.systemd1",
5367 "/org/freedesktop/systemd1",
5368 "org.freedesktop.systemd1.Manager",
5371 return bus_log_create_error(r);
5373 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5375 return bus_log_create_error(r);
5377 r = sd_bus_message_append_strv(m, names);
5379 return bus_log_create_error(r);
5381 if (send_preset_mode) {
5382 r = sd_bus_message_append(m, "s", unit_file_preset_mode_to_string(arg_preset_mode));
5384 return bus_log_create_error(r);
5387 r = sd_bus_message_append(m, "b", arg_runtime);
5389 return bus_log_create_error(r);
5392 r = sd_bus_message_append(m, "b", arg_force);
5394 return bus_log_create_error(r);
5397 r = sd_bus_call(bus, m, 0, &error, &reply);
5399 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5403 if (expect_carries_install_info) {
5404 r = sd_bus_message_read(reply, "b", &carries_install_info);
5406 return bus_log_parse_error(r);
5409 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5413 /* Try to reload if enabled */
5415 r = daemon_reload(bus, args);
5420 if (carries_install_info == 0)
5421 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5422 "using systemctl.\n"
5423 "Possible reasons for having this kind of units are:\n"
5424 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5425 " .wants/ or .requires/ directory.\n"
5426 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5427 " a requirement dependency on it.\n"
5428 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5429 " D-Bus, udev, scripted systemctl call, ...).\n");
5432 unit_file_changes_free(changes, n_changes);
5437 static int add_dependency(sd_bus *bus, char **args) {
5438 _cleanup_strv_free_ char **names = NULL;
5439 _cleanup_free_ char *target = NULL;
5440 const char *verb = args[0];
5447 target = unit_name_mangle_with_suffix(args[1], MANGLE_NOGLOB, ".target");
5451 r = mangle_names(args+2, &names);
5455 if (streq(verb, "add-wants"))
5457 else if (streq(verb, "add-requires"))
5458 dep = UNIT_REQUIRES;
5460 assert_not_reached("Unknown verb");
5462 if (!bus || avoid_bus()) {
5463 UnitFileChange *changes = NULL;
5464 unsigned n_changes = 0;
5466 r = unit_file_add_dependency(arg_scope, arg_runtime, arg_root, names, target, dep, arg_force, &changes, &n_changes);
5469 return log_error_errno(r, "Can't add dependency: %m");
5472 dump_unit_file_changes(changes, n_changes);
5474 unit_file_changes_free(changes, n_changes);
5477 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
5478 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5480 polkit_agent_open_if_enabled();
5482 r = sd_bus_message_new_method_call(
5485 "org.freedesktop.systemd1",
5486 "/org/freedesktop/systemd1",
5487 "org.freedesktop.systemd1.Manager",
5488 "AddDependencyUnitFiles");
5490 return bus_log_create_error(r);
5492 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5494 return bus_log_create_error(r);
5496 r = sd_bus_message_append_strv(m, names);
5498 return bus_log_create_error(r);
5500 r = sd_bus_message_append(m, "ssbb", target, unit_dependency_to_string(dep), arg_runtime, arg_force);
5502 return bus_log_create_error(r);
5504 r = sd_bus_call(bus, m, 0, &error, &reply);
5506 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5510 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5515 r = daemon_reload(bus, args);
5523 static int preset_all(sd_bus *bus, char **args) {
5524 UnitFileChange *changes = NULL;
5525 unsigned n_changes = 0;
5528 if (!bus || avoid_bus()) {
5530 r = unit_file_preset_all(arg_scope, arg_runtime, arg_root, arg_preset_mode, arg_force, &changes, &n_changes);
5532 log_error_errno(r, "Operation failed: %m");
5537 dump_unit_file_changes(changes, n_changes);
5542 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
5543 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5545 polkit_agent_open_if_enabled();
5547 r = sd_bus_message_new_method_call(
5550 "org.freedesktop.systemd1",
5551 "/org/freedesktop/systemd1",
5552 "org.freedesktop.systemd1.Manager",
5553 "PresetAllUnitFiles");
5555 return bus_log_create_error(r);
5557 r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
5559 return bus_log_create_error(r);
5561 r = sd_bus_message_append(
5564 unit_file_preset_mode_to_string(arg_preset_mode),
5568 return bus_log_create_error(r);
5570 r = sd_bus_call(bus, m, 0, &error, &reply);
5572 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
5576 r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
5581 r = daemon_reload(bus, args);
5587 unit_file_changes_free(changes, n_changes);
5592 static int unit_is_enabled(sd_bus *bus, char **args) {
5594 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
5595 _cleanup_strv_free_ char **names = NULL;
5600 r = mangle_names(args+1, &names);
5604 r = enable_sysv_units(args[0], names);
5610 if (!bus || avoid_bus()) {
5612 STRV_FOREACH(name, names) {
5613 UnitFileState state;
5615 state = unit_file_get_state(arg_scope, arg_root, *name);
5617 return log_error_errno(state, "Failed to get unit file state for %s: %m", *name);
5619 if (state == UNIT_FILE_ENABLED ||
5620 state == UNIT_FILE_ENABLED_RUNTIME ||
5621 state == UNIT_FILE_STATIC ||
5622 state == UNIT_FILE_INDIRECT)
5626 puts(unit_file_state_to_string(state));
5630 STRV_FOREACH(name, names) {
5631 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5634 r = sd_bus_call_method(
5636 "org.freedesktop.systemd1",
5637 "/org/freedesktop/systemd1",
5638 "org.freedesktop.systemd1.Manager",
5644 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
5648 r = sd_bus_message_read(reply, "s", &s);
5650 return bus_log_parse_error(r);
5652 if (STR_IN_SET(s, "enabled", "enabled-runtime", "static", "indirect"))
5663 static int is_system_running(sd_bus *bus, char **args) {
5664 _cleanup_free_ char *state = NULL;
5667 r = sd_bus_get_property_string(
5669 "org.freedesktop.systemd1",
5670 "/org/freedesktop/systemd1",
5671 "org.freedesktop.systemd1.Manager",
5684 return streq(state, "running") ? EXIT_SUCCESS : EXIT_FAILURE;
5687 static int create_edit_temp_file(const char *new_path, const char *original_path, char **ret_tmp_fn) {
5692 assert(original_path);
5695 r = tempfn_random(new_path, &t);
5697 return log_error_errno(r, "Failed to determine temporary filename for \"%s\": %m", new_path);
5699 r = mkdir_parents(new_path, 0755);
5701 log_error_errno(r, "Failed to create directories for \"%s\": %m", new_path);
5706 r = copy_file(original_path, t, 0, 0644, 0);
5710 log_error_errno(r, "Failed to create temporary file \"%s\": %m", t);
5715 log_error_errno(r, "Failed to copy \"%s\" to \"%s\": %m", original_path, t);
5725 static int get_file_to_edit(const char *name, const char *user_home, const char *user_runtime, char **ret_path) {
5726 _cleanup_free_ char *path = NULL, *path2 = NULL, *run = NULL;
5728 switch (arg_scope) {
5729 case UNIT_FILE_SYSTEM:
5730 path = path_join(arg_root, SYSTEM_CONFIG_UNIT_PATH, name);
5732 run = path_join(arg_root, "/run/systemd/system/", name);
5734 case UNIT_FILE_GLOBAL:
5735 path = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5737 run = path_join(arg_root, "/run/systemd/user/", name);
5739 case UNIT_FILE_USER:
5741 assert(user_runtime);
5743 path = path_join(arg_root, user_home, name);
5745 path2 = path_join(arg_root, USER_CONFIG_UNIT_PATH, name);
5748 run = path_join(arg_root, user_runtime, name);
5752 assert_not_reached("Invalid scope");
5754 if (!path || (arg_runtime && !run))
5758 if (access(path, F_OK) >= 0)
5759 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5761 if (path2 && access(path2, F_OK) >= 0)
5762 return log_error_errno(EEXIST, "Refusing to create \"%s\" because it would be overriden by \"%s\" anyway.",
5775 static int unit_file_create_dropin(const char *unit_name, const char *user_home, const char *user_runtime, char **ret_new_path, char **ret_tmp_path) {
5776 char *tmp_new_path, *ending;
5781 assert(ret_new_path);
5782 assert(ret_tmp_path);
5784 ending = strjoina(unit_name, ".d/override.conf");
5785 r = get_file_to_edit(ending, user_home, user_runtime, &tmp_new_path);
5789 r = create_edit_temp_file(tmp_new_path, tmp_new_path, &tmp_tmp_path);
5795 *ret_new_path = tmp_new_path;
5796 *ret_tmp_path = tmp_tmp_path;
5801 static int unit_file_create_copy(const char *unit_name,
5802 const char *fragment_path,
5803 const char *user_home,
5804 const char *user_runtime,
5805 char **ret_new_path,
5806 char **ret_tmp_path) {
5811 assert(fragment_path);
5813 assert(ret_new_path);
5814 assert(ret_tmp_path);
5816 r = get_file_to_edit(unit_name, user_home, user_runtime, &tmp_new_path);
5820 if (!path_equal(fragment_path, tmp_new_path) && access(tmp_new_path, F_OK) == 0) {
5823 r = ask_char(&response, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path, fragment_path);
5828 if (response != 'y') {
5829 log_warning("%s ignored", unit_name);
5835 r = create_edit_temp_file(tmp_new_path, fragment_path, &tmp_tmp_path);
5837 log_error_errno(r, "Failed to create temporary file for \"%s\": %m", tmp_new_path);
5842 *ret_new_path = tmp_new_path;
5843 *ret_tmp_path = tmp_tmp_path;
5848 static int run_editor(char **paths) {
5856 log_error_errno(errno, "Failed to fork: %m");
5862 char **backup_editors = STRV_MAKE("nano", "vim", "vi");
5864 char **tmp_path, **original_path, **p;
5868 argc = strv_length(paths)/2 + 1;
5869 args = newa(const char*, argc + 1);
5872 STRV_FOREACH_PAIR(original_path, tmp_path, paths) {
5873 args[i] = *tmp_path;
5878 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5879 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5880 * we try to execute well known editors
5882 editor = getenv("SYSTEMD_EDITOR");
5884 editor = getenv("EDITOR");
5886 editor = getenv("VISUAL");
5888 if (!isempty(editor)) {
5890 execvp(editor, (char* const*) args);
5893 STRV_FOREACH(p, backup_editors) {
5895 execvp(*p, (char* const*) args);
5896 /* We do not fail if the editor doesn't exist
5897 * because we want to try each one of them before
5900 if (errno != ENOENT) {
5901 log_error("Failed to execute %s: %m", editor);
5902 _exit(EXIT_FAILURE);
5906 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR or $EDITOR or $VISUAL.");
5907 _exit(EXIT_FAILURE);
5910 r = wait_for_terminate_and_warn("editor", pid, true);
5912 return log_error_errno(r, "Failed to wait for child: %m");
5917 static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) {
5918 _cleanup_free_ char *user_home = NULL;
5919 _cleanup_free_ char *user_runtime = NULL;
5920 _cleanup_lookup_paths_free_ LookupPaths lp = {};
5921 bool avoid_bus_cache;
5928 r = init_home_and_lookup_paths(&user_home, &user_runtime, &lp);
5932 avoid_bus_cache = !bus || avoid_bus();
5934 STRV_FOREACH(name, names) {
5935 _cleanup_free_ char *path = NULL;
5936 char *new_path, *tmp_path;
5938 r = unit_find_paths(bus, *name, avoid_bus_cache, &lp, &path, NULL);
5944 // FIXME: support units with path==NULL (no FragmentPath)
5945 log_error("No fragment exists for %s.", *name);
5950 r = unit_file_create_copy(*name, path, user_home, user_runtime, &new_path, &tmp_path);
5952 r = unit_file_create_dropin(*name, user_home, user_runtime, &new_path, &tmp_path);
5956 r = strv_push_pair(paths, new_path, tmp_path);
5964 static int edit(sd_bus *bus, char **args) {
5965 _cleanup_strv_free_ char **names = NULL;
5966 _cleanup_strv_free_ char **paths = NULL;
5967 char **original, **tmp;
5973 log_error("Cannot edit units if not on a tty");
5977 if (arg_transport != BUS_TRANSPORT_LOCAL) {
5978 log_error("Cannot remotely edit units");
5982 r = expand_names(bus, args + 1, NULL, &names);
5984 return log_error_errno(r, "Failed to expand names: %m");
5986 r = find_paths_to_edit(bus, names, &paths);
5990 if (strv_isempty(paths))
5993 r = run_editor(paths);
5997 STRV_FOREACH_PAIR(original, tmp, paths) {
5998 /* If the temporary file is empty we ignore it.
5999 * It's useful if the user wants to cancel its modification
6001 if (null_or_empty_path(*tmp)) {
6002 log_warning("Editing \"%s\" canceled: temporary file is empty", *original);
6005 r = rename(*tmp, *original);
6007 r = log_error_errno(errno, "Failed to rename \"%s\" to \"%s\": %m", *tmp, *original);
6012 if (!arg_no_reload && bus && !avoid_bus())
6013 r = daemon_reload(bus, args);
6016 STRV_FOREACH_PAIR(original, tmp, paths)
6017 unlink_noerrno(*tmp);
6022 static void systemctl_help(void) {
6024 pager_open_if_enabled();
6026 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6027 "Query or send control commands to the systemd manager.\n\n"
6028 " -h --help Show this help\n"
6029 " --version Show package version\n"
6030 " --system Connect to system manager\n"
6031 " --user Connect to user service manager\n"
6032 " -H --host=[USER@]HOST\n"
6033 " Operate on remote host\n"
6034 " -M --machine=CONTAINER\n"
6035 " Operate on local container\n"
6036 " -t --type=TYPE List units of a particular type\n"
6037 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6038 " -p --property=NAME Show only properties by this name\n"
6039 " -a --all Show all loaded units/properties, including dead/empty\n"
6040 " ones. To list all units installed on the system, use\n"
6041 " the 'list-unit-files' command instead.\n"
6042 " -l --full Don't ellipsize unit names on output\n"
6043 " -r --recursive Show unit list of host and local containers\n"
6044 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6045 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6046 " queueing a new job\n"
6047 " --show-types When showing sockets, explicitly show their type\n"
6048 " -i --ignore-inhibitors\n"
6049 " When shutting down or sleeping, ignore inhibitors\n"
6050 " --kill-who=WHO Who to send signal to\n"
6051 " -s --signal=SIGNAL Which signal to send\n"
6052 " -q --quiet Suppress output\n"
6053 " --no-block Do not wait until operation finished\n"
6054 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6055 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6056 " --no-legend Do not print a legend (column headers and hints)\n"
6057 " --no-pager Do not pipe output into a pager\n"
6058 " --no-ask-password\n"
6059 " Do not ask for system passwords\n"
6060 " --global Enable/disable unit files globally\n"
6061 " --runtime Enable unit files only temporarily until next reboot\n"
6062 " -f --force When enabling unit files, override existing symlinks\n"
6063 " When shutting down, execute action immediately\n"
6064 " --preset-mode= Apply only enable, only disable, or all presets\n"
6065 " --root=PATH Enable unit files in the specified root directory\n"
6066 " -n --lines=INTEGER Number of journal entries to show\n"
6067 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6068 " short-precise, short-monotonic, verbose,\n"
6069 " export, json, json-pretty, json-sse, cat)\n"
6070 " --plain Print unit dependencies as a list instead of a tree\n\n"
6072 " list-units [PATTERN...] List loaded units\n"
6073 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6074 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6075 " start NAME... Start (activate) one or more units\n"
6076 " stop NAME... Stop (deactivate) one or more units\n"
6077 " reload NAME... Reload one or more units\n"
6078 " restart NAME... Start or restart one or more units\n"
6079 " try-restart NAME... Restart one or more units if active\n"
6080 " reload-or-restart NAME... Reload one or more units if possible,\n"
6081 " otherwise start or restart\n"
6082 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6083 " otherwise restart if active\n"
6084 " isolate NAME Start one unit and stop all others\n"
6085 " kill NAME... Send signal to processes of a unit\n"
6086 " is-active PATTERN... Check whether units are active\n"
6087 " is-failed PATTERN... Check whether units are failed\n"
6088 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6089 " show [PATTERN...|JOB...] Show properties of one or more\n"
6090 " units/jobs or the manager\n"
6091 " cat PATTERN... Show files and drop-ins of one or more units\n"
6092 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6093 " help PATTERN...|PID... Show manual for one or more units\n"
6094 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6096 " list-dependencies [NAME] Recursively show units which are required\n"
6097 " or wanted by this unit or by which this\n"
6098 " unit is required or wanted\n\n"
6099 "Unit File Commands:\n"
6100 " list-unit-files [PATTERN...] List installed unit files\n"
6101 " enable NAME... Enable one or more unit files\n"
6102 " disable NAME... Disable one or more unit files\n"
6103 " reenable NAME... Reenable one or more unit files\n"
6104 " preset NAME... Enable/disable one or more unit files\n"
6105 " based on preset configuration\n"
6106 " preset-all Enable/disable all unit files based on\n"
6107 " preset configuration\n"
6108 " is-enabled NAME... Check whether unit files are enabled\n"
6109 " mask NAME... Mask one or more units\n"
6110 " unmask NAME... Unmask one or more units\n"
6111 " link PATH... Link one or more units files into\n"
6112 " the search path\n"
6113 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6114 " on specified one or more units\n"
6115 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6116 " on specified one or more units\n"
6117 " edit NAME... Edit one or more unit files\n"
6118 " get-default Get the name of the default target\n"
6119 " set-default NAME Set the default target\n\n"
6120 "Machine Commands:\n"
6121 " list-machines [PATTERN...] List local containers and host\n\n"
6123 " list-jobs [PATTERN...] List jobs\n"
6124 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6125 "Snapshot Commands:\n"
6126 " snapshot [NAME] Create a snapshot\n"
6127 " delete NAME... Remove one or more snapshots\n\n"
6128 "Environment Commands:\n"
6129 " show-environment Dump environment\n"
6130 " set-environment NAME=VALUE... Set one or more environment variables\n"
6131 " unset-environment NAME... Unset one or more environment variables\n"
6132 " import-environment [NAME...] Import all or some environment variables\n\n"
6133 "Manager Lifecycle Commands:\n"
6134 " daemon-reload Reload systemd manager configuration\n"
6135 " daemon-reexec Reexecute systemd manager\n\n"
6136 "System Commands:\n"
6137 " is-system-running Check whether system is fully running\n"
6138 " default Enter system default mode\n"
6139 " rescue Enter system rescue mode\n"
6140 " emergency Enter system emergency mode\n"
6141 " halt Shut down and halt the system\n"
6142 " poweroff Shut down and power-off the system\n"
6143 " reboot [ARG] Shut down and reboot the system\n"
6144 " kexec Shut down and reboot the system with kexec\n"
6145 " exit Request user instance exit\n"
6146 " switch-root ROOT [INIT] Change to a different root file system\n"
6147 " suspend Suspend the system\n"
6148 " hibernate Hibernate the system\n"
6149 " hybrid-sleep Hibernate and suspend the system\n",
6150 program_invocation_short_name);
6153 static void halt_help(void) {
6154 printf("%s [OPTIONS...]%s\n\n"
6155 "%s the system.\n\n"
6156 " --help Show this help\n"
6157 " --halt Halt the machine\n"
6158 " -p --poweroff Switch off the machine\n"
6159 " --reboot Reboot the machine\n"
6160 " -f --force Force immediate halt/power-off/reboot\n"
6161 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6162 " -d --no-wtmp Don't write wtmp record\n"
6163 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6164 program_invocation_short_name,
6165 arg_action == ACTION_REBOOT ? " [ARG]" : "",
6166 arg_action == ACTION_REBOOT ? "Reboot" :
6167 arg_action == ACTION_POWEROFF ? "Power off" :
6171 static void shutdown_help(void) {
6172 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6173 "Shut down the system.\n\n"
6174 " --help Show this help\n"
6175 " -H --halt Halt the machine\n"
6176 " -P --poweroff Power-off the machine\n"
6177 " -r --reboot Reboot the machine\n"
6178 " -h Equivalent to --poweroff, overridden by --halt\n"
6179 " -k Don't halt/power-off/reboot, just send warnings\n"
6180 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6181 " -c Cancel a pending shutdown\n",
6182 program_invocation_short_name);
6185 static void telinit_help(void) {
6186 printf("%s [OPTIONS...] {COMMAND}\n\n"
6187 "Send control commands to the init daemon.\n\n"
6188 " --help Show this help\n"
6189 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6191 " 0 Power-off the machine\n"
6192 " 6 Reboot the machine\n"
6193 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6194 " 1, s, S Enter rescue mode\n"
6195 " q, Q Reload init daemon configuration\n"
6196 " u, U Reexecute init daemon\n",
6197 program_invocation_short_name);
6200 static void runlevel_help(void) {
6201 printf("%s [OPTIONS...]\n\n"
6202 "Prints the previous and current runlevel of the init system.\n\n"
6203 " --help Show this help\n",
6204 program_invocation_short_name);
6207 static void help_types(void) {
6212 puts("Available unit types:");
6213 for (i = 0; i < _UNIT_TYPE_MAX; i++) {
6214 t = unit_type_to_string(i);
6220 static int systemctl_parse_argv(int argc, char *argv[]) {
6229 ARG_IGNORE_DEPENDENCIES,
6241 ARG_NO_ASK_PASSWORD,
6251 static const struct option options[] = {
6252 { "help", no_argument, NULL, 'h' },
6253 { "version", no_argument, NULL, ARG_VERSION },
6254 { "type", required_argument, NULL, 't' },
6255 { "property", required_argument, NULL, 'p' },
6256 { "all", no_argument, NULL, 'a' },
6257 { "reverse", no_argument, NULL, ARG_REVERSE },
6258 { "after", no_argument, NULL, ARG_AFTER },
6259 { "before", no_argument, NULL, ARG_BEFORE },
6260 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
6261 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
6262 { "full", no_argument, NULL, 'l' },
6263 { "job-mode", required_argument, NULL, ARG_JOB_MODE },
6264 { "fail", no_argument, NULL, ARG_FAIL }, /* compatibility only */
6265 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE }, /* compatibility only */
6266 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES }, /* compatibility only */
6267 { "ignore-inhibitors", no_argument, NULL, 'i' },
6268 { "user", no_argument, NULL, ARG_USER },
6269 { "system", no_argument, NULL, ARG_SYSTEM },
6270 { "global", no_argument, NULL, ARG_GLOBAL },
6271 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
6272 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
6273 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
6274 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6275 { "quiet", no_argument, NULL, 'q' },
6276 { "root", required_argument, NULL, ARG_ROOT },
6277 { "force", no_argument, NULL, ARG_FORCE },
6278 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
6279 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
6280 { "signal", required_argument, NULL, 's' },
6281 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
6282 { "host", required_argument, NULL, 'H' },
6283 { "machine", required_argument, NULL, 'M' },
6284 { "runtime", no_argument, NULL, ARG_RUNTIME },
6285 { "lines", required_argument, NULL, 'n' },
6286 { "output", required_argument, NULL, 'o' },
6287 { "plain", no_argument, NULL, ARG_PLAIN },
6288 { "state", required_argument, NULL, ARG_STATE },
6289 { "recursive", no_argument, NULL, 'r' },
6290 { "preset-mode", required_argument, NULL, ARG_PRESET_MODE },
6299 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:ir", options, NULL)) >= 0)
6308 puts(PACKAGE_STRING);
6309 puts(SYSTEMD_FEATURES);
6313 const char *word, *state;
6316 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6317 _cleanup_free_ char *type;
6319 type = strndup(word, size);
6323 if (streq(type, "help")) {
6328 if (unit_type_from_string(type) >= 0) {
6329 if (strv_push(&arg_types, type))
6335 /* It's much nicer to use --state= for
6336 * load states, but let's support this
6337 * in --types= too for compatibility
6338 * with old versions */
6339 if (unit_load_state_from_string(optarg) >= 0) {
6340 if (strv_push(&arg_states, type) < 0)
6346 log_error("Unknown unit type or load state '%s'.", type);
6347 log_info("Use -t help to see a list of allowed values.");
6355 /* Make sure that if the empty property list
6356 was specified, we won't show any properties. */
6357 if (isempty(optarg) && !arg_properties) {
6358 arg_properties = new0(char*, 1);
6359 if (!arg_properties)
6362 const char *word, *state;
6365 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6368 prop = strndup(word, size);
6372 if (strv_consume(&arg_properties, prop) < 0)
6377 /* If the user asked for a particular
6378 * property, show it to him, even if it is
6390 arg_dependency = DEPENDENCY_REVERSE;
6394 arg_dependency = DEPENDENCY_AFTER;
6398 arg_dependency = DEPENDENCY_BEFORE;
6401 case ARG_SHOW_TYPES:
6402 arg_show_types = true;
6406 arg_job_mode = optarg;
6410 arg_job_mode = "fail";
6413 case ARG_IRREVERSIBLE:
6414 arg_job_mode = "replace-irreversibly";
6417 case ARG_IGNORE_DEPENDENCIES:
6418 arg_job_mode = "ignore-dependencies";
6422 arg_scope = UNIT_FILE_USER;
6426 arg_scope = UNIT_FILE_SYSTEM;
6430 arg_scope = UNIT_FILE_GLOBAL;
6434 arg_no_block = true;
6438 arg_no_legend = true;
6442 arg_no_pager = true;
6458 if (strv_extend(&arg_states, "failed") < 0)
6476 arg_no_reload = true;
6480 arg_kill_who = optarg;
6484 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
6485 log_error("Failed to parse signal string %s.", optarg);
6490 case ARG_NO_ASK_PASSWORD:
6491 arg_ask_password = false;
6495 arg_transport = BUS_TRANSPORT_REMOTE;
6500 arg_transport = BUS_TRANSPORT_MACHINE;
6509 if (safe_atou(optarg, &arg_lines) < 0) {
6510 log_error("Failed to parse lines '%s'", optarg);
6516 arg_output = output_mode_from_string(optarg);
6517 if (arg_output < 0) {
6518 log_error("Unknown output '%s'.", optarg);
6524 arg_ignore_inhibitors = true;
6532 const char *word, *state;
6535 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
6538 s = strndup(word, size);
6542 if (strv_consume(&arg_states, s) < 0)
6549 if (geteuid() != 0) {
6550 log_error("--recursive requires root privileges.");
6554 arg_recursive = true;
6557 case ARG_PRESET_MODE:
6559 arg_preset_mode = unit_file_preset_mode_from_string(optarg);
6560 if (arg_preset_mode < 0) {
6561 log_error("Failed to parse preset mode: %s.", optarg);
6571 assert_not_reached("Unhandled option");
6574 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
6575 log_error("Cannot access user instance remotely.");
6582 static int halt_parse_argv(int argc, char *argv[]) {
6591 static const struct option options[] = {
6592 { "help", no_argument, NULL, ARG_HELP },
6593 { "halt", no_argument, NULL, ARG_HALT },
6594 { "poweroff", no_argument, NULL, 'p' },
6595 { "reboot", no_argument, NULL, ARG_REBOOT },
6596 { "force", no_argument, NULL, 'f' },
6597 { "wtmp-only", no_argument, NULL, 'w' },
6598 { "no-wtmp", no_argument, NULL, 'd' },
6599 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6608 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
6609 if (runlevel == '0' || runlevel == '6')
6612 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0)
6620 arg_action = ACTION_HALT;
6624 if (arg_action != ACTION_REBOOT)
6625 arg_action = ACTION_POWEROFF;
6629 arg_action = ACTION_REBOOT;
6651 /* Compatibility nops */
6658 assert_not_reached("Unhandled option");
6661 if (arg_action == ACTION_REBOOT && (argc == optind || argc == optind + 1)) {
6662 r = update_reboot_param_file(argc == optind + 1 ? argv[optind] : NULL);
6665 } else if (optind < argc) {
6666 log_error("Too many arguments.");
6673 static int parse_time_spec(const char *t, usec_t *_u) {
6677 if (streq(t, "now"))
6679 else if (!strchr(t, ':')) {
6682 if (safe_atou64(t, &u) < 0)
6685 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
6694 hour = strtol(t, &e, 10);
6695 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
6698 minute = strtol(e+1, &e, 10);
6699 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
6702 n = now(CLOCK_REALTIME);
6703 s = (time_t) (n / USEC_PER_SEC);
6705 assert_se(localtime_r(&s, &tm));
6707 tm.tm_hour = (int) hour;
6708 tm.tm_min = (int) minute;
6711 assert_se(s = mktime(&tm));
6713 *_u = (usec_t) s * USEC_PER_SEC;
6716 *_u += USEC_PER_DAY;
6722 static int shutdown_parse_argv(int argc, char *argv[]) {
6729 static const struct option options[] = {
6730 { "help", no_argument, NULL, ARG_HELP },
6731 { "halt", no_argument, NULL, 'H' },
6732 { "poweroff", no_argument, NULL, 'P' },
6733 { "reboot", no_argument, NULL, 'r' },
6734 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
6735 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6744 while ((c = getopt_long(argc, argv, "HPrhkKt:afFc", options, NULL)) >= 0)
6752 arg_action = ACTION_HALT;
6756 arg_action = ACTION_POWEROFF;
6761 arg_action = ACTION_KEXEC;
6763 arg_action = ACTION_REBOOT;
6767 arg_action = ACTION_KEXEC;
6771 if (arg_action != ACTION_HALT)
6772 arg_action = ACTION_POWEROFF;
6787 /* Compatibility nops */
6791 arg_action = ACTION_CANCEL_SHUTDOWN;
6798 assert_not_reached("Unhandled option");
6801 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
6802 r = parse_time_spec(argv[optind], &arg_when);
6804 log_error("Failed to parse time specification: %s", argv[optind]);
6808 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
6810 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
6811 /* No time argument for shutdown cancel */
6812 arg_wall = argv + optind;
6813 else if (argc > optind + 1)
6814 /* We skip the time argument */
6815 arg_wall = argv + optind + 1;
6822 static int telinit_parse_argv(int argc, char *argv[]) {
6829 static const struct option options[] = {
6830 { "help", no_argument, NULL, ARG_HELP },
6831 { "no-wall", no_argument, NULL, ARG_NO_WALL },
6835 static const struct {
6839 { '0', ACTION_POWEROFF },
6840 { '6', ACTION_REBOOT },
6841 { '1', ACTION_RESCUE },
6842 { '2', ACTION_RUNLEVEL2 },
6843 { '3', ACTION_RUNLEVEL3 },
6844 { '4', ACTION_RUNLEVEL4 },
6845 { '5', ACTION_RUNLEVEL5 },
6846 { 's', ACTION_RESCUE },
6847 { 'S', ACTION_RESCUE },
6848 { 'q', ACTION_RELOAD },
6849 { 'Q', ACTION_RELOAD },
6850 { 'u', ACTION_REEXEC },
6851 { 'U', ACTION_REEXEC }
6860 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6875 assert_not_reached("Unhandled option");
6878 if (optind >= argc) {
6879 log_error("%s: required argument missing.",
6880 program_invocation_short_name);
6884 if (optind + 1 < argc) {
6885 log_error("Too many arguments.");
6889 if (strlen(argv[optind]) != 1) {
6890 log_error("Expected single character argument.");
6894 for (i = 0; i < ELEMENTSOF(table); i++)
6895 if (table[i].from == argv[optind][0])
6898 if (i >= ELEMENTSOF(table)) {
6899 log_error("Unknown command '%s'.", argv[optind]);
6903 arg_action = table[i].to;
6910 static int runlevel_parse_argv(int argc, char *argv[]) {
6916 static const struct option options[] = {
6917 { "help", no_argument, NULL, ARG_HELP },
6926 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0)
6937 assert_not_reached("Unhandled option");
6940 if (optind < argc) {
6941 log_error("Too many arguments.");
6948 static int parse_argv(int argc, char *argv[]) {
6952 if (program_invocation_short_name) {
6954 if (strstr(program_invocation_short_name, "halt")) {
6955 arg_action = ACTION_HALT;
6956 return halt_parse_argv(argc, argv);
6957 } else if (strstr(program_invocation_short_name, "poweroff")) {
6958 arg_action = ACTION_POWEROFF;
6959 return halt_parse_argv(argc, argv);
6960 } else if (strstr(program_invocation_short_name, "reboot")) {
6962 arg_action = ACTION_KEXEC;
6964 arg_action = ACTION_REBOOT;
6965 return halt_parse_argv(argc, argv);
6966 } else if (strstr(program_invocation_short_name, "shutdown")) {
6967 arg_action = ACTION_POWEROFF;
6968 return shutdown_parse_argv(argc, argv);
6969 } else if (strstr(program_invocation_short_name, "init")) {
6971 if (sd_booted() > 0) {
6972 arg_action = _ACTION_INVALID;
6973 return telinit_parse_argv(argc, argv);
6975 /* Hmm, so some other init system is
6976 * running, we need to forward this
6977 * request to it. For now we simply
6978 * guess that it is Upstart. */
6980 execv(TELINIT, argv);
6982 log_error("Couldn't find an alternative telinit implementation to spawn.");
6986 } else if (strstr(program_invocation_short_name, "runlevel")) {
6987 arg_action = ACTION_RUNLEVEL;
6988 return runlevel_parse_argv(argc, argv);
6992 arg_action = ACTION_SYSTEMCTL;
6993 return systemctl_parse_argv(argc, argv);
6996 _pure_ static int action_to_runlevel(void) {
6998 static const char table[_ACTION_MAX] = {
6999 [ACTION_HALT] = '0',
7000 [ACTION_POWEROFF] = '0',
7001 [ACTION_REBOOT] = '6',
7002 [ACTION_RUNLEVEL2] = '2',
7003 [ACTION_RUNLEVEL3] = '3',
7004 [ACTION_RUNLEVEL4] = '4',
7005 [ACTION_RUNLEVEL5] = '5',
7006 [ACTION_RESCUE] = '1'
7009 assert(arg_action < _ACTION_MAX);
7011 return table[arg_action];
7014 static int talk_initctl(void) {
7016 struct init_request request = {
7017 .magic = INIT_MAGIC,
7019 .cmd = INIT_CMD_RUNLVL
7022 _cleanup_close_ int fd = -1;
7026 rl = action_to_runlevel();
7030 request.runlevel = rl;
7032 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
7034 if (errno == ENOENT)
7037 log_error_errno(errno, "Failed to open "INIT_FIFO": %m");
7041 r = loop_write(fd, &request, sizeof(request), false);
7043 return log_error_errno(r, "Failed to write to "INIT_FIFO": %m");
7048 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
7050 static const struct {
7058 int (* const dispatch)(sd_bus *bus, char **args);
7064 { "list-units", MORE, 0, list_units },
7065 { "list-unit-files", MORE, 1, list_unit_files, NOBUS },
7066 { "list-sockets", MORE, 1, list_sockets },
7067 { "list-timers", MORE, 1, list_timers },
7068 { "list-jobs", MORE, 1, list_jobs },
7069 { "list-machines", MORE, 1, list_machines },
7070 { "clear-jobs", EQUAL, 1, daemon_reload },
7071 { "cancel", MORE, 2, cancel_job },
7072 { "start", MORE, 2, start_unit },
7073 { "stop", MORE, 2, start_unit },
7074 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7075 { "reload", MORE, 2, start_unit },
7076 { "restart", MORE, 2, start_unit },
7077 { "try-restart", MORE, 2, start_unit },
7078 { "reload-or-restart", MORE, 2, start_unit },
7079 { "reload-or-try-restart", MORE, 2, start_unit },
7080 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
7081 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
7082 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
7083 { "isolate", EQUAL, 2, start_unit },
7084 { "kill", MORE, 2, kill_unit },
7085 { "is-active", MORE, 2, check_unit_active },
7086 { "check", MORE, 2, check_unit_active },
7087 { "is-failed", MORE, 2, check_unit_failed },
7088 { "show", MORE, 1, show },
7089 { "cat", MORE, 2, cat, NOBUS },
7090 { "status", MORE, 1, show },
7091 { "help", MORE, 2, show },
7092 { "snapshot", LESS, 2, snapshot },
7093 { "delete", MORE, 2, delete_snapshot },
7094 { "daemon-reload", EQUAL, 1, daemon_reload },
7095 { "daemon-reexec", EQUAL, 1, daemon_reload },
7096 { "show-environment", EQUAL, 1, show_environment },
7097 { "set-environment", MORE, 2, set_environment },
7098 { "unset-environment", MORE, 2, set_environment },
7099 { "import-environment", MORE, 1, import_environment},
7100 { "halt", EQUAL, 1, start_special, FORCE },
7101 { "poweroff", EQUAL, 1, start_special, FORCE },
7102 { "reboot", MORE, 1, start_special, FORCE },
7103 { "kexec", EQUAL, 1, start_special },
7104 { "suspend", EQUAL, 1, start_special },
7105 { "hibernate", EQUAL, 1, start_special },
7106 { "hybrid-sleep", EQUAL, 1, start_special },
7107 { "default", EQUAL, 1, start_special },
7108 { "rescue", EQUAL, 1, start_special },
7109 { "emergency", EQUAL, 1, start_special },
7110 { "exit", EQUAL, 1, start_special },
7111 { "reset-failed", MORE, 1, reset_failed },
7112 { "enable", MORE, 2, enable_unit, NOBUS },
7113 { "disable", MORE, 2, enable_unit, NOBUS },
7114 { "is-enabled", MORE, 2, unit_is_enabled, NOBUS },
7115 { "reenable", MORE, 2, enable_unit, NOBUS },
7116 { "preset", MORE, 2, enable_unit, NOBUS },
7117 { "preset-all", EQUAL, 1, preset_all, NOBUS },
7118 { "mask", MORE, 2, enable_unit, NOBUS },
7119 { "unmask", MORE, 2, enable_unit, NOBUS },
7120 { "link", MORE, 2, enable_unit, NOBUS },
7121 { "switch-root", MORE, 2, switch_root },
7122 { "list-dependencies", LESS, 2, list_dependencies },
7123 { "set-default", EQUAL, 2, set_default, NOBUS },
7124 { "get-default", EQUAL, 1, get_default, NOBUS },
7125 { "set-property", MORE, 3, set_property },
7126 { "is-system-running", EQUAL, 1, is_system_running },
7127 { "add-wants", MORE, 3, add_dependency, NOBUS },
7128 { "add-requires", MORE, 3, add_dependency, NOBUS },
7129 { "edit", MORE, 2, edit, NOBUS },
7138 left = argc - optind;
7140 /* Special rule: no arguments (left == 0) means "list-units" */
7142 if (streq(argv[optind], "help") && !argv[optind+1]) {
7143 log_error("This command expects one or more "
7144 "unit names. Did you mean --help?");
7148 for (; verb->verb; verb++)
7149 if (streq(argv[optind], verb->verb))
7152 log_error("Unknown operation '%s'.", argv[optind]);
7157 switch (verb->argc_cmp) {
7160 if (left != verb->argc) {
7161 log_error("Invalid number of arguments.");
7168 if (left < verb->argc) {
7169 log_error("Too few arguments.");
7176 if (left > verb->argc) {
7177 log_error("Too many arguments.");
7184 assert_not_reached("Unknown comparison operator.");
7187 /* Require a bus connection for all operations but
7189 if (verb->bus == NOBUS) {
7190 if (!bus && !avoid_bus()) {
7191 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7196 if (running_in_chroot() > 0) {
7197 log_info("Running in chroot, ignoring request.");
7201 if ((verb->bus != FORCE || arg_force <= 0) && !bus) {
7202 log_error_errno(bus_error, "Failed to get D-Bus connection: %m");
7207 return verb->dispatch(bus, argv + optind);
7210 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
7212 struct sd_shutdown_command c = {
7219 union sockaddr_union sockaddr = {
7220 .un.sun_family = AF_UNIX,
7221 .un.sun_path = "/run/systemd/shutdownd",
7224 struct iovec iovec[2] = {{
7225 .iov_base = (char*) &c,
7226 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
7229 struct msghdr msghdr = {
7230 .msg_name = &sockaddr,
7231 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
7232 + strlen("/run/systemd/shutdownd"),
7237 _cleanup_close_ int fd;
7239 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
7243 if (!isempty(message)) {
7244 iovec[1].iov_base = (char*) message;
7245 iovec[1].iov_len = strlen(message);
7246 msghdr.msg_iovlen++;
7249 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
7255 static int reload_with_fallback(sd_bus *bus) {
7258 /* First, try systemd via D-Bus. */
7259 if (daemon_reload(bus, NULL) >= 0)
7263 /* Nothing else worked, so let's try signals */
7264 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
7266 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0)
7267 return log_error_errno(errno, "kill() failed: %m");
7272 static int start_with_fallback(sd_bus *bus) {
7275 /* First, try systemd via D-Bus. */
7276 if (start_unit(bus, NULL) >= 0)
7280 /* Nothing else worked, so let's try
7282 if (talk_initctl() > 0)
7285 log_error("Failed to talk to init daemon.");
7289 warn_wall(arg_action);
7293 static int halt_now(enum action a) {
7295 /* The kernel will automaticall flush ATA disks and suchlike
7296 * on reboot(), but the file systems need to be synce'd
7297 * explicitly in advance. */
7300 /* Make sure C-A-D is handled by the kernel from this point
7302 reboot(RB_ENABLE_CAD);
7307 log_info("Halting.");
7308 reboot(RB_HALT_SYSTEM);
7311 case ACTION_POWEROFF:
7312 log_info("Powering off.");
7313 reboot(RB_POWER_OFF);
7316 case ACTION_REBOOT: {
7317 _cleanup_free_ char *param = NULL;
7319 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) {
7320 log_info("Rebooting with argument '%s'.", param);
7321 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
7322 LINUX_REBOOT_CMD_RESTART2, param);
7325 log_info("Rebooting.");
7326 reboot(RB_AUTOBOOT);
7331 assert_not_reached("Unknown action.");
7335 static int halt_main(sd_bus *bus) {
7338 r = check_inhibitors(bus, arg_action);
7342 if (geteuid() != 0) {
7343 /* Try logind if we are a normal user and no special
7344 * mode applies. Maybe PolicyKit allows us to shutdown
7347 if (arg_when <= 0 &&
7350 (arg_action == ACTION_POWEROFF ||
7351 arg_action == ACTION_REBOOT)) {
7352 r = reboot_with_logind(bus, arg_action);
7357 log_error("Must be root.");
7362 _cleanup_free_ char *m;
7364 m = strv_join(arg_wall, " ");
7368 r = send_shutdownd(arg_when,
7369 arg_action == ACTION_HALT ? 'H' :
7370 arg_action == ACTION_POWEROFF ? 'P' :
7371 arg_action == ACTION_KEXEC ? 'K' :
7378 log_warning_errno(r, "Failed to talk to shutdownd, proceeding with immediate shutdown: %m");
7380 char date[FORMAT_TIMESTAMP_MAX];
7382 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7383 format_timestamp(date, sizeof(date), arg_when));
7388 if (!arg_dry && !arg_force)
7389 return start_with_fallback(bus);
7392 if (sd_booted() > 0)
7393 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7395 r = utmp_put_shutdown();
7397 log_warning_errno(r, "Failed to write utmp record: %m");
7404 r = halt_now(arg_action);
7405 log_error_errno(r, "Failed to reboot: %m");
7410 static int runlevel_main(void) {
7411 int r, runlevel, previous;
7413 r = utmp_get_runlevel(&runlevel, &previous);
7420 previous <= 0 ? 'N' : previous,
7421 runlevel <= 0 ? 'N' : runlevel);
7426 int main(int argc, char*argv[]) {
7427 _cleanup_bus_close_unref_ sd_bus *bus = NULL;
7430 setlocale(LC_ALL, "");
7431 log_parse_environment();
7434 /* Explicitly not on_tty() to avoid setting cached value.
7435 * This becomes relevant for piping output which might be
7437 original_stdout_is_tty = isatty(STDOUT_FILENO);
7439 r = parse_argv(argc, argv);
7443 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7444 * let's shortcut this */
7445 if (arg_action == ACTION_RUNLEVEL) {
7446 r = runlevel_main();
7450 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
7451 log_info("Running in chroot, ignoring request.");
7456 /* Increase max number of open files to 16K if we can, we
7457 * might needs this when browsing journal files, which might
7458 * be split up into many files. */
7459 setrlimit_closest(RLIMIT_NOFILE, &RLIMIT_MAKE_CONST(16384));
7462 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
7464 /* systemctl_main() will print an error message for the bus
7465 * connection, but only if it needs to */
7467 switch (arg_action) {
7469 case ACTION_SYSTEMCTL:
7470 r = systemctl_main(bus, argc, argv, r);
7474 case ACTION_POWEROFF:
7480 case ACTION_RUNLEVEL2:
7481 case ACTION_RUNLEVEL3:
7482 case ACTION_RUNLEVEL4:
7483 case ACTION_RUNLEVEL5:
7485 case ACTION_EMERGENCY:
7486 case ACTION_DEFAULT:
7487 r = start_with_fallback(bus);
7492 r = reload_with_fallback(bus);
7495 case ACTION_CANCEL_SHUTDOWN: {
7496 _cleanup_free_ char *m = NULL;
7499 m = strv_join(arg_wall, " ");
7506 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
7508 log_warning_errno(r, "Failed to talk to shutdownd, shutdown hasn't been cancelled: %m");
7512 case ACTION_RUNLEVEL:
7513 case _ACTION_INVALID:
7515 assert_not_reached("Unknown action");
7520 ask_password_agent_close();
7521 polkit_agent_close();
7523 strv_free(arg_types);
7524 strv_free(arg_states);
7525 strv_free(arg_properties);
7527 return r < 0 ? EXIT_FAILURE : r;