1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
41 #include "sd-daemon.h"
42 #include "sd-shutdown.h"
49 #include "utmp-wtmp.h"
52 #include "path-util.h"
54 #include "cgroup-show.h"
55 #include "cgroup-util.h"
57 #include "path-lookup.h"
58 #include "conf-parser.h"
59 #include "exit-status.h"
60 #include "bus-errors.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "path-util.h"
69 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
75 static char **arg_types = NULL;
76 static char **arg_states = NULL;
77 static char **arg_properties = NULL;
78 static bool arg_all = false;
79 static bool original_stdout_is_tty;
80 static enum dependency {
85 } arg_dependency = DEPENDENCY_FORWARD;
86 static const char *arg_job_mode = "replace";
87 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
88 static bool arg_no_block = false;
89 static bool arg_no_legend = false;
90 static bool arg_no_pager = false;
91 static bool arg_no_wtmp = false;
92 static bool arg_no_wall = false;
93 static bool arg_no_reload = false;
94 static bool arg_show_types = false;
95 static bool arg_ignore_inhibitors = false;
96 static bool arg_dry = false;
97 static bool arg_quiet = false;
98 static bool arg_full = false;
99 static int arg_force = 0;
100 static bool arg_ask_password = true;
101 static bool arg_runtime = false;
102 static char **arg_wall = NULL;
103 static const char *arg_kill_who = NULL;
104 static int arg_signal = SIGTERM;
105 static const char *arg_root = NULL;
106 static usec_t arg_when = 0;
128 ACTION_CANCEL_SHUTDOWN,
130 } arg_action = ACTION_SYSTEMCTL;
131 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
132 static char *arg_host = NULL;
133 static unsigned arg_lines = 10;
134 static OutputMode arg_output = OUTPUT_SHORT;
135 static bool arg_plain = false;
137 static int daemon_reload(sd_bus *bus, char **args);
138 static void halt_now(enum action a);
140 static void pager_open_if_enabled(void) {
148 static void ask_password_agent_open_if_enabled(void) {
150 /* Open the password agent as a child process if necessary */
152 if (!arg_ask_password)
155 if (arg_scope != UNIT_FILE_SYSTEM)
158 if (arg_transport != BUS_TRANSPORT_LOCAL)
161 ask_password_agent_open();
165 static void polkit_agent_open_if_enabled(void) {
167 /* Open the polkit agent as a child process if necessary */
169 if (!arg_ask_password)
172 if (arg_scope != UNIT_FILE_SYSTEM)
175 if (arg_transport != BUS_TRANSPORT_LOCAL)
182 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
185 if (!sd_bus_error_is_set(error))
188 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
189 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
190 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
191 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
192 return EXIT_NOPERMISSION;
194 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
195 return EXIT_NOTINSTALLED;
197 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
198 sd_bus_error_has_name(error, BUS_ERROR_NOT_SUPPORTED))
199 return EXIT_NOTIMPLEMENTED;
201 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
202 return EXIT_NOTCONFIGURED;
210 static void warn_wall(enum action a) {
211 static const char *table[_ACTION_MAX] = {
212 [ACTION_HALT] = "The system is going down for system halt NOW!",
213 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
214 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
215 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
216 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
217 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
218 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
225 _cleanup_free_ char *p;
227 p = strv_join(arg_wall, " ");
242 utmp_wall(table[a], NULL);
245 static bool avoid_bus(void) {
247 if (running_in_chroot() > 0)
250 if (sd_booted() <= 0)
253 if (!isempty(arg_root))
256 if (arg_scope == UNIT_FILE_GLOBAL)
262 static int compare_unit_info(const void *a, const void *b) {
263 const UnitInfo *u = a, *v = b;
266 d1 = strrchr(u->id, '.');
267 d2 = strrchr(v->id, '.');
272 r = strcasecmp(d1, d2);
277 return strcasecmp(u->id, v->id);
280 static bool output_show_unit(const UnitInfo *u) {
283 if (!strv_isempty(arg_states))
285 strv_contains(arg_states, u->load_state) ||
286 strv_contains(arg_states, u->sub_state) ||
287 strv_contains(arg_states, u->active_state);
289 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
290 strv_find(arg_types, dot+1))) &&
291 (arg_all || !(streq(u->active_state, "inactive")
292 || u->following[0]) || u->job_id > 0);
295 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
296 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
298 unsigned n_shown = 0;
301 max_id_len = sizeof("UNIT")-1;
302 load_len = sizeof("LOAD")-1;
303 active_len = sizeof("ACTIVE")-1;
304 sub_len = sizeof("SUB")-1;
305 job_len = sizeof("JOB")-1;
308 for (u = unit_infos; u < unit_infos + c; u++) {
309 if (!output_show_unit(u))
312 max_id_len = MAX(max_id_len, strlen(u->id));
313 load_len = MAX(load_len, strlen(u->load_state));
314 active_len = MAX(active_len, strlen(u->active_state));
315 sub_len = MAX(sub_len, strlen(u->sub_state));
317 if (u->job_id != 0) {
318 job_len = MAX(job_len, strlen(u->job_type));
323 if (!arg_full && original_stdout_is_tty) {
326 id_len = MIN(max_id_len, 25u);
327 basic_len = 5 + id_len + 5 + active_len + sub_len;
330 basic_len += job_len + 1;
332 if (basic_len < (unsigned) columns()) {
333 unsigned extra_len, incr;
334 extra_len = columns() - basic_len;
336 /* Either UNIT already got 25, or is fully satisfied.
337 * Grant up to 25 to DESC now. */
338 incr = MIN(extra_len, 25u);
342 /* split the remaining space between UNIT and DESC,
343 * but do not give UNIT more than it needs. */
345 incr = MIN(extra_len / 2, max_id_len - id_len);
347 desc_len += extra_len - incr;
353 for (u = unit_infos; u < unit_infos + c; u++) {
354 _cleanup_free_ char *e = NULL;
355 const char *on_loaded, *off_loaded, *on = "";
356 const char *on_active, *off_active, *off = "";
358 if (!output_show_unit(u))
361 if (!n_shown && !arg_no_legend) {
362 printf("%-*s %-*s %-*s %-*s ",
365 active_len, "ACTIVE",
369 printf("%-*s ", job_len, "JOB");
371 if (!arg_full && arg_no_pager)
372 printf("%.*s\n", desc_len, "DESCRIPTION");
374 printf("%s\n", "DESCRIPTION");
379 if (streq(u->load_state, "error") ||
380 streq(u->load_state, "not-found")) {
381 on_loaded = on = ansi_highlight_red();
382 off_loaded = off = ansi_highlight_off();
384 on_loaded = off_loaded = "";
386 if (streq(u->active_state, "failed")) {
387 on_active = on = ansi_highlight_red();
388 off_active = off = ansi_highlight_off();
390 on_active = off_active = "";
392 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
394 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
395 on, id_len, e ? e : u->id, off,
396 on_loaded, load_len, u->load_state, off_loaded,
397 on_active, active_len, u->active_state,
398 sub_len, u->sub_state, off_active,
399 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
402 printf("%.*s\n", desc_len, u->description);
404 printf("%s\n", u->description);
407 if (!arg_no_legend) {
408 const char *on, *off;
411 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
412 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
413 "SUB = The low-level unit activation state, values depend on unit type.\n");
415 printf("JOB = Pending job for the unit.\n");
417 on = ansi_highlight();
418 off = ansi_highlight_off();
420 on = ansi_highlight_red();
421 off = ansi_highlight_off();
425 printf("%s%u loaded units listed.%s\n"
426 "To show all installed unit files use 'systemctl list-unit-files'.\n",
429 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
430 "To show all installed unit files use 'systemctl list-unit-files'.\n",
435 static int get_unit_list(
437 sd_bus_message **_reply,
438 UnitInfo **_unit_infos) {
440 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
441 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
442 _cleanup_free_ UnitInfo *unit_infos = NULL;
451 r = sd_bus_call_method(
453 "org.freedesktop.systemd1",
454 "/org/freedesktop/systemd1",
455 "org.freedesktop.systemd1.Manager",
461 log_error("Failed to list units: %s", bus_error_message(&error, r));
465 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
467 return bus_log_parse_error(r);
469 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
471 if (!GREEDY_REALLOC(unit_infos, size, c+1))
477 return bus_log_parse_error(r);
479 r = sd_bus_message_exit_container(reply);
481 return bus_log_parse_error(r);
486 *_unit_infos = unit_infos;
492 static int list_units(sd_bus *bus, char **args) {
493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
494 _cleanup_free_ UnitInfo *unit_infos = NULL;
497 pager_open_if_enabled();
499 r = get_unit_list(bus, &reply, &unit_infos);
503 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
504 output_units_list(unit_infos, r);
509 static int get_triggered_units(
514 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
517 r = sd_bus_get_property_strv(
519 "org.freedesktop.systemd1",
521 "org.freedesktop.systemd1.Unit",
527 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
532 static int get_listening(
534 const char* unit_path,
538 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
539 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
540 const char *type, *path;
543 r = sd_bus_get_property(
545 "org.freedesktop.systemd1",
547 "org.freedesktop.systemd1.Socket",
553 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
557 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
559 return bus_log_parse_error(r);
561 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
563 r = strv_extend(listen, type);
567 r = strv_extend(listen, path);
574 return bus_log_parse_error(r);
576 r = sd_bus_message_exit_container(reply);
578 return bus_log_parse_error(r);
589 /* Note: triggered is a list here, although it almost certainly
590 * will always be one unit. Nevertheless, dbus API allows for multiple
591 * values, so let's follow that.*/
594 /* The strv above is shared. free is set only in the first one. */
598 static int socket_info_compare(struct socket_info *a, struct socket_info *b) {
601 o = strcmp(a->path, b->path);
603 o = strcmp(a->type, b->type);
608 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
609 struct socket_info *s;
610 unsigned pathlen = sizeof("LISTEN") - 1,
611 typelen = (sizeof("TYPE") - 1) * arg_show_types,
612 socklen = sizeof("UNIT") - 1,
613 servlen = sizeof("ACTIVATES") - 1;
614 const char *on, *off;
616 for (s = socket_infos; s < socket_infos + cs; s++) {
620 socklen = MAX(socklen, strlen(s->id));
622 typelen = MAX(typelen, strlen(s->type));
623 pathlen = MAX(pathlen, strlen(s->path));
625 STRV_FOREACH(a, s->triggered)
626 tmp += strlen(*a) + 2*(a != s->triggered);
627 servlen = MAX(servlen, tmp);
632 printf("%-*s %-*.*s%-*s %s\n",
634 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
638 for (s = socket_infos; s < socket_infos + cs; s++) {
642 printf("%-*s %-*s %-*s",
643 pathlen, s->path, typelen, s->type, socklen, s->id);
646 pathlen, s->path, socklen, s->id);
647 STRV_FOREACH(a, s->triggered)
649 a == s->triggered ? "" : ",", *a);
653 on = ansi_highlight();
654 off = ansi_highlight_off();
658 on = ansi_highlight_red();
659 off = ansi_highlight_off();
662 if (!arg_no_legend) {
663 printf("%s%u sockets listed.%s\n", on, cs, off);
665 printf("Pass --all to see loaded but inactive sockets, too.\n");
671 static int list_sockets(sd_bus *bus, char **args) {
672 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
673 _cleanup_free_ UnitInfo *unit_infos = NULL;
674 struct socket_info *socket_infos = NULL;
676 struct socket_info *s;
677 unsigned cu = 0, cs = 0;
681 pager_open_if_enabled();
683 r = get_unit_list(bus, &reply, &unit_infos);
689 for (u = unit_infos; u < unit_infos + cu; u++) {
690 _cleanup_strv_free_ char **listen = NULL, **triggered = NULL;
693 if (!output_show_unit(u))
696 if (!endswith(u->id, ".socket"))
699 r = get_triggered_units(bus, u->unit_path, &triggered);
703 r = get_listening(bus, u->unit_path, &listen, &c);
707 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
712 for (i = 0; i < c; i++)
713 socket_infos[cs + i] = (struct socket_info) {
716 .path = listen[i*2 + 1],
717 .triggered = triggered,
718 .own_triggered = i==0,
721 /* from this point on we will cleanup those socket_infos */
724 listen = triggered = NULL; /* avoid cleanup */
727 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
728 (__compar_fn_t) socket_info_compare);
730 output_sockets_list(socket_infos, cs);
733 assert(cs == 0 || socket_infos);
734 for (s = socket_infos; s < socket_infos + cs; s++) {
737 if (s->own_triggered)
738 strv_free(s->triggered);
745 static int compare_unit_file_list(const void *a, const void *b) {
747 const UnitFileList *u = a, *v = b;
749 d1 = strrchr(u->path, '.');
750 d2 = strrchr(v->path, '.');
755 r = strcasecmp(d1, d2);
760 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
763 static bool output_show_unit_file(const UnitFileList *u) {
766 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
769 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
770 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
771 const UnitFileList *u;
773 max_id_len = sizeof("UNIT FILE")-1;
774 state_cols = sizeof("STATE")-1;
776 for (u = units; u < units + c; u++) {
777 if (!output_show_unit_file(u))
780 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
781 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
787 id_cols = MIN(max_id_len, 25u);
788 basic_cols = 1 + id_cols + state_cols;
789 if (basic_cols < (unsigned) columns())
790 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
792 id_cols = max_id_len;
795 printf("%-*s %-*s\n",
796 id_cols, "UNIT FILE",
797 state_cols, "STATE");
799 for (u = units; u < units + c; u++) {
800 _cleanup_free_ char *e = NULL;
801 const char *on, *off;
804 if (!output_show_unit_file(u))
809 if (u->state == UNIT_FILE_MASKED ||
810 u->state == UNIT_FILE_MASKED_RUNTIME ||
811 u->state == UNIT_FILE_DISABLED ||
812 u->state == UNIT_FILE_INVALID) {
813 on = ansi_highlight_red();
814 off = ansi_highlight_off();
815 } else if (u->state == UNIT_FILE_ENABLED) {
816 on = ansi_highlight_green();
817 off = ansi_highlight_off();
821 id = path_get_file_name(u->path);
823 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
825 printf("%-*s %s%-*s%s\n",
827 on, state_cols, unit_file_state_to_string(u->state), off);
831 printf("\n%u unit files listed.\n", n_shown);
834 static int list_unit_files(sd_bus *bus, char **args) {
835 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
836 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
837 _cleanup_free_ UnitFileList *units = NULL;
843 pager_open_if_enabled();
851 h = hashmap_new(string_hash_func, string_compare_func);
855 r = unit_file_get_list(arg_scope, arg_root, h);
857 unit_file_list_free(h);
858 log_error("Failed to get unit file list: %s", strerror(-r));
862 n_units = hashmap_size(h);
863 units = new(UnitFileList, n_units);
865 unit_file_list_free(h);
869 HASHMAP_FOREACH(u, h, i) {
870 memcpy(units + c++, u, sizeof(UnitFileList));
874 assert(c == n_units);
879 r = sd_bus_call_method(
881 "org.freedesktop.systemd1",
882 "/org/freedesktop/systemd1",
883 "org.freedesktop.systemd1.Manager",
889 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
893 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
895 return bus_log_parse_error(r);
897 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
899 if (!GREEDY_REALLOC(units, size, c + 1))
902 units[c++] = (struct UnitFileList) {
904 unit_file_state_from_string(state)
908 return bus_log_parse_error(r);
910 r = sd_bus_message_exit_container(reply);
912 return bus_log_parse_error(r);
916 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
917 output_unit_file_list(units, c);
923 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
924 _cleanup_free_ char *n = NULL;
925 size_t max_len = MAX(columns(),20u);
931 for (i = level - 1; i >= 0; i--) {
933 if(len > max_len - 3 && !arg_full) {
934 printf("%s...\n",max_len % 2 ? "" : " ");
937 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
941 if(len > max_len - 3 && !arg_full) {
942 printf("%s...\n",max_len % 2 ? "" : " ");
946 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
950 printf("%s\n", name);
954 n = ellipsize(name, max_len-len, 100);
962 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
964 static const char *dependencies[] = {
965 [DEPENDENCY_FORWARD] = "Requires\0"
966 "RequiresOverridable\0"
968 "RequisiteOverridable\0"
970 [DEPENDENCY_REVERSE] = "RequiredBy\0"
971 "RequiredByOverridable\0"
974 [DEPENDENCY_AFTER] = "After\0",
975 [DEPENDENCY_BEFORE] = "Before\0",
978 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
979 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
980 _cleanup_strv_free_ char **ret = NULL;
981 _cleanup_free_ char *path = NULL;
987 assert(arg_dependency < ELEMENTSOF(dependencies));
989 path = unit_dbus_path_from_name(name);
993 r = sd_bus_call_method(
995 "org.freedesktop.systemd1",
997 "org.freedesktop.DBus.Properties",
1001 "s", "org.freedesktop.systemd1.Unit");
1003 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1007 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1009 return bus_log_parse_error(r);
1011 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1014 r = sd_bus_message_read(reply, "s", &prop);
1016 return bus_log_parse_error(r);
1018 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1019 r = sd_bus_message_skip(reply, "v");
1021 return bus_log_parse_error(r);
1024 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1026 return bus_log_parse_error(r);
1028 r = bus_message_read_strv_extend(reply, &ret);
1030 return bus_log_parse_error(r);
1032 r = sd_bus_message_exit_container(reply);
1034 return bus_log_parse_error(r);
1037 r = sd_bus_message_exit_container(reply);
1039 return bus_log_parse_error(r);
1043 return bus_log_parse_error(r);
1045 r = sd_bus_message_exit_container(reply);
1047 return bus_log_parse_error(r);
1055 static int list_dependencies_compare(const void *_a, const void *_b) {
1056 const char **a = (const char**) _a, **b = (const char**) _b;
1058 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1060 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1063 return strcasecmp(*a, *b);
1066 static int list_dependencies_one(
1071 unsigned int branches) {
1073 _cleanup_strv_free_ char **deps = NULL, **u;
1081 u = strv_append(*units, name);
1085 r = list_dependencies_get_dependencies(bus, name, &deps);
1089 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1091 STRV_FOREACH(c, deps) {
1092 if (strv_contains(u, *c)) {
1094 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1101 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1105 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1106 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1121 static int list_dependencies(sd_bus *bus, char **args) {
1122 _cleanup_strv_free_ char **units = NULL;
1123 _cleanup_free_ char *unit = NULL;
1129 unit = unit_name_mangle(args[1]);
1134 u = SPECIAL_DEFAULT_TARGET;
1136 pager_open_if_enabled();
1140 return list_dependencies_one(bus, u, 0, &units, 0);
1143 static int get_default(sd_bus *bus, char **args) {
1144 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1145 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1146 _cleanup_free_ char *_path = NULL;
1150 if (!bus || avoid_bus()) {
1151 r = unit_file_get_default(arg_scope, arg_root, &_path);
1153 log_error("Failed to get default target: %s", strerror(-r));
1159 r = sd_bus_call_method(
1161 "org.freedesktop.systemd1",
1162 "/org/freedesktop/systemd1",
1163 "org.freedesktop.systemd1.Manager",
1169 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1173 r = sd_bus_message_read(reply, "s", &path);
1175 return bus_log_parse_error(r);
1179 printf("%s\n", path);
1186 const char *name, *type, *state;
1189 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1190 unsigned id_len, unit_len, type_len, state_len;
1191 const struct job_info *j;
1192 const char *on, *off;
1193 bool shorten = false;
1195 assert(n == 0 || jobs);
1198 on = ansi_highlight_green();
1199 off = ansi_highlight_off();
1201 printf("%sNo jobs running.%s\n", on, off);
1205 pager_open_if_enabled();
1207 id_len = unit_len = type_len = state_len = 0;
1208 for (j = jobs; j < jobs + n; j++) {
1209 uint32_t id = j->id;
1210 assert(j->name && j->type && j->state);
1212 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1213 unit_len = MAX(unit_len, strlen(j->name));
1214 type_len = MAX(type_len, strlen(j->type));
1215 state_len = MAX(state_len, strlen(j->state));
1218 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1219 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1223 printf("%*s %-*s %-*s %-*s\n",
1227 state_len, "STATE");
1229 for (j = jobs; j < jobs + n; j++) {
1230 _cleanup_free_ char *e = NULL;
1232 if (streq(j->state, "running")) {
1233 on = ansi_highlight();
1234 off = ansi_highlight_off();
1238 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1239 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1241 on, unit_len, e ? e : j->name, off,
1243 on, state_len, j->state, off);
1246 on = ansi_highlight();
1247 off = ansi_highlight_off();
1249 printf("\n%s%u jobs listed%s.\n", on, n, off);
1252 static int list_jobs(sd_bus *bus, char **args) {
1253 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1254 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1255 const char *name, *type, *state, *job_path, *unit_path;
1256 _cleanup_free_ struct job_info *jobs = NULL;
1262 r = sd_bus_call_method(
1264 "org.freedesktop.systemd1",
1265 "/org/freedesktop/systemd1",
1266 "org.freedesktop.systemd1.Manager",
1272 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1276 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1278 return bus_log_parse_error(r);
1280 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1282 if (!GREEDY_REALLOC(jobs, size, c + 1))
1285 jobs[c++] = (struct job_info) {
1293 return bus_log_parse_error(r);
1295 r = sd_bus_message_exit_container(reply);
1297 return bus_log_parse_error(r);
1299 output_jobs_list(jobs, c);
1303 static int cancel_job(sd_bus *bus, char **args) {
1304 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1309 if (strv_length(args) <= 1)
1310 return daemon_reload(bus, args);
1312 STRV_FOREACH(name, args+1) {
1316 r = safe_atou32(*name, &id);
1318 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1322 r = sd_bus_call_method(
1324 "org.freedesktop.systemd1",
1325 "/org/freedesktop/systemd1",
1326 "org.freedesktop.systemd1.Manager",
1332 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1340 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1341 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1342 _cleanup_free_ char *n = NULL;
1346 /* We ignore all errors here, since this is used to show a
1349 n = unit_name_mangle(unit);
1353 /* We don't use unit_dbus_path_from_name() directly since we
1354 * don't want to load the unit if it isn't loaded. */
1356 r = sd_bus_call_method(
1358 "org.freedesktop.systemd1",
1359 "/org/freedesktop/systemd1",
1360 "org.freedesktop.systemd1.Manager",
1368 r = sd_bus_message_read(reply, "o", &path);
1372 r = sd_bus_get_property_trivial(
1374 "org.freedesktop.systemd1",
1376 "org.freedesktop.systemd1.Unit",
1386 typedef struct WaitData {
1393 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1400 log_debug("Got D-Bus request: %s.%s() on %s",
1401 sd_bus_message_get_interface(m),
1402 sd_bus_message_get_member(m),
1403 sd_bus_message_get_path(m));
1405 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1406 log_error("Warning! D-Bus connection terminated.");
1408 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1410 const char *path, *result, *unit;
1414 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1416 ret = set_remove(d->set, (char*) path);
1422 if (!isempty(result))
1423 d->result = strdup(result);
1426 d->name = strdup(unit);
1431 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1433 ret = set_remove(d->set, (char*) path);
1440 d->result = strdup(result);
1446 log_error("Failed to parse message.");
1452 static int enable_wait_for_jobs(sd_bus *bus) {
1457 r = sd_bus_add_match(
1460 "sender='org.freedesktop.systemd1',"
1461 "interface='org.freedesktop.systemd1.Manager',"
1462 "member='JobRemoved',"
1463 "path='/org/freedesktop/systemd1'",
1466 log_error("Failed to add match");
1470 /* This is slightly dirty, since we don't undo the match registrations. */
1474 static int wait_for_jobs(sd_bus *bus, Set *s) {
1475 WaitData d = { .set = s };
1481 r = sd_bus_add_filter(bus, wait_filter, &d);
1485 while (!set_isempty(s)) {
1487 r = sd_bus_process(bus, NULL);
1492 r = sd_bus_wait(bus, (uint64_t) -1);
1501 if (streq(d.result, "timeout"))
1502 log_error("Job for %s timed out.", strna(d.name));
1503 else if (streq(d.result, "canceled"))
1504 log_error("Job for %s canceled.", strna(d.name));
1505 else if (streq(d.result, "dependency"))
1506 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1507 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1508 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1511 if (streq_ptr(d.result, "timeout"))
1513 else if (streq_ptr(d.result, "canceled"))
1515 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1526 return sd_bus_remove_filter(bus, wait_filter, &d);
1529 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1530 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1531 _cleanup_free_ char *n = NULL, *state = NULL;
1537 n = unit_name_mangle(name);
1541 /* We don't use unit_dbus_path_from_name() directly since we
1542 * don't want to load the unit if it isn't loaded. */
1544 r = sd_bus_call_method(
1546 "org.freedesktop.systemd1",
1547 "/org/freedesktop/systemd1",
1548 "org.freedesktop.systemd1.Manager",
1559 r = sd_bus_message_read(reply, "o", &path);
1561 return bus_log_parse_error(r);
1563 r = sd_bus_get_property_string(
1565 "org.freedesktop.systemd1",
1567 "org.freedesktop.systemd1.Unit",
1580 return nulstr_contains(good_states, state);
1583 static int check_triggering_units(
1587 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1588 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1589 _cleanup_strv_free_ char **triggered_by = NULL;
1590 bool print_warning_label = true;
1594 n = unit_name_mangle(name);
1598 path = unit_dbus_path_from_name(n);
1602 r = sd_bus_get_property_string(
1604 "org.freedesktop.systemd1",
1606 "org.freedesktop.systemd1.Unit",
1611 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1615 if (streq(state, "masked"))
1618 r = sd_bus_get_property_strv(
1620 "org.freedesktop.systemd1",
1622 "org.freedesktop.systemd1.Unit",
1627 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1631 STRV_FOREACH(i, triggered_by) {
1632 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1634 log_error("Failed to check unit: %s", strerror(-r));
1641 if (print_warning_label) {
1642 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1643 print_warning_label = false;
1646 log_warning(" %s", *i);
1652 static int start_unit_one(
1657 sd_bus_error *error,
1660 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1661 _cleanup_free_ char *n;
1670 n = unit_name_mangle(name);
1674 r = sd_bus_call_method(
1676 "org.freedesktop.systemd1",
1677 "/org/freedesktop/systemd1",
1678 "org.freedesktop.systemd1.Manager",
1684 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1685 /* There's always a fallback possible for
1686 * legacy actions. */
1687 return -EADDRNOTAVAIL;
1689 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1693 r = sd_bus_message_read(reply, "o", &path);
1695 return bus_log_parse_error(r);
1697 if (need_daemon_reload(bus, n) > 0)
1698 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1699 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1708 r = set_consume(s, p);
1716 static const struct {
1720 } action_table[_ACTION_MAX] = {
1721 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1722 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1723 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1724 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1725 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1726 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1727 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1728 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1729 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1730 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1731 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1732 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1733 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1734 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1735 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1738 static enum action verb_to_action(const char *verb) {
1741 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1742 if (streq_ptr(action_table[i].verb, verb))
1745 return _ACTION_INVALID;
1748 static int start_unit(sd_bus *bus, char **args) {
1749 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1750 _cleanup_set_free_free_ Set *s = NULL;
1751 const char *method, *mode, *one_name;
1757 ask_password_agent_open_if_enabled();
1759 if (arg_action == ACTION_SYSTEMCTL) {
1762 streq(args[0], "stop") ||
1763 streq(args[0], "condstop") ? "StopUnit" :
1764 streq(args[0], "reload") ? "ReloadUnit" :
1765 streq(args[0], "restart") ? "RestartUnit" :
1767 streq(args[0], "try-restart") ||
1768 streq(args[0], "condrestart") ? "TryRestartUnit" :
1770 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1772 streq(args[0], "reload-or-try-restart") ||
1773 streq(args[0], "condreload") ||
1774 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
1776 action = verb_to_action(args[0]);
1778 mode = streq(args[0], "isolate") ? "isolate" :
1779 action_table[action].mode ?: arg_job_mode;
1781 one_name = action_table[action].target;
1783 assert(arg_action < ELEMENTSOF(action_table));
1784 assert(action_table[arg_action].target);
1786 method = "StartUnit";
1788 mode = action_table[arg_action].mode;
1789 one_name = action_table[arg_action].target;
1792 if (!arg_no_block) {
1793 r = enable_wait_for_jobs(bus);
1795 log_error("Could not watch jobs: %s", strerror(-r));
1799 s = set_new(string_hash_func, string_compare_func);
1805 r = start_unit_one(bus, method, one_name, mode, &error, s);
1807 r = translate_bus_error_to_exit_status(r, &error);
1811 STRV_FOREACH(name, args+1) {
1814 q = start_unit_one(bus, method, *name, mode, &error, s);
1816 r = translate_bus_error_to_exit_status(r, &error);
1817 sd_bus_error_free(&error);
1822 if (!arg_no_block) {
1825 q = wait_for_jobs(bus, s);
1829 /* When stopping units, warn if they can still be triggered by
1830 * another active unit (socket, path, timer) */
1831 if (!arg_quiet && streq(method, "StopUnit")) {
1833 check_triggering_units(bus, one_name);
1835 STRV_FOREACH(name, args+1)
1836 check_triggering_units(bus, *name);
1843 /* Ask systemd-logind, which might grant access to unprivileged users
1844 * through PolicyKit */
1845 static int reboot_with_logind(sd_bus *bus, enum action a) {
1847 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1854 polkit_agent_open_if_enabled();
1862 case ACTION_POWEROFF:
1863 method = "PowerOff";
1866 case ACTION_SUSPEND:
1870 case ACTION_HIBERNATE:
1871 method = "Hibernate";
1874 case ACTION_HYBRID_SLEEP:
1875 method = "HybridSleep";
1882 r = sd_bus_call_method(
1884 "org.freedesktop.login1",
1885 "/org/freedesktop/login1",
1886 "org.freedesktop.login1.Manager",
1892 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
1900 static int check_inhibitors(sd_bus *bus, enum action a) {
1902 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1903 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1904 _cleanup_strv_free_ char **sessions = NULL;
1905 const char *what, *who, *why, *mode;
1914 if (arg_ignore_inhibitors || arg_force > 0)
1926 r = sd_bus_call_method(
1928 "org.freedesktop.login1",
1929 "/org/freedesktop/login1",
1930 "org.freedesktop.login1.Manager",
1936 /* If logind is not around, then there are no inhibitors... */
1939 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
1941 return bus_log_parse_error(r);
1943 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
1944 _cleanup_free_ char *comm = NULL, *user = NULL;
1945 _cleanup_strv_free_ char **sv = NULL;
1947 if (!streq(mode, "block"))
1950 sv = strv_split(what, ":");
1954 if (!strv_contains(sv,
1956 a == ACTION_POWEROFF ||
1957 a == ACTION_REBOOT ||
1958 a == ACTION_KEXEC ? "shutdown" : "sleep"))
1961 get_process_comm(pid, &comm);
1962 user = uid_to_name(uid);
1964 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
1965 who, (unsigned long) pid, strna(comm), strna(user), why);
1970 return bus_log_parse_error(r);
1972 r = sd_bus_message_exit_container(reply);
1974 return bus_log_parse_error(r);
1976 /* Check for current sessions */
1977 sd_get_sessions(&sessions);
1978 STRV_FOREACH(s, sessions) {
1979 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
1981 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
1984 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
1987 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
1990 sd_session_get_tty(*s, &tty);
1991 sd_session_get_seat(*s, &seat);
1992 sd_session_get_service(*s, &service);
1993 user = uid_to_name(uid);
1995 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2002 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2003 action_table[a].verb);
2011 static int start_special(sd_bus *bus, char **args) {
2017 a = verb_to_action(args[0]);
2019 r = check_inhibitors(bus, a);
2023 if (arg_force >= 2 && geteuid() != 0) {
2024 log_error("Must be root.");
2028 if (arg_force >= 2 &&
2029 (a == ACTION_HALT ||
2030 a == ACTION_POWEROFF ||
2031 a == ACTION_REBOOT))
2034 if (arg_force >= 1 &&
2035 (a == ACTION_HALT ||
2036 a == ACTION_POWEROFF ||
2037 a == ACTION_REBOOT ||
2038 a == ACTION_KEXEC ||
2040 return daemon_reload(bus, args);
2042 /* first try logind, to allow authentication with polkit */
2043 if (geteuid() != 0 &&
2044 (a == ACTION_POWEROFF ||
2045 a == ACTION_REBOOT ||
2046 a == ACTION_SUSPEND ||
2047 a == ACTION_HIBERNATE ||
2048 a == ACTION_HYBRID_SLEEP)) {
2049 r = reboot_with_logind(bus, a);
2054 r = start_unit(bus, args);
2055 if (r == EXIT_SUCCESS)
2061 static int check_unit_active(sd_bus *bus, char **args) {
2063 int r = 3; /* According to LSB: "program is not running" */
2068 STRV_FOREACH(name, args+1) {
2071 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2081 static int check_unit_failed(sd_bus *bus, char **args) {
2088 STRV_FOREACH(name, args+1) {
2091 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2101 static int kill_unit(sd_bus *bus, char **args) {
2102 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2110 arg_kill_who = "all";
2112 STRV_FOREACH(name, args+1) {
2113 _cleanup_free_ char *n = NULL;
2115 n = unit_name_mangle(*name);
2119 r = sd_bus_call_method(
2121 "org.freedesktop.systemd1",
2122 "/org/freedesktop/systemd1",
2123 "org.freedesktop.systemd1.Manager",
2127 "ssi", n, arg_kill_who, arg_signal);
2129 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2137 typedef struct ExecStatusInfo {
2145 usec_t start_timestamp;
2146 usec_t exit_timestamp;
2151 LIST_FIELDS(struct ExecStatusInfo, exec);
2154 static void exec_status_info_free(ExecStatusInfo *i) {
2163 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2164 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2167 int32_t code, status;
2173 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2175 return bus_log_parse_error(r);
2179 r = sd_bus_message_read(m, "s", &path);
2181 return bus_log_parse_error(r);
2183 i->path = strdup(path);
2187 r = sd_bus_message_read_strv(m, &i->argv);
2189 return bus_log_parse_error(r);
2191 r = sd_bus_message_read(m,
2194 &start_timestamp, &start_timestamp_monotonic,
2195 &exit_timestamp, &exit_timestamp_monotonic,
2199 return bus_log_parse_error(r);
2202 i->start_timestamp = (usec_t) start_timestamp;
2203 i->exit_timestamp = (usec_t) exit_timestamp;
2204 i->pid = (pid_t) pid;
2208 r = sd_bus_message_exit_container(m);
2210 return bus_log_parse_error(r);
2215 typedef struct UnitStatusInfo {
2217 const char *load_state;
2218 const char *active_state;
2219 const char *sub_state;
2220 const char *unit_file_state;
2222 const char *description;
2223 const char *following;
2225 char **documentation;
2227 const char *fragment_path;
2228 const char *source_path;
2229 const char *control_group;
2231 char **dropin_paths;
2233 const char *load_error;
2236 usec_t inactive_exit_timestamp;
2237 usec_t inactive_exit_timestamp_monotonic;
2238 usec_t active_enter_timestamp;
2239 usec_t active_exit_timestamp;
2240 usec_t inactive_enter_timestamp;
2242 bool need_daemon_reload;
2247 const char *status_text;
2248 const char *pid_file;
2251 usec_t start_timestamp;
2252 usec_t exit_timestamp;
2254 int exit_code, exit_status;
2256 usec_t condition_timestamp;
2257 bool condition_result;
2258 bool failed_condition_trigger;
2259 bool failed_condition_negate;
2260 const char *failed_condition;
2261 const char *failed_condition_param;
2264 unsigned n_accepted;
2265 unsigned n_connections;
2268 /* Pairs of type, path */
2272 const char *sysfs_path;
2274 /* Mount, Automount */
2280 LIST_HEAD(ExecStatusInfo, exec);
2283 static void print_status_info(
2288 const char *on, *off, *ss;
2290 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2291 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2294 arg_all * OUTPUT_SHOW_ALL |
2295 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2296 on_tty() * OUTPUT_COLOR |
2297 !arg_quiet * OUTPUT_WARN_CUTOFF |
2298 arg_full * OUTPUT_FULL_WIDTH;
2303 /* This shows pretty information about a unit. See
2304 * print_property() for a low-level property printer */
2306 printf("%s", strna(i->id));
2308 if (i->description && !streq_ptr(i->id, i->description))
2309 printf(" - %s", i->description);
2314 printf(" Follow: unit currently follows state of %s\n", i->following);
2316 if (streq_ptr(i->load_state, "error")) {
2317 on = ansi_highlight_red();
2318 off = ansi_highlight_off();
2322 path = i->source_path ? i->source_path : i->fragment_path;
2325 printf(" Loaded: %s%s%s (Reason: %s)\n",
2326 on, strna(i->load_state), off, i->load_error);
2327 else if (path && i->unit_file_state)
2328 printf(" Loaded: %s%s%s (%s; %s)\n",
2329 on, strna(i->load_state), off, path, i->unit_file_state);
2331 printf(" Loaded: %s%s%s (%s)\n",
2332 on, strna(i->load_state), off, path);
2334 printf(" Loaded: %s%s%s\n",
2335 on, strna(i->load_state), off);
2337 if (!strv_isempty(i->dropin_paths)) {
2338 _cleanup_free_ char *dir = NULL;
2342 STRV_FOREACH(dropin, i->dropin_paths) {
2343 if (! dir || last) {
2344 printf(dir ? " " : " Drop-In: ");
2349 if (path_get_parent(*dropin, &dir) < 0) {
2354 printf("%s\n %s", dir,
2355 draw_special_char(DRAW_TREE_RIGHT));
2358 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2360 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2364 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2366 if (streq_ptr(i->active_state, "failed")) {
2367 on = ansi_highlight_red();
2368 off = ansi_highlight_off();
2369 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2370 on = ansi_highlight_green();
2371 off = ansi_highlight_off();
2376 printf(" Active: %s%s (%s)%s",
2377 on, strna(i->active_state), ss, off);
2379 printf(" Active: %s%s%s",
2380 on, strna(i->active_state), off);
2382 if (!isempty(i->result) && !streq(i->result, "success"))
2383 printf(" (Result: %s)", i->result);
2385 timestamp = (streq_ptr(i->active_state, "active") ||
2386 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2387 (streq_ptr(i->active_state, "inactive") ||
2388 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2389 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2390 i->active_exit_timestamp;
2392 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2393 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2396 printf(" since %s; %s\n", s2, s1);
2398 printf(" since %s\n", s2);
2402 if (!i->condition_result && i->condition_timestamp > 0) {
2403 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2404 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2406 printf(" start condition failed at %s%s%s\n",
2407 s2, s1 ? "; " : "", s1 ? s1 : "");
2408 if (i->failed_condition_trigger)
2409 printf(" none of the trigger conditions were met\n");
2410 else if (i->failed_condition)
2411 printf(" %s=%s%s was not met\n",
2412 i->failed_condition,
2413 i->failed_condition_negate ? "!" : "",
2414 i->failed_condition_param);
2418 printf(" Device: %s\n", i->sysfs_path);
2420 printf(" Where: %s\n", i->where);
2422 printf(" What: %s\n", i->what);
2424 STRV_FOREACH(t, i->documentation)
2425 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2427 STRV_FOREACH_PAIR(t, t2, i->listen)
2428 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2431 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2433 LIST_FOREACH(exec, p, i->exec) {
2434 _cleanup_free_ char *argv = NULL;
2437 /* Only show exited processes here */
2441 argv = strv_join(p->argv, " ");
2442 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2444 good = is_clean_exit_lsb(p->code, p->status, NULL);
2446 on = ansi_highlight_red();
2447 off = ansi_highlight_off();
2451 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2453 if (p->code == CLD_EXITED) {
2456 printf("status=%i", p->status);
2458 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2463 printf("signal=%s", signal_to_string(p->status));
2465 printf(")%s\n", off);
2467 if (i->main_pid == p->pid &&
2468 i->start_timestamp == p->start_timestamp &&
2469 i->exit_timestamp == p->start_timestamp)
2470 /* Let's not show this twice */
2473 if (p->pid == i->control_pid)
2477 if (i->main_pid > 0 || i->control_pid > 0) {
2478 if (i->main_pid > 0) {
2479 printf(" Main PID: %u", (unsigned) i->main_pid);
2482 _cleanup_free_ char *comm = NULL;
2483 get_process_comm(i->main_pid, &comm);
2485 printf(" (%s)", comm);
2486 } else if (i->exit_code > 0) {
2487 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2489 if (i->exit_code == CLD_EXITED) {
2492 printf("status=%i", i->exit_status);
2494 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2499 printf("signal=%s", signal_to_string(i->exit_status));
2503 if (i->control_pid > 0)
2507 if (i->control_pid > 0) {
2508 _cleanup_free_ char *c = NULL;
2510 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2512 get_process_comm(i->control_pid, &c);
2521 printf(" Status: \"%s\"\n", i->status_text);
2523 if (i->control_group &&
2524 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2527 printf(" CGroup: %s\n", i->control_group);
2529 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2532 char prefix[] = " ";
2535 if (c > sizeof(prefix) - 1)
2536 c -= sizeof(prefix) - 1;
2540 if (i->main_pid > 0)
2541 extra[k++] = i->main_pid;
2543 if (i->control_pid > 0)
2544 extra[k++] = i->control_pid;
2546 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2547 c, false, extra, k, flags);
2551 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2553 show_journal_by_unit(stdout,
2557 i->inactive_exit_timestamp_monotonic,
2561 arg_scope == UNIT_FILE_SYSTEM,
2565 if (i->need_daemon_reload)
2566 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2567 ansi_highlight_red(),
2568 ansi_highlight_off(),
2569 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2572 static void show_unit_help(UnitStatusInfo *i) {
2577 if (!i->documentation) {
2578 log_info("Documentation for %s not known.", i->id);
2582 STRV_FOREACH(p, i->documentation) {
2584 if (startswith(*p, "man:")) {
2585 const char *args[4] = { "man", NULL, NULL, NULL };
2586 _cleanup_free_ char *page = NULL, *section = NULL;
2593 if ((*p)[k-1] == ')')
2594 e = strrchr(*p, '(');
2597 page = strndup((*p) + 4, e - *p - 4);
2598 section = strndup(e + 1, *p + k - e - 2);
2599 if (!page || !section) {
2611 log_error("Failed to fork: %m");
2617 execvp(args[0], (char**) args);
2618 log_error("Failed to execute man: %m");
2619 _exit(EXIT_FAILURE);
2622 wait_for_terminate(pid, NULL);
2624 log_info("Can't show: %s", *p);
2628 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2635 switch (contents[0]) {
2637 case SD_BUS_TYPE_STRING: {
2640 r = sd_bus_message_read(m, "s", &s);
2642 return bus_log_parse_error(r);
2645 if (streq(name, "Id"))
2647 else if (streq(name, "LoadState"))
2649 else if (streq(name, "ActiveState"))
2650 i->active_state = s;
2651 else if (streq(name, "SubState"))
2653 else if (streq(name, "Description"))
2655 else if (streq(name, "FragmentPath"))
2656 i->fragment_path = s;
2657 else if (streq(name, "SourcePath"))
2660 else if (streq(name, "DefaultControlGroup")) {
2662 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2664 i->control_group = e;
2667 else if (streq(name, "ControlGroup"))
2668 i->control_group = s;
2669 else if (streq(name, "StatusText"))
2671 else if (streq(name, "PIDFile"))
2673 else if (streq(name, "SysFSPath"))
2675 else if (streq(name, "Where"))
2677 else if (streq(name, "What"))
2679 else if (streq(name, "Following"))
2681 else if (streq(name, "UnitFileState"))
2682 i->unit_file_state = s;
2683 else if (streq(name, "Result"))
2690 case SD_BUS_TYPE_BOOLEAN: {
2693 r = sd_bus_message_read(m, "b", &b);
2695 return bus_log_parse_error(r);
2697 if (streq(name, "Accept"))
2699 else if (streq(name, "NeedDaemonReload"))
2700 i->need_daemon_reload = b;
2701 else if (streq(name, "ConditionResult"))
2702 i->condition_result = b;
2707 case SD_BUS_TYPE_UINT32: {
2710 r = sd_bus_message_read(m, "u", &u);
2712 return bus_log_parse_error(r);
2714 if (streq(name, "MainPID")) {
2716 i->main_pid = (pid_t) u;
2719 } else if (streq(name, "ControlPID"))
2720 i->control_pid = (pid_t) u;
2721 else if (streq(name, "ExecMainPID")) {
2723 i->main_pid = (pid_t) u;
2724 } else if (streq(name, "NAccepted"))
2726 else if (streq(name, "NConnections"))
2727 i->n_connections = u;
2732 case SD_BUS_TYPE_INT32: {
2735 r = sd_bus_message_read(m, "i", &j);
2737 return bus_log_parse_error(r);
2739 if (streq(name, "ExecMainCode"))
2740 i->exit_code = (int) j;
2741 else if (streq(name, "ExecMainStatus"))
2742 i->exit_status = (int) j;
2747 case SD_BUS_TYPE_UINT64: {
2750 r = sd_bus_message_read(m, "t", &u);
2752 return bus_log_parse_error(r);
2754 if (streq(name, "ExecMainStartTimestamp"))
2755 i->start_timestamp = (usec_t) u;
2756 else if (streq(name, "ExecMainExitTimestamp"))
2757 i->exit_timestamp = (usec_t) u;
2758 else if (streq(name, "ActiveEnterTimestamp"))
2759 i->active_enter_timestamp = (usec_t) u;
2760 else if (streq(name, "InactiveEnterTimestamp"))
2761 i->inactive_enter_timestamp = (usec_t) u;
2762 else if (streq(name, "InactiveExitTimestamp"))
2763 i->inactive_exit_timestamp = (usec_t) u;
2764 else if (streq(name, "InactiveExitTimestampMonotonic"))
2765 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2766 else if (streq(name, "ActiveExitTimestamp"))
2767 i->active_exit_timestamp = (usec_t) u;
2768 else if (streq(name, "ConditionTimestamp"))
2769 i->condition_timestamp = (usec_t) u;
2774 case SD_BUS_TYPE_ARRAY:
2776 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
2777 _cleanup_free_ ExecStatusInfo *info = NULL;
2779 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
2781 return bus_log_parse_error(r);
2783 info = new0(ExecStatusInfo, 1);
2787 while ((r = exec_status_info_deserialize(m, info)) > 0) {
2789 info->name = strdup(name);
2793 LIST_PREPEND(exec, i->exec, info);
2795 info = new0(ExecStatusInfo, 1);
2801 return bus_log_parse_error(r);
2803 r = sd_bus_message_exit_container(m);
2805 return bus_log_parse_error(r);
2809 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
2810 const char *type, *path;
2812 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2814 return bus_log_parse_error(r);
2816 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
2818 r = strv_extend(&i->listen, type);
2822 r = strv_extend(&i->listen, path);
2827 return bus_log_parse_error(r);
2829 r = sd_bus_message_exit_container(m);
2831 return bus_log_parse_error(r);
2835 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
2837 r = sd_bus_message_read_strv(m, &i->dropin_paths);
2839 return bus_log_parse_error(r);
2841 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
2843 r = sd_bus_message_read_strv(m, &i->documentation);
2845 return bus_log_parse_error(r);
2847 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
2848 const char *cond, *param;
2849 int trigger, negate;
2852 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
2854 return bus_log_parse_error(r);
2856 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
2857 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
2858 if (state < 0 && (!trigger || !i->failed_condition)) {
2859 i->failed_condition = cond;
2860 i->failed_condition_trigger = trigger;
2861 i->failed_condition_negate = negate;
2862 i->failed_condition_param = param;
2866 return bus_log_parse_error(r);
2868 r = sd_bus_message_exit_container(m);
2870 return bus_log_parse_error(r);
2877 case SD_BUS_TYPE_STRUCT_BEGIN:
2879 if (streq(name, "LoadError")) {
2880 const char *n, *message;
2882 r = sd_bus_message_read(m, "(ss)", &n, &message);
2884 return bus_log_parse_error(r);
2886 if (!isempty(message))
2887 i->load_error = message;
2900 r = sd_bus_message_skip(m, contents);
2902 return bus_log_parse_error(r);
2907 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
2913 /* This is a low-level property printer, see
2914 * print_status_info() for the nicer output */
2916 if (arg_properties && !strv_find(arg_properties, name))
2919 switch (contents[0]) {
2921 case SD_BUS_TYPE_STRUCT_BEGIN:
2923 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
2926 r = sd_bus_message_read(m, "(uo)", &u, NULL);
2928 return bus_log_parse_error(r);
2931 printf("%s=%u\n", name, (unsigned) u);
2933 printf("%s=\n", name);
2937 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
2940 r = sd_bus_message_read(m, "(so)", &s, NULL);
2942 return bus_log_parse_error(r);
2944 if (arg_all || !isempty(s))
2945 printf("%s=%s\n", name, s);
2949 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
2950 const char *a = NULL, *b = NULL;
2952 r = sd_bus_message_read(m, "(ss)", &a, &b);
2954 return bus_log_parse_error(r);
2956 if (arg_all || !isempty(a) || !isempty(b))
2957 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
2964 case SD_BUS_TYPE_ARRAY:
2966 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
2970 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
2972 return bus_log_parse_error(r);
2974 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
2975 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
2978 return bus_log_parse_error(r);
2980 r = sd_bus_message_exit_container(m);
2982 return bus_log_parse_error(r);
2986 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
2987 const char *type, *path;
2989 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2991 return bus_log_parse_error(r);
2993 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
2994 printf("%s=%s\n", type, path);
2996 return bus_log_parse_error(r);
2998 r = sd_bus_message_exit_container(m);
3000 return bus_log_parse_error(r);
3004 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3005 const char *type, *path;
3007 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3009 return bus_log_parse_error(r);
3011 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3012 printf("Listen%s=%s\n", type, path);
3014 return bus_log_parse_error(r);
3016 r = sd_bus_message_exit_container(m);
3018 return bus_log_parse_error(r);
3022 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3024 uint64_t value, next_elapse;
3026 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3028 return bus_log_parse_error(r);
3030 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3031 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3033 printf("%s={ value=%s ; next_elapse=%s }\n",
3035 format_timespan(timespan1, sizeof(timespan1), value, 0),
3036 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3039 return bus_log_parse_error(r);
3041 r = sd_bus_message_exit_container(m);
3043 return bus_log_parse_error(r);
3047 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3048 ExecStatusInfo info = {};
3050 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3052 return bus_log_parse_error(r);
3054 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3055 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3056 _cleanup_free_ char *tt;
3058 tt = strv_join(info.argv, " ");
3060 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3064 yes_no(info.ignore),
3065 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3066 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3067 (unsigned) info. pid,
3068 sigchld_code_to_string(info.code),
3070 info.code == CLD_EXITED ? "" : "/",
3071 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3074 strv_free(info.argv);
3078 r = sd_bus_message_exit_container(m);
3080 return bus_log_parse_error(r);
3084 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3085 const char *path, *rwm;
3087 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3089 return bus_log_parse_error(r);
3091 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3092 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3094 return bus_log_parse_error(r);
3096 r = sd_bus_message_exit_container(m);
3098 return bus_log_parse_error(r);
3102 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3106 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3108 return bus_log_parse_error(r);
3110 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3111 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3113 return bus_log_parse_error(r);
3115 r = sd_bus_message_exit_container(m);
3117 return bus_log_parse_error(r);
3121 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3125 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3127 return bus_log_parse_error(r);
3129 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3130 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3132 return bus_log_parse_error(r);
3134 r = sd_bus_message_exit_container(m);
3136 return bus_log_parse_error(r);
3144 r = bus_print_property(name, m, arg_all);
3146 return bus_log_parse_error(r);
3149 r = sd_bus_message_skip(m, contents);
3151 return bus_log_parse_error(r);
3154 printf("%s=[unprintable]\n", name);
3160 static int show_one(
3164 bool show_properties,
3168 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3169 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3170 UnitStatusInfo info = {};
3177 r = sd_bus_call_method(
3179 "org.freedesktop.systemd1",
3181 "org.freedesktop.DBus.Properties",
3187 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3191 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3193 return bus_log_parse_error(r);
3200 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3201 const char *name, *contents;
3203 r = sd_bus_message_read(reply, "s", &name);
3205 return bus_log_parse_error(r);
3207 r = sd_bus_message_peek_type(reply, NULL, &contents);
3209 return bus_log_parse_error(r);
3211 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3213 return bus_log_parse_error(r);
3215 if (show_properties)
3216 r = print_property(name, reply, contents);
3218 r = status_property(name, reply, &info, contents);
3222 r = sd_bus_message_exit_container(reply);
3224 return bus_log_parse_error(r);
3226 r = sd_bus_message_exit_container(reply);
3228 return bus_log_parse_error(r);
3231 return bus_log_parse_error(r);
3233 r = sd_bus_message_exit_container(reply);
3235 return bus_log_parse_error(r);
3239 if (!show_properties) {
3240 if (streq(verb, "help"))
3241 show_unit_help(&info);
3243 print_status_info(&info, ellipsized);
3246 strv_free(info.documentation);
3247 strv_free(info.dropin_paths);
3248 strv_free(info.listen);
3250 if (!streq_ptr(info.active_state, "active") &&
3251 !streq_ptr(info.active_state, "reloading") &&
3252 streq(verb, "status")) {
3253 /* According to LSB: "program not running" */
3254 /* 0: program is running or service is OK
3255 * 1: program is dead and /var/run pid file exists
3256 * 2: program is dead and /var/lock lock file exists
3257 * 3: program is not running
3258 * 4: program or service status is unknown
3260 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3266 while ((p = info.exec)) {
3267 LIST_REMOVE(exec, info.exec, p);
3268 exec_status_info_free(p);
3274 static int show_one_by_pid(
3281 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3282 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3283 const char *path = NULL;
3286 r = sd_bus_call_method(
3288 "org.freedesktop.systemd1",
3289 "/org/freedesktop/systemd1",
3290 "org.freedesktop.systemd1.Manager",
3296 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3300 r = sd_bus_message_read(reply, "o", &path);
3302 return bus_log_parse_error(r);
3304 return show_one(verb, bus, path, false, new_line, ellipsized);
3307 static int show_all(
3310 bool show_properties,
3314 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3315 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3316 _cleanup_free_ UnitInfo *unit_infos = NULL;
3321 r = get_unit_list(bus, &reply, &unit_infos);
3327 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3329 for (u = unit_infos; u < unit_infos + c; u++) {
3330 _cleanup_free_ char *p = NULL;
3332 if (!output_show_unit(u))
3335 p = unit_dbus_path_from_name(u->id);
3339 printf("%s -> '%s'\n", u->id, p);
3341 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3349 static int show(sd_bus *bus, char **args) {
3351 bool show_properties, show_status, new_line = false;
3353 bool ellipsized = false;
3358 show_properties = streq(args[0], "show");
3359 show_status = streq(args[0], "status");
3361 if (show_properties)
3362 pager_open_if_enabled();
3364 /* If no argument is specified inspect the manager itself */
3366 if (show_properties && strv_length(args) <= 1)
3367 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3369 if (show_status && strv_length(args) <= 1)
3370 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3372 STRV_FOREACH(name, args+1) {
3375 if (safe_atou32(*name, &id) < 0) {
3376 _cleanup_free_ char *p = NULL, *n = NULL;
3377 /* Interpret as unit name */
3379 n = unit_name_mangle(*name);
3383 p = unit_dbus_path_from_name(n);
3387 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3391 } else if (show_properties) {
3392 _cleanup_free_ char *p = NULL;
3394 /* Interpret as job id */
3395 if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
3398 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3403 /* Interpret as PID */
3404 r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized);
3410 if (ellipsized && !arg_quiet)
3411 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3416 static int append_assignment(sd_bus_message *m, const char *assignment) {
3424 eq = strchr(assignment, '=');
3426 log_error("Not an assignment: %s", assignment);
3430 field = strndupa(assignment, eq - assignment);
3433 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3435 return bus_log_create_error(r);
3437 if (streq(field, "CPUAccounting") ||
3438 streq(field, "MemoryAccounting") ||
3439 streq(field, "BlockIOAccounting")) {
3441 r = parse_boolean(eq);
3443 log_error("Failed to parse boolean assignment %s.", assignment);
3447 r = sd_bus_message_append(m, "v", "b", r);
3449 } else if (streq(field, "MemoryLimit")) {
3452 r = parse_bytes(eq, &bytes);
3454 log_error("Failed to parse bytes specification %s", assignment);
3458 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3460 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3463 r = safe_atou64(eq, &u);
3465 log_error("Failed to parse %s value %s.", field, eq);
3469 r = sd_bus_message_append(m, "v", "t", u);
3471 } else if (streq(field, "DevicePolicy"))
3472 r = sd_bus_message_append(m, "v", "s", eq);
3474 else if (streq(field, "DeviceAllow")) {
3477 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3479 const char *path, *rwm;
3482 e = strchr(eq, ' ');
3484 path = strndupa(eq, e - eq);
3491 if (!path_startswith(path, "/dev")) {
3492 log_error("%s is not a device file in /dev.", path);
3496 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3499 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3502 r = sd_bus_message_append(m, "v", "a(st)", 0);
3504 const char *path, *bandwidth;
3508 e = strchr(eq, ' ');
3510 path = strndupa(eq, e - eq);
3513 log_error("Failed to parse %s value %s.", field, eq);
3517 if (!path_startswith(path, "/dev")) {
3518 log_error("%s is not a device file in /dev.", path);
3522 r = parse_bytes(bandwidth, &bytes);
3524 log_error("Failed to parse byte value %s.", bandwidth);
3528 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3531 } else if (streq(field, "BlockIODeviceWeight")) {
3534 r = sd_bus_message_append(m, "v", "a(st)", 0);
3536 const char *path, *weight;
3540 e = strchr(eq, ' ');
3542 path = strndupa(eq, e - eq);
3545 log_error("Failed to parse %s value %s.", field, eq);
3549 if (!path_startswith(path, "/dev")) {
3550 log_error("%s is not a device file in /dev.", path);
3554 r = safe_atou64(weight, &u);
3556 log_error("Failed to parse %s value %s.", field, weight);
3559 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3563 log_error("Unknown assignment %s.", assignment);
3568 return bus_log_create_error(r);
3573 static int set_property(sd_bus *bus, char **args) {
3574 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3575 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3576 _cleanup_free_ char *n = NULL;
3580 r = sd_bus_message_new_method_call(
3582 "org.freedesktop.systemd1",
3583 "/org/freedesktop/systemd1",
3584 "org.freedesktop.systemd1.Manager",
3585 "SetUnitProperties",
3588 return bus_log_create_error(r);
3590 n = unit_name_mangle(args[1]);
3594 r = sd_bus_message_append(m, "sb", n, arg_runtime);
3596 return bus_log_create_error(r);
3598 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
3600 return bus_log_create_error(r);
3602 STRV_FOREACH(i, args + 2) {
3603 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
3605 return bus_log_create_error(r);
3607 r = append_assignment(m, *i);
3611 r = sd_bus_message_close_container(m);
3613 return bus_log_create_error(r);
3616 r = sd_bus_message_close_container(m);
3618 return bus_log_create_error(r);
3620 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
3622 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
3629 static int snapshot(sd_bus *bus, char **args) {
3630 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3631 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3632 _cleanup_free_ char *n = NULL, *id = NULL;
3636 if (strv_length(args) > 1)
3637 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
3643 r = sd_bus_call_method(
3645 "org.freedesktop.systemd1",
3646 "/org/freedesktop/systemd1",
3647 "org.freedesktop.systemd1.Manager",
3653 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
3657 r = sd_bus_message_read(reply, "o", &path);
3659 return bus_log_parse_error(r);
3661 r = sd_bus_get_property_string(
3663 "org.freedesktop.systemd1",
3665 "org.freedesktop.systemd1.Unit",
3670 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
3680 static int delete_snapshot(sd_bus *bus, char **args) {
3681 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3687 STRV_FOREACH(name, args+1) {
3688 _cleanup_free_ char *n = NULL;
3690 n = unit_name_mangle_with_suffix(*name, ".snapshot");
3694 r = sd_bus_call_method(
3696 "org.freedesktop.systemd1",
3697 "/org/freedesktop/systemd1",
3698 "org.freedesktop.systemd1.Manager",
3704 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
3712 static int daemon_reload(sd_bus *bus, char **args) {
3713 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3717 if (arg_action == ACTION_RELOAD)
3719 else if (arg_action == ACTION_REEXEC)
3720 method = "Reexecute";
3722 assert(arg_action == ACTION_SYSTEMCTL);
3725 streq(args[0], "clear-jobs") ||
3726 streq(args[0], "cancel") ? "ClearJobs" :
3727 streq(args[0], "daemon-reexec") ? "Reexecute" :
3728 streq(args[0], "reset-failed") ? "ResetFailed" :
3729 streq(args[0], "halt") ? "Halt" :
3730 streq(args[0], "poweroff") ? "PowerOff" :
3731 streq(args[0], "reboot") ? "Reboot" :
3732 streq(args[0], "kexec") ? "KExec" :
3733 streq(args[0], "exit") ? "Exit" :
3734 /* "daemon-reload" */ "Reload";
3737 r = sd_bus_call_method(
3739 "org.freedesktop.systemd1",
3740 "/org/freedesktop/systemd1",
3741 "org.freedesktop.systemd1.Manager",
3747 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
3748 /* There's always a fallback possible for
3749 * legacy actions. */
3751 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
3752 /* On reexecution, we expect a disconnect, not a
3756 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3761 static int reset_failed(sd_bus *bus, char **args) {
3762 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3766 if (strv_length(args) <= 1)
3767 return daemon_reload(bus, args);
3769 STRV_FOREACH(name, args+1) {
3770 _cleanup_free_ char *n;
3772 n = unit_name_mangle(*name);
3776 r = sd_bus_call_method(
3778 "org.freedesktop.systemd1",
3779 "/org/freedesktop/systemd1",
3780 "org.freedesktop.systemd1.Manager",
3786 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
3794 static int show_environment(sd_bus *bus, char **args) {
3795 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3796 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3800 pager_open_if_enabled();
3802 r = sd_bus_get_property(
3804 "org.freedesktop.systemd1",
3805 "/org/freedesktop/systemd1",
3806 "org.freedesktop.systemd1.Manager",
3812 log_error("Failed to get environment: %s", bus_error_message(&error, r));
3816 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
3818 return bus_log_parse_error(r);
3820 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
3823 return bus_log_parse_error(r);
3825 r = sd_bus_message_exit_container(reply);
3827 return bus_log_parse_error(r);
3832 static int switch_root(sd_bus *bus, char **args) {
3833 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3834 _cleanup_free_ char *init = NULL;
3839 l = strv_length(args);
3840 if (l < 2 || l > 3) {
3841 log_error("Wrong number of arguments.");
3848 init = strdup(args[2]);
3850 parse_env_file("/proc/cmdline", WHITESPACE,
3861 log_debug("switching root - root: %s; init: %s", root, init);
3863 r = sd_bus_call_method(
3865 "org.freedesktop.systemd1",
3866 "/org/freedesktop/systemd1",
3867 "org.freedesktop.systemd1.Manager",
3873 log_error("Failed to switch root: %s", bus_error_message(&error, r));
3880 static int set_environment(sd_bus *bus, char **args) {
3881 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3882 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3889 method = streq(args[0], "set-environment")
3891 : "UnsetEnvironment";
3893 r = sd_bus_message_new_method_call(
3895 "org.freedesktop.systemd1",
3896 "/org/freedesktop/systemd1",
3897 "org.freedesktop.systemd1.Manager",
3901 return bus_log_create_error(r);
3903 r = sd_bus_message_append_strv(m, args + 1);
3905 return bus_log_create_error(r);
3907 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
3909 log_error("Failed to set environment: %s", bus_error_message(&error, r));
3916 static int enable_sysv_units(const char *verb, char **args) {
3919 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
3920 unsigned f = 1, t = 1;
3921 _cleanup_lookup_paths_free_ LookupPaths paths = {};
3923 if (arg_scope != UNIT_FILE_SYSTEM)
3926 if (!streq(verb, "enable") &&
3927 !streq(verb, "disable") &&
3928 !streq(verb, "is-enabled"))
3931 /* Processes all SysV units, and reshuffles the array so that
3932 * afterwards only the native units remain */
3934 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
3939 for (f = 0; args[f]; f++) {
3941 _cleanup_free_ char *p = NULL, *q = NULL;
3942 bool found_native = false, found_sysv;
3944 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
3952 if (!endswith(name, ".service"))
3955 if (path_is_absolute(name))
3958 STRV_FOREACH(k, paths.unit_path) {
3959 if (!isempty(arg_root))
3960 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
3962 asprintf(&p, "%s/%s", *k, name);
3969 found_native = access(p, F_OK) >= 0;
3980 if (!isempty(arg_root))
3981 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
3983 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
3989 p[strlen(p) - sizeof(".service") + 1] = 0;
3990 found_sysv = access(p, F_OK) >= 0;
3995 /* Mark this entry, so that we don't try enabling it as native unit */
3996 args[f] = (char*) "";
3998 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
4000 if (!isempty(arg_root))
4001 argv[c++] = q = strappend("--root=", arg_root);
4003 argv[c++] = path_get_file_name(p);
4005 streq(verb, "enable") ? "on" :
4006 streq(verb, "disable") ? "off" : "--level=5";
4009 l = strv_join((char**)argv, " ");
4015 log_info("Executing %s", l);
4020 log_error("Failed to fork: %m");
4023 } else if (pid == 0) {
4026 execv(argv[0], (char**) argv);
4027 _exit(EXIT_FAILURE);
4030 j = wait_for_terminate(pid, &status);
4032 log_error("Failed to wait for child: %s", strerror(-r));
4037 if (status.si_code == CLD_EXITED) {
4038 if (streq(verb, "is-enabled")) {
4039 if (status.si_status == 0) {
4048 } else if (status.si_status != 0) {
4059 /* Drop all SysV units */
4060 for (f = 0, t = 0; args[f]; f++) {
4062 if (isempty(args[f]))
4065 args[t++] = args[f];
4074 static int mangle_names(char **original_names, char ***mangled_names) {
4075 char **i, **l, **name;
4077 l = new(char*, strv_length(original_names) + 1);
4082 STRV_FOREACH(name, original_names) {
4084 /* When enabling units qualified path names are OK,
4085 * too, hence allow them explicitly. */
4090 *i = unit_name_mangle(*name);
4106 static int enable_unit(sd_bus *bus, char **args) {
4107 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4108 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4109 _cleanup_strv_free_ char **mangled_names = NULL;
4110 const char *verb = args[0];
4111 UnitFileChange *changes = NULL;
4112 unsigned n_changes = 0, i;
4113 int carries_install_info = -1;
4119 r = mangle_names(args+1, &mangled_names);
4123 r = enable_sysv_units(verb, mangled_names);
4127 if (!bus || avoid_bus()) {
4128 if (streq(verb, "enable")) {
4129 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4130 carries_install_info = r;
4131 } else if (streq(verb, "disable"))
4132 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4133 else if (streq(verb, "reenable")) {
4134 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4135 carries_install_info = r;
4136 } else if (streq(verb, "link"))
4137 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4138 else if (streq(verb, "preset")) {
4139 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4140 carries_install_info = r;
4141 } else if (streq(verb, "mask"))
4142 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4143 else if (streq(verb, "unmask"))
4144 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4145 else if (streq(verb, "set-default"))
4146 r = unit_file_set_default(arg_scope, arg_root, args[1], &changes, &n_changes);
4148 assert_not_reached("Unknown verb");
4151 log_error("Operation failed: %s", strerror(-r));
4156 for (i = 0; i < n_changes; i++) {
4157 if (changes[i].type == UNIT_FILE_SYMLINK)
4158 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
4160 log_info("rm '%s'", changes[i].path);
4166 const char *method, *type, *path, *source;
4167 int expect_carries_install_info = false;
4168 bool send_force = true;
4170 if (streq(verb, "enable")) {
4171 method = "EnableUnitFiles";
4172 expect_carries_install_info = true;
4173 } else if (streq(verb, "disable")) {
4174 method = "DisableUnitFiles";
4176 } else if (streq(verb, "reenable")) {
4177 method = "ReenableUnitFiles";
4178 expect_carries_install_info = true;
4179 } else if (streq(verb, "link"))
4180 method = "LinkUnitFiles";
4181 else if (streq(verb, "preset")) {
4182 method = "PresetUnitFiles";
4183 expect_carries_install_info = true;
4184 } else if (streq(verb, "mask"))
4185 method = "MaskUnitFiles";
4186 else if (streq(verb, "unmask")) {
4187 method = "UnmaskUnitFiles";
4189 } else if (streq(verb, "set-default")) {
4190 method = "SetDefaultTarget";
4192 assert_not_reached("Unknown verb");
4194 r = sd_bus_message_new_method_call(
4196 "org.freedesktop.systemd1",
4197 "/org/freedesktop/systemd1",
4198 "org.freedesktop.systemd1.Manager",
4202 return bus_log_create_error(r);
4204 r = sd_bus_message_append_strv(m, mangled_names);
4206 return bus_log_create_error(r);
4208 r = sd_bus_message_append(m, "b", arg_runtime);
4210 return bus_log_create_error(r);
4213 r = sd_bus_message_append(m, "b", arg_force);
4215 return bus_log_create_error(r);
4218 r = sd_bus_send_with_reply_and_block(bus, m, -0, &error, &reply);
4220 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4224 if (expect_carries_install_info) {
4225 r = sd_bus_message_read(reply, "b", &carries_install_info);
4227 return bus_log_parse_error(r);
4230 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(sss)");
4232 return bus_log_parse_error(r);
4234 while ((r = sd_bus_message_read(reply, "(sss)", &type, &path, &source)) > 0) {
4236 if (streq(type, "symlink"))
4237 log_info("ln -s '%s' '%s'", source, path);
4239 log_info("rm '%s'", path);
4243 return bus_log_parse_error(r);
4245 r = sd_bus_message_exit_container(reply);
4247 return bus_log_parse_error(r);
4249 /* Try to reload if enabeld */
4251 r = daemon_reload(bus, args);
4256 if (carries_install_info == 0)
4257 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4258 "using systemctl.\n"
4259 "Possible reasons for having this kind of units are:\n"
4260 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4261 " .wants/ or .requires/ directory.\n"
4262 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4263 " a requirement dependency on it.\n"
4264 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4265 " D-Bus, udev, scripted systemctl call, ...).\n");
4268 unit_file_changes_free(changes, n_changes);
4273 static int unit_is_enabled(sd_bus *bus, char **args) {
4275 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4276 _cleanup_strv_free_ char **mangled_names = NULL;
4281 r = mangle_names(args+1, &mangled_names);
4285 r = enable_sysv_units(args[0], mangled_names);
4291 if (!bus || avoid_bus()) {
4293 STRV_FOREACH(name, mangled_names) {
4294 UnitFileState state;
4296 state = unit_file_get_state(arg_scope, arg_root, *name);
4298 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4302 if (state == UNIT_FILE_ENABLED ||
4303 state == UNIT_FILE_ENABLED_RUNTIME ||
4304 state == UNIT_FILE_STATIC)
4308 puts(unit_file_state_to_string(state));
4312 STRV_FOREACH(name, mangled_names) {
4313 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4316 r = sd_bus_call_method(
4318 "org.freedesktop.systemd1",
4319 "/org/freedesktop/systemd1",
4320 "org.freedesktop.systemd1.Manager",
4326 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4330 r = sd_bus_message_read(reply, "s", &s);
4332 return bus_log_parse_error(r);
4334 if (streq(s, "enabled") ||
4335 streq(s, "enabled-runtime") ||
4347 static int systemctl_help(void) {
4349 pager_open_if_enabled();
4351 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4352 "Query or send control commands to the systemd manager.\n\n"
4353 " -h --help Show this help\n"
4354 " --version Show package version\n"
4355 " --system Connect to system manager\n"
4356 " --user Connect to user service manager\n"
4357 " -H --host=[USER@]HOST\n"
4358 " Operate on remote host\n"
4359 " -M --machine=CONTAINER\n"
4360 " Operate on local container\n"
4361 " -t --type=TYPE List only units of a particular type\n"
4362 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4363 " -p --property=NAME Show only properties by this name\n"
4364 " -a --all Show all loaded units/properties, including dead/empty\n"
4365 " ones. To list all units installed on the system, use\n"
4366 " the 'list-unit-files' command instead.\n"
4367 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4368 " -l --full Don't ellipsize unit names on output\n"
4369 " --fail When queueing a new job, fail if conflicting jobs are\n"
4371 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4373 " --ignore-dependencies\n"
4374 " When queueing a new job, ignore all its dependencies\n"
4375 " --show-types When showing sockets, explicitly show their type\n"
4376 " -i --ignore-inhibitors\n"
4377 " When shutting down or sleeping, ignore inhibitors\n"
4378 " --kill-who=WHO Who to send signal to\n"
4379 " -s --signal=SIGNAL Which signal to send\n"
4380 " -q --quiet Suppress output\n"
4381 " --no-block Do not wait until operation finished\n"
4382 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4383 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4385 " --no-legend Do not print a legend (column headers and hints)\n"
4386 " --no-pager Do not pipe output into a pager\n"
4387 " --no-ask-password\n"
4388 " Do not ask for system passwords\n"
4389 " --global Enable/disable unit files globally\n"
4390 " --runtime Enable unit files only temporarily until next reboot\n"
4391 " -f --force When enabling unit files, override existing symlinks\n"
4392 " When shutting down, execute action immediately\n"
4393 " --root=PATH Enable unit files in the specified root directory\n"
4394 " -n --lines=INTEGER Number of journal entries to show\n"
4395 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4396 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4398 " list-units List loaded units\n"
4399 " list-sockets List loaded sockets ordered by address\n"
4400 " start [NAME...] Start (activate) one or more units\n"
4401 " stop [NAME...] Stop (deactivate) one or more units\n"
4402 " reload [NAME...] Reload one or more units\n"
4403 " restart [NAME...] Start or restart one or more units\n"
4404 " try-restart [NAME...] Restart one or more units if active\n"
4405 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4406 " otherwise start or restart\n"
4407 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4408 " otherwise restart if active\n"
4409 " isolate [NAME] Start one unit and stop all others\n"
4410 " kill [NAME...] Send signal to processes of a unit\n"
4411 " is-active [NAME...] Check whether units are active\n"
4412 " is-failed [NAME...] Check whether units are failed\n"
4413 " status [NAME...|PID...] Show runtime status of one or more units\n"
4414 " show [NAME...|JOB...] Show properties of one or more\n"
4415 " units/jobs or the manager\n"
4416 " set-property [NAME] [ASSIGNMENT...]\n"
4417 " Sets one or more properties of a unit\n"
4418 " help [NAME...|PID...] Show manual for one or more units\n"
4419 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4421 " list-dependencies [NAME] Recursively show units which are required\n"
4422 " or wanted by this unit or by which this\n"
4423 " unit is required or wanted\n\n"
4424 "Unit File Commands:\n"
4425 " list-unit-files List installed unit files\n"
4426 " enable [NAME...] Enable one or more unit files\n"
4427 " disable [NAME...] Disable one or more unit files\n"
4428 " reenable [NAME...] Reenable one or more unit files\n"
4429 " preset [NAME...] Enable/disable one or more unit files\n"
4430 " based on preset configuration\n"
4431 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4432 " mask [NAME...] Mask one or more units\n"
4433 " unmask [NAME...] Unmask one or more units\n"
4434 " link [PATH...] Link one or more units files into\n"
4435 " the search path\n"
4436 " get-default Get the name of the default target\n"
4437 " set-default NAME Set the default target\n\n"
4439 " list-jobs List jobs\n"
4440 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4441 "Snapshot Commands:\n"
4442 " snapshot [NAME] Create a snapshot\n"
4443 " delete [NAME...] Remove one or more snapshots\n\n"
4444 "Environment Commands:\n"
4445 " show-environment Dump environment\n"
4446 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4447 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4448 "Manager Lifecycle Commands:\n"
4449 " daemon-reload Reload systemd manager configuration\n"
4450 " daemon-reexec Reexecute systemd manager\n\n"
4451 "System Commands:\n"
4452 " default Enter system default mode\n"
4453 " rescue Enter system rescue mode\n"
4454 " emergency Enter system emergency mode\n"
4455 " halt Shut down and halt the system\n"
4456 " poweroff Shut down and power-off the system\n"
4457 " reboot [ARG] Shut down and reboot the system\n"
4458 " kexec Shut down and reboot the system with kexec\n"
4459 " exit Request user instance exit\n"
4460 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4461 " suspend Suspend the system\n"
4462 " hibernate Hibernate the system\n"
4463 " hybrid-sleep Hibernate and suspend the system\n",
4464 program_invocation_short_name);
4469 static int halt_help(void) {
4471 printf("%s [OPTIONS...]%s\n\n"
4472 "%s the system.\n\n"
4473 " --help Show this help\n"
4474 " --halt Halt the machine\n"
4475 " -p --poweroff Switch off the machine\n"
4476 " --reboot Reboot the machine\n"
4477 " -f --force Force immediate halt/power-off/reboot\n"
4478 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4479 " -d --no-wtmp Don't write wtmp record\n"
4480 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4481 program_invocation_short_name,
4482 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4483 arg_action == ACTION_REBOOT ? "Reboot" :
4484 arg_action == ACTION_POWEROFF ? "Power off" :
4490 static int shutdown_help(void) {
4492 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4493 "Shut down the system.\n\n"
4494 " --help Show this help\n"
4495 " -H --halt Halt the machine\n"
4496 " -P --poweroff Power-off the machine\n"
4497 " -r --reboot Reboot the machine\n"
4498 " -h Equivalent to --poweroff, overridden by --halt\n"
4499 " -k Don't halt/power-off/reboot, just send warnings\n"
4500 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4501 " -c Cancel a pending shutdown\n",
4502 program_invocation_short_name);
4507 static int telinit_help(void) {
4509 printf("%s [OPTIONS...] {COMMAND}\n\n"
4510 "Send control commands to the init daemon.\n\n"
4511 " --help Show this help\n"
4512 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4514 " 0 Power-off the machine\n"
4515 " 6 Reboot the machine\n"
4516 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4517 " 1, s, S Enter rescue mode\n"
4518 " q, Q Reload init daemon configuration\n"
4519 " u, U Reexecute init daemon\n",
4520 program_invocation_short_name);
4525 static int runlevel_help(void) {
4527 printf("%s [OPTIONS...]\n\n"
4528 "Prints the previous and current runlevel of the init system.\n\n"
4529 " --help Show this help\n",
4530 program_invocation_short_name);
4535 static int help_types(void) {
4539 puts("Available unit types:");
4540 for(i = 0; i < _UNIT_TYPE_MAX; i++) {
4541 t = unit_type_to_string(i);
4549 static int systemctl_parse_argv(int argc, char *argv[]) {
4558 ARG_IGNORE_DEPENDENCIES,
4570 ARG_NO_ASK_PASSWORD,
4578 static const struct option options[] = {
4579 { "help", no_argument, NULL, 'h' },
4580 { "version", no_argument, NULL, ARG_VERSION },
4581 { "type", required_argument, NULL, 't' },
4582 { "property", required_argument, NULL, 'p' },
4583 { "all", no_argument, NULL, 'a' },
4584 { "reverse", no_argument, NULL, ARG_REVERSE },
4585 { "after", no_argument, NULL, ARG_AFTER },
4586 { "before", no_argument, NULL, ARG_BEFORE },
4587 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4588 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4589 { "full", no_argument, NULL, 'l' },
4590 { "fail", no_argument, NULL, ARG_FAIL },
4591 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
4592 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
4593 { "ignore-inhibitors", no_argument, NULL, 'i' },
4594 { "user", no_argument, NULL, ARG_USER },
4595 { "system", no_argument, NULL, ARG_SYSTEM },
4596 { "global", no_argument, NULL, ARG_GLOBAL },
4597 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4598 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4599 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4600 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4601 { "quiet", no_argument, NULL, 'q' },
4602 { "root", required_argument, NULL, ARG_ROOT },
4603 { "force", no_argument, NULL, ARG_FORCE },
4604 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4605 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4606 { "signal", required_argument, NULL, 's' },
4607 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4608 { "host", required_argument, NULL, 'H' },
4609 { "machine", required_argument, NULL, 'M' },
4610 { "runtime", no_argument, NULL, ARG_RUNTIME },
4611 { "lines", required_argument, NULL, 'n' },
4612 { "output", required_argument, NULL, 'o' },
4613 { "plain", no_argument, NULL, ARG_PLAIN },
4614 { "state", required_argument, NULL, ARG_STATE },
4623 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
4628 return systemctl_help();
4631 puts(PACKAGE_STRING);
4632 puts(SYSTEMD_FEATURES);
4639 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4640 _cleanup_free_ char *type;
4642 type = strndup(word, size);
4646 if (streq(type, "help")) {
4651 if (unit_type_from_string(type) >= 0) {
4652 if (strv_push(&arg_types, type))
4658 /* It's much nicer to use --state= for
4659 * load states, but let's support this
4660 * in --types= too for compatibility
4661 * with old versions */
4662 if (unit_load_state_from_string(optarg) >= 0) {
4663 if (strv_push(&arg_states, type) < 0)
4669 log_error("Unknown unit type or load state '%s'.", type);
4670 log_info("Use -t help to see a list of allowed values.");
4678 /* Make sure that if the empty property list
4679 was specified, we won't show any properties. */
4680 if (isempty(optarg) && !arg_properties) {
4681 arg_properties = new0(char*, 1);
4682 if (!arg_properties)
4688 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4691 prop = strndup(word, size);
4695 if (strv_push(&arg_properties, prop) < 0) {
4702 /* If the user asked for a particular
4703 * property, show it to him, even if it is
4715 arg_dependency = DEPENDENCY_REVERSE;
4719 arg_dependency = DEPENDENCY_AFTER;
4723 arg_dependency = DEPENDENCY_BEFORE;
4726 case ARG_SHOW_TYPES:
4727 arg_show_types = true;
4731 arg_job_mode = "fail";
4734 case ARG_IRREVERSIBLE:
4735 arg_job_mode = "replace-irreversibly";
4738 case ARG_IGNORE_DEPENDENCIES:
4739 arg_job_mode = "ignore-dependencies";
4743 arg_scope = UNIT_FILE_USER;
4747 arg_scope = UNIT_FILE_SYSTEM;
4751 arg_scope = UNIT_FILE_GLOBAL;
4755 arg_no_block = true;
4759 arg_no_legend = true;
4763 arg_no_pager = true;
4779 if (strv_extend(&arg_states, "failed") < 0)
4797 arg_no_reload = true;
4801 arg_kill_who = optarg;
4805 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
4806 log_error("Failed to parse signal string %s.", optarg);
4811 case ARG_NO_ASK_PASSWORD:
4812 arg_ask_password = false;
4816 arg_transport = BUS_TRANSPORT_REMOTE;
4821 arg_transport = BUS_TRANSPORT_CONTAINER;
4830 if (safe_atou(optarg, &arg_lines) < 0) {
4831 log_error("Failed to parse lines '%s'", optarg);
4837 arg_output = output_mode_from_string(optarg);
4838 if (arg_output < 0) {
4839 log_error("Unknown output '%s'.", optarg);
4845 arg_ignore_inhibitors = true;
4856 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4859 s = strndup(word, size);
4863 if (strv_push(&arg_states, s) < 0) {
4875 assert_not_reached("Unhandled option");
4879 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
4880 log_error("Cannot access user instance remotely.");
4887 static int halt_parse_argv(int argc, char *argv[]) {
4896 static const struct option options[] = {
4897 { "help", no_argument, NULL, ARG_HELP },
4898 { "halt", no_argument, NULL, ARG_HALT },
4899 { "poweroff", no_argument, NULL, 'p' },
4900 { "reboot", no_argument, NULL, ARG_REBOOT },
4901 { "force", no_argument, NULL, 'f' },
4902 { "wtmp-only", no_argument, NULL, 'w' },
4903 { "no-wtmp", no_argument, NULL, 'd' },
4904 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4913 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
4914 if (runlevel == '0' || runlevel == '6')
4917 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
4924 arg_action = ACTION_HALT;
4928 if (arg_action != ACTION_REBOOT)
4929 arg_action = ACTION_POWEROFF;
4933 arg_action = ACTION_REBOOT;
4955 /* Compatibility nops */
4962 assert_not_reached("Unhandled option");
4966 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
4967 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
4969 log_error("Failed to write reboot param to "
4970 REBOOT_PARAM_FILE": %s", strerror(-r));
4973 } else if (optind < argc) {
4974 log_error("Too many arguments.");
4981 static int parse_time_spec(const char *t, usec_t *_u) {
4985 if (streq(t, "now"))
4987 else if (!strchr(t, ':')) {
4990 if (safe_atou64(t, &u) < 0)
4993 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5002 hour = strtol(t, &e, 10);
5003 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5006 minute = strtol(e+1, &e, 10);
5007 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5010 n = now(CLOCK_REALTIME);
5011 s = (time_t) (n / USEC_PER_SEC);
5013 assert_se(localtime_r(&s, &tm));
5015 tm.tm_hour = (int) hour;
5016 tm.tm_min = (int) minute;
5019 assert_se(s = mktime(&tm));
5021 *_u = (usec_t) s * USEC_PER_SEC;
5024 *_u += USEC_PER_DAY;
5030 static int shutdown_parse_argv(int argc, char *argv[]) {
5037 static const struct option options[] = {
5038 { "help", no_argument, NULL, ARG_HELP },
5039 { "halt", no_argument, NULL, 'H' },
5040 { "poweroff", no_argument, NULL, 'P' },
5041 { "reboot", no_argument, NULL, 'r' },
5042 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5043 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5052 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5056 return shutdown_help();
5059 arg_action = ACTION_HALT;
5063 arg_action = ACTION_POWEROFF;
5068 arg_action = ACTION_KEXEC;
5070 arg_action = ACTION_REBOOT;
5074 arg_action = ACTION_KEXEC;
5078 if (arg_action != ACTION_HALT)
5079 arg_action = ACTION_POWEROFF;
5092 /* Compatibility nops */
5096 arg_action = ACTION_CANCEL_SHUTDOWN;
5103 assert_not_reached("Unhandled option");
5107 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5108 r = parse_time_spec(argv[optind], &arg_when);
5110 log_error("Failed to parse time specification: %s", argv[optind]);
5114 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5116 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5117 /* No time argument for shutdown cancel */
5118 arg_wall = argv + optind;
5119 else if (argc > optind + 1)
5120 /* We skip the time argument */
5121 arg_wall = argv + optind + 1;
5128 static int telinit_parse_argv(int argc, char *argv[]) {
5135 static const struct option options[] = {
5136 { "help", no_argument, NULL, ARG_HELP },
5137 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5141 static const struct {
5145 { '0', ACTION_POWEROFF },
5146 { '6', ACTION_REBOOT },
5147 { '1', ACTION_RESCUE },
5148 { '2', ACTION_RUNLEVEL2 },
5149 { '3', ACTION_RUNLEVEL3 },
5150 { '4', ACTION_RUNLEVEL4 },
5151 { '5', ACTION_RUNLEVEL5 },
5152 { 's', ACTION_RESCUE },
5153 { 'S', ACTION_RESCUE },
5154 { 'q', ACTION_RELOAD },
5155 { 'Q', ACTION_RELOAD },
5156 { 'u', ACTION_REEXEC },
5157 { 'U', ACTION_REEXEC }
5166 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5170 return telinit_help();
5180 assert_not_reached("Unhandled option");
5184 if (optind >= argc) {
5189 if (optind + 1 < argc) {
5190 log_error("Too many arguments.");
5194 if (strlen(argv[optind]) != 1) {
5195 log_error("Expected single character argument.");
5199 for (i = 0; i < ELEMENTSOF(table); i++)
5200 if (table[i].from == argv[optind][0])
5203 if (i >= ELEMENTSOF(table)) {
5204 log_error("Unknown command '%s'.", argv[optind]);
5208 arg_action = table[i].to;
5215 static int runlevel_parse_argv(int argc, char *argv[]) {
5221 static const struct option options[] = {
5222 { "help", no_argument, NULL, ARG_HELP },
5231 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5235 return runlevel_help();
5242 assert_not_reached("Unhandled option");
5246 if (optind < argc) {
5247 log_error("Too many arguments.");
5254 static int parse_argv(int argc, char *argv[]) {
5258 if (program_invocation_short_name) {
5260 if (strstr(program_invocation_short_name, "halt")) {
5261 arg_action = ACTION_HALT;
5262 return halt_parse_argv(argc, argv);
5263 } else if (strstr(program_invocation_short_name, "poweroff")) {
5264 arg_action = ACTION_POWEROFF;
5265 return halt_parse_argv(argc, argv);
5266 } else if (strstr(program_invocation_short_name, "reboot")) {
5268 arg_action = ACTION_KEXEC;
5270 arg_action = ACTION_REBOOT;
5271 return halt_parse_argv(argc, argv);
5272 } else if (strstr(program_invocation_short_name, "shutdown")) {
5273 arg_action = ACTION_POWEROFF;
5274 return shutdown_parse_argv(argc, argv);
5275 } else if (strstr(program_invocation_short_name, "init")) {
5277 if (sd_booted() > 0) {
5278 arg_action = _ACTION_INVALID;
5279 return telinit_parse_argv(argc, argv);
5281 /* Hmm, so some other init system is
5282 * running, we need to forward this
5283 * request to it. For now we simply
5284 * guess that it is Upstart. */
5286 execv(TELINIT, argv);
5288 log_error("Couldn't find an alternative telinit implementation to spawn.");
5292 } else if (strstr(program_invocation_short_name, "runlevel")) {
5293 arg_action = ACTION_RUNLEVEL;
5294 return runlevel_parse_argv(argc, argv);
5298 arg_action = ACTION_SYSTEMCTL;
5299 return systemctl_parse_argv(argc, argv);
5302 _pure_ static int action_to_runlevel(void) {
5304 static const char table[_ACTION_MAX] = {
5305 [ACTION_HALT] = '0',
5306 [ACTION_POWEROFF] = '0',
5307 [ACTION_REBOOT] = '6',
5308 [ACTION_RUNLEVEL2] = '2',
5309 [ACTION_RUNLEVEL3] = '3',
5310 [ACTION_RUNLEVEL4] = '4',
5311 [ACTION_RUNLEVEL5] = '5',
5312 [ACTION_RESCUE] = '1'
5315 assert(arg_action < _ACTION_MAX);
5317 return table[arg_action];
5320 static int talk_initctl(void) {
5322 struct init_request request = {
5323 .magic = INIT_MAGIC,
5325 .cmd = INIT_CMD_RUNLVL
5328 _cleanup_close_ int fd = -1;
5332 rl = action_to_runlevel();
5336 request.runlevel = rl;
5338 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5340 if (errno == ENOENT)
5343 log_error("Failed to open "INIT_FIFO": %m");
5348 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5350 log_error("Failed to write to "INIT_FIFO": %m");
5351 return errno > 0 ? -errno : -EIO;
5357 static int systemctl_main(sd_bus *bus, int argc, char *argv[], int bus_error) {
5359 static const struct {
5367 int (* const dispatch)(sd_bus *bus, char **args);
5369 { "list-units", LESS, 1, list_units },
5370 { "list-unit-files", EQUAL, 1, list_unit_files },
5371 { "list-sockets", LESS, 1, list_sockets },
5372 { "list-jobs", EQUAL, 1, list_jobs },
5373 { "clear-jobs", EQUAL, 1, daemon_reload },
5374 { "cancel", MORE, 2, cancel_job },
5375 { "start", MORE, 2, start_unit },
5376 { "stop", MORE, 2, start_unit },
5377 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5378 { "reload", MORE, 2, start_unit },
5379 { "restart", MORE, 2, start_unit },
5380 { "try-restart", MORE, 2, start_unit },
5381 { "reload-or-restart", MORE, 2, start_unit },
5382 { "reload-or-try-restart", MORE, 2, start_unit },
5383 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5384 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5385 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5386 { "isolate", EQUAL, 2, start_unit },
5387 { "kill", MORE, 2, kill_unit },
5388 { "is-active", MORE, 2, check_unit_active },
5389 { "check", MORE, 2, check_unit_active },
5390 { "is-failed", MORE, 2, check_unit_failed },
5391 { "show", MORE, 1, show },
5392 { "status", MORE, 1, show },
5393 { "help", MORE, 2, show },
5394 { "snapshot", LESS, 2, snapshot },
5395 { "delete", MORE, 2, delete_snapshot },
5396 { "daemon-reload", EQUAL, 1, daemon_reload },
5397 { "daemon-reexec", EQUAL, 1, daemon_reload },
5398 { "show-environment", EQUAL, 1, show_environment },
5399 { "set-environment", MORE, 2, set_environment },
5400 { "unset-environment", MORE, 2, set_environment },
5401 { "halt", EQUAL, 1, start_special },
5402 { "poweroff", EQUAL, 1, start_special },
5403 { "reboot", EQUAL, 1, start_special },
5404 { "kexec", EQUAL, 1, start_special },
5405 { "suspend", EQUAL, 1, start_special },
5406 { "hibernate", EQUAL, 1, start_special },
5407 { "hybrid-sleep", EQUAL, 1, start_special },
5408 { "default", EQUAL, 1, start_special },
5409 { "rescue", EQUAL, 1, start_special },
5410 { "emergency", EQUAL, 1, start_special },
5411 { "exit", EQUAL, 1, start_special },
5412 { "reset-failed", MORE, 1, reset_failed },
5413 { "enable", MORE, 2, enable_unit },
5414 { "disable", MORE, 2, enable_unit },
5415 { "is-enabled", MORE, 2, unit_is_enabled },
5416 { "reenable", MORE, 2, enable_unit },
5417 { "preset", MORE, 2, enable_unit },
5418 { "mask", MORE, 2, enable_unit },
5419 { "unmask", MORE, 2, enable_unit },
5420 { "link", MORE, 2, enable_unit },
5421 { "switch-root", MORE, 2, switch_root },
5422 { "list-dependencies", LESS, 2, list_dependencies },
5423 { "set-default", EQUAL, 2, enable_unit },
5424 { "get-default", LESS, 1, get_default },
5425 { "set-property", MORE, 3, set_property },
5434 left = argc - optind;
5437 /* Special rule: no arguments means "list-units" */
5440 if (streq(argv[optind], "help") && !argv[optind+1]) {
5441 log_error("This command expects one or more "
5442 "unit names. Did you mean --help?");
5446 for (i = 0; i < ELEMENTSOF(verbs); i++)
5447 if (streq(argv[optind], verbs[i].verb))
5450 if (i >= ELEMENTSOF(verbs)) {
5451 log_error("Unknown operation '%s'.", argv[optind]);
5456 switch (verbs[i].argc_cmp) {
5459 if (left != verbs[i].argc) {
5460 log_error("Invalid number of arguments.");
5467 if (left < verbs[i].argc) {
5468 log_error("Too few arguments.");
5475 if (left > verbs[i].argc) {
5476 log_error("Too many arguments.");
5483 assert_not_reached("Unknown comparison operator.");
5486 /* Require a bus connection for all operations but
5488 if (!streq(verbs[i].verb, "enable") &&
5489 !streq(verbs[i].verb, "disable") &&
5490 !streq(verbs[i].verb, "is-enabled") &&
5491 !streq(verbs[i].verb, "list-unit-files") &&
5492 !streq(verbs[i].verb, "reenable") &&
5493 !streq(verbs[i].verb, "preset") &&
5494 !streq(verbs[i].verb, "mask") &&
5495 !streq(verbs[i].verb, "unmask") &&
5496 !streq(verbs[i].verb, "link") &&
5497 !streq(verbs[i].verb, "set-default") &&
5498 !streq(verbs[i].verb, "get-default")) {
5500 if (running_in_chroot() > 0) {
5501 log_info("Running in chroot, ignoring request.");
5505 if (((!streq(verbs[i].verb, "reboot") &&
5506 !streq(verbs[i].verb, "halt") &&
5507 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5508 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5514 if (!bus && !avoid_bus()) {
5515 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error));
5520 return verbs[i].dispatch(bus, argv + optind);
5523 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5525 struct sd_shutdown_command c = {
5532 union sockaddr_union sockaddr = {
5533 .un.sun_family = AF_UNIX,
5534 .un.sun_path = "/run/systemd/shutdownd",
5537 struct iovec iovec[2] = {{
5538 .iov_base = (char*) &c,
5539 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5542 struct msghdr msghdr = {
5543 .msg_name = &sockaddr,
5544 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5545 + sizeof("/run/systemd/shutdownd") - 1,
5550 _cleanup_close_ int fd;
5552 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5556 if (!isempty(message)) {
5557 iovec[1].iov_base = (char*) message;
5558 iovec[1].iov_len = strlen(message);
5559 msghdr.msg_iovlen++;
5562 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5568 static int reload_with_fallback(sd_bus *bus) {
5571 /* First, try systemd via D-Bus. */
5572 if (daemon_reload(bus, NULL) >= 0)
5576 /* Nothing else worked, so let's try signals */
5577 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5579 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5580 log_error("kill() failed: %m");
5587 static int start_with_fallback(sd_bus *bus) {
5590 /* First, try systemd via D-Bus. */
5591 if (start_unit(bus, NULL) >= 0)
5595 /* Nothing else worked, so let's try
5597 if (talk_initctl() > 0)
5600 log_error("Failed to talk to init daemon.");
5604 warn_wall(arg_action);
5608 static _noreturn_ void halt_now(enum action a) {
5610 _cleanup_free_ char *param = NULL;
5612 /* Make sure C-A-D is handled by the kernel from this
5614 reboot(RB_ENABLE_CAD);
5619 log_info("Halting.");
5620 reboot(RB_HALT_SYSTEM);
5623 case ACTION_POWEROFF:
5624 log_info("Powering off.");
5625 reboot(RB_POWER_OFF);
5630 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) == 0) {
5631 log_info("Rebooting with arg '%s'.", param);
5632 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
5633 LINUX_REBOOT_CMD_RESTART2, param);
5635 log_info("Rebooting.");
5636 reboot(RB_AUTOBOOT);
5641 assert_not_reached("Unknown halt action.");
5644 assert_not_reached("Uh? This shouldn't happen.");
5647 static int halt_main(sd_bus *bus) {
5650 r = check_inhibitors(bus, arg_action);
5654 if (geteuid() != 0) {
5655 /* Try logind if we are a normal user and no special
5656 * mode applies. Maybe PolicyKit allows us to shutdown
5659 if (arg_when <= 0 &&
5662 (arg_action == ACTION_POWEROFF ||
5663 arg_action == ACTION_REBOOT)) {
5664 r = reboot_with_logind(bus, arg_action);
5669 log_error("Must be root.");
5674 _cleanup_free_ char *m;
5676 m = strv_join(arg_wall, " ");
5680 r = send_shutdownd(arg_when,
5681 arg_action == ACTION_HALT ? 'H' :
5682 arg_action == ACTION_POWEROFF ? 'P' :
5683 arg_action == ACTION_KEXEC ? 'K' :
5690 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
5692 char date[FORMAT_TIMESTAMP_MAX];
5694 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5695 format_timestamp(date, sizeof(date), arg_when));
5700 if (!arg_dry && !arg_force)
5701 return start_with_fallback(bus);
5704 if (sd_booted() > 0)
5705 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5707 r = utmp_put_shutdown();
5709 log_warning("Failed to write utmp record: %s", strerror(-r));
5716 halt_now(arg_action);
5717 /* We should never reach this. */
5721 static int runlevel_main(void) {
5722 int r, runlevel, previous;
5724 r = utmp_get_runlevel(&runlevel, &previous);
5731 previous <= 0 ? 'N' : previous,
5732 runlevel <= 0 ? 'N' : runlevel);
5737 int main(int argc, char*argv[]) {
5738 _cleanup_bus_unref_ sd_bus *bus = NULL;
5741 setlocale(LC_ALL, "");
5742 log_parse_environment();
5745 /* Explicitly not on_tty() to avoid setting cached value.
5746 * This becomes relevant for piping output which might be
5748 original_stdout_is_tty = isatty(STDOUT_FILENO);
5750 r = parse_argv(argc, argv);
5754 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5755 * let's shortcut this */
5756 if (arg_action == ACTION_RUNLEVEL) {
5757 r = runlevel_main();
5761 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
5762 log_info("Running in chroot, ignoring request.");
5768 r = bus_open_transport_systemd(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
5770 /* systemctl_main() will print an error message for the bus
5771 * connection, but only if it needs to */
5773 switch (arg_action) {
5775 case ACTION_SYSTEMCTL:
5776 r = systemctl_main(bus, argc, argv, r);
5780 case ACTION_POWEROFF:
5786 case ACTION_RUNLEVEL2:
5787 case ACTION_RUNLEVEL3:
5788 case ACTION_RUNLEVEL4:
5789 case ACTION_RUNLEVEL5:
5791 case ACTION_EMERGENCY:
5792 case ACTION_DEFAULT:
5793 r = start_with_fallback(bus);
5798 r = reload_with_fallback(bus);
5801 case ACTION_CANCEL_SHUTDOWN: {
5802 _cleanup_free_ char *m = NULL;
5805 m = strv_join(arg_wall, " ");
5812 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
5814 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
5818 case ACTION_RUNLEVEL:
5819 case _ACTION_INVALID:
5821 assert_not_reached("Unknown action");
5826 ask_password_agent_close();
5827 polkit_agent_close();
5829 strv_free(arg_types);
5830 strv_free(arg_states);
5831 strv_free(arg_properties);
5833 return r < 0 ? EXIT_FAILURE : r;