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 for (j = jobs; j < jobs + n; j++) {
1208 uint32_t id = j->id;
1209 assert(j->name && j->type && j->state);
1211 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1212 unit_len = MAX(unit_len, strlen(j->name));
1213 type_len = MAX(type_len, strlen(j->type));
1214 state_len = MAX(state_len, strlen(j->state));
1217 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1218 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1222 printf("%*s %-*s %-*s %-*s\n",
1226 state_len, "STATE");
1228 for (j = jobs; j < jobs + n; j++) {
1229 _cleanup_free_ char *e = NULL;
1231 if (streq(j->state, "running")) {
1232 on = ansi_highlight();
1233 off = ansi_highlight_off();
1237 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1238 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1240 on, unit_len, e ? e : j->name, off,
1242 on, state_len, j->state, off);
1245 on = ansi_highlight();
1246 off = ansi_highlight_off();
1248 printf("\n%s%u jobs listed%s.\n", on, n, off);
1251 static int list_jobs(sd_bus *bus, char **args) {
1252 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1253 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1254 const char *name, *type, *state, *job_path, *unit_path;
1255 _cleanup_free_ struct job_info *jobs = NULL;
1261 r = sd_bus_call_method(
1263 "org.freedesktop.systemd1",
1264 "/org/freedesktop/systemd1",
1265 "org.freedesktop.systemd1.Manager",
1271 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1275 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1277 return bus_log_parse_error(r);
1279 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1281 if (!GREEDY_REALLOC(jobs, size, c + 1))
1284 jobs[c++] = (struct job_info) {
1292 return bus_log_parse_error(r);
1294 r = sd_bus_message_exit_container(reply);
1296 return bus_log_parse_error(r);
1298 output_jobs_list(jobs, c);
1302 static int cancel_job(sd_bus *bus, char **args) {
1303 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1308 if (strv_length(args) <= 1)
1309 return daemon_reload(bus, args);
1311 STRV_FOREACH(name, args+1) {
1315 r = safe_atou32(*name, &id);
1317 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1321 r = sd_bus_call_method(
1323 "org.freedesktop.systemd1",
1324 "/org/freedesktop/systemd1",
1325 "org.freedesktop.systemd1.Manager",
1331 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1339 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1340 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1341 _cleanup_free_ char *n = NULL;
1345 /* We ignore all errors here, since this is used to show a
1348 n = unit_name_mangle(unit);
1352 /* We don't use unit_dbus_path_from_name() directly since we
1353 * don't want to load the unit if it isn't loaded. */
1355 r = sd_bus_call_method(
1357 "org.freedesktop.systemd1",
1358 "/org/freedesktop/systemd1",
1359 "org.freedesktop.systemd1.Manager",
1367 r = sd_bus_message_read(reply, "o", &path);
1371 r = sd_bus_get_property_trivial(
1373 "org.freedesktop.systemd1",
1375 "org.freedesktop.systemd1.Unit",
1385 typedef struct WaitData {
1392 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1399 log_debug("Got D-Bus request: %s.%s() on %s",
1400 sd_bus_message_get_interface(m),
1401 sd_bus_message_get_member(m),
1402 sd_bus_message_get_path(m));
1404 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1405 log_error("Warning! D-Bus connection terminated.");
1407 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1409 const char *path, *result, *unit;
1413 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1415 ret = set_remove(d->set, (char*) path);
1421 if (!isempty(result))
1422 d->result = strdup(result);
1425 d->name = strdup(unit);
1430 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1432 ret = set_remove(d->set, (char*) path);
1439 d->result = strdup(result);
1445 log_error("Failed to parse message.");
1451 static int enable_wait_for_jobs(sd_bus *bus) {
1456 r = sd_bus_add_match(
1459 "sender='org.freedesktop.systemd1',"
1460 "interface='org.freedesktop.systemd1.Manager',"
1461 "member='JobRemoved',"
1462 "path='/org/freedesktop/systemd1'",
1465 log_error("Failed to add match");
1469 /* This is slightly dirty, since we don't undo the match registrations. */
1473 static int wait_for_jobs(sd_bus *bus, Set *s) {
1474 WaitData d = { .set = s };
1480 r = sd_bus_add_filter(bus, wait_filter, &d);
1484 while (!set_isempty(s)) {
1486 r = sd_bus_process(bus, NULL);
1491 r = sd_bus_wait(bus, (uint64_t) -1);
1500 if (streq(d.result, "timeout"))
1501 log_error("Job for %s timed out.", strna(d.name));
1502 else if (streq(d.result, "canceled"))
1503 log_error("Job for %s canceled.", strna(d.name));
1504 else if (streq(d.result, "dependency"))
1505 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1506 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1507 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1510 if (streq_ptr(d.result, "timeout"))
1512 else if (streq_ptr(d.result, "canceled"))
1514 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1525 return sd_bus_remove_filter(bus, wait_filter, &d);
1528 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1529 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1530 _cleanup_free_ char *n = NULL, *state = NULL;
1536 n = unit_name_mangle(name);
1540 /* We don't use unit_dbus_path_from_name() directly since we
1541 * don't want to load the unit if it isn't loaded. */
1543 r = sd_bus_call_method(
1545 "org.freedesktop.systemd1",
1546 "/org/freedesktop/systemd1",
1547 "org.freedesktop.systemd1.Manager",
1558 r = sd_bus_message_read(reply, "o", &path);
1560 return bus_log_parse_error(r);
1562 r = sd_bus_get_property_string(
1564 "org.freedesktop.systemd1",
1566 "org.freedesktop.systemd1.Unit",
1579 return nulstr_contains(good_states, state);
1582 static int check_triggering_units(
1586 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1587 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1588 _cleanup_strv_free_ char **triggered_by = NULL;
1589 bool print_warning_label = true;
1593 n = unit_name_mangle(name);
1597 path = unit_dbus_path_from_name(n);
1601 r = sd_bus_get_property_string(
1603 "org.freedesktop.systemd1",
1605 "org.freedesktop.systemd1.Unit",
1610 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1614 if (streq(state, "masked"))
1617 r = sd_bus_get_property_strv(
1619 "org.freedesktop.systemd1",
1621 "org.freedesktop.systemd1.Unit",
1626 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1630 STRV_FOREACH(i, triggered_by) {
1631 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1633 log_error("Failed to check unit: %s", strerror(-r));
1640 if (print_warning_label) {
1641 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1642 print_warning_label = false;
1645 log_warning(" %s", *i);
1651 static int start_unit_one(
1656 sd_bus_error *error,
1659 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1660 _cleanup_free_ char *n;
1669 n = unit_name_mangle(name);
1673 r = sd_bus_call_method(
1675 "org.freedesktop.systemd1",
1676 "/org/freedesktop/systemd1",
1677 "org.freedesktop.systemd1.Manager",
1683 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1684 /* There's always a fallback possible for
1685 * legacy actions. */
1686 return -EADDRNOTAVAIL;
1688 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1692 r = sd_bus_message_read(reply, "o", &path);
1694 return bus_log_parse_error(r);
1696 if (need_daemon_reload(bus, n) > 0)
1697 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1698 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1707 r = set_consume(s, p);
1715 static const struct {
1719 } action_table[_ACTION_MAX] = {
1720 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1721 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1722 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1723 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1724 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1725 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1726 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1727 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1728 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1729 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1730 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1731 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1732 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1733 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1734 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1737 static enum action verb_to_action(const char *verb) {
1740 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1741 if (streq_ptr(action_table[i].verb, verb))
1744 return _ACTION_INVALID;
1747 static int start_unit(sd_bus *bus, char **args) {
1748 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1749 _cleanup_set_free_free_ Set *s = NULL;
1750 const char *method, *mode, *one_name;
1756 ask_password_agent_open_if_enabled();
1758 if (arg_action == ACTION_SYSTEMCTL) {
1761 streq(args[0], "stop") ||
1762 streq(args[0], "condstop") ? "StopUnit" :
1763 streq(args[0], "reload") ? "ReloadUnit" :
1764 streq(args[0], "restart") ? "RestartUnit" :
1766 streq(args[0], "try-restart") ||
1767 streq(args[0], "condrestart") ? "TryRestartUnit" :
1769 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1771 streq(args[0], "reload-or-try-restart") ||
1772 streq(args[0], "condreload") ||
1773 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
1775 action = verb_to_action(args[0]);
1777 mode = streq(args[0], "isolate") ? "isolate" :
1778 action_table[action].mode ?: arg_job_mode;
1780 one_name = action_table[action].target;
1782 assert(arg_action < ELEMENTSOF(action_table));
1783 assert(action_table[arg_action].target);
1785 method = "StartUnit";
1787 mode = action_table[arg_action].mode;
1788 one_name = action_table[arg_action].target;
1791 if (!arg_no_block) {
1792 r = enable_wait_for_jobs(bus);
1794 log_error("Could not watch jobs: %s", strerror(-r));
1798 s = set_new(string_hash_func, string_compare_func);
1804 r = start_unit_one(bus, method, one_name, mode, &error, s);
1806 r = translate_bus_error_to_exit_status(r, &error);
1810 STRV_FOREACH(name, args+1) {
1813 q = start_unit_one(bus, method, *name, mode, &error, s);
1815 r = translate_bus_error_to_exit_status(r, &error);
1816 sd_bus_error_free(&error);
1821 if (!arg_no_block) {
1824 q = wait_for_jobs(bus, s);
1828 /* When stopping units, warn if they can still be triggered by
1829 * another active unit (socket, path, timer) */
1830 if (!arg_quiet && streq(method, "StopUnit")) {
1832 check_triggering_units(bus, one_name);
1834 STRV_FOREACH(name, args+1)
1835 check_triggering_units(bus, *name);
1842 /* Ask systemd-logind, which might grant access to unprivileged users
1843 * through PolicyKit */
1844 static int reboot_with_logind(sd_bus *bus, enum action a) {
1846 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1853 polkit_agent_open_if_enabled();
1861 case ACTION_POWEROFF:
1862 method = "PowerOff";
1865 case ACTION_SUSPEND:
1869 case ACTION_HIBERNATE:
1870 method = "Hibernate";
1873 case ACTION_HYBRID_SLEEP:
1874 method = "HybridSleep";
1881 r = sd_bus_call_method(
1883 "org.freedesktop.login1",
1884 "/org/freedesktop/login1",
1885 "org.freedesktop.login1.Manager",
1891 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
1899 static int check_inhibitors(sd_bus *bus, enum action a) {
1901 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1902 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1903 _cleanup_strv_free_ char **sessions = NULL;
1904 const char *what, *who, *why, *mode;
1913 if (arg_ignore_inhibitors || arg_force > 0)
1925 r = sd_bus_call_method(
1927 "org.freedesktop.login1",
1928 "/org/freedesktop/login1",
1929 "org.freedesktop.login1.Manager",
1935 /* If logind is not around, then there are no inhibitors... */
1938 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "ssssuu");
1940 return bus_log_parse_error(r);
1942 while ((r = sd_bus_message_read(reply, "ssssuu", &what, &who, &why, &mode, &uid, &pid)) > 0) {
1943 _cleanup_free_ char *comm = NULL, *user = NULL;
1944 _cleanup_strv_free_ char **sv = NULL;
1946 if (!streq(mode, "block"))
1949 sv = strv_split(what, ":");
1953 if (!strv_contains(sv,
1955 a == ACTION_POWEROFF ||
1956 a == ACTION_REBOOT ||
1957 a == ACTION_KEXEC ? "shutdown" : "sleep"))
1960 get_process_comm(pid, &comm);
1961 user = uid_to_name(uid);
1963 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
1964 who, (unsigned long) pid, strna(comm), strna(user), why);
1969 return bus_log_parse_error(r);
1971 r = sd_bus_message_exit_container(reply);
1973 return bus_log_parse_error(r);
1975 /* Check for current sessions */
1976 sd_get_sessions(&sessions);
1977 STRV_FOREACH(s, sessions) {
1978 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
1980 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
1983 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
1986 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
1989 sd_session_get_tty(*s, &tty);
1990 sd_session_get_seat(*s, &seat);
1991 sd_session_get_service(*s, &service);
1992 user = uid_to_name(uid);
1994 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2001 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2002 action_table[a].verb);
2010 static int start_special(sd_bus *bus, char **args) {
2016 a = verb_to_action(args[0]);
2018 r = check_inhibitors(bus, a);
2022 if (arg_force >= 2 && geteuid() != 0) {
2023 log_error("Must be root.");
2027 if (arg_force >= 2 &&
2028 (a == ACTION_HALT ||
2029 a == ACTION_POWEROFF ||
2030 a == ACTION_REBOOT))
2033 if (arg_force >= 1 &&
2034 (a == ACTION_HALT ||
2035 a == ACTION_POWEROFF ||
2036 a == ACTION_REBOOT ||
2037 a == ACTION_KEXEC ||
2039 return daemon_reload(bus, args);
2041 /* first try logind, to allow authentication with polkit */
2042 if (geteuid() != 0 &&
2043 (a == ACTION_POWEROFF ||
2044 a == ACTION_REBOOT ||
2045 a == ACTION_SUSPEND ||
2046 a == ACTION_HIBERNATE ||
2047 a == ACTION_HYBRID_SLEEP)) {
2048 r = reboot_with_logind(bus, a);
2053 r = start_unit(bus, args);
2054 if (r == EXIT_SUCCESS)
2060 static int check_unit_active(sd_bus *bus, char **args) {
2062 int r = 3; /* According to LSB: "program is not running" */
2067 STRV_FOREACH(name, args+1) {
2070 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2080 static int check_unit_failed(sd_bus *bus, char **args) {
2087 STRV_FOREACH(name, args+1) {
2090 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2100 static int kill_unit(sd_bus *bus, char **args) {
2101 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2109 arg_kill_who = "all";
2111 STRV_FOREACH(name, args+1) {
2112 _cleanup_free_ char *n = NULL;
2114 n = unit_name_mangle(*name);
2118 r = sd_bus_call_method(
2120 "org.freedesktop.systemd1",
2121 "/org/freedesktop/systemd1",
2122 "org.freedesktop.systemd1.Manager",
2126 "ssi", n, arg_kill_who, arg_signal);
2128 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2136 typedef struct ExecStatusInfo {
2144 usec_t start_timestamp;
2145 usec_t exit_timestamp;
2150 LIST_FIELDS(struct ExecStatusInfo, exec);
2153 static void exec_status_info_free(ExecStatusInfo *i) {
2162 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2163 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2166 int32_t code, status;
2172 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2174 return bus_log_parse_error(r);
2178 r = sd_bus_message_read(m, "s", &path);
2180 return bus_log_parse_error(r);
2182 i->path = strdup(path);
2186 r = sd_bus_message_read_strv(m, &i->argv);
2188 return bus_log_parse_error(r);
2190 r = sd_bus_message_read(m,
2193 &start_timestamp, &start_timestamp_monotonic,
2194 &exit_timestamp, &exit_timestamp_monotonic,
2198 return bus_log_parse_error(r);
2201 i->start_timestamp = (usec_t) start_timestamp;
2202 i->exit_timestamp = (usec_t) exit_timestamp;
2203 i->pid = (pid_t) pid;
2207 r = sd_bus_message_exit_container(m);
2209 return bus_log_parse_error(r);
2214 typedef struct UnitStatusInfo {
2216 const char *load_state;
2217 const char *active_state;
2218 const char *sub_state;
2219 const char *unit_file_state;
2221 const char *description;
2222 const char *following;
2224 char **documentation;
2226 const char *fragment_path;
2227 const char *source_path;
2228 const char *control_group;
2230 char **dropin_paths;
2232 const char *load_error;
2235 usec_t inactive_exit_timestamp;
2236 usec_t inactive_exit_timestamp_monotonic;
2237 usec_t active_enter_timestamp;
2238 usec_t active_exit_timestamp;
2239 usec_t inactive_enter_timestamp;
2241 bool need_daemon_reload;
2246 const char *status_text;
2247 const char *pid_file;
2250 usec_t start_timestamp;
2251 usec_t exit_timestamp;
2253 int exit_code, exit_status;
2255 usec_t condition_timestamp;
2256 bool condition_result;
2257 bool failed_condition_trigger;
2258 bool failed_condition_negate;
2259 const char *failed_condition;
2260 const char *failed_condition_param;
2263 unsigned n_accepted;
2264 unsigned n_connections;
2267 /* Pairs of type, path */
2271 const char *sysfs_path;
2273 /* Mount, Automount */
2279 LIST_HEAD(ExecStatusInfo, exec);
2282 static void print_status_info(
2287 const char *on, *off, *ss;
2289 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2290 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2293 arg_all * OUTPUT_SHOW_ALL |
2294 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2295 on_tty() * OUTPUT_COLOR |
2296 !arg_quiet * OUTPUT_WARN_CUTOFF |
2297 arg_full * OUTPUT_FULL_WIDTH;
2302 /* This shows pretty information about a unit. See
2303 * print_property() for a low-level property printer */
2305 printf("%s", strna(i->id));
2307 if (i->description && !streq_ptr(i->id, i->description))
2308 printf(" - %s", i->description);
2313 printf(" Follow: unit currently follows state of %s\n", i->following);
2315 if (streq_ptr(i->load_state, "error")) {
2316 on = ansi_highlight_red();
2317 off = ansi_highlight_off();
2321 path = i->source_path ? i->source_path : i->fragment_path;
2324 printf(" Loaded: %s%s%s (Reason: %s)\n",
2325 on, strna(i->load_state), off, i->load_error);
2326 else if (path && i->unit_file_state)
2327 printf(" Loaded: %s%s%s (%s; %s)\n",
2328 on, strna(i->load_state), off, path, i->unit_file_state);
2330 printf(" Loaded: %s%s%s (%s)\n",
2331 on, strna(i->load_state), off, path);
2333 printf(" Loaded: %s%s%s\n",
2334 on, strna(i->load_state), off);
2336 if (!strv_isempty(i->dropin_paths)) {
2337 _cleanup_free_ char *dir = NULL;
2341 STRV_FOREACH(dropin, i->dropin_paths) {
2342 if (! dir || last) {
2343 printf(dir ? " " : " Drop-In: ");
2348 if (path_get_parent(*dropin, &dir) < 0) {
2353 printf("%s\n %s", dir,
2354 draw_special_char(DRAW_TREE_RIGHT));
2357 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2359 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2363 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2365 if (streq_ptr(i->active_state, "failed")) {
2366 on = ansi_highlight_red();
2367 off = ansi_highlight_off();
2368 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2369 on = ansi_highlight_green();
2370 off = ansi_highlight_off();
2375 printf(" Active: %s%s (%s)%s",
2376 on, strna(i->active_state), ss, off);
2378 printf(" Active: %s%s%s",
2379 on, strna(i->active_state), off);
2381 if (!isempty(i->result) && !streq(i->result, "success"))
2382 printf(" (Result: %s)", i->result);
2384 timestamp = (streq_ptr(i->active_state, "active") ||
2385 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2386 (streq_ptr(i->active_state, "inactive") ||
2387 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2388 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2389 i->active_exit_timestamp;
2391 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2392 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2395 printf(" since %s; %s\n", s2, s1);
2397 printf(" since %s\n", s2);
2401 if (!i->condition_result && i->condition_timestamp > 0) {
2402 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2403 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2405 printf(" start condition failed at %s%s%s\n",
2406 s2, s1 ? "; " : "", s1 ? s1 : "");
2407 if (i->failed_condition_trigger)
2408 printf(" none of the trigger conditions were met\n");
2409 else if (i->failed_condition)
2410 printf(" %s=%s%s was not met\n",
2411 i->failed_condition,
2412 i->failed_condition_negate ? "!" : "",
2413 i->failed_condition_param);
2417 printf(" Device: %s\n", i->sysfs_path);
2419 printf(" Where: %s\n", i->where);
2421 printf(" What: %s\n", i->what);
2423 STRV_FOREACH(t, i->documentation)
2424 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2426 STRV_FOREACH_PAIR(t, t2, i->listen)
2427 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2430 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2432 LIST_FOREACH(exec, p, i->exec) {
2433 _cleanup_free_ char *argv = NULL;
2436 /* Only show exited processes here */
2440 argv = strv_join(p->argv, " ");
2441 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2443 good = is_clean_exit_lsb(p->code, p->status, NULL);
2445 on = ansi_highlight_red();
2446 off = ansi_highlight_off();
2450 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2452 if (p->code == CLD_EXITED) {
2455 printf("status=%i", p->status);
2457 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2462 printf("signal=%s", signal_to_string(p->status));
2464 printf(")%s\n", off);
2466 if (i->main_pid == p->pid &&
2467 i->start_timestamp == p->start_timestamp &&
2468 i->exit_timestamp == p->start_timestamp)
2469 /* Let's not show this twice */
2472 if (p->pid == i->control_pid)
2476 if (i->main_pid > 0 || i->control_pid > 0) {
2477 if (i->main_pid > 0) {
2478 printf(" Main PID: %u", (unsigned) i->main_pid);
2481 _cleanup_free_ char *comm = NULL;
2482 get_process_comm(i->main_pid, &comm);
2484 printf(" (%s)", comm);
2485 } else if (i->exit_code > 0) {
2486 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2488 if (i->exit_code == CLD_EXITED) {
2491 printf("status=%i", i->exit_status);
2493 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2498 printf("signal=%s", signal_to_string(i->exit_status));
2502 if (i->control_pid > 0)
2506 if (i->control_pid > 0) {
2507 _cleanup_free_ char *c = NULL;
2509 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2511 get_process_comm(i->control_pid, &c);
2520 printf(" Status: \"%s\"\n", i->status_text);
2522 if (i->control_group &&
2523 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2526 printf(" CGroup: %s\n", i->control_group);
2528 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2531 char prefix[] = " ";
2534 if (c > sizeof(prefix) - 1)
2535 c -= sizeof(prefix) - 1;
2539 if (i->main_pid > 0)
2540 extra[k++] = i->main_pid;
2542 if (i->control_pid > 0)
2543 extra[k++] = i->control_pid;
2545 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2546 c, false, extra, k, flags);
2550 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2552 show_journal_by_unit(stdout,
2556 i->inactive_exit_timestamp_monotonic,
2560 arg_scope == UNIT_FILE_SYSTEM,
2564 if (i->need_daemon_reload)
2565 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2566 ansi_highlight_red(),
2567 ansi_highlight_off(),
2568 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2571 static void show_unit_help(UnitStatusInfo *i) {
2576 if (!i->documentation) {
2577 log_info("Documentation for %s not known.", i->id);
2581 STRV_FOREACH(p, i->documentation) {
2583 if (startswith(*p, "man:")) {
2584 const char *args[4] = { "man", NULL, NULL, NULL };
2585 _cleanup_free_ char *page = NULL, *section = NULL;
2592 if ((*p)[k-1] == ')')
2593 e = strrchr(*p, '(');
2596 page = strndup((*p) + 4, e - *p - 4);
2597 section = strndup(e + 1, *p + k - e - 2);
2598 if (!page || !section) {
2610 log_error("Failed to fork: %m");
2616 execvp(args[0], (char**) args);
2617 log_error("Failed to execute man: %m");
2618 _exit(EXIT_FAILURE);
2621 wait_for_terminate(pid, NULL);
2623 log_info("Can't show: %s", *p);
2627 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2634 switch (contents[0]) {
2636 case SD_BUS_TYPE_STRING: {
2639 r = sd_bus_message_read(m, "s", &s);
2641 return bus_log_parse_error(r);
2644 if (streq(name, "Id"))
2646 else if (streq(name, "LoadState"))
2648 else if (streq(name, "ActiveState"))
2649 i->active_state = s;
2650 else if (streq(name, "SubState"))
2652 else if (streq(name, "Description"))
2654 else if (streq(name, "FragmentPath"))
2655 i->fragment_path = s;
2656 else if (streq(name, "SourcePath"))
2659 else if (streq(name, "DefaultControlGroup")) {
2661 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2663 i->control_group = e;
2666 else if (streq(name, "ControlGroup"))
2667 i->control_group = s;
2668 else if (streq(name, "StatusText"))
2670 else if (streq(name, "PIDFile"))
2672 else if (streq(name, "SysFSPath"))
2674 else if (streq(name, "Where"))
2676 else if (streq(name, "What"))
2678 else if (streq(name, "Following"))
2680 else if (streq(name, "UnitFileState"))
2681 i->unit_file_state = s;
2682 else if (streq(name, "Result"))
2689 case SD_BUS_TYPE_BOOLEAN: {
2692 r = sd_bus_message_read(m, "b", &b);
2694 return bus_log_parse_error(r);
2696 if (streq(name, "Accept"))
2698 else if (streq(name, "NeedDaemonReload"))
2699 i->need_daemon_reload = b;
2700 else if (streq(name, "ConditionResult"))
2701 i->condition_result = b;
2706 case SD_BUS_TYPE_UINT32: {
2709 r = sd_bus_message_read(m, "u", &u);
2711 return bus_log_parse_error(r);
2713 if (streq(name, "MainPID")) {
2715 i->main_pid = (pid_t) u;
2718 } else if (streq(name, "ControlPID"))
2719 i->control_pid = (pid_t) u;
2720 else if (streq(name, "ExecMainPID")) {
2722 i->main_pid = (pid_t) u;
2723 } else if (streq(name, "NAccepted"))
2725 else if (streq(name, "NConnections"))
2726 i->n_connections = u;
2731 case SD_BUS_TYPE_INT32: {
2734 r = sd_bus_message_read(m, "i", &j);
2736 return bus_log_parse_error(r);
2738 if (streq(name, "ExecMainCode"))
2739 i->exit_code = (int) j;
2740 else if (streq(name, "ExecMainStatus"))
2741 i->exit_status = (int) j;
2746 case SD_BUS_TYPE_UINT64: {
2749 r = sd_bus_message_read(m, "t", &u);
2751 return bus_log_parse_error(r);
2753 if (streq(name, "ExecMainStartTimestamp"))
2754 i->start_timestamp = (usec_t) u;
2755 else if (streq(name, "ExecMainExitTimestamp"))
2756 i->exit_timestamp = (usec_t) u;
2757 else if (streq(name, "ActiveEnterTimestamp"))
2758 i->active_enter_timestamp = (usec_t) u;
2759 else if (streq(name, "InactiveEnterTimestamp"))
2760 i->inactive_enter_timestamp = (usec_t) u;
2761 else if (streq(name, "InactiveExitTimestamp"))
2762 i->inactive_exit_timestamp = (usec_t) u;
2763 else if (streq(name, "InactiveExitTimestampMonotonic"))
2764 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2765 else if (streq(name, "ActiveExitTimestamp"))
2766 i->active_exit_timestamp = (usec_t) u;
2767 else if (streq(name, "ConditionTimestamp"))
2768 i->condition_timestamp = (usec_t) u;
2773 case SD_BUS_TYPE_ARRAY:
2775 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
2776 _cleanup_free_ ExecStatusInfo *info = NULL;
2778 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
2780 return bus_log_parse_error(r);
2782 info = new0(ExecStatusInfo, 1);
2786 while ((r = exec_status_info_deserialize(m, info)) > 0) {
2788 info->name = strdup(name);
2792 LIST_PREPEND(exec, i->exec, info);
2794 info = new0(ExecStatusInfo, 1);
2800 return bus_log_parse_error(r);
2802 r = sd_bus_message_exit_container(m);
2804 return bus_log_parse_error(r);
2808 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
2809 const char *type, *path;
2811 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2813 return bus_log_parse_error(r);
2815 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
2817 r = strv_extend(&i->listen, type);
2821 r = strv_extend(&i->listen, path);
2826 return bus_log_parse_error(r);
2828 r = sd_bus_message_exit_container(m);
2830 return bus_log_parse_error(r);
2834 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
2836 r = sd_bus_message_read_strv(m, &i->dropin_paths);
2838 return bus_log_parse_error(r);
2840 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
2842 r = sd_bus_message_read_strv(m, &i->documentation);
2844 return bus_log_parse_error(r);
2846 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
2847 const char *cond, *param;
2848 int trigger, negate;
2851 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
2853 return bus_log_parse_error(r);
2855 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
2856 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
2857 if (state < 0 && (!trigger || !i->failed_condition)) {
2858 i->failed_condition = cond;
2859 i->failed_condition_trigger = trigger;
2860 i->failed_condition_negate = negate;
2861 i->failed_condition_param = param;
2865 return bus_log_parse_error(r);
2867 r = sd_bus_message_exit_container(m);
2869 return bus_log_parse_error(r);
2876 case SD_BUS_TYPE_STRUCT_BEGIN:
2878 if (streq(name, "LoadError")) {
2879 const char *n, *message;
2881 r = sd_bus_message_read(m, "(ss)", &n, &message);
2883 return bus_log_parse_error(r);
2885 if (!isempty(message))
2886 i->load_error = message;
2899 r = sd_bus_message_skip(m, contents);
2901 return bus_log_parse_error(r);
2906 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
2912 /* This is a low-level property printer, see
2913 * print_status_info() for the nicer output */
2915 if (arg_properties && !strv_find(arg_properties, name))
2918 switch (contents[0]) {
2920 case SD_BUS_TYPE_STRUCT_BEGIN:
2922 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
2925 r = sd_bus_message_read(m, "(uo)", &u, NULL);
2927 return bus_log_parse_error(r);
2930 printf("%s=%u\n", name, (unsigned) u);
2932 printf("%s=\n", name);
2936 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
2939 r = sd_bus_message_read(m, "(so)", &s, NULL);
2941 return bus_log_parse_error(r);
2943 if (arg_all || !isempty(s))
2944 printf("%s=%s\n", name, s);
2948 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
2949 const char *a = NULL, *b = NULL;
2951 r = sd_bus_message_read(m, "(ss)", &a, &b);
2953 return bus_log_parse_error(r);
2955 if (arg_all || !isempty(a) || !isempty(b))
2956 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
2963 case SD_BUS_TYPE_ARRAY:
2965 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
2969 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
2971 return bus_log_parse_error(r);
2973 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
2974 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
2977 return bus_log_parse_error(r);
2979 r = sd_bus_message_exit_container(m);
2981 return bus_log_parse_error(r);
2985 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
2986 const char *type, *path;
2988 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2990 return bus_log_parse_error(r);
2992 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
2993 printf("%s=%s\n", type, path);
2995 return bus_log_parse_error(r);
2997 r = sd_bus_message_exit_container(m);
2999 return bus_log_parse_error(r);
3003 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3004 const char *type, *path;
3006 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3008 return bus_log_parse_error(r);
3010 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3011 printf("Listen%s=%s\n", type, path);
3013 return bus_log_parse_error(r);
3015 r = sd_bus_message_exit_container(m);
3017 return bus_log_parse_error(r);
3021 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3023 uint64_t value, next_elapse;
3025 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3027 return bus_log_parse_error(r);
3029 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3030 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3032 printf("%s={ value=%s ; next_elapse=%s }\n",
3034 format_timespan(timespan1, sizeof(timespan1), value, 0),
3035 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3038 return bus_log_parse_error(r);
3040 r = sd_bus_message_exit_container(m);
3042 return bus_log_parse_error(r);
3046 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3047 ExecStatusInfo info = {};
3049 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3051 return bus_log_parse_error(r);
3053 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3054 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3055 _cleanup_free_ char *tt;
3057 tt = strv_join(info.argv, " ");
3059 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3063 yes_no(info.ignore),
3064 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3065 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3066 (unsigned) info. pid,
3067 sigchld_code_to_string(info.code),
3069 info.code == CLD_EXITED ? "" : "/",
3070 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3073 strv_free(info.argv);
3077 r = sd_bus_message_exit_container(m);
3079 return bus_log_parse_error(r);
3083 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3084 const char *path, *rwm;
3086 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3088 return bus_log_parse_error(r);
3090 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3091 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3093 return bus_log_parse_error(r);
3095 r = sd_bus_message_exit_container(m);
3097 return bus_log_parse_error(r);
3101 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3105 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3107 return bus_log_parse_error(r);
3109 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3110 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3112 return bus_log_parse_error(r);
3114 r = sd_bus_message_exit_container(m);
3116 return bus_log_parse_error(r);
3120 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3124 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3126 return bus_log_parse_error(r);
3128 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3129 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3131 return bus_log_parse_error(r);
3133 r = sd_bus_message_exit_container(m);
3135 return bus_log_parse_error(r);
3143 r = bus_print_property(name, m, arg_all);
3145 return bus_log_parse_error(r);
3148 r = sd_bus_message_skip(m, contents);
3150 return bus_log_parse_error(r);
3153 printf("%s=[unprintable]\n", name);
3159 static int show_one(
3163 bool show_properties,
3167 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3168 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3169 UnitStatusInfo info = {};
3176 r = sd_bus_call_method(
3178 "org.freedesktop.systemd1",
3180 "org.freedesktop.DBus.Properties",
3186 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3190 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3192 return bus_log_parse_error(r);
3199 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3200 const char *name, *contents;
3202 r = sd_bus_message_read(reply, "s", &name);
3204 return bus_log_parse_error(r);
3206 r = sd_bus_message_peek_type(reply, NULL, &contents);
3208 return bus_log_parse_error(r);
3210 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3212 return bus_log_parse_error(r);
3214 if (show_properties)
3215 r = print_property(name, reply, contents);
3217 r = status_property(name, reply, &info, contents);
3221 r = sd_bus_message_exit_container(reply);
3223 return bus_log_parse_error(r);
3225 r = sd_bus_message_exit_container(reply);
3227 return bus_log_parse_error(r);
3230 return bus_log_parse_error(r);
3232 r = sd_bus_message_exit_container(reply);
3234 return bus_log_parse_error(r);
3238 if (!show_properties) {
3239 if (streq(verb, "help"))
3240 show_unit_help(&info);
3242 print_status_info(&info, ellipsized);
3245 strv_free(info.documentation);
3246 strv_free(info.dropin_paths);
3247 strv_free(info.listen);
3249 if (!streq_ptr(info.active_state, "active") &&
3250 !streq_ptr(info.active_state, "reloading") &&
3251 streq(verb, "status")) {
3252 /* According to LSB: "program not running" */
3253 /* 0: program is running or service is OK
3254 * 1: program is dead and /var/run pid file exists
3255 * 2: program is dead and /var/lock lock file exists
3256 * 3: program is not running
3257 * 4: program or service status is unknown
3259 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3265 while ((p = info.exec)) {
3266 LIST_REMOVE(exec, info.exec, p);
3267 exec_status_info_free(p);
3273 static int show_one_by_pid(
3280 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3281 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3282 const char *path = NULL;
3285 r = sd_bus_call_method(
3287 "org.freedesktop.systemd1",
3288 "/org/freedesktop/systemd1",
3289 "org.freedesktop.systemd1.Manager",
3295 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3299 r = sd_bus_message_read(reply, "o", &path);
3301 return bus_log_parse_error(r);
3303 return show_one(verb, bus, path, false, new_line, ellipsized);
3306 static int show_all(
3309 bool show_properties,
3313 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3314 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3315 _cleanup_free_ UnitInfo *unit_infos = NULL;
3320 r = get_unit_list(bus, &reply, &unit_infos);
3326 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3328 for (u = unit_infos; u < unit_infos + c; u++) {
3329 _cleanup_free_ char *p = NULL;
3331 if (!output_show_unit(u))
3334 p = unit_dbus_path_from_name(u->id);
3338 printf("%s -> '%s'\n", u->id, p);
3340 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3348 static int show(sd_bus *bus, char **args) {
3350 bool show_properties, show_status, new_line = false;
3352 bool ellipsized = false;
3357 show_properties = streq(args[0], "show");
3358 show_status = streq(args[0], "status");
3360 if (show_properties)
3361 pager_open_if_enabled();
3363 /* If no argument is specified inspect the manager itself */
3365 if (show_properties && strv_length(args) <= 1)
3366 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3368 if (show_status && strv_length(args) <= 1)
3369 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3371 STRV_FOREACH(name, args+1) {
3374 if (safe_atou32(*name, &id) < 0) {
3375 _cleanup_free_ char *p = NULL, *n = NULL;
3376 /* Interpret as unit name */
3378 n = unit_name_mangle(*name);
3382 p = unit_dbus_path_from_name(n);
3386 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3390 } else if (show_properties) {
3391 _cleanup_free_ char *p = NULL;
3393 /* Interpret as job id */
3394 if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
3397 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3402 /* Interpret as PID */
3403 r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized);
3409 if (ellipsized && !arg_quiet)
3410 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3415 static int append_assignment(sd_bus_message *m, const char *assignment) {
3423 eq = strchr(assignment, '=');
3425 log_error("Not an assignment: %s", assignment);
3429 field = strndupa(assignment, eq - assignment);
3432 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3434 return bus_log_create_error(r);
3436 if (streq(field, "CPUAccounting") ||
3437 streq(field, "MemoryAccounting") ||
3438 streq(field, "BlockIOAccounting")) {
3440 r = parse_boolean(eq);
3442 log_error("Failed to parse boolean assignment %s.", assignment);
3446 r = sd_bus_message_append(m, "v", "b", r);
3448 } else if (streq(field, "MemoryLimit")) {
3451 r = parse_bytes(eq, &bytes);
3453 log_error("Failed to parse bytes specification %s", assignment);
3457 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3459 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3462 r = safe_atou64(eq, &u);
3464 log_error("Failed to parse %s value %s.", field, eq);
3468 r = sd_bus_message_append(m, "v", "t", u);
3470 } else if (streq(field, "DevicePolicy"))
3471 r = sd_bus_message_append(m, "v", "s", eq);
3473 else if (streq(field, "DeviceAllow")) {
3476 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3478 const char *path, *rwm;
3481 e = strchr(eq, ' ');
3483 path = strndupa(eq, e - eq);
3490 if (!path_startswith(path, "/dev")) {
3491 log_error("%s is not a device file in /dev.", path);
3495 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3498 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3501 r = sd_bus_message_append(m, "v", "a(st)", 0);
3503 const char *path, *bandwidth;
3507 e = strchr(eq, ' ');
3509 path = strndupa(eq, e - eq);
3512 log_error("Failed to parse %s value %s.", field, eq);
3516 if (!path_startswith(path, "/dev")) {
3517 log_error("%s is not a device file in /dev.", path);
3521 r = parse_bytes(bandwidth, &bytes);
3523 log_error("Failed to parse byte value %s.", bandwidth);
3527 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3530 } else if (streq(field, "BlockIODeviceWeight")) {
3533 r = sd_bus_message_append(m, "v", "a(st)", 0);
3535 const char *path, *weight;
3539 e = strchr(eq, ' ');
3541 path = strndupa(eq, e - eq);
3544 log_error("Failed to parse %s value %s.", field, eq);
3548 if (!path_startswith(path, "/dev")) {
3549 log_error("%s is not a device file in /dev.", path);
3553 r = safe_atou64(weight, &u);
3555 log_error("Failed to parse %s value %s.", field, weight);
3558 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3562 log_error("Unknown assignment %s.", assignment);
3567 return bus_log_create_error(r);
3572 static int set_property(sd_bus *bus, char **args) {
3573 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3574 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3575 _cleanup_free_ char *n = NULL;
3579 r = sd_bus_message_new_method_call(
3581 "org.freedesktop.systemd1",
3582 "/org/freedesktop/systemd1",
3583 "org.freedesktop.systemd1.Manager",
3584 "SetUnitProperties",
3587 return bus_log_create_error(r);
3589 n = unit_name_mangle(args[1]);
3593 r = sd_bus_message_append(m, "sb", n, arg_runtime);
3595 return bus_log_create_error(r);
3597 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
3599 return bus_log_create_error(r);
3601 STRV_FOREACH(i, args + 2) {
3602 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
3604 return bus_log_create_error(r);
3606 r = append_assignment(m, *i);
3610 r = sd_bus_message_close_container(m);
3612 return bus_log_create_error(r);
3615 r = sd_bus_message_close_container(m);
3617 return bus_log_create_error(r);
3619 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
3621 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
3628 static int snapshot(sd_bus *bus, char **args) {
3629 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3630 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3631 _cleanup_free_ char *n = NULL, *id = NULL;
3635 if (strv_length(args) > 1)
3636 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
3642 r = sd_bus_call_method(
3644 "org.freedesktop.systemd1",
3645 "/org/freedesktop/systemd1",
3646 "org.freedesktop.systemd1.Manager",
3652 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
3656 r = sd_bus_message_read(reply, "o", &path);
3658 return bus_log_parse_error(r);
3660 r = sd_bus_get_property_string(
3662 "org.freedesktop.systemd1",
3664 "org.freedesktop.systemd1.Unit",
3669 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
3679 static int delete_snapshot(sd_bus *bus, char **args) {
3680 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3686 STRV_FOREACH(name, args+1) {
3687 _cleanup_free_ char *n = NULL;
3689 n = unit_name_mangle_with_suffix(*name, ".snapshot");
3693 r = sd_bus_call_method(
3695 "org.freedesktop.systemd1",
3696 "/org/freedesktop/systemd1",
3697 "org.freedesktop.systemd1.Manager",
3703 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
3711 static int daemon_reload(sd_bus *bus, char **args) {
3712 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3716 if (arg_action == ACTION_RELOAD)
3718 else if (arg_action == ACTION_REEXEC)
3719 method = "Reexecute";
3721 assert(arg_action == ACTION_SYSTEMCTL);
3724 streq(args[0], "clear-jobs") ||
3725 streq(args[0], "cancel") ? "ClearJobs" :
3726 streq(args[0], "daemon-reexec") ? "Reexecute" :
3727 streq(args[0], "reset-failed") ? "ResetFailed" :
3728 streq(args[0], "halt") ? "Halt" :
3729 streq(args[0], "poweroff") ? "PowerOff" :
3730 streq(args[0], "reboot") ? "Reboot" :
3731 streq(args[0], "kexec") ? "KExec" :
3732 streq(args[0], "exit") ? "Exit" :
3733 /* "daemon-reload" */ "Reload";
3736 r = sd_bus_call_method(
3738 "org.freedesktop.systemd1",
3739 "/org/freedesktop/systemd1",
3740 "org.freedesktop.systemd1.Manager",
3746 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
3747 /* There's always a fallback possible for
3748 * legacy actions. */
3750 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
3751 /* On reexecution, we expect a disconnect, not a
3755 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3760 static int reset_failed(sd_bus *bus, char **args) {
3761 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3765 if (strv_length(args) <= 1)
3766 return daemon_reload(bus, args);
3768 STRV_FOREACH(name, args+1) {
3769 _cleanup_free_ char *n;
3771 n = unit_name_mangle(*name);
3775 r = sd_bus_call_method(
3777 "org.freedesktop.systemd1",
3778 "/org/freedesktop/systemd1",
3779 "org.freedesktop.systemd1.Manager",
3785 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
3793 static int show_environment(sd_bus *bus, char **args) {
3794 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3795 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3799 pager_open_if_enabled();
3801 r = sd_bus_get_property(
3803 "org.freedesktop.systemd1",
3804 "/org/freedesktop/systemd1",
3805 "org.freedesktop.systemd1.Manager",
3811 log_error("Failed to get environment: %s", bus_error_message(&error, r));
3815 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
3817 return bus_log_parse_error(r);
3819 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
3822 return bus_log_parse_error(r);
3824 r = sd_bus_message_exit_container(reply);
3826 return bus_log_parse_error(r);
3831 static int switch_root(sd_bus *bus, char **args) {
3832 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3833 _cleanup_free_ char *init = NULL;
3838 l = strv_length(args);
3839 if (l < 2 || l > 3) {
3840 log_error("Wrong number of arguments.");
3847 init = strdup(args[2]);
3849 parse_env_file("/proc/cmdline", WHITESPACE,
3860 log_debug("switching root - root: %s; init: %s", root, init);
3862 r = sd_bus_call_method(
3864 "org.freedesktop.systemd1",
3865 "/org/freedesktop/systemd1",
3866 "org.freedesktop.systemd1.Manager",
3872 log_error("Failed to switch root: %s", bus_error_message(&error, r));
3879 static int set_environment(sd_bus *bus, char **args) {
3880 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3881 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3888 method = streq(args[0], "set-environment")
3890 : "UnsetEnvironment";
3892 r = sd_bus_message_new_method_call(
3894 "org.freedesktop.systemd1",
3895 "/org/freedesktop/systemd1",
3896 "org.freedesktop.systemd1.Manager",
3900 return bus_log_create_error(r);
3902 r = sd_bus_message_append_strv(m, args + 1);
3904 return bus_log_create_error(r);
3906 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
3908 log_error("Failed to set environment: %s", bus_error_message(&error, r));
3915 static int enable_sysv_units(const char *verb, char **args) {
3918 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
3919 unsigned f = 1, t = 1;
3920 _cleanup_lookup_paths_free_ LookupPaths paths = {};
3922 if (arg_scope != UNIT_FILE_SYSTEM)
3925 if (!streq(verb, "enable") &&
3926 !streq(verb, "disable") &&
3927 !streq(verb, "is-enabled"))
3930 /* Processes all SysV units, and reshuffles the array so that
3931 * afterwards only the native units remain */
3933 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
3938 for (f = 0; args[f]; f++) {
3940 _cleanup_free_ char *p = NULL, *q = NULL;
3941 bool found_native = false, found_sysv;
3943 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
3951 if (!endswith(name, ".service"))
3954 if (path_is_absolute(name))
3957 STRV_FOREACH(k, paths.unit_path) {
3958 if (!isempty(arg_root))
3959 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
3961 asprintf(&p, "%s/%s", *k, name);
3968 found_native = access(p, F_OK) >= 0;
3979 if (!isempty(arg_root))
3980 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
3982 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
3988 p[strlen(p) - sizeof(".service") + 1] = 0;
3989 found_sysv = access(p, F_OK) >= 0;
3994 /* Mark this entry, so that we don't try enabling it as native unit */
3995 args[f] = (char*) "";
3997 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
3999 if (!isempty(arg_root))
4000 argv[c++] = q = strappend("--root=", arg_root);
4002 argv[c++] = path_get_file_name(p);
4004 streq(verb, "enable") ? "on" :
4005 streq(verb, "disable") ? "off" : "--level=5";
4008 l = strv_join((char**)argv, " ");
4014 log_info("Executing %s", l);
4019 log_error("Failed to fork: %m");
4022 } else if (pid == 0) {
4025 execv(argv[0], (char**) argv);
4026 _exit(EXIT_FAILURE);
4029 j = wait_for_terminate(pid, &status);
4031 log_error("Failed to wait for child: %s", strerror(-r));
4036 if (status.si_code == CLD_EXITED) {
4037 if (streq(verb, "is-enabled")) {
4038 if (status.si_status == 0) {
4047 } else if (status.si_status != 0) {
4058 /* Drop all SysV units */
4059 for (f = 0, t = 0; args[f]; f++) {
4061 if (isempty(args[f]))
4064 args[t++] = args[f];
4073 static int mangle_names(char **original_names, char ***mangled_names) {
4074 char **i, **l, **name;
4076 l = new(char*, strv_length(original_names) + 1);
4081 STRV_FOREACH(name, original_names) {
4083 /* When enabling units qualified path names are OK,
4084 * too, hence allow them explicitly. */
4089 *i = unit_name_mangle(*name);
4105 static int enable_unit(sd_bus *bus, char **args) {
4106 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4107 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4108 _cleanup_strv_free_ char **mangled_names = NULL;
4109 const char *verb = args[0];
4110 UnitFileChange *changes = NULL;
4111 unsigned n_changes = 0, i;
4112 int carries_install_info = -1;
4118 r = mangle_names(args+1, &mangled_names);
4122 r = enable_sysv_units(verb, mangled_names);
4126 if (!bus || avoid_bus()) {
4127 if (streq(verb, "enable")) {
4128 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4129 carries_install_info = r;
4130 } else if (streq(verb, "disable"))
4131 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4132 else if (streq(verb, "reenable")) {
4133 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4134 carries_install_info = r;
4135 } else if (streq(verb, "link"))
4136 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4137 else if (streq(verb, "preset")) {
4138 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4139 carries_install_info = r;
4140 } else if (streq(verb, "mask"))
4141 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4142 else if (streq(verb, "unmask"))
4143 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4144 else if (streq(verb, "set-default"))
4145 r = unit_file_set_default(arg_scope, arg_root, args[1], &changes, &n_changes);
4147 assert_not_reached("Unknown verb");
4150 log_error("Operation failed: %s", strerror(-r));
4155 for (i = 0; i < n_changes; i++) {
4156 if (changes[i].type == UNIT_FILE_SYMLINK)
4157 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
4159 log_info("rm '%s'", changes[i].path);
4165 const char *method, *type, *path, *source;
4166 int expect_carries_install_info = false;
4167 bool send_force = true;
4169 if (streq(verb, "enable")) {
4170 method = "EnableUnitFiles";
4171 expect_carries_install_info = true;
4172 } else if (streq(verb, "disable")) {
4173 method = "DisableUnitFiles";
4175 } else if (streq(verb, "reenable")) {
4176 method = "ReenableUnitFiles";
4177 expect_carries_install_info = true;
4178 } else if (streq(verb, "link"))
4179 method = "LinkUnitFiles";
4180 else if (streq(verb, "preset")) {
4181 method = "PresetUnitFiles";
4182 expect_carries_install_info = true;
4183 } else if (streq(verb, "mask"))
4184 method = "MaskUnitFiles";
4185 else if (streq(verb, "unmask")) {
4186 method = "UnmaskUnitFiles";
4188 } else if (streq(verb, "set-default")) {
4189 method = "SetDefaultTarget";
4191 assert_not_reached("Unknown verb");
4193 r = sd_bus_message_new_method_call(
4195 "org.freedesktop.systemd1",
4196 "/org/freedesktop/systemd1",
4197 "org.freedesktop.systemd1.Manager",
4201 return bus_log_create_error(r);
4203 r = sd_bus_message_append_strv(m, mangled_names);
4205 return bus_log_create_error(r);
4207 r = sd_bus_message_append(m, "b", arg_runtime);
4209 return bus_log_create_error(r);
4212 r = sd_bus_message_append(m, "b", arg_force);
4214 return bus_log_create_error(r);
4217 r = sd_bus_send_with_reply_and_block(bus, m, -0, &error, &reply);
4219 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4223 if (expect_carries_install_info) {
4224 r = sd_bus_message_read(reply, "b", &carries_install_info);
4226 return bus_log_parse_error(r);
4229 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(sss)");
4231 return bus_log_parse_error(r);
4233 while ((r = sd_bus_message_read(reply, "(sss)", &type, &path, &source)) > 0) {
4235 if (streq(type, "symlink"))
4236 log_info("ln -s '%s' '%s'", source, path);
4238 log_info("rm '%s'", path);
4242 return bus_log_parse_error(r);
4244 r = sd_bus_message_exit_container(reply);
4246 return bus_log_parse_error(r);
4248 /* Try to reload if enabeld */
4250 r = daemon_reload(bus, args);
4255 if (carries_install_info == 0)
4256 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4257 "using systemctl.\n"
4258 "Possible reasons for having this kind of units are:\n"
4259 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4260 " .wants/ or .requires/ directory.\n"
4261 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4262 " a requirement dependency on it.\n"
4263 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4264 " D-Bus, udev, scripted systemctl call, ...).\n");
4267 unit_file_changes_free(changes, n_changes);
4272 static int unit_is_enabled(sd_bus *bus, char **args) {
4274 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4275 _cleanup_strv_free_ char **mangled_names = NULL;
4280 r = mangle_names(args+1, &mangled_names);
4284 r = enable_sysv_units(args[0], mangled_names);
4290 if (!bus || avoid_bus()) {
4292 STRV_FOREACH(name, mangled_names) {
4293 UnitFileState state;
4295 state = unit_file_get_state(arg_scope, arg_root, *name);
4297 log_error("Failed to get unit file state for %s: %s", *name, strerror(-state));
4301 if (state == UNIT_FILE_ENABLED ||
4302 state == UNIT_FILE_ENABLED_RUNTIME ||
4303 state == UNIT_FILE_STATIC)
4307 puts(unit_file_state_to_string(state));
4311 STRV_FOREACH(name, mangled_names) {
4312 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4315 r = sd_bus_call_method(
4317 "org.freedesktop.systemd1",
4318 "/org/freedesktop/systemd1",
4319 "org.freedesktop.systemd1.Manager",
4325 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4329 r = sd_bus_message_read(reply, "s", &s);
4331 return bus_log_parse_error(r);
4333 if (streq(s, "enabled") ||
4334 streq(s, "enabled-runtime") ||
4346 static int systemctl_help(void) {
4348 pager_open_if_enabled();
4350 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4351 "Query or send control commands to the systemd manager.\n\n"
4352 " -h --help Show this help\n"
4353 " --version Show package version\n"
4354 " --system Connect to system manager\n"
4355 " --user Connect to user service manager\n"
4356 " -H --host=[USER@]HOST\n"
4357 " Operate on remote host\n"
4358 " -M --machine=CONTAINER\n"
4359 " Operate on local container\n"
4360 " -t --type=TYPE List only units of a particular type\n"
4361 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4362 " -p --property=NAME Show only properties by this name\n"
4363 " -a --all Show all loaded units/properties, including dead/empty\n"
4364 " ones. To list all units installed on the system, use\n"
4365 " the 'list-unit-files' command instead.\n"
4366 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4367 " -l --full Don't ellipsize unit names on output\n"
4368 " --fail When queueing a new job, fail if conflicting jobs are\n"
4370 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4372 " --ignore-dependencies\n"
4373 " When queueing a new job, ignore all its dependencies\n"
4374 " --show-types When showing sockets, explicitly show their type\n"
4375 " -i --ignore-inhibitors\n"
4376 " When shutting down or sleeping, ignore inhibitors\n"
4377 " --kill-who=WHO Who to send signal to\n"
4378 " -s --signal=SIGNAL Which signal to send\n"
4379 " -q --quiet Suppress output\n"
4380 " --no-block Do not wait until operation finished\n"
4381 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4382 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4384 " --no-legend Do not print a legend (column headers and hints)\n"
4385 " --no-pager Do not pipe output into a pager\n"
4386 " --no-ask-password\n"
4387 " Do not ask for system passwords\n"
4388 " --global Enable/disable unit files globally\n"
4389 " --runtime Enable unit files only temporarily until next reboot\n"
4390 " -f --force When enabling unit files, override existing symlinks\n"
4391 " When shutting down, execute action immediately\n"
4392 " --root=PATH Enable unit files in the specified root directory\n"
4393 " -n --lines=INTEGER Number of journal entries to show\n"
4394 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4395 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4397 " list-units List loaded units\n"
4398 " list-sockets List loaded sockets ordered by address\n"
4399 " start [NAME...] Start (activate) one or more units\n"
4400 " stop [NAME...] Stop (deactivate) one or more units\n"
4401 " reload [NAME...] Reload one or more units\n"
4402 " restart [NAME...] Start or restart one or more units\n"
4403 " try-restart [NAME...] Restart one or more units if active\n"
4404 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4405 " otherwise start or restart\n"
4406 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4407 " otherwise restart if active\n"
4408 " isolate [NAME] Start one unit and stop all others\n"
4409 " kill [NAME...] Send signal to processes of a unit\n"
4410 " is-active [NAME...] Check whether units are active\n"
4411 " is-failed [NAME...] Check whether units are failed\n"
4412 " status [NAME...|PID...] Show runtime status of one or more units\n"
4413 " show [NAME...|JOB...] Show properties of one or more\n"
4414 " units/jobs or the manager\n"
4415 " set-property [NAME] [ASSIGNMENT...]\n"
4416 " Sets one or more properties of a unit\n"
4417 " help [NAME...|PID...] Show manual for one or more units\n"
4418 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4420 " list-dependencies [NAME] Recursively show units which are required\n"
4421 " or wanted by this unit or by which this\n"
4422 " unit is required or wanted\n\n"
4423 "Unit File Commands:\n"
4424 " list-unit-files List installed unit files\n"
4425 " enable [NAME...] Enable one or more unit files\n"
4426 " disable [NAME...] Disable one or more unit files\n"
4427 " reenable [NAME...] Reenable one or more unit files\n"
4428 " preset [NAME...] Enable/disable one or more unit files\n"
4429 " based on preset configuration\n"
4430 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4431 " mask [NAME...] Mask one or more units\n"
4432 " unmask [NAME...] Unmask one or more units\n"
4433 " link [PATH...] Link one or more units files into\n"
4434 " the search path\n"
4435 " get-default Get the name of the default target\n"
4436 " set-default NAME Set the default target\n\n"
4438 " list-jobs List jobs\n"
4439 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4440 "Snapshot Commands:\n"
4441 " snapshot [NAME] Create a snapshot\n"
4442 " delete [NAME...] Remove one or more snapshots\n\n"
4443 "Environment Commands:\n"
4444 " show-environment Dump environment\n"
4445 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4446 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4447 "Manager Lifecycle Commands:\n"
4448 " daemon-reload Reload systemd manager configuration\n"
4449 " daemon-reexec Reexecute systemd manager\n\n"
4450 "System Commands:\n"
4451 " default Enter system default mode\n"
4452 " rescue Enter system rescue mode\n"
4453 " emergency Enter system emergency mode\n"
4454 " halt Shut down and halt the system\n"
4455 " poweroff Shut down and power-off the system\n"
4456 " reboot [ARG] Shut down and reboot the system\n"
4457 " kexec Shut down and reboot the system with kexec\n"
4458 " exit Request user instance exit\n"
4459 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4460 " suspend Suspend the system\n"
4461 " hibernate Hibernate the system\n"
4462 " hybrid-sleep Hibernate and suspend the system\n",
4463 program_invocation_short_name);
4468 static int halt_help(void) {
4470 printf("%s [OPTIONS...]%s\n\n"
4471 "%s the system.\n\n"
4472 " --help Show this help\n"
4473 " --halt Halt the machine\n"
4474 " -p --poweroff Switch off the machine\n"
4475 " --reboot Reboot the machine\n"
4476 " -f --force Force immediate halt/power-off/reboot\n"
4477 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4478 " -d --no-wtmp Don't write wtmp record\n"
4479 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4480 program_invocation_short_name,
4481 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4482 arg_action == ACTION_REBOOT ? "Reboot" :
4483 arg_action == ACTION_POWEROFF ? "Power off" :
4489 static int shutdown_help(void) {
4491 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4492 "Shut down the system.\n\n"
4493 " --help Show this help\n"
4494 " -H --halt Halt the machine\n"
4495 " -P --poweroff Power-off the machine\n"
4496 " -r --reboot Reboot the machine\n"
4497 " -h Equivalent to --poweroff, overridden by --halt\n"
4498 " -k Don't halt/power-off/reboot, just send warnings\n"
4499 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4500 " -c Cancel a pending shutdown\n",
4501 program_invocation_short_name);
4506 static int telinit_help(void) {
4508 printf("%s [OPTIONS...] {COMMAND}\n\n"
4509 "Send control commands to the init daemon.\n\n"
4510 " --help Show this help\n"
4511 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4513 " 0 Power-off the machine\n"
4514 " 6 Reboot the machine\n"
4515 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4516 " 1, s, S Enter rescue mode\n"
4517 " q, Q Reload init daemon configuration\n"
4518 " u, U Reexecute init daemon\n",
4519 program_invocation_short_name);
4524 static int runlevel_help(void) {
4526 printf("%s [OPTIONS...]\n\n"
4527 "Prints the previous and current runlevel of the init system.\n\n"
4528 " --help Show this help\n",
4529 program_invocation_short_name);
4534 static int help_types(void) {
4538 puts("Available unit types:");
4539 for(i = 0; i < _UNIT_TYPE_MAX; i++) {
4540 t = unit_type_to_string(i);
4548 static int systemctl_parse_argv(int argc, char *argv[]) {
4557 ARG_IGNORE_DEPENDENCIES,
4569 ARG_NO_ASK_PASSWORD,
4577 static const struct option options[] = {
4578 { "help", no_argument, NULL, 'h' },
4579 { "version", no_argument, NULL, ARG_VERSION },
4580 { "type", required_argument, NULL, 't' },
4581 { "property", required_argument, NULL, 'p' },
4582 { "all", no_argument, NULL, 'a' },
4583 { "reverse", no_argument, NULL, ARG_REVERSE },
4584 { "after", no_argument, NULL, ARG_AFTER },
4585 { "before", no_argument, NULL, ARG_BEFORE },
4586 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4587 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4588 { "full", no_argument, NULL, 'l' },
4589 { "fail", no_argument, NULL, ARG_FAIL },
4590 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
4591 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
4592 { "ignore-inhibitors", no_argument, NULL, 'i' },
4593 { "user", no_argument, NULL, ARG_USER },
4594 { "system", no_argument, NULL, ARG_SYSTEM },
4595 { "global", no_argument, NULL, ARG_GLOBAL },
4596 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4597 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4598 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4599 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4600 { "quiet", no_argument, NULL, 'q' },
4601 { "root", required_argument, NULL, ARG_ROOT },
4602 { "force", no_argument, NULL, ARG_FORCE },
4603 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4604 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4605 { "signal", required_argument, NULL, 's' },
4606 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4607 { "host", required_argument, NULL, 'H' },
4608 { "machine", required_argument, NULL, 'M' },
4609 { "runtime", no_argument, NULL, ARG_RUNTIME },
4610 { "lines", required_argument, NULL, 'n' },
4611 { "output", required_argument, NULL, 'o' },
4612 { "plain", no_argument, NULL, ARG_PLAIN },
4613 { "state", required_argument, NULL, ARG_STATE },
4622 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
4627 return systemctl_help();
4630 puts(PACKAGE_STRING);
4631 puts(SYSTEMD_FEATURES);
4638 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4639 _cleanup_free_ char *type;
4641 type = strndup(word, size);
4645 if (streq(type, "help")) {
4650 if (unit_type_from_string(type) >= 0) {
4651 if (strv_push(&arg_types, type))
4657 /* It's much nicer to use --state= for
4658 * load states, but let's support this
4659 * in --types= too for compatibility
4660 * with old versions */
4661 if (unit_load_state_from_string(optarg) >= 0) {
4662 if (strv_push(&arg_states, type) < 0)
4668 log_error("Unknown unit type or load state '%s'.", type);
4669 log_info("Use -t help to see a list of allowed values.");
4677 /* Make sure that if the empty property list
4678 was specified, we won't show any properties. */
4679 if (isempty(optarg) && !arg_properties) {
4680 arg_properties = new0(char*, 1);
4681 if (!arg_properties)
4687 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4690 prop = strndup(word, size);
4694 if (strv_push(&arg_properties, prop) < 0) {
4701 /* If the user asked for a particular
4702 * property, show it to him, even if it is
4714 arg_dependency = DEPENDENCY_REVERSE;
4718 arg_dependency = DEPENDENCY_AFTER;
4722 arg_dependency = DEPENDENCY_BEFORE;
4725 case ARG_SHOW_TYPES:
4726 arg_show_types = true;
4730 arg_job_mode = "fail";
4733 case ARG_IRREVERSIBLE:
4734 arg_job_mode = "replace-irreversibly";
4737 case ARG_IGNORE_DEPENDENCIES:
4738 arg_job_mode = "ignore-dependencies";
4742 arg_scope = UNIT_FILE_USER;
4746 arg_scope = UNIT_FILE_SYSTEM;
4750 arg_scope = UNIT_FILE_GLOBAL;
4754 arg_no_block = true;
4758 arg_no_legend = true;
4762 arg_no_pager = true;
4778 if (strv_extend(&arg_states, "failed") < 0)
4796 arg_no_reload = true;
4800 arg_kill_who = optarg;
4804 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
4805 log_error("Failed to parse signal string %s.", optarg);
4810 case ARG_NO_ASK_PASSWORD:
4811 arg_ask_password = false;
4815 arg_transport = BUS_TRANSPORT_REMOTE;
4820 arg_transport = BUS_TRANSPORT_CONTAINER;
4829 if (safe_atou(optarg, &arg_lines) < 0) {
4830 log_error("Failed to parse lines '%s'", optarg);
4836 arg_output = output_mode_from_string(optarg);
4837 if (arg_output < 0) {
4838 log_error("Unknown output '%s'.", optarg);
4844 arg_ignore_inhibitors = true;
4855 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4858 s = strndup(word, size);
4862 if (strv_push(&arg_states, s) < 0) {
4874 assert_not_reached("Unhandled option");
4878 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
4879 log_error("Cannot access user instance remotely.");
4886 static int halt_parse_argv(int argc, char *argv[]) {
4895 static const struct option options[] = {
4896 { "help", no_argument, NULL, ARG_HELP },
4897 { "halt", no_argument, NULL, ARG_HALT },
4898 { "poweroff", no_argument, NULL, 'p' },
4899 { "reboot", no_argument, NULL, ARG_REBOOT },
4900 { "force", no_argument, NULL, 'f' },
4901 { "wtmp-only", no_argument, NULL, 'w' },
4902 { "no-wtmp", no_argument, NULL, 'd' },
4903 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4912 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
4913 if (runlevel == '0' || runlevel == '6')
4916 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
4923 arg_action = ACTION_HALT;
4927 if (arg_action != ACTION_REBOOT)
4928 arg_action = ACTION_POWEROFF;
4932 arg_action = ACTION_REBOOT;
4954 /* Compatibility nops */
4961 assert_not_reached("Unhandled option");
4965 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
4966 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
4968 log_error("Failed to write reboot param to "
4969 REBOOT_PARAM_FILE": %s", strerror(-r));
4972 } else if (optind < argc) {
4973 log_error("Too many arguments.");
4980 static int parse_time_spec(const char *t, usec_t *_u) {
4984 if (streq(t, "now"))
4986 else if (!strchr(t, ':')) {
4989 if (safe_atou64(t, &u) < 0)
4992 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
5001 hour = strtol(t, &e, 10);
5002 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
5005 minute = strtol(e+1, &e, 10);
5006 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
5009 n = now(CLOCK_REALTIME);
5010 s = (time_t) (n / USEC_PER_SEC);
5012 assert_se(localtime_r(&s, &tm));
5014 tm.tm_hour = (int) hour;
5015 tm.tm_min = (int) minute;
5018 assert_se(s = mktime(&tm));
5020 *_u = (usec_t) s * USEC_PER_SEC;
5023 *_u += USEC_PER_DAY;
5029 static int shutdown_parse_argv(int argc, char *argv[]) {
5036 static const struct option options[] = {
5037 { "help", no_argument, NULL, ARG_HELP },
5038 { "halt", no_argument, NULL, 'H' },
5039 { "poweroff", no_argument, NULL, 'P' },
5040 { "reboot", no_argument, NULL, 'r' },
5041 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5042 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5051 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5055 return shutdown_help();
5058 arg_action = ACTION_HALT;
5062 arg_action = ACTION_POWEROFF;
5067 arg_action = ACTION_KEXEC;
5069 arg_action = ACTION_REBOOT;
5073 arg_action = ACTION_KEXEC;
5077 if (arg_action != ACTION_HALT)
5078 arg_action = ACTION_POWEROFF;
5091 /* Compatibility nops */
5095 arg_action = ACTION_CANCEL_SHUTDOWN;
5102 assert_not_reached("Unhandled option");
5106 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5107 r = parse_time_spec(argv[optind], &arg_when);
5109 log_error("Failed to parse time specification: %s", argv[optind]);
5113 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5115 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5116 /* No time argument for shutdown cancel */
5117 arg_wall = argv + optind;
5118 else if (argc > optind + 1)
5119 /* We skip the time argument */
5120 arg_wall = argv + optind + 1;
5127 static int telinit_parse_argv(int argc, char *argv[]) {
5134 static const struct option options[] = {
5135 { "help", no_argument, NULL, ARG_HELP },
5136 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5140 static const struct {
5144 { '0', ACTION_POWEROFF },
5145 { '6', ACTION_REBOOT },
5146 { '1', ACTION_RESCUE },
5147 { '2', ACTION_RUNLEVEL2 },
5148 { '3', ACTION_RUNLEVEL3 },
5149 { '4', ACTION_RUNLEVEL4 },
5150 { '5', ACTION_RUNLEVEL5 },
5151 { 's', ACTION_RESCUE },
5152 { 'S', ACTION_RESCUE },
5153 { 'q', ACTION_RELOAD },
5154 { 'Q', ACTION_RELOAD },
5155 { 'u', ACTION_REEXEC },
5156 { 'U', ACTION_REEXEC }
5165 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5169 return telinit_help();
5179 assert_not_reached("Unhandled option");
5183 if (optind >= argc) {
5188 if (optind + 1 < argc) {
5189 log_error("Too many arguments.");
5193 if (strlen(argv[optind]) != 1) {
5194 log_error("Expected single character argument.");
5198 for (i = 0; i < ELEMENTSOF(table); i++)
5199 if (table[i].from == argv[optind][0])
5202 if (i >= ELEMENTSOF(table)) {
5203 log_error("Unknown command '%s'.", argv[optind]);
5207 arg_action = table[i].to;
5214 static int runlevel_parse_argv(int argc, char *argv[]) {
5220 static const struct option options[] = {
5221 { "help", no_argument, NULL, ARG_HELP },
5230 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5234 return runlevel_help();
5241 assert_not_reached("Unhandled option");
5245 if (optind < argc) {
5246 log_error("Too many arguments.");
5253 static int parse_argv(int argc, char *argv[]) {
5257 if (program_invocation_short_name) {
5259 if (strstr(program_invocation_short_name, "halt")) {
5260 arg_action = ACTION_HALT;
5261 return halt_parse_argv(argc, argv);
5262 } else if (strstr(program_invocation_short_name, "poweroff")) {
5263 arg_action = ACTION_POWEROFF;
5264 return halt_parse_argv(argc, argv);
5265 } else if (strstr(program_invocation_short_name, "reboot")) {
5267 arg_action = ACTION_KEXEC;
5269 arg_action = ACTION_REBOOT;
5270 return halt_parse_argv(argc, argv);
5271 } else if (strstr(program_invocation_short_name, "shutdown")) {
5272 arg_action = ACTION_POWEROFF;
5273 return shutdown_parse_argv(argc, argv);
5274 } else if (strstr(program_invocation_short_name, "init")) {
5276 if (sd_booted() > 0) {
5277 arg_action = _ACTION_INVALID;
5278 return telinit_parse_argv(argc, argv);
5280 /* Hmm, so some other init system is
5281 * running, we need to forward this
5282 * request to it. For now we simply
5283 * guess that it is Upstart. */
5285 execv(TELINIT, argv);
5287 log_error("Couldn't find an alternative telinit implementation to spawn.");
5291 } else if (strstr(program_invocation_short_name, "runlevel")) {
5292 arg_action = ACTION_RUNLEVEL;
5293 return runlevel_parse_argv(argc, argv);
5297 arg_action = ACTION_SYSTEMCTL;
5298 return systemctl_parse_argv(argc, argv);
5301 _pure_ static int action_to_runlevel(void) {
5303 static const char table[_ACTION_MAX] = {
5304 [ACTION_HALT] = '0',
5305 [ACTION_POWEROFF] = '0',
5306 [ACTION_REBOOT] = '6',
5307 [ACTION_RUNLEVEL2] = '2',
5308 [ACTION_RUNLEVEL3] = '3',
5309 [ACTION_RUNLEVEL4] = '4',
5310 [ACTION_RUNLEVEL5] = '5',
5311 [ACTION_RESCUE] = '1'
5314 assert(arg_action < _ACTION_MAX);
5316 return table[arg_action];
5319 static int talk_initctl(void) {
5321 struct init_request request = {
5322 .magic = INIT_MAGIC,
5324 .cmd = INIT_CMD_RUNLVL
5327 _cleanup_close_ int fd = -1;
5331 rl = action_to_runlevel();
5335 request.runlevel = rl;
5337 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5339 if (errno == ENOENT)
5342 log_error("Failed to open "INIT_FIFO": %m");
5347 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5349 log_error("Failed to write to "INIT_FIFO": %m");
5350 return errno > 0 ? -errno : -EIO;
5356 static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
5358 static const struct {
5366 int (* const dispatch)(sd_bus *bus, char **args);
5368 { "list-units", LESS, 1, list_units },
5369 { "list-unit-files", EQUAL, 1, list_unit_files },
5370 { "list-sockets", LESS, 1, list_sockets },
5371 { "list-jobs", EQUAL, 1, list_jobs },
5372 { "clear-jobs", EQUAL, 1, daemon_reload },
5373 { "cancel", MORE, 2, cancel_job },
5374 { "start", MORE, 2, start_unit },
5375 { "stop", MORE, 2, start_unit },
5376 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5377 { "reload", MORE, 2, start_unit },
5378 { "restart", MORE, 2, start_unit },
5379 { "try-restart", MORE, 2, start_unit },
5380 { "reload-or-restart", MORE, 2, start_unit },
5381 { "reload-or-try-restart", MORE, 2, start_unit },
5382 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5383 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5384 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5385 { "isolate", EQUAL, 2, start_unit },
5386 { "kill", MORE, 2, kill_unit },
5387 { "is-active", MORE, 2, check_unit_active },
5388 { "check", MORE, 2, check_unit_active },
5389 { "is-failed", MORE, 2, check_unit_failed },
5390 { "show", MORE, 1, show },
5391 { "status", MORE, 1, show },
5392 { "help", MORE, 2, show },
5393 { "snapshot", LESS, 2, snapshot },
5394 { "delete", MORE, 2, delete_snapshot },
5395 { "daemon-reload", EQUAL, 1, daemon_reload },
5396 { "daemon-reexec", EQUAL, 1, daemon_reload },
5397 { "show-environment", EQUAL, 1, show_environment },
5398 { "set-environment", MORE, 2, set_environment },
5399 { "unset-environment", MORE, 2, set_environment },
5400 { "halt", EQUAL, 1, start_special },
5401 { "poweroff", EQUAL, 1, start_special },
5402 { "reboot", EQUAL, 1, start_special },
5403 { "kexec", EQUAL, 1, start_special },
5404 { "suspend", EQUAL, 1, start_special },
5405 { "hibernate", EQUAL, 1, start_special },
5406 { "hybrid-sleep", EQUAL, 1, start_special },
5407 { "default", EQUAL, 1, start_special },
5408 { "rescue", EQUAL, 1, start_special },
5409 { "emergency", EQUAL, 1, start_special },
5410 { "exit", EQUAL, 1, start_special },
5411 { "reset-failed", MORE, 1, reset_failed },
5412 { "enable", MORE, 2, enable_unit },
5413 { "disable", MORE, 2, enable_unit },
5414 { "is-enabled", MORE, 2, unit_is_enabled },
5415 { "reenable", MORE, 2, enable_unit },
5416 { "preset", MORE, 2, enable_unit },
5417 { "mask", MORE, 2, enable_unit },
5418 { "unmask", MORE, 2, enable_unit },
5419 { "link", MORE, 2, enable_unit },
5420 { "switch-root", MORE, 2, switch_root },
5421 { "list-dependencies", LESS, 2, list_dependencies },
5422 { "set-default", EQUAL, 2, enable_unit },
5423 { "get-default", LESS, 1, get_default },
5424 { "set-property", MORE, 3, set_property },
5433 left = argc - optind;
5436 /* Special rule: no arguments means "list-units" */
5439 if (streq(argv[optind], "help") && !argv[optind+1]) {
5440 log_error("This command expects one or more "
5441 "unit names. Did you mean --help?");
5445 for (i = 0; i < ELEMENTSOF(verbs); i++)
5446 if (streq(argv[optind], verbs[i].verb))
5449 if (i >= ELEMENTSOF(verbs)) {
5450 log_error("Unknown operation '%s'.", argv[optind]);
5455 switch (verbs[i].argc_cmp) {
5458 if (left != verbs[i].argc) {
5459 log_error("Invalid number of arguments.");
5466 if (left < verbs[i].argc) {
5467 log_error("Too few arguments.");
5474 if (left > verbs[i].argc) {
5475 log_error("Too many arguments.");
5482 assert_not_reached("Unknown comparison operator.");
5485 /* Require a bus connection for all operations but
5487 if (!streq(verbs[i].verb, "enable") &&
5488 !streq(verbs[i].verb, "disable") &&
5489 !streq(verbs[i].verb, "is-enabled") &&
5490 !streq(verbs[i].verb, "list-unit-files") &&
5491 !streq(verbs[i].verb, "reenable") &&
5492 !streq(verbs[i].verb, "preset") &&
5493 !streq(verbs[i].verb, "mask") &&
5494 !streq(verbs[i].verb, "unmask") &&
5495 !streq(verbs[i].verb, "link") &&
5496 !streq(verbs[i].verb, "set-default") &&
5497 !streq(verbs[i].verb, "get-default")) {
5499 if (running_in_chroot() > 0) {
5500 log_info("Running in chroot, ignoring request.");
5504 if (((!streq(verbs[i].verb, "reboot") &&
5505 !streq(verbs[i].verb, "halt") &&
5506 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5507 log_error("Failed to get D-Bus connection: %s", strerror (-r));
5513 if (!bus && !avoid_bus()) {
5514 log_error("Failed to get D-Bus connection: %s", strerror (-r));
5519 return verbs[i].dispatch(bus, argv + optind);
5522 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5524 struct sd_shutdown_command c = {
5531 union sockaddr_union sockaddr = {
5532 .un.sun_family = AF_UNIX,
5533 .un.sun_path = "/run/systemd/shutdownd",
5536 struct iovec iovec[2] = {{
5537 .iov_base = (char*) &c,
5538 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5541 struct msghdr msghdr = {
5542 .msg_name = &sockaddr,
5543 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5544 + sizeof("/run/systemd/shutdownd") - 1,
5549 _cleanup_close_ int fd;
5551 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5555 if (!isempty(message)) {
5556 iovec[1].iov_base = (char*) message;
5557 iovec[1].iov_len = strlen(message);
5558 msghdr.msg_iovlen++;
5561 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5567 static int reload_with_fallback(sd_bus *bus) {
5570 /* First, try systemd via D-Bus. */
5571 if (daemon_reload(bus, NULL) >= 0)
5575 /* Nothing else worked, so let's try signals */
5576 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5578 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5579 log_error("kill() failed: %m");
5586 static int start_with_fallback(sd_bus *bus) {
5589 /* First, try systemd via D-Bus. */
5590 if (start_unit(bus, NULL) >= 0)
5594 /* Nothing else worked, so let's try
5596 if (talk_initctl() > 0)
5599 log_error("Failed to talk to init daemon.");
5603 warn_wall(arg_action);
5607 static _noreturn_ void halt_now(enum action a) {
5609 _cleanup_free_ char *param = NULL;
5611 /* Make sure C-A-D is handled by the kernel from this
5613 reboot(RB_ENABLE_CAD);
5618 log_info("Halting.");
5619 reboot(RB_HALT_SYSTEM);
5622 case ACTION_POWEROFF:
5623 log_info("Powering off.");
5624 reboot(RB_POWER_OFF);
5629 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) == 0) {
5630 log_info("Rebooting with arg '%s'.", param);
5631 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
5632 LINUX_REBOOT_CMD_RESTART2, param);
5634 log_info("Rebooting.");
5635 reboot(RB_AUTOBOOT);
5640 assert_not_reached("Unknown halt action.");
5643 assert_not_reached("Uh? This shouldn't happen.");
5646 static int halt_main(sd_bus *bus) {
5649 r = check_inhibitors(bus, arg_action);
5653 if (geteuid() != 0) {
5654 /* Try logind if we are a normal user and no special
5655 * mode applies. Maybe PolicyKit allows us to shutdown
5658 if (arg_when <= 0 &&
5661 (arg_action == ACTION_POWEROFF ||
5662 arg_action == ACTION_REBOOT)) {
5663 r = reboot_with_logind(bus, arg_action);
5668 log_error("Must be root.");
5673 _cleanup_free_ char *m;
5675 m = strv_join(arg_wall, " ");
5679 r = send_shutdownd(arg_when,
5680 arg_action == ACTION_HALT ? 'H' :
5681 arg_action == ACTION_POWEROFF ? 'P' :
5682 arg_action == ACTION_KEXEC ? 'K' :
5689 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
5691 char date[FORMAT_TIMESTAMP_MAX];
5693 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5694 format_timestamp(date, sizeof(date), arg_when));
5699 if (!arg_dry && !arg_force)
5700 return start_with_fallback(bus);
5703 if (sd_booted() > 0)
5704 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5706 r = utmp_put_shutdown();
5708 log_warning("Failed to write utmp record: %s", strerror(-r));
5715 halt_now(arg_action);
5716 /* We should never reach this. */
5720 static int runlevel_main(void) {
5721 int r, runlevel, previous;
5723 r = utmp_get_runlevel(&runlevel, &previous);
5730 previous <= 0 ? 'N' : previous,
5731 runlevel <= 0 ? 'N' : runlevel);
5736 int main(int argc, char*argv[]) {
5737 _cleanup_bus_unref_ sd_bus *bus = NULL;
5740 setlocale(LC_ALL, "");
5741 log_parse_environment();
5744 /* Explicitly not on_tty() to avoid setting cached value.
5745 * This becomes relevant for piping output which might be
5747 original_stdout_is_tty = isatty(STDOUT_FILENO);
5749 r = parse_argv(argc, argv);
5753 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5754 * let's shortcut this */
5755 if (arg_action == ACTION_RUNLEVEL) {
5756 r = runlevel_main();
5760 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
5761 log_info("Running in chroot, ignoring request.");
5767 r = bus_open_transport(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
5769 log_error("Failed to create bus connection: %s", strerror(-r));
5774 switch (arg_action) {
5776 case ACTION_SYSTEMCTL:
5777 r = systemctl_main(bus, argc, argv, r);
5781 case ACTION_POWEROFF:
5787 case ACTION_RUNLEVEL2:
5788 case ACTION_RUNLEVEL3:
5789 case ACTION_RUNLEVEL4:
5790 case ACTION_RUNLEVEL5:
5792 case ACTION_EMERGENCY:
5793 case ACTION_DEFAULT:
5794 r = start_with_fallback(bus);
5799 r = reload_with_fallback(bus);
5802 case ACTION_CANCEL_SHUTDOWN: {
5803 _cleanup_free_ char *m = NULL;
5806 m = strv_join(arg_wall, " ");
5813 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
5815 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
5819 case ACTION_RUNLEVEL:
5820 case _ACTION_INVALID:
5822 assert_not_reached("Unknown action");
5827 ask_password_agent_close();
5828 polkit_agent_close();
5830 strv_free(arg_types);
5831 strv_free(arg_states);
5832 strv_free(arg_properties);
5834 return r < 0 ? EXIT_FAILURE : r;