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 ask_password_agent_open();
162 static void polkit_agent_open_if_enabled(void) {
164 /* Open the polkit agent as a child process if necessary */
166 if (!arg_ask_password)
169 if (arg_scope != UNIT_FILE_SYSTEM)
172 if (arg_transport != BUS_TRANSPORT_LOCAL)
179 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
182 if (!sd_bus_error_is_set(error))
185 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
186 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
187 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
188 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
189 return EXIT_NOPERMISSION;
191 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
192 return EXIT_NOTINSTALLED;
194 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
195 sd_bus_error_has_name(error, BUS_ERROR_NOT_SUPPORTED))
196 return EXIT_NOTIMPLEMENTED;
198 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
199 return EXIT_NOTCONFIGURED;
207 static void warn_wall(enum action a) {
208 static const char *table[_ACTION_MAX] = {
209 [ACTION_HALT] = "The system is going down for system halt NOW!",
210 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
211 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
212 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
213 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
214 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
215 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
222 _cleanup_free_ char *p;
224 p = strv_join(arg_wall, " ");
239 utmp_wall(table[a], NULL);
242 static bool avoid_bus(void) {
244 if (running_in_chroot() > 0)
247 if (sd_booted() <= 0)
250 if (!isempty(arg_root))
253 if (arg_scope == UNIT_FILE_GLOBAL)
259 static int compare_unit_info(const void *a, const void *b) {
260 const UnitInfo *u = a, *v = b;
263 d1 = strrchr(u->id, '.');
264 d2 = strrchr(v->id, '.');
269 r = strcasecmp(d1, d2);
274 return strcasecmp(u->id, v->id);
277 static bool output_show_unit(const UnitInfo *u) {
280 if (!strv_isempty(arg_states))
282 strv_contains(arg_states, u->load_state) ||
283 strv_contains(arg_states, u->sub_state) ||
284 strv_contains(arg_states, u->active_state);
286 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
287 strv_find(arg_types, dot+1))) &&
288 (arg_all || !(streq(u->active_state, "inactive")
289 || u->following[0]) || u->job_id > 0);
292 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
293 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
295 unsigned n_shown = 0;
298 max_id_len = sizeof("UNIT")-1;
299 load_len = sizeof("LOAD")-1;
300 active_len = sizeof("ACTIVE")-1;
301 sub_len = sizeof("SUB")-1;
302 job_len = sizeof("JOB")-1;
305 for (u = unit_infos; u < unit_infos + c; u++) {
306 if (!output_show_unit(u))
309 max_id_len = MAX(max_id_len, strlen(u->id));
310 load_len = MAX(load_len, strlen(u->load_state));
311 active_len = MAX(active_len, strlen(u->active_state));
312 sub_len = MAX(sub_len, strlen(u->sub_state));
314 if (u->job_id != 0) {
315 job_len = MAX(job_len, strlen(u->job_type));
320 if (!arg_full && original_stdout_is_tty) {
322 id_len = MIN(max_id_len, 25u);
323 basic_len = 5 + id_len + 5 + active_len + sub_len;
325 basic_len += job_len + 1;
326 if (basic_len < (unsigned) columns()) {
327 unsigned extra_len, incr;
328 extra_len = columns() - basic_len;
329 /* Either UNIT already got 25, or is fully satisfied.
330 * Grant up to 25 to DESC now. */
331 incr = MIN(extra_len, 25u);
334 /* split the remaining space between UNIT and DESC,
335 * but do not give UNIT more than it needs. */
337 incr = MIN(extra_len / 2, max_id_len - id_len);
339 desc_len += extra_len - incr;
345 for (u = unit_infos; u < unit_infos + c; u++) {
346 _cleanup_free_ char *e = NULL;
347 const char *on_loaded, *off_loaded, *on = "";
348 const char *on_active, *off_active, *off = "";
350 if (!output_show_unit(u))
353 if (!n_shown && !arg_no_legend) {
354 printf("%-*s %-*s %-*s %-*s ", id_len, "UNIT", load_len, "LOAD",
355 active_len, "ACTIVE", sub_len, "SUB");
357 printf("%-*s ", job_len, "JOB");
358 if (!arg_full && arg_no_pager)
359 printf("%.*s\n", desc_len, "DESCRIPTION");
361 printf("%s\n", "DESCRIPTION");
366 if (streq(u->load_state, "error") ||
367 streq(u->load_state, "not-found")) {
368 on_loaded = on = ansi_highlight_red();
369 off_loaded = off = ansi_highlight_off();
371 on_loaded = off_loaded = "";
373 if (streq(u->active_state, "failed")) {
374 on_active = on = ansi_highlight_red();
375 off_active = off = ansi_highlight_off();
377 on_active = off_active = "";
379 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
381 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
382 on, id_len, e ? e : u->id, off,
383 on_loaded, load_len, u->load_state, off_loaded,
384 on_active, active_len, u->active_state,
385 sub_len, u->sub_state, off_active,
386 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
388 printf("%.*s\n", desc_len, u->description);
390 printf("%s\n", u->description);
393 if (!arg_no_legend) {
394 const char *on, *off;
397 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
398 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
399 "SUB = The low-level unit activation state, values depend on unit type.\n");
401 printf("JOB = Pending job for the unit.\n");
403 on = ansi_highlight();
404 off = ansi_highlight_off();
406 on = ansi_highlight_red();
407 off = ansi_highlight_off();
411 printf("%s%u loaded units listed.%s\n"
412 "To show all installed unit files use 'systemctl list-unit-files'.\n",
415 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
416 "To show all installed unit files use 'systemctl list-unit-files'.\n",
421 static int get_unit_list(
423 sd_bus_message **_reply,
424 UnitInfo **_unit_infos) {
426 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
427 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
428 _cleanup_free_ UnitInfo *unit_infos = NULL;
437 r = sd_bus_call_method(
439 "org.freedesktop.systemd1",
440 "/org/freedesktop/systemd1",
441 "org.freedesktop.systemd1.Manager",
447 log_error("Failed to list units: %s", bus_error_message(&error, r));
451 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
453 return bus_log_parse_error(r);
455 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
457 if (!GREEDY_REALLOC(unit_infos, size, c+1))
463 return bus_log_parse_error(r);
465 r = sd_bus_message_exit_container(reply);
467 return bus_log_parse_error(r);
472 *_unit_infos = unit_infos;
478 static int list_units(sd_bus *bus, char **args) {
479 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
480 _cleanup_free_ UnitInfo *unit_infos = NULL;
483 pager_open_if_enabled();
485 r = get_unit_list(bus, &reply, &unit_infos);
489 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
490 output_units_list(unit_infos, r);
495 static int get_triggered_units(
500 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
503 r = sd_bus_get_property_strv(
505 "org.freedesktop.systemd1",
507 "org.freedesktop.systemd1.Unit",
513 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
518 static int get_listening(
520 const char* unit_path,
524 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
525 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
526 const char *type, *path;
529 r = sd_bus_get_property(
531 "org.freedesktop.systemd1",
533 "org.freedesktop.systemd1.Socket",
539 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
543 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
545 return bus_log_parse_error(r);
547 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
549 r = strv_extend(listen, type);
553 r = strv_extend(listen, path);
560 return bus_log_parse_error(r);
562 r = sd_bus_message_exit_container(reply);
564 return bus_log_parse_error(r);
575 /* Note: triggered is a list here, although it almost certainly
576 * will always be one unit. Nevertheless, dbus API allows for multiple
577 * values, so let's follow that.*/
580 /* The strv above is shared. free is set only in the first one. */
584 static int socket_info_compare(struct socket_info *a, struct socket_info *b) {
585 int o = strcmp(a->path, b->path);
587 o = strcmp(a->type, b->type);
591 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
592 struct socket_info *s;
593 unsigned pathlen = sizeof("LISTEN") - 1,
594 typelen = (sizeof("TYPE") - 1) * arg_show_types,
595 socklen = sizeof("UNIT") - 1,
596 servlen = sizeof("ACTIVATES") - 1;
597 const char *on, *off;
599 for (s = socket_infos; s < socket_infos + cs; s++) {
603 socklen = MAX(socklen, strlen(s->id));
605 typelen = MAX(typelen, strlen(s->type));
606 pathlen = MAX(pathlen, strlen(s->path));
608 STRV_FOREACH(a, s->triggered)
609 tmp += strlen(*a) + 2*(a != s->triggered);
610 servlen = MAX(servlen, tmp);
615 printf("%-*s %-*.*s%-*s %s\n",
617 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
621 for (s = socket_infos; s < socket_infos + cs; s++) {
625 printf("%-*s %-*s %-*s",
626 pathlen, s->path, typelen, s->type, socklen, s->id);
629 pathlen, s->path, socklen, s->id);
630 STRV_FOREACH(a, s->triggered)
632 a == s->triggered ? "" : ",", *a);
636 on = ansi_highlight();
637 off = ansi_highlight_off();
641 on = ansi_highlight_red();
642 off = ansi_highlight_off();
645 if (!arg_no_legend) {
646 printf("%s%u sockets listed.%s\n", on, cs, off);
648 printf("Pass --all to see loaded but inactive sockets, too.\n");
654 static int list_sockets(sd_bus *bus, char **args) {
655 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
656 _cleanup_free_ UnitInfo *unit_infos = NULL;
657 struct socket_info *socket_infos = NULL;
659 struct socket_info *s;
660 unsigned cu = 0, cs = 0;
664 pager_open_if_enabled();
666 r = get_unit_list(bus, &reply, &unit_infos);
672 for (u = unit_infos; u < unit_infos + cu; u++) {
674 _cleanup_strv_free_ char **listen = NULL, **triggered = NULL;
677 if (!output_show_unit(u))
680 if ((dot = strrchr(u->id, '.')) && !streq(dot+1, "socket"))
683 r = get_triggered_units(bus, u->unit_path, &triggered);
687 r = get_listening(bus, u->unit_path, &listen, &c);
691 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
696 for (i = 0; i < c; i++)
697 socket_infos[cs + i] = (struct socket_info) {
700 .path = listen[i*2 + 1],
701 .triggered = triggered,
702 .own_triggered = i==0,
705 /* from this point on we will cleanup those socket_infos */
708 listen = triggered = NULL; /* avoid cleanup */
711 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
712 (__compar_fn_t) socket_info_compare);
714 output_sockets_list(socket_infos, cs);
717 assert(cs == 0 || socket_infos);
718 for (s = socket_infos; s < socket_infos + cs; s++) {
721 if (s->own_triggered)
722 strv_free(s->triggered);
729 static int compare_unit_file_list(const void *a, const void *b) {
731 const UnitFileList *u = a, *v = b;
733 d1 = strrchr(u->path, '.');
734 d2 = strrchr(v->path, '.');
739 r = strcasecmp(d1, d2);
744 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
747 static bool output_show_unit_file(const UnitFileList *u) {
750 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
753 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
754 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
755 const UnitFileList *u;
757 max_id_len = sizeof("UNIT FILE")-1;
758 state_cols = sizeof("STATE")-1;
759 for (u = units; u < units + c; u++) {
760 if (!output_show_unit_file(u))
763 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
764 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
769 id_cols = MIN(max_id_len, 25u);
770 basic_cols = 1 + id_cols + state_cols;
771 if (basic_cols < (unsigned) columns())
772 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
774 id_cols = max_id_len;
777 printf("%-*s %-*s\n", id_cols, "UNIT FILE", state_cols, "STATE");
779 for (u = units; u < units + c; u++) {
780 _cleanup_free_ char *e = NULL;
781 const char *on, *off;
784 if (!output_show_unit_file(u))
789 if (u->state == UNIT_FILE_MASKED ||
790 u->state == UNIT_FILE_MASKED_RUNTIME ||
791 u->state == UNIT_FILE_DISABLED ||
792 u->state == UNIT_FILE_INVALID) {
793 on = ansi_highlight_red();
794 off = ansi_highlight_off();
795 } else if (u->state == UNIT_FILE_ENABLED) {
796 on = ansi_highlight_green();
797 off = ansi_highlight_off();
801 id = path_get_file_name(u->path);
803 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
805 printf("%-*s %s%-*s%s\n",
807 on, state_cols, unit_file_state_to_string(u->state), off);
811 printf("\n%u unit files listed.\n", n_shown);
814 static int list_unit_files(sd_bus *bus, char **args) {
815 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
816 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
817 _cleanup_free_ UnitFileList *units = NULL;
823 pager_open_if_enabled();
831 h = hashmap_new(string_hash_func, string_compare_func);
835 r = unit_file_get_list(arg_scope, arg_root, h);
837 unit_file_list_free(h);
838 log_error("Failed to get unit file list: %s", strerror(-r));
842 n_units = hashmap_size(h);
843 units = new(UnitFileList, n_units);
845 unit_file_list_free(h);
849 HASHMAP_FOREACH(u, h, i) {
850 memcpy(units + c++, u, sizeof(UnitFileList));
854 assert(c == n_units);
859 r = sd_bus_call_method(
861 "org.freedesktop.systemd1",
862 "/org/freedesktop/systemd1",
863 "org.freedesktop.systemd1.Manager",
869 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
873 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
875 return bus_log_parse_error(r);
877 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
879 if (!GREEDY_REALLOC(units, size, c + 1))
882 units[c++] = (struct UnitFileList) {
884 unit_file_state_from_string(state)
888 return bus_log_parse_error(r);
890 r = sd_bus_message_exit_container(reply);
892 return bus_log_parse_error(r);
896 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
897 output_unit_file_list(units, c);
903 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
905 _cleanup_free_ char *n = NULL;
907 size_t max_len = MAX(columns(),20u);
910 for (i = level - 1; i >= 0; i--) {
912 if(len > max_len - 3 && !arg_full) {
913 printf("%s...\n",max_len % 2 ? "" : " ");
916 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
919 if(len > max_len - 3 && !arg_full) {
920 printf("%s...\n",max_len % 2 ? "" : " ");
923 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
927 printf("%s\n", name);
931 n = ellipsize(name, max_len-len, 100);
939 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
941 static const char *dependencies[] = {
942 [DEPENDENCY_FORWARD] = "Requires\0"
943 "RequiresOverridable\0"
945 "RequisiteOverridable\0"
947 [DEPENDENCY_REVERSE] = "RequiredBy\0"
948 "RequiredByOverridable\0"
951 [DEPENDENCY_AFTER] = "After\0",
952 [DEPENDENCY_BEFORE] = "Before\0",
955 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
956 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
957 _cleanup_strv_free_ char **ret = NULL;
958 _cleanup_free_ char *path = NULL;
964 assert(arg_dependency < ELEMENTSOF(dependencies));
966 path = unit_dbus_path_from_name(name);
970 r = sd_bus_call_method(
972 "org.freedesktop.systemd1",
974 "org.freedesktop.DBus.Properties",
978 "s", "org.freedesktop.systemd1.Unit");
980 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
984 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
986 return bus_log_parse_error(r);
988 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
991 r = sd_bus_message_read(reply, "s", &prop);
993 return bus_log_parse_error(r);
995 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
996 r = sd_bus_message_skip(reply, "v");
998 return bus_log_parse_error(r);
1001 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1003 return bus_log_parse_error(r);
1005 r = bus_message_read_strv_extend(reply, &ret);
1007 return bus_log_parse_error(r);
1009 r = sd_bus_message_exit_container(reply);
1011 return bus_log_parse_error(r);
1014 r = sd_bus_message_exit_container(reply);
1016 return bus_log_parse_error(r);
1020 return bus_log_parse_error(r);
1022 r = sd_bus_message_exit_container(reply);
1024 return bus_log_parse_error(r);
1032 static int list_dependencies_compare(const void *_a, const void *_b) {
1033 const char **a = (const char**) _a, **b = (const char**) _b;
1034 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1036 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1038 return strcasecmp(*a, *b);
1041 static int list_dependencies_one(
1046 unsigned int branches) {
1048 _cleanup_strv_free_ char **deps = NULL, **u;
1052 u = strv_append(*units, name);
1056 r = list_dependencies_get_dependencies(bus, name, &deps);
1060 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1062 STRV_FOREACH(c, deps) {
1063 if (strv_contains(u, *c)) {
1065 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1072 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1076 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1077 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1092 static int list_dependencies(sd_bus *bus, char **args) {
1093 _cleanup_strv_free_ char **units = NULL;
1094 _cleanup_free_ char *unit = NULL;
1100 unit = unit_name_mangle(args[1]);
1105 u = SPECIAL_DEFAULT_TARGET;
1107 pager_open_if_enabled();
1111 return list_dependencies_one(bus, u, 0, &units, 0);
1114 static int get_default(sd_bus *bus, char **args) {
1115 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1116 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1117 _cleanup_free_ char *_path = NULL;
1121 if (!bus || avoid_bus()) {
1122 r = unit_file_get_default(arg_scope, arg_root, &_path);
1124 log_error("Failed to get default target: %s", strerror(-r));
1130 r = sd_bus_call_method(
1132 "org.freedesktop.systemd1",
1133 "/org/freedesktop/systemd1",
1134 "org.freedesktop.systemd1.Manager",
1140 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1144 r = sd_bus_message_read(reply, "s", &path);
1146 return bus_log_parse_error(r);
1150 printf("%s\n", path);
1157 const char *name, *type, *state;
1160 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1161 unsigned id_len, unit_len, type_len, state_len;
1162 const struct job_info *j;
1163 const char *on, *off;
1164 bool shorten = false;
1166 assert(n == 0 || jobs);
1169 on = ansi_highlight_green();
1170 off = ansi_highlight_off();
1172 printf("%sNo jobs running.%s\n", on, off);
1176 pager_open_if_enabled();
1178 for (j = jobs; j < jobs + n; j++) {
1179 uint32_t id = j->id;
1180 assert(j->name && j->type && j->state);
1182 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1183 unit_len = MAX(unit_len, strlen(j->name));
1184 type_len = MAX(type_len, strlen(j->type));
1185 state_len = MAX(state_len, strlen(j->state));
1188 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1189 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1193 printf("%*s %-*s %-*s %-*s\n",
1197 state_len, "STATE");
1199 for (j = jobs; j < jobs + n; j++) {
1200 _cleanup_free_ char *e = NULL;
1202 if (streq(j->state, "running")) {
1203 on = ansi_highlight();
1204 off = ansi_highlight_off();
1208 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1209 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1211 on, unit_len, e ? e : j->name, off,
1213 on, state_len, j->state, off);
1216 on = ansi_highlight();
1217 off = ansi_highlight_off();
1219 printf("\n%s%u jobs listed%s.\n", on, n, off);
1222 static int list_jobs(sd_bus *bus, char **args) {
1223 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1224 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1225 const char *name, *type, *state, *job_path, *unit_path;
1226 _cleanup_free_ struct job_info *jobs = NULL;
1232 r = sd_bus_call_method(
1234 "org.freedesktop.systemd1",
1235 "/org/freedesktop/systemd1",
1236 "org.freedesktop.systemd1.Manager",
1242 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1246 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1248 return bus_log_parse_error(r);
1250 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1252 if (!GREEDY_REALLOC(jobs, size, c + 1))
1255 jobs[c++] = (struct job_info) {
1263 return bus_log_parse_error(r);
1265 r = sd_bus_message_exit_container(reply);
1267 return bus_log_parse_error(r);
1269 output_jobs_list(jobs, c);
1273 static int cancel_job(sd_bus *bus, char **args) {
1274 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1279 if (strv_length(args) <= 1)
1280 return daemon_reload(bus, args);
1282 STRV_FOREACH(name, args+1) {
1286 r = safe_atou32(*name, &id);
1288 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1292 r = sd_bus_call_method(
1294 "org.freedesktop.systemd1",
1295 "/org/freedesktop/systemd1",
1296 "org.freedesktop.systemd1.Manager",
1302 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1310 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1311 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1312 _cleanup_free_ char *n = NULL;
1316 /* We ignore all errors here, since this is used to show a
1319 n = unit_name_mangle(unit);
1323 /* We don't use unit_dbus_path_from_name() directly since we
1324 * don't want to load the unit if it isn't loaded. */
1326 r = sd_bus_call_method(
1328 "org.freedesktop.systemd1",
1329 "/org/freedesktop/systemd1",
1330 "org.freedesktop.systemd1.Manager",
1338 r = sd_bus_message_read(reply, "o", &path);
1342 r = sd_bus_get_property_trivial(
1344 "org.freedesktop.systemd1",
1346 "org.freedesktop.systemd1.Unit",
1356 typedef struct WaitData {
1363 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1370 log_debug("Got D-Bus request: %s.%s() on %s",
1371 sd_bus_message_get_interface(m),
1372 sd_bus_message_get_member(m),
1373 sd_bus_message_get_path(m));
1375 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1376 log_error("Warning! D-Bus connection terminated.");
1378 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1380 const char *path, *result, *unit;
1384 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1386 ret = set_remove(d->set, (char*) path);
1392 if (!isempty(result))
1393 d->result = strdup(result);
1396 d->name = strdup(unit);
1401 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1403 ret = set_remove(d->set, (char*) path);
1410 d->result = strdup(result);
1416 log_error("Failed to parse message.");
1422 static int enable_wait_for_jobs(sd_bus *bus) {
1427 r = sd_bus_add_match(
1430 "sender='org.freedesktop.systemd1',"
1431 "interface='org.freedesktop.systemd1.Manager',"
1432 "member='JobRemoved',"
1433 "path='/org/freedesktop/systemd1'",
1436 log_error("Failed to add match");
1440 /* This is slightly dirty, since we don't undo the match registrations. */
1444 static int wait_for_jobs(sd_bus *bus, Set *s) {
1445 WaitData d = { .set = s };
1451 r = sd_bus_add_filter(bus, wait_filter, &d);
1455 while (!set_isempty(s)) {
1457 r = sd_bus_process(bus, NULL);
1462 r = sd_bus_wait(bus, (uint64_t) -1);
1471 if (streq(d.result, "timeout"))
1472 log_error("Job for %s timed out.", strna(d.name));
1473 else if (streq(d.result, "canceled"))
1474 log_error("Job for %s canceled.", strna(d.name));
1475 else if (streq(d.result, "dependency"))
1476 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1477 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1478 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1481 if (streq_ptr(d.result, "timeout"))
1483 else if (streq_ptr(d.result, "canceled"))
1485 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1496 return sd_bus_remove_filter(bus, wait_filter, &d);
1499 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1500 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1501 _cleanup_free_ char *n = NULL, *state = NULL;
1507 n = unit_name_mangle(name);
1511 /* We don't use unit_dbus_path_from_name() directly since we
1512 * don't want to load the unit if it isn't loaded. */
1514 r = sd_bus_call_method(
1516 "org.freedesktop.systemd1",
1517 "/org/freedesktop/systemd1",
1518 "org.freedesktop.systemd1.Manager",
1529 r = sd_bus_message_read(reply, "o", &path);
1531 return bus_log_parse_error(r);
1533 r = sd_bus_get_property_string(
1535 "org.freedesktop.systemd1",
1537 "org.freedesktop.systemd1.Unit",
1550 return nulstr_contains(good_states, state);
1553 static int check_triggering_units(
1557 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1558 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1559 _cleanup_strv_free_ char **triggered_by = NULL;
1560 bool print_warning_label = true;
1564 n = unit_name_mangle(name);
1568 path = unit_dbus_path_from_name(n);
1572 r = sd_bus_get_property_string(
1574 "org.freedesktop.systemd1",
1576 "org.freedesktop.systemd1.Unit",
1581 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1585 if (streq(state, "masked"))
1588 r = sd_bus_get_property_strv(
1590 "org.freedesktop.systemd1",
1592 "org.freedesktop.systemd1.Unit",
1597 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1601 STRV_FOREACH(i, triggered_by) {
1602 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1604 log_error("Failed to check unit: %s", strerror(-r));
1611 if (print_warning_label) {
1612 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1613 print_warning_label = false;
1616 log_warning(" %s", *i);
1622 static int start_unit_one(
1627 sd_bus_error *error,
1630 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1631 _cleanup_free_ char *n;
1640 n = unit_name_mangle(name);
1644 r = sd_bus_call_method(
1646 "org.freedesktop.systemd1",
1647 "/org/freedesktop/systemd1",
1648 "org.freedesktop.systemd1.Manager",
1654 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1655 /* There's always a fallback possible for
1656 * legacy actions. */
1657 return -EADDRNOTAVAIL;
1659 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1663 r = sd_bus_message_read(reply, "o", &path);
1665 return bus_log_parse_error(r);
1667 if (need_daemon_reload(bus, n) > 0)
1668 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1669 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1678 r = set_consume(s, p);
1680 log_error("Failed to add path to set.");
1688 static const struct {
1692 } action_table[_ACTION_MAX] = {
1693 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1694 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1695 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1696 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1697 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1698 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1699 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1700 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1701 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1702 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1703 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1704 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1705 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1706 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1707 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1710 static enum action verb_to_action(const char *verb) {
1713 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1714 if (streq_ptr(action_table[i].verb, verb))
1717 return _ACTION_INVALID;
1720 static int start_unit(sd_bus *bus, char **args) {
1721 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1722 _cleanup_set_free_free_ Set *s = NULL;
1723 const char *method, *mode, *one_name;
1729 ask_password_agent_open_if_enabled();
1731 if (arg_action == ACTION_SYSTEMCTL) {
1734 streq(args[0], "stop") ||
1735 streq(args[0], "condstop") ? "StopUnit" :
1736 streq(args[0], "reload") ? "ReloadUnit" :
1737 streq(args[0], "restart") ? "RestartUnit" :
1739 streq(args[0], "try-restart") ||
1740 streq(args[0], "condrestart") ? "TryRestartUnit" :
1742 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1744 streq(args[0], "reload-or-try-restart") ||
1745 streq(args[0], "condreload") ||
1747 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
1749 action = verb_to_action(args[0]);
1751 mode = streq(args[0], "isolate") ? "isolate" :
1752 action_table[action].mode ?: arg_job_mode;
1754 one_name = action_table[action].target;
1757 assert(arg_action < ELEMENTSOF(action_table));
1758 assert(action_table[arg_action].target);
1760 method = "StartUnit";
1762 mode = action_table[arg_action].mode;
1763 one_name = action_table[arg_action].target;
1766 if (!arg_no_block) {
1767 r = enable_wait_for_jobs(bus);
1769 log_error("Could not watch jobs: %s", strerror(-r));
1773 s = set_new(string_hash_func, string_compare_func);
1779 r = start_unit_one(bus, method, one_name, mode, &error, s);
1781 r = translate_bus_error_to_exit_status(r, &error);
1785 STRV_FOREACH(name, args+1) {
1788 q = start_unit_one(bus, method, *name, mode, &error, s);
1790 r = translate_bus_error_to_exit_status(r, &error);
1791 sd_bus_error_free(&error);
1796 if (!arg_no_block) {
1799 q = wait_for_jobs(bus, s);
1803 /* When stopping units, warn if they can still be triggered by
1804 * another active unit (socket, path, timer) */
1805 if (!arg_quiet && streq(method, "StopUnit")) {
1807 check_triggering_units(bus, one_name);
1809 STRV_FOREACH(name, args+1)
1810 check_triggering_units(bus, *name);
1817 /* Ask systemd-logind, which might grant access to unprivileged users
1818 * through PolicyKit */
1819 static int reboot_with_logind(sd_bus *bus, enum action a) {
1821 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1828 polkit_agent_open_if_enabled();
1836 case ACTION_POWEROFF:
1837 method = "PowerOff";
1840 case ACTION_SUSPEND:
1844 case ACTION_HIBERNATE:
1845 method = "Hibernate";
1848 case ACTION_HYBRID_SLEEP:
1849 method = "HybridSleep";
1856 r = sd_bus_call_method(
1858 "org.freedesktop.login1",
1859 "/org/freedesktop/login1",
1860 "org.freedesktop.login1.Manager",
1866 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
1874 static int check_inhibitors(sd_bus *bus, enum action a) {
1876 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1877 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1878 _cleanup_strv_free_ char **sessions = NULL;
1879 const char *what, *who, *why, *mode;
1888 if (arg_ignore_inhibitors || arg_force > 0)
1900 r = sd_bus_call_method(
1902 "org.freedesktop.login1",
1903 "/org/freedesktop/login1",
1904 "org.freedesktop.login1.Manager",
1910 /* If logind is not around, then there are no inhibitors... */
1913 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "ssssuu");
1915 return bus_log_parse_error(r);
1917 while ((r = sd_bus_message_read(reply, "ssssuu", &what, &who, &why, &mode, &uid, &pid)) > 0) {
1918 _cleanup_free_ char *comm = NULL, *user = NULL;
1919 _cleanup_strv_free_ char **sv = NULL;
1921 if (!streq(mode, "block"))
1924 sv = strv_split(what, ":");
1928 if (!strv_contains(sv,
1930 a == ACTION_POWEROFF ||
1931 a == ACTION_REBOOT ||
1932 a == ACTION_KEXEC ? "shutdown" : "sleep"))
1935 get_process_comm(pid, &comm);
1936 user = uid_to_name(uid);
1938 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
1939 who, (unsigned long) pid, strna(comm), strna(user), why);
1944 return bus_log_parse_error(r);
1946 r = sd_bus_message_exit_container(reply);
1948 return bus_log_parse_error(r);
1950 /* Check for current sessions */
1951 sd_get_sessions(&sessions);
1952 STRV_FOREACH(s, sessions) {
1953 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
1955 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
1958 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
1961 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
1964 sd_session_get_tty(*s, &tty);
1965 sd_session_get_seat(*s, &seat);
1966 sd_session_get_service(*s, &service);
1967 user = uid_to_name(uid);
1969 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
1976 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
1977 action_table[a].verb);
1985 static int start_special(sd_bus *bus, char **args) {
1991 a = verb_to_action(args[0]);
1993 r = check_inhibitors(bus, a);
1997 if (arg_force >= 2 && geteuid() != 0) {
1998 log_error("Must be root.");
2002 if (arg_force >= 2 &&
2003 (a == ACTION_HALT ||
2004 a == ACTION_POWEROFF ||
2005 a == ACTION_REBOOT))
2008 if (arg_force >= 1 &&
2009 (a == ACTION_HALT ||
2010 a == ACTION_POWEROFF ||
2011 a == ACTION_REBOOT ||
2012 a == ACTION_KEXEC ||
2014 return daemon_reload(bus, args);
2016 /* first try logind, to allow authentication with polkit */
2017 if (geteuid() != 0 &&
2018 (a == ACTION_POWEROFF ||
2019 a == ACTION_REBOOT ||
2020 a == ACTION_SUSPEND ||
2021 a == ACTION_HIBERNATE ||
2022 a == ACTION_HYBRID_SLEEP)) {
2023 r = reboot_with_logind(bus, a);
2028 r = start_unit(bus, args);
2029 if (r == EXIT_SUCCESS)
2035 static int check_unit_active(sd_bus *bus, char **args) {
2037 int r = 3; /* According to LSB: "program is not running" */
2042 STRV_FOREACH(name, args+1) {
2045 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2055 static int check_unit_failed(sd_bus *bus, char **args) {
2062 STRV_FOREACH(name, args+1) {
2065 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2075 static int kill_unit(sd_bus *bus, char **args) {
2076 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2084 arg_kill_who = "all";
2086 STRV_FOREACH(name, args+1) {
2087 _cleanup_free_ char *n = NULL;
2089 n = unit_name_mangle(*name);
2093 r = sd_bus_call_method(
2095 "org.freedesktop.systemd1",
2096 "/org/freedesktop/systemd1",
2097 "org.freedesktop.systemd1.Manager",
2101 "ssi", n, arg_kill_who, arg_signal);
2103 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2111 typedef struct ExecStatusInfo {
2119 usec_t start_timestamp;
2120 usec_t exit_timestamp;
2125 LIST_FIELDS(struct ExecStatusInfo, exec);
2128 static void exec_status_info_free(ExecStatusInfo *i) {
2137 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2138 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2141 int32_t code, status;
2147 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2149 return bus_log_parse_error(r);
2153 r = sd_bus_message_read(m, "s", &path);
2155 return bus_log_parse_error(r);
2157 i->path = strdup(path);
2161 r = sd_bus_message_read_strv(m, &i->argv);
2163 return bus_log_parse_error(r);
2165 r = sd_bus_message_read(m,
2168 &start_timestamp, &start_timestamp_monotonic,
2169 &exit_timestamp, &exit_timestamp_monotonic,
2173 return bus_log_parse_error(r);
2176 i->start_timestamp = (usec_t) start_timestamp;
2177 i->exit_timestamp = (usec_t) exit_timestamp;
2178 i->pid = (pid_t) pid;
2182 r = sd_bus_message_exit_container(m);
2184 return bus_log_parse_error(r);
2189 typedef struct UnitStatusInfo {
2191 const char *load_state;
2192 const char *active_state;
2193 const char *sub_state;
2194 const char *unit_file_state;
2196 const char *description;
2197 const char *following;
2199 char **documentation;
2201 const char *fragment_path;
2202 const char *source_path;
2203 const char *control_group;
2205 char **dropin_paths;
2207 const char *load_error;
2210 usec_t inactive_exit_timestamp;
2211 usec_t inactive_exit_timestamp_monotonic;
2212 usec_t active_enter_timestamp;
2213 usec_t active_exit_timestamp;
2214 usec_t inactive_enter_timestamp;
2216 bool need_daemon_reload;
2221 const char *status_text;
2222 const char *pid_file;
2225 usec_t start_timestamp;
2226 usec_t exit_timestamp;
2228 int exit_code, exit_status;
2230 usec_t condition_timestamp;
2231 bool condition_result;
2232 bool failed_condition_trigger;
2233 bool failed_condition_negate;
2234 const char *failed_condition;
2235 const char *failed_condition_param;
2238 unsigned n_accepted;
2239 unsigned n_connections;
2242 /* Pairs of type, path */
2246 const char *sysfs_path;
2248 /* Mount, Automount */
2254 LIST_HEAD(ExecStatusInfo, exec);
2257 static void print_status_info(
2262 const char *on, *off, *ss;
2264 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2265 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2268 arg_all * OUTPUT_SHOW_ALL |
2269 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2270 on_tty() * OUTPUT_COLOR |
2271 !arg_quiet * OUTPUT_WARN_CUTOFF |
2272 arg_full * OUTPUT_FULL_WIDTH;
2277 /* This shows pretty information about a unit. See
2278 * print_property() for a low-level property printer */
2280 printf("%s", strna(i->id));
2282 if (i->description && !streq_ptr(i->id, i->description))
2283 printf(" - %s", i->description);
2288 printf(" Follow: unit currently follows state of %s\n", i->following);
2290 if (streq_ptr(i->load_state, "error")) {
2291 on = ansi_highlight_red();
2292 off = ansi_highlight_off();
2296 path = i->source_path ? i->source_path : i->fragment_path;
2299 printf(" Loaded: %s%s%s (Reason: %s)\n",
2300 on, strna(i->load_state), off, i->load_error);
2301 else if (path && i->unit_file_state)
2302 printf(" Loaded: %s%s%s (%s; %s)\n",
2303 on, strna(i->load_state), off, path, i->unit_file_state);
2305 printf(" Loaded: %s%s%s (%s)\n",
2306 on, strna(i->load_state), off, path);
2308 printf(" Loaded: %s%s%s\n",
2309 on, strna(i->load_state), off);
2311 if (!strv_isempty(i->dropin_paths)) {
2312 _cleanup_free_ char *dir = NULL;
2316 STRV_FOREACH(dropin, i->dropin_paths) {
2317 if (! dir || last) {
2318 printf(dir ? " " : " Drop-In: ");
2323 if (path_get_parent(*dropin, &dir) < 0) {
2328 printf("%s\n %s", dir,
2329 draw_special_char(DRAW_TREE_RIGHT));
2332 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2334 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2338 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2340 if (streq_ptr(i->active_state, "failed")) {
2341 on = ansi_highlight_red();
2342 off = ansi_highlight_off();
2343 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2344 on = ansi_highlight_green();
2345 off = ansi_highlight_off();
2350 printf(" Active: %s%s (%s)%s",
2351 on, strna(i->active_state), ss, off);
2353 printf(" Active: %s%s%s",
2354 on, strna(i->active_state), off);
2356 if (!isempty(i->result) && !streq(i->result, "success"))
2357 printf(" (Result: %s)", i->result);
2359 timestamp = (streq_ptr(i->active_state, "active") ||
2360 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2361 (streq_ptr(i->active_state, "inactive") ||
2362 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2363 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2364 i->active_exit_timestamp;
2366 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2367 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2370 printf(" since %s; %s\n", s2, s1);
2372 printf(" since %s\n", s2);
2376 if (!i->condition_result && i->condition_timestamp > 0) {
2377 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2378 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2380 printf(" start condition failed at %s%s%s\n",
2381 s2, s1 ? "; " : "", s1 ? s1 : "");
2382 if (i->failed_condition_trigger)
2383 printf(" none of the trigger conditions were met\n");
2384 else if (i->failed_condition)
2385 printf(" %s=%s%s was not met\n",
2386 i->failed_condition,
2387 i->failed_condition_negate ? "!" : "",
2388 i->failed_condition_param);
2392 printf(" Device: %s\n", i->sysfs_path);
2394 printf(" Where: %s\n", i->where);
2396 printf(" What: %s\n", i->what);
2398 STRV_FOREACH(t, i->documentation)
2399 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2401 STRV_FOREACH_PAIR(t, t2, i->listen)
2402 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2405 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2407 LIST_FOREACH(exec, p, i->exec) {
2408 _cleanup_free_ char *argv = NULL;
2411 /* Only show exited processes here */
2415 argv = strv_join(p->argv, " ");
2416 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2418 good = is_clean_exit_lsb(p->code, p->status, NULL);
2420 on = ansi_highlight_red();
2421 off = ansi_highlight_off();
2425 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2427 if (p->code == CLD_EXITED) {
2430 printf("status=%i", p->status);
2432 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2437 printf("signal=%s", signal_to_string(p->status));
2439 printf(")%s\n", off);
2441 if (i->main_pid == p->pid &&
2442 i->start_timestamp == p->start_timestamp &&
2443 i->exit_timestamp == p->start_timestamp)
2444 /* Let's not show this twice */
2447 if (p->pid == i->control_pid)
2451 if (i->main_pid > 0 || i->control_pid > 0) {
2452 if (i->main_pid > 0) {
2453 printf(" Main PID: %u", (unsigned) i->main_pid);
2456 _cleanup_free_ char *comm = NULL;
2457 get_process_comm(i->main_pid, &comm);
2459 printf(" (%s)", comm);
2460 } else if (i->exit_code > 0) {
2461 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2463 if (i->exit_code == CLD_EXITED) {
2466 printf("status=%i", i->exit_status);
2468 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2473 printf("signal=%s", signal_to_string(i->exit_status));
2477 if (i->control_pid > 0)
2481 if (i->control_pid > 0) {
2482 _cleanup_free_ char *c = NULL;
2484 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2486 get_process_comm(i->control_pid, &c);
2495 printf(" Status: \"%s\"\n", i->status_text);
2497 if (i->control_group &&
2498 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2501 printf(" CGroup: %s\n", i->control_group);
2503 if (arg_transport == BUS_TRANSPORT_LOCAL) {
2506 char prefix[] = " ";
2509 if (c > sizeof(prefix) - 1)
2510 c -= sizeof(prefix) - 1;
2514 if (i->main_pid > 0)
2515 extra[k++] = i->main_pid;
2517 if (i->control_pid > 0)
2518 extra[k++] = i->control_pid;
2520 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2521 c, false, extra, k, flags);
2525 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2527 show_journal_by_unit(stdout,
2531 i->inactive_exit_timestamp_monotonic,
2535 arg_scope == UNIT_FILE_SYSTEM,
2539 if (i->need_daemon_reload)
2540 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2541 ansi_highlight_red(),
2542 ansi_highlight_off(),
2543 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2546 static void show_unit_help(UnitStatusInfo *i) {
2551 if (!i->documentation) {
2552 log_info("Documentation for %s not known.", i->id);
2556 STRV_FOREACH(p, i->documentation) {
2558 if (startswith(*p, "man:")) {
2561 _cleanup_free_ char *page = NULL, *section = NULL;
2562 const char *args[4] = { "man", NULL, NULL, NULL };
2567 if ((*p)[k-1] == ')')
2568 e = strrchr(*p, '(');
2571 page = strndup((*p) + 4, e - *p - 4);
2572 section = strndup(e + 1, *p + k - e - 2);
2573 if (!page || !section) {
2585 log_error("Failed to fork: %m");
2591 execvp(args[0], (char**) args);
2592 log_error("Failed to execute man: %m");
2593 _exit(EXIT_FAILURE);
2596 wait_for_terminate(pid, NULL);
2598 log_info("Can't show: %s", *p);
2602 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2609 switch (contents[0]) {
2611 case SD_BUS_TYPE_STRING: {
2614 r = sd_bus_message_read(m, "s", &s);
2616 return bus_log_parse_error(r);
2619 if (streq(name, "Id"))
2621 else if (streq(name, "LoadState"))
2623 else if (streq(name, "ActiveState"))
2624 i->active_state = s;
2625 else if (streq(name, "SubState"))
2627 else if (streq(name, "Description"))
2629 else if (streq(name, "FragmentPath"))
2630 i->fragment_path = s;
2631 else if (streq(name, "SourcePath"))
2634 else if (streq(name, "DefaultControlGroup")) {
2636 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2638 i->control_group = e;
2641 else if (streq(name, "ControlGroup"))
2642 i->control_group = s;
2643 else if (streq(name, "StatusText"))
2645 else if (streq(name, "PIDFile"))
2647 else if (streq(name, "SysFSPath"))
2649 else if (streq(name, "Where"))
2651 else if (streq(name, "What"))
2653 else if (streq(name, "Following"))
2655 else if (streq(name, "UnitFileState"))
2656 i->unit_file_state = s;
2657 else if (streq(name, "Result"))
2664 case SD_BUS_TYPE_BOOLEAN: {
2667 r = sd_bus_message_read(m, "b", &b);
2669 return bus_log_parse_error(r);
2671 if (streq(name, "Accept"))
2673 else if (streq(name, "NeedDaemonReload"))
2674 i->need_daemon_reload = b;
2675 else if (streq(name, "ConditionResult"))
2676 i->condition_result = b;
2681 case SD_BUS_TYPE_UINT32: {
2684 r = sd_bus_message_read(m, "u", &u);
2686 return bus_log_parse_error(r);
2688 if (streq(name, "MainPID")) {
2690 i->main_pid = (pid_t) u;
2693 } else if (streq(name, "ControlPID"))
2694 i->control_pid = (pid_t) u;
2695 else if (streq(name, "ExecMainPID")) {
2697 i->main_pid = (pid_t) u;
2698 } else if (streq(name, "NAccepted"))
2700 else if (streq(name, "NConnections"))
2701 i->n_connections = u;
2706 case SD_BUS_TYPE_INT32: {
2709 r = sd_bus_message_read(m, "i", &j);
2711 return bus_log_parse_error(r);
2713 if (streq(name, "ExecMainCode"))
2714 i->exit_code = (int) j;
2715 else if (streq(name, "ExecMainStatus"))
2716 i->exit_status = (int) j;
2721 case SD_BUS_TYPE_UINT64: {
2724 r = sd_bus_message_read(m, "t", &u);
2726 return bus_log_parse_error(r);
2728 if (streq(name, "ExecMainStartTimestamp"))
2729 i->start_timestamp = (usec_t) u;
2730 else if (streq(name, "ExecMainExitTimestamp"))
2731 i->exit_timestamp = (usec_t) u;
2732 else if (streq(name, "ActiveEnterTimestamp"))
2733 i->active_enter_timestamp = (usec_t) u;
2734 else if (streq(name, "InactiveEnterTimestamp"))
2735 i->inactive_enter_timestamp = (usec_t) u;
2736 else if (streq(name, "InactiveExitTimestamp"))
2737 i->inactive_exit_timestamp = (usec_t) u;
2738 else if (streq(name, "InactiveExitTimestampMonotonic"))
2739 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2740 else if (streq(name, "ActiveExitTimestamp"))
2741 i->active_exit_timestamp = (usec_t) u;
2742 else if (streq(name, "ConditionTimestamp"))
2743 i->condition_timestamp = (usec_t) u;
2748 case SD_BUS_TYPE_ARRAY:
2750 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
2751 _cleanup_free_ ExecStatusInfo *info = NULL;
2753 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
2755 return bus_log_parse_error(r);
2757 info = new0(ExecStatusInfo, 1);
2761 while ((r = exec_status_info_deserialize(m, info)) > 0) {
2763 info->name = strdup(name);
2767 LIST_PREPEND(exec, i->exec, info);
2769 info = new0(ExecStatusInfo, 1);
2775 return bus_log_parse_error(r);
2777 r = sd_bus_message_exit_container(m);
2779 return bus_log_parse_error(r);
2783 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
2784 const char *type, *path;
2786 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2788 return bus_log_parse_error(r);
2790 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
2792 r = strv_extend(&i->listen, type);
2796 r = strv_extend(&i->listen, path);
2801 return bus_log_parse_error(r);
2803 r = sd_bus_message_exit_container(m);
2805 return bus_log_parse_error(r);
2809 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
2811 r = sd_bus_message_read_strv(m, &i->dropin_paths);
2813 return bus_log_parse_error(r);
2815 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
2817 r = sd_bus_message_read_strv(m, &i->documentation);
2819 return bus_log_parse_error(r);
2821 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
2822 const char *cond, *param;
2823 int trigger, negate;
2826 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
2828 return bus_log_parse_error(r);
2830 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
2831 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
2832 if (state < 0 && (!trigger || !i->failed_condition)) {
2833 i->failed_condition = cond;
2834 i->failed_condition_trigger = trigger;
2835 i->failed_condition_negate = negate;
2836 i->failed_condition_param = param;
2840 return bus_log_parse_error(r);
2842 r = sd_bus_message_exit_container(m);
2844 return bus_log_parse_error(r);
2851 case SD_BUS_TYPE_STRUCT_BEGIN:
2853 if (streq(name, "LoadError")) {
2854 const char *n, *message;
2856 r = sd_bus_message_read(m, "(ss)", &n, &message);
2858 return bus_log_parse_error(r);
2860 if (!isempty(message))
2861 i->load_error = message;
2874 r = sd_bus_message_skip(m, contents);
2876 return bus_log_parse_error(r);
2881 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
2887 /* This is a low-level property printer, see
2888 * print_status_info() for the nicer output */
2890 if (arg_properties && !strv_find(arg_properties, name))
2893 switch (contents[0]) {
2895 case SD_BUS_TYPE_STRUCT_BEGIN:
2897 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
2900 r = sd_bus_message_read(m, "(uo)", &u, NULL);
2902 return bus_log_parse_error(r);
2905 printf("%s=%u\n", name, (unsigned) u);
2907 printf("%s=\n", name);
2911 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
2914 r = sd_bus_message_read(m, "(so)", &s, NULL);
2916 return bus_log_parse_error(r);
2918 if (arg_all || !isempty(s))
2919 printf("%s=%s\n", name, s);
2923 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
2924 const char *a = NULL, *b = NULL;
2926 r = sd_bus_message_read(m, "(ss)", &a, &b);
2928 return bus_log_parse_error(r);
2930 if (arg_all || !isempty(a) || !isempty(b))
2931 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
2938 case SD_BUS_TYPE_ARRAY:
2940 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
2944 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
2946 return bus_log_parse_error(r);
2948 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
2949 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
2952 return bus_log_parse_error(r);
2954 r = sd_bus_message_exit_container(m);
2956 return bus_log_parse_error(r);
2960 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
2961 const char *type, *path;
2963 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2965 return bus_log_parse_error(r);
2967 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
2968 printf("%s=%s\n", type, path);
2970 return bus_log_parse_error(r);
2972 r = sd_bus_message_exit_container(m);
2974 return bus_log_parse_error(r);
2978 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
2979 const char *type, *path;
2981 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2983 return bus_log_parse_error(r);
2985 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
2986 printf("Listen%s=%s\n", type, path);
2988 return bus_log_parse_error(r);
2990 r = sd_bus_message_exit_container(m);
2992 return bus_log_parse_error(r);
2996 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
2998 uint64_t value, next_elapse;
3000 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3002 return bus_log_parse_error(r);
3004 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3005 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3007 printf("%s={ value=%s ; next_elapse=%s }\n",
3009 format_timespan(timespan1, sizeof(timespan1), value, 0),
3010 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
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 && startswith(name, "Exec")) {
3022 ExecStatusInfo info = {};
3024 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3026 return bus_log_parse_error(r);
3028 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3029 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3030 _cleanup_free_ char *tt;
3032 tt = strv_join(info.argv, " ");
3034 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3038 yes_no(info.ignore),
3039 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3040 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3041 (unsigned) info. pid,
3042 sigchld_code_to_string(info.code),
3044 info.code == CLD_EXITED ? "" : "/",
3045 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3048 strv_free(info.argv);
3052 r = sd_bus_message_exit_container(m);
3054 return bus_log_parse_error(r);
3058 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "DeviceAllow")) {
3059 const char *path, *rwm;
3061 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3063 return bus_log_parse_error(r);
3065 while ((r = sd_bus_message_read(m, "(ss)", &path, &rwm)) > 0)
3066 printf("%s=%s %s\n", name, strna(path), strna(rwm));
3068 return bus_log_parse_error(r);
3070 r = sd_bus_message_exit_container(m);
3072 return bus_log_parse_error(r);
3076 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "BlockIODeviceWeight")) {
3080 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3082 return bus_log_parse_error(r);
3084 while ((r = sd_bus_message_read(m, "(st)", &path, &weight)) > 0)
3085 printf("%s=%s %" PRIu64 "\n", name, strna(path), weight);
3087 return bus_log_parse_error(r);
3089 r = sd_bus_message_exit_container(m);
3091 return bus_log_parse_error(r);
3095 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && (streq(name, "BlockIOReadBandwidth") || streq(name, "BlockIOWriteBandwidth"))) {
3099 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(st)");
3101 return bus_log_parse_error(r);
3103 while ((r = sd_bus_message_read(m, "(st)", &path, &bandwidth)) > 0)
3104 printf("%s=%s %" PRIu64 "\n", name, strna(path), bandwidth);
3106 return bus_log_parse_error(r);
3108 r = sd_bus_message_exit_container(m);
3110 return bus_log_parse_error(r);
3118 r = bus_print_property(name, m, arg_all);
3120 return bus_log_parse_error(r);
3123 r = sd_bus_message_skip(m, contents);
3125 return bus_log_parse_error(r);
3128 printf("%s=[unprintable]\n", name);
3134 static int show_one(
3138 bool show_properties,
3142 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3143 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3144 UnitStatusInfo info = {};
3151 r = sd_bus_call_method(
3153 "org.freedesktop.systemd1",
3155 "org.freedesktop.DBus.Properties",
3161 log_error("Failed to get properties: %s", bus_error_message(&error, r));
3165 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
3167 return bus_log_parse_error(r);
3174 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
3175 const char *name, *contents;
3177 r = sd_bus_message_read(reply, "s", &name);
3179 return bus_log_parse_error(r);
3181 r = sd_bus_message_peek_type(reply, NULL, &contents);
3183 return bus_log_parse_error(r);
3185 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, contents);
3187 return bus_log_parse_error(r);
3189 if (show_properties)
3190 r = print_property(name, reply, contents);
3192 r = status_property(name, reply, &info, contents);
3196 r = sd_bus_message_exit_container(reply);
3198 return bus_log_parse_error(r);
3200 r = sd_bus_message_exit_container(reply);
3202 return bus_log_parse_error(r);
3205 return bus_log_parse_error(r);
3207 r = sd_bus_message_exit_container(reply);
3209 return bus_log_parse_error(r);
3213 if (!show_properties) {
3214 if (streq(verb, "help"))
3215 show_unit_help(&info);
3217 print_status_info(&info, ellipsized);
3220 strv_free(info.documentation);
3221 strv_free(info.dropin_paths);
3222 strv_free(info.listen);
3224 if (!streq_ptr(info.active_state, "active") &&
3225 !streq_ptr(info.active_state, "reloading") &&
3226 streq(verb, "status")) {
3227 /* According to LSB: "program not running" */
3228 /* 0: program is running or service is OK
3229 * 1: program is dead and /var/run pid file exists
3230 * 2: program is dead and /var/lock lock file exists
3231 * 3: program is not running
3232 * 4: program or service status is unknown
3234 if (info.pid_file && access(info.pid_file, F_OK) == 0)
3240 while ((p = info.exec)) {
3241 LIST_REMOVE(exec, info.exec, p);
3242 exec_status_info_free(p);
3248 static int show_one_by_pid(
3255 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3256 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3257 const char *path = NULL;
3260 r = sd_bus_call_method(
3262 "org.freedesktop.systemd1",
3263 "/org/freedesktop/systemd1",
3264 "org.freedesktop.systemd1.Manager",
3270 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid, bus_error_message(&error, r));
3274 r = sd_bus_message_read(reply, "o", &path);
3276 return bus_log_parse_error(r);
3278 return show_one(verb, bus, path, false, new_line, ellipsized);
3281 static int show_all(
3284 bool show_properties,
3288 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3289 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3290 _cleanup_free_ UnitInfo *unit_infos = NULL;
3295 r = get_unit_list(bus, &reply, &unit_infos);
3301 qsort_safe(unit_infos, c, sizeof(UnitInfo), compare_unit_info);
3303 for (u = unit_infos; u < unit_infos + c; u++) {
3304 _cleanup_free_ char *p = NULL;
3306 if (!output_show_unit(u))
3309 p = unit_dbus_path_from_name(u->id);
3313 printf("%s -> '%s'\n", u->id, p);
3315 r = show_one(verb, bus, p, show_properties, new_line, ellipsized);
3323 static int show(sd_bus *bus, char **args) {
3325 bool show_properties, show_status, new_line = false;
3327 bool ellipsized = false;
3332 show_properties = streq(args[0], "show");
3333 show_status = streq(args[0], "status");
3335 if (show_properties)
3336 pager_open_if_enabled();
3338 /* If no argument is specified inspect the manager itself */
3340 if (show_properties && strv_length(args) <= 1)
3341 return show_one(args[0], bus, "/org/freedesktop/systemd1", show_properties, &new_line, &ellipsized);
3343 if (show_status && strv_length(args) <= 1)
3344 ret = show_all(args[0], bus, false, &new_line, &ellipsized);
3346 STRV_FOREACH(name, args+1) {
3349 if (safe_atou32(*name, &id) < 0) {
3350 _cleanup_free_ char *p = NULL, *n = NULL;
3351 /* Interpret as unit name */
3353 n = unit_name_mangle(*name);
3357 p = unit_dbus_path_from_name(n);
3361 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3365 } else if (show_properties) {
3366 _cleanup_free_ char *p = NULL;
3368 /* Interpret as job id */
3369 if (asprintf(&p, "/org/freedesktop/systemd1/job/%u", id) < 0)
3372 r = show_one(args[0], bus, p, show_properties, &new_line, &ellipsized);
3377 /* Interpret as PID */
3378 r = show_one_by_pid(args[0], bus, id, &new_line, &ellipsized);
3384 if (ellipsized && !arg_quiet)
3385 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3390 static int append_assignment(sd_bus_message *m, const char *assignment) {
3398 eq = strchr(assignment, '=');
3400 log_error("Not an assignment: %s", assignment);
3404 field = strndupa(assignment, eq - assignment);
3407 r = sd_bus_message_append_basic(m, SD_BUS_TYPE_STRING, field);
3409 return bus_log_create_error(r);
3411 if (streq(field, "CPUAccounting") ||
3412 streq(field, "MemoryAccounting") ||
3413 streq(field, "BlockIOAccounting")) {
3415 r = parse_boolean(eq);
3417 log_error("Failed to parse boolean assignment %s.", assignment);
3421 r = sd_bus_message_append(m, "v", "b", r);
3423 } else if (streq(field, "MemoryLimit")) {
3426 r = parse_bytes(eq, &bytes);
3428 log_error("Failed to parse bytes specification %s", assignment);
3432 r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
3434 } else if (streq(field, "CPUShares") || streq(field, "BlockIOWeight")) {
3437 r = safe_atou64(eq, &u);
3439 log_error("Failed to parse %s value %s.", field, eq);
3443 r = sd_bus_message_append(m, "v", "t", u);
3445 } else if (streq(field, "DevicePolicy"))
3446 r = sd_bus_message_append(m, "v", "s", eq);
3448 else if (streq(field, "DeviceAllow")) {
3451 r = sd_bus_message_append(m, "v", "a(ss)", 0);
3453 const char *path, *rwm;
3456 e = strchr(eq, ' ');
3458 path = strndupa(eq, e - eq);
3465 if (!path_startswith(path, "/dev")) {
3466 log_error("%s is not a device file in /dev.", path);
3470 r = sd_bus_message_append(m, "v", "a(ss)", 1, path, rwm);
3473 } else if (streq(field, "BlockIOReadBandwidth") || streq(field, "BlockIOWriteBandwidth")) {
3476 r = sd_bus_message_append(m, "v", "a(st)", 0);
3478 const char *path, *bandwidth;
3482 e = strchr(eq, ' ');
3484 path = strndupa(eq, e - eq);
3487 log_error("Failed to parse %s value %s.", field, eq);
3491 if (!path_startswith(path, "/dev")) {
3492 log_error("%s is not a device file in /dev.", path);
3496 r = parse_bytes(bandwidth, &bytes);
3498 log_error("Failed to parse byte value %s.", bandwidth);
3502 r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
3505 } else if (streq(field, "BlockIODeviceWeight")) {
3508 r = sd_bus_message_append(m, "v", "a(st)", 0);
3510 const char *path, *weight;
3514 e = strchr(eq, ' ');
3516 path = strndupa(eq, e - eq);
3519 log_error("Failed to parse %s value %s.", field, eq);
3523 if (!path_startswith(path, "/dev")) {
3524 log_error("%s is not a device file in /dev.", path);
3528 r = safe_atou64(weight, &u);
3530 log_error("Failed to parse %s value %s.", field, weight);
3533 r = sd_bus_message_append(m, "v", "a(st)", path, u);
3537 log_error("Unknown assignment %s.", assignment);
3542 return bus_log_create_error(r);
3547 static int set_property(sd_bus *bus, char **args) {
3548 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3549 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3550 _cleanup_free_ char *n = NULL;
3554 r = sd_bus_message_new_method_call(
3556 "org.freedesktop.systemd1",
3557 "/org/freedesktop/systemd1",
3558 "org.freedesktop.systemd1.Manager",
3559 "SetUnitProperties",
3562 return bus_log_create_error(r);
3564 n = unit_name_mangle(args[1]);
3568 r = sd_bus_message_append(m, "sb", n, arg_runtime);
3570 return bus_log_create_error(r);
3572 r = sd_bus_message_open_container(m, SD_BUS_TYPE_ARRAY, "(sv)");
3574 return bus_log_create_error(r);
3576 STRV_FOREACH(i, args + 2) {
3577 r = sd_bus_message_open_container(m, SD_BUS_TYPE_STRUCT, "sv");
3579 return bus_log_create_error(r);
3581 r = append_assignment(m, *i);
3585 r = sd_bus_message_close_container(m);
3587 return bus_log_create_error(r);
3590 r = sd_bus_message_close_container(m);
3592 return bus_log_create_error(r);
3594 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
3596 log_error("Failed to set unit properties on %s: %s", n, bus_error_message(&error, r));
3603 static int snapshot(sd_bus *bus, char **args) {
3604 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3605 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3606 _cleanup_free_ char *n = NULL, *id = NULL;
3610 if (strv_length(args) > 1)
3611 n = unit_name_mangle_with_suffix(args[1], ".snapshot");
3617 r = sd_bus_call_method(
3619 "org.freedesktop.systemd1",
3620 "/org/freedesktop/systemd1",
3621 "org.freedesktop.systemd1.Manager",
3627 log_error("Failed to create snapshot: %s", bus_error_message(&error, r));
3631 r = sd_bus_message_read(reply, "o", &path);
3633 return bus_log_parse_error(r);
3635 r = sd_bus_get_property_string(
3637 "org.freedesktop.systemd1",
3639 "org.freedesktop.systemd1.Unit",
3644 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error, r));
3654 static int delete_snapshot(sd_bus *bus, char **args) {
3655 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3661 STRV_FOREACH(name, args+1) {
3662 _cleanup_free_ char *n = NULL;
3664 n = unit_name_mangle_with_suffix(*name, ".snapshot");
3668 r = sd_bus_call_method(
3670 "org.freedesktop.systemd1",
3671 "/org/freedesktop/systemd1",
3672 "org.freedesktop.systemd1.Manager",
3678 log_error("Failed to remove snapshot %s: %s", n, bus_error_message(&error, r));
3686 static int daemon_reload(sd_bus *bus, char **args) {
3687 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3691 if (arg_action == ACTION_RELOAD)
3693 else if (arg_action == ACTION_REEXEC)
3694 method = "Reexecute";
3696 assert(arg_action == ACTION_SYSTEMCTL);
3699 streq(args[0], "clear-jobs") ||
3700 streq(args[0], "cancel") ? "ClearJobs" :
3701 streq(args[0], "daemon-reexec") ? "Reexecute" :
3702 streq(args[0], "reset-failed") ? "ResetFailed" :
3703 streq(args[0], "halt") ? "Halt" :
3704 streq(args[0], "poweroff") ? "PowerOff" :
3705 streq(args[0], "reboot") ? "Reboot" :
3706 streq(args[0], "kexec") ? "KExec" :
3707 streq(args[0], "exit") ? "Exit" :
3708 /* "daemon-reload" */ "Reload";
3711 r = sd_bus_call_method(
3713 "org.freedesktop.systemd1",
3714 "/org/freedesktop/systemd1",
3715 "org.freedesktop.systemd1.Manager",
3721 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
3722 /* There's always a fallback possible for
3723 * legacy actions. */
3725 else if ((r == -ETIMEDOUT || r == -ECONNRESET) && streq(method, "Reexecute"))
3726 /* On reexecution, we expect a disconnect, not a
3730 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
3735 static int reset_failed(sd_bus *bus, char **args) {
3736 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3740 if (strv_length(args) <= 1)
3741 return daemon_reload(bus, args);
3743 STRV_FOREACH(name, args+1) {
3744 _cleanup_free_ char *n;
3746 n = unit_name_mangle(*name);
3750 r = sd_bus_call_method(
3752 "org.freedesktop.systemd1",
3753 "/org/freedesktop/systemd1",
3754 "org.freedesktop.systemd1.Manager",
3760 log_error("Failed to reset failed state of unit %s: %s", n, bus_error_message(&error, r));
3768 static int show_environment(sd_bus *bus, char **args) {
3769 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3770 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3774 pager_open_if_enabled();
3776 r = sd_bus_get_property(
3778 "org.freedesktop.systemd1",
3779 "/org/freedesktop/systemd1",
3780 "org.freedesktop.systemd1.Manager",
3786 log_error("Failed to get environment: %s", bus_error_message(&error, r));
3790 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "s");
3792 return bus_log_parse_error(r);
3794 while ((r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_STRING, &text)) > 0)
3797 return bus_log_parse_error(r);
3799 r = sd_bus_message_exit_container(reply);
3801 return bus_log_parse_error(r);
3806 static int switch_root(sd_bus *bus, char **args) {
3807 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3808 _cleanup_free_ char *init = NULL;
3813 l = strv_length(args);
3814 if (l < 2 || l > 3) {
3815 log_error("Wrong number of arguments.");
3822 init = strdup(args[2]);
3824 parse_env_file("/proc/cmdline", WHITESPACE,
3835 log_debug("switching root - root: %s; init: %s", root, init);
3837 r = sd_bus_call_method(
3839 "org.freedesktop.systemd1",
3840 "/org/freedesktop/systemd1",
3841 "org.freedesktop.systemd1.Manager",
3847 log_error("Failed to switch root: %s", bus_error_message(&error, r));
3854 static int set_environment(sd_bus *bus, char **args) {
3855 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3856 _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
3863 method = streq(args[0], "set-environment")
3865 : "UnsetEnvironment";
3867 r = sd_bus_message_new_method_call(
3869 "org.freedesktop.systemd1",
3870 "/org/freedesktop/systemd1",
3871 "org.freedesktop.systemd1.Manager",
3875 return bus_log_create_error(r);
3877 r = sd_bus_message_append_strv(m, args + 1);
3879 return bus_log_create_error(r);
3881 r = sd_bus_send_with_reply_and_block(bus, m, -1, &error, NULL);
3883 log_error("Failed to set environment: %s", bus_error_message(&error, r));
3890 static int enable_sysv_units(const char *verb, char **args) {
3893 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
3894 unsigned f = 1, t = 1;
3895 _cleanup_lookup_paths_free_ LookupPaths paths = {};
3897 if (arg_scope != UNIT_FILE_SYSTEM)
3900 if (!streq(verb, "enable") &&
3901 !streq(verb, "disable") &&
3902 !streq(verb, "is-enabled"))
3905 /* Processes all SysV units, and reshuffles the array so that
3906 * afterwards only the native units remain */
3908 r = lookup_paths_init(&paths, SYSTEMD_SYSTEM, false, NULL, NULL, NULL);
3913 for (f = 0; args[f]; f++) {
3915 _cleanup_free_ char *p = NULL, *q = NULL;
3916 bool found_native = false, found_sysv;
3918 const char *argv[6] = { "/sbin/chkconfig", NULL, NULL, NULL, NULL };
3926 if (!endswith(name, ".service"))
3929 if (path_is_absolute(name))
3932 STRV_FOREACH(k, paths.unit_path) {
3933 if (!isempty(arg_root))
3934 asprintf(&p, "%s/%s/%s", arg_root, *k, name);
3936 asprintf(&p, "%s/%s", *k, name);
3943 found_native = access(p, F_OK) >= 0;
3954 if (!isempty(arg_root))
3955 asprintf(&p, "%s/" SYSTEM_SYSVINIT_PATH "/%s", arg_root, name);
3957 asprintf(&p, SYSTEM_SYSVINIT_PATH "/%s", name);
3963 p[strlen(p) - sizeof(".service") + 1] = 0;
3964 found_sysv = access(p, F_OK) >= 0;
3969 /* Mark this entry, so that we don't try enabling it as native unit */
3970 args[f] = (char*) "";
3972 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name);
3974 if (!isempty(arg_root))
3975 argv[c++] = q = strappend("--root=", arg_root);
3977 argv[c++] = path_get_file_name(p);
3979 streq(verb, "enable") ? "on" :
3980 streq(verb, "disable") ? "off" : "--level=5";
3983 l = strv_join((char**)argv, " ");
3989 log_info("Executing %s", l);
3994 log_error("Failed to fork: %m");
3997 } else if (pid == 0) {
4000 execv(argv[0], (char**) argv);
4001 _exit(EXIT_FAILURE);
4004 j = wait_for_terminate(pid, &status);
4006 log_error("Failed to wait for child: %s", strerror(-r));
4011 if (status.si_code == CLD_EXITED) {
4012 if (streq(verb, "is-enabled")) {
4013 if (status.si_status == 0) {
4022 } else if (status.si_status != 0) {
4033 /* Drop all SysV units */
4034 for (f = 0, t = 0; args[f]; f++) {
4036 if (isempty(args[f]))
4039 args[t++] = args[f];
4048 static int mangle_names(char **original_names, char ***mangled_names) {
4049 char **i, **l, **name;
4051 l = new(char*, strv_length(original_names) + 1);
4056 STRV_FOREACH(name, original_names) {
4058 /* When enabling units qualified path names are OK,
4059 * too, hence allow them explicitly. */
4064 *i = unit_name_mangle(*name);
4080 static int enable_unit(sd_bus *bus, char **args) {
4081 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *m = NULL;
4082 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4083 _cleanup_strv_free_ char **mangled_names = NULL;
4084 const char *verb = args[0];
4085 UnitFileChange *changes = NULL;
4086 unsigned n_changes = 0, i;
4087 int carries_install_info = -1;
4093 r = mangle_names(args+1, &mangled_names);
4097 r = enable_sysv_units(verb, mangled_names);
4101 if (!bus || avoid_bus()) {
4102 if (streq(verb, "enable")) {
4103 r = unit_file_enable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4104 carries_install_info = r;
4105 } else if (streq(verb, "disable"))
4106 r = unit_file_disable(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4107 else if (streq(verb, "reenable")) {
4108 r = unit_file_reenable(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4109 carries_install_info = r;
4110 } else if (streq(verb, "link"))
4111 r = unit_file_link(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4112 else if (streq(verb, "preset")) {
4113 r = unit_file_preset(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4114 carries_install_info = r;
4115 } else if (streq(verb, "mask"))
4116 r = unit_file_mask(arg_scope, arg_runtime, arg_root, mangled_names, arg_force, &changes, &n_changes);
4117 else if (streq(verb, "unmask"))
4118 r = unit_file_unmask(arg_scope, arg_runtime, arg_root, mangled_names, &changes, &n_changes);
4119 else if (streq(verb, "set-default"))
4120 r = unit_file_set_default(arg_scope, arg_root, args[1], &changes, &n_changes);
4122 assert_not_reached("Unknown verb");
4125 log_error("Operation failed: %s", strerror(-r));
4130 for (i = 0; i < n_changes; i++) {
4131 if (changes[i].type == UNIT_FILE_SYMLINK)
4132 log_info("ln -s '%s' '%s'", changes[i].source, changes[i].path);
4134 log_info("rm '%s'", changes[i].path);
4140 const char *method, *type, *path, *source;
4141 int expect_carries_install_info = false;
4142 bool send_force = true;
4144 if (streq(verb, "enable")) {
4145 method = "EnableUnitFiles";
4146 expect_carries_install_info = true;
4147 } else if (streq(verb, "disable")) {
4148 method = "DisableUnitFiles";
4150 } else if (streq(verb, "reenable")) {
4151 method = "ReenableUnitFiles";
4152 expect_carries_install_info = true;
4153 } else if (streq(verb, "link"))
4154 method = "LinkUnitFiles";
4155 else if (streq(verb, "preset")) {
4156 method = "PresetUnitFiles";
4157 expect_carries_install_info = true;
4158 } else if (streq(verb, "mask"))
4159 method = "MaskUnitFiles";
4160 else if (streq(verb, "unmask")) {
4161 method = "UnmaskUnitFiles";
4163 } else if (streq(verb, "set-default")) {
4164 method = "SetDefaultTarget";
4166 assert_not_reached("Unknown verb");
4168 r = sd_bus_message_new_method_call(
4170 "org.freedesktop.systemd1",
4171 "/org/freedesktop/systemd1",
4172 "org.freedesktop.systemd1.Manager",
4176 return bus_log_create_error(r);
4178 r = sd_bus_message_append_strv(m, mangled_names);
4180 return bus_log_create_error(r);
4182 r = sd_bus_message_append(m, "b", arg_runtime);
4184 return bus_log_create_error(r);
4187 r = sd_bus_message_append(m, "b", arg_force);
4189 return bus_log_create_error(r);
4192 r = sd_bus_send_with_reply_and_block(bus, m, -0, &error, &reply);
4194 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
4198 if (expect_carries_install_info) {
4199 r = sd_bus_message_read(reply, "b", &carries_install_info);
4201 return bus_log_parse_error(r);
4204 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(sss)");
4206 return bus_log_parse_error(r);
4208 while ((r = sd_bus_message_read(reply, "(sss)", &type, &path, &source)) > 0) {
4210 if (streq(type, "symlink"))
4211 log_info("ln -s '%s' '%s'", source, path);
4213 log_info("rm '%s'", path);
4217 return bus_log_parse_error(r);
4219 r = sd_bus_message_exit_container(reply);
4221 return bus_log_parse_error(r);
4223 /* Try to reload if enabeld */
4225 r = daemon_reload(bus, args);
4230 if (carries_install_info == 0)
4231 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4232 "using systemctl.\n"
4233 "Possible reasons for having this kind of units are:\n"
4234 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4235 " .wants/ or .requires/ directory.\n"
4236 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4237 " a requirement dependency on it.\n"
4238 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4239 " D-Bus, udev, scripted systemctl call, ...).\n");
4242 unit_file_changes_free(changes, n_changes);
4247 static int unit_is_enabled(sd_bus *bus, char **args) {
4249 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4250 _cleanup_strv_free_ char **mangled_names = NULL;
4255 r = mangle_names(args+1, &mangled_names);
4259 r = enable_sysv_units(args[0], mangled_names);
4265 if (!bus || avoid_bus()) {
4267 STRV_FOREACH(name, mangled_names) {
4268 UnitFileState state;
4270 state = unit_file_get_state(arg_scope, arg_root, *name);
4275 if (state == UNIT_FILE_ENABLED ||
4276 state == UNIT_FILE_ENABLED_RUNTIME ||
4277 state == UNIT_FILE_STATIC)
4281 puts(unit_file_state_to_string(state));
4285 STRV_FOREACH(name, mangled_names) {
4286 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
4289 r = sd_bus_call_method(
4291 "org.freedesktop.systemd1",
4292 "/org/freedesktop/systemd1",
4293 "org.freedesktop.systemd1.Manager",
4299 log_error("Failed to get unit file state for %s: %s", *name, bus_error_message(&error, r));
4303 r = sd_bus_message_read(reply, "s", &s);
4305 return bus_log_parse_error(r);
4307 if (streq(s, "enabled") ||
4308 streq(s, "enabled-runtime") ||
4320 static int systemctl_help(void) {
4322 pager_open_if_enabled();
4324 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4325 "Query or send control commands to the systemd manager.\n\n"
4326 " -h --help Show this help\n"
4327 " --version Show package version\n"
4328 " --system Connect to system manager\n"
4329 " --user Connect to user service manager\n"
4330 " -H --host=[USER@]HOST\n"
4331 " Operate on remote host\n"
4332 " -M --machine=CONTAINER\n"
4333 " Operate on local container\n"
4334 " -t --type=TYPE List only units of a particular type\n"
4335 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4336 " -p --property=NAME Show only properties by this name\n"
4337 " -a --all Show all loaded units/properties, including dead/empty\n"
4338 " ones. To list all units installed on the system, use\n"
4339 " the 'list-unit-files' command instead.\n"
4340 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4341 " -l --full Don't ellipsize unit names on output\n"
4342 " --fail When queueing a new job, fail if conflicting jobs are\n"
4344 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4346 " --ignore-dependencies\n"
4347 " When queueing a new job, ignore all its dependencies\n"
4348 " --show-types When showing sockets, explicitly show their type\n"
4349 " -i --ignore-inhibitors\n"
4350 " When shutting down or sleeping, ignore inhibitors\n"
4351 " --kill-who=WHO Who to send signal to\n"
4352 " -s --signal=SIGNAL Which signal to send\n"
4353 " -q --quiet Suppress output\n"
4354 " --no-block Do not wait until operation finished\n"
4355 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4356 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4358 " --no-legend Do not print a legend (column headers and hints)\n"
4359 " --no-pager Do not pipe output into a pager\n"
4360 " --no-ask-password\n"
4361 " Do not ask for system passwords\n"
4362 " --global Enable/disable unit files globally\n"
4363 " --runtime Enable unit files only temporarily until next reboot\n"
4364 " -f --force When enabling unit files, override existing symlinks\n"
4365 " When shutting down, execute action immediately\n"
4366 " --root=PATH Enable unit files in the specified root directory\n"
4367 " -n --lines=INTEGER Number of journal entries to show\n"
4368 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4369 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4371 " list-units List loaded units\n"
4372 " list-sockets List loaded sockets ordered by address\n"
4373 " start [NAME...] Start (activate) one or more units\n"
4374 " stop [NAME...] Stop (deactivate) one or more units\n"
4375 " reload [NAME...] Reload one or more units\n"
4376 " restart [NAME...] Start or restart one or more units\n"
4377 " try-restart [NAME...] Restart one or more units if active\n"
4378 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4379 " otherwise start or restart\n"
4380 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4381 " otherwise restart if active\n"
4382 " isolate [NAME] Start one unit and stop all others\n"
4383 " kill [NAME...] Send signal to processes of a unit\n"
4384 " is-active [NAME...] Check whether units are active\n"
4385 " is-failed [NAME...] Check whether units are failed\n"
4386 " status [NAME...|PID...] Show runtime status of one or more units\n"
4387 " show [NAME...|JOB...] Show properties of one or more\n"
4388 " units/jobs or the manager\n"
4389 " set-property [NAME] [ASSIGNMENT...]\n"
4390 " Sets one or more properties of a unit\n"
4391 " help [NAME...|PID...] Show manual for one or more units\n"
4392 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4394 " list-dependencies [NAME] Recursively show units which are required\n"
4395 " or wanted by this unit or by which this\n"
4396 " unit is required or wanted\n\n"
4397 "Unit File Commands:\n"
4398 " list-unit-files List installed unit files\n"
4399 " enable [NAME...] Enable one or more unit files\n"
4400 " disable [NAME...] Disable one or more unit files\n"
4401 " reenable [NAME...] Reenable one or more unit files\n"
4402 " preset [NAME...] Enable/disable one or more unit files\n"
4403 " based on preset configuration\n"
4404 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4405 " mask [NAME...] Mask one or more units\n"
4406 " unmask [NAME...] Unmask one or more units\n"
4407 " link [PATH...] Link one or more units files into\n"
4408 " the search path\n"
4409 " get-default Get the name of the default target\n"
4410 " set-default NAME Set the default target\n\n"
4412 " list-jobs List jobs\n"
4413 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4414 "Snapshot Commands:\n"
4415 " snapshot [NAME] Create a snapshot\n"
4416 " delete [NAME...] Remove one or more snapshots\n\n"
4417 "Environment Commands:\n"
4418 " show-environment Dump environment\n"
4419 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4420 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4421 "Manager Lifecycle Commands:\n"
4422 " daemon-reload Reload systemd manager configuration\n"
4423 " daemon-reexec Reexecute systemd manager\n\n"
4424 "System Commands:\n"
4425 " default Enter system default mode\n"
4426 " rescue Enter system rescue mode\n"
4427 " emergency Enter system emergency mode\n"
4428 " halt Shut down and halt the system\n"
4429 " poweroff Shut down and power-off the system\n"
4430 " reboot [ARG] Shut down and reboot the system\n"
4431 " kexec Shut down and reboot the system with kexec\n"
4432 " exit Request user instance exit\n"
4433 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4434 " suspend Suspend the system\n"
4435 " hibernate Hibernate the system\n"
4436 " hybrid-sleep Hibernate and suspend the system\n",
4437 program_invocation_short_name);
4442 static int halt_help(void) {
4444 printf("%s [OPTIONS...]%s\n\n"
4445 "%s the system.\n\n"
4446 " --help Show this help\n"
4447 " --halt Halt the machine\n"
4448 " -p --poweroff Switch off the machine\n"
4449 " --reboot Reboot the machine\n"
4450 " -f --force Force immediate halt/power-off/reboot\n"
4451 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4452 " -d --no-wtmp Don't write wtmp record\n"
4453 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4454 program_invocation_short_name,
4455 arg_action == ACTION_REBOOT ? " [ARG]" : "",
4456 arg_action == ACTION_REBOOT ? "Reboot" :
4457 arg_action == ACTION_POWEROFF ? "Power off" :
4463 static int shutdown_help(void) {
4465 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4466 "Shut down the system.\n\n"
4467 " --help Show this help\n"
4468 " -H --halt Halt the machine\n"
4469 " -P --poweroff Power-off the machine\n"
4470 " -r --reboot Reboot the machine\n"
4471 " -h Equivalent to --poweroff, overridden by --halt\n"
4472 " -k Don't halt/power-off/reboot, just send warnings\n"
4473 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4474 " -c Cancel a pending shutdown\n",
4475 program_invocation_short_name);
4480 static int telinit_help(void) {
4482 printf("%s [OPTIONS...] {COMMAND}\n\n"
4483 "Send control commands to the init daemon.\n\n"
4484 " --help Show this help\n"
4485 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4487 " 0 Power-off the machine\n"
4488 " 6 Reboot the machine\n"
4489 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4490 " 1, s, S Enter rescue mode\n"
4491 " q, Q Reload init daemon configuration\n"
4492 " u, U Reexecute init daemon\n",
4493 program_invocation_short_name);
4498 static int runlevel_help(void) {
4500 printf("%s [OPTIONS...]\n\n"
4501 "Prints the previous and current runlevel of the init system.\n\n"
4502 " --help Show this help\n",
4503 program_invocation_short_name);
4508 static int help_types(void) {
4512 puts("Available unit types:");
4513 for(i = 0; i < _UNIT_TYPE_MAX; i++) {
4514 t = unit_type_to_string(i);
4522 static int systemctl_parse_argv(int argc, char *argv[]) {
4531 ARG_IGNORE_DEPENDENCIES,
4543 ARG_NO_ASK_PASSWORD,
4551 static const struct option options[] = {
4552 { "help", no_argument, NULL, 'h' },
4553 { "version", no_argument, NULL, ARG_VERSION },
4554 { "type", required_argument, NULL, 't' },
4555 { "property", required_argument, NULL, 'p' },
4556 { "all", no_argument, NULL, 'a' },
4557 { "reverse", no_argument, NULL, ARG_REVERSE },
4558 { "after", no_argument, NULL, ARG_AFTER },
4559 { "before", no_argument, NULL, ARG_BEFORE },
4560 { "show-types", no_argument, NULL, ARG_SHOW_TYPES },
4561 { "failed", no_argument, NULL, ARG_FAILED }, /* compatibility only */
4562 { "full", no_argument, NULL, 'l' },
4563 { "fail", no_argument, NULL, ARG_FAIL },
4564 { "irreversible", no_argument, NULL, ARG_IRREVERSIBLE },
4565 { "ignore-dependencies", no_argument, NULL, ARG_IGNORE_DEPENDENCIES },
4566 { "ignore-inhibitors", no_argument, NULL, 'i' },
4567 { "user", no_argument, NULL, ARG_USER },
4568 { "system", no_argument, NULL, ARG_SYSTEM },
4569 { "global", no_argument, NULL, ARG_GLOBAL },
4570 { "no-block", no_argument, NULL, ARG_NO_BLOCK },
4571 { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
4572 { "no-pager", no_argument, NULL, ARG_NO_PAGER },
4573 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4574 { "quiet", no_argument, NULL, 'q' },
4575 { "root", required_argument, NULL, ARG_ROOT },
4576 { "force", no_argument, NULL, ARG_FORCE },
4577 { "no-reload", no_argument, NULL, ARG_NO_RELOAD },
4578 { "kill-who", required_argument, NULL, ARG_KILL_WHO },
4579 { "signal", required_argument, NULL, 's' },
4580 { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
4581 { "host", required_argument, NULL, 'H' },
4582 { "machine", required_argument, NULL, 'M' },
4583 { "runtime", no_argument, NULL, ARG_RUNTIME },
4584 { "lines", required_argument, NULL, 'n' },
4585 { "output", required_argument, NULL, 'o' },
4586 { "plain", no_argument, NULL, ARG_PLAIN },
4587 { "state", required_argument, NULL, ARG_STATE },
4596 while ((c = getopt_long(argc, argv, "ht:p:alqfs:H:M:n:o:i", options, NULL)) >= 0) {
4601 return systemctl_help();
4604 puts(PACKAGE_STRING);
4605 puts(SYSTEMD_FEATURES);
4612 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4613 _cleanup_free_ char *type;
4615 type = strndup(word, size);
4619 if (streq(type, "help")) {
4624 if (unit_type_from_string(type) >= 0) {
4625 if (strv_push(&arg_types, type))
4631 /* It's much nicer to use --state= for
4632 * load states, but let's support this
4633 * in --types= too for compatibility
4634 * with old versions */
4635 if (unit_load_state_from_string(optarg) >= 0) {
4636 if (strv_push(&arg_states, type) < 0)
4642 log_error("Unknown unit type or load state '%s'.", type);
4643 log_info("Use -t help to see a list of allowed values.");
4651 /* Make sure that if the empty property list
4652 was specified, we won't show any properties. */
4653 if (isempty(optarg) && !arg_properties) {
4654 arg_properties = strv_new(NULL, NULL);
4655 if (!arg_properties)
4661 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4664 prop = strndup(word, size);
4668 if (strv_push(&arg_properties, prop) < 0) {
4675 /* If the user asked for a particular
4676 * property, show it to him, even if it is
4688 arg_dependency = DEPENDENCY_REVERSE;
4692 arg_dependency = DEPENDENCY_AFTER;
4696 arg_dependency = DEPENDENCY_BEFORE;
4699 case ARG_SHOW_TYPES:
4700 arg_show_types = true;
4704 arg_job_mode = "fail";
4707 case ARG_IRREVERSIBLE:
4708 arg_job_mode = "replace-irreversibly";
4711 case ARG_IGNORE_DEPENDENCIES:
4712 arg_job_mode = "ignore-dependencies";
4716 arg_scope = UNIT_FILE_USER;
4720 arg_scope = UNIT_FILE_SYSTEM;
4724 arg_scope = UNIT_FILE_GLOBAL;
4728 arg_no_block = true;
4732 arg_no_legend = true;
4736 arg_no_pager = true;
4752 if (strv_extend(&arg_states, "failed") < 0)
4770 arg_no_reload = true;
4774 arg_kill_who = optarg;
4778 if ((arg_signal = signal_from_string_try_harder(optarg)) < 0) {
4779 log_error("Failed to parse signal string %s.", optarg);
4784 case ARG_NO_ASK_PASSWORD:
4785 arg_ask_password = false;
4789 arg_transport = BUS_TRANSPORT_REMOTE;
4794 arg_transport = BUS_TRANSPORT_CONTAINER;
4803 if (safe_atou(optarg, &arg_lines) < 0) {
4804 log_error("Failed to parse lines '%s'", optarg);
4810 arg_output = output_mode_from_string(optarg);
4811 if (arg_output < 0) {
4812 log_error("Unknown output '%s'.", optarg);
4818 arg_ignore_inhibitors = true;
4829 FOREACH_WORD_SEPARATOR(word, size, optarg, ",", state) {
4832 s = strndup(word, size);
4836 if (strv_push(&arg_states, s) < 0) {
4848 assert_not_reached("Unhandled option");
4852 if (arg_transport != BUS_TRANSPORT_LOCAL && arg_scope != UNIT_FILE_SYSTEM) {
4853 log_error("Cannot access user instance remotely.");
4860 static int halt_parse_argv(int argc, char *argv[]) {
4869 static const struct option options[] = {
4870 { "help", no_argument, NULL, ARG_HELP },
4871 { "halt", no_argument, NULL, ARG_HALT },
4872 { "poweroff", no_argument, NULL, 'p' },
4873 { "reboot", no_argument, NULL, ARG_REBOOT },
4874 { "force", no_argument, NULL, 'f' },
4875 { "wtmp-only", no_argument, NULL, 'w' },
4876 { "no-wtmp", no_argument, NULL, 'd' },
4877 { "no-wall", no_argument, NULL, ARG_NO_WALL },
4886 if (utmp_get_runlevel(&runlevel, NULL) >= 0)
4887 if (runlevel == '0' || runlevel == '6')
4890 while ((c = getopt_long(argc, argv, "pfwdnih", options, NULL)) >= 0) {
4897 arg_action = ACTION_HALT;
4901 if (arg_action != ACTION_REBOOT)
4902 arg_action = ACTION_POWEROFF;
4906 arg_action = ACTION_REBOOT;
4928 /* Compatibility nops */
4935 assert_not_reached("Unhandled option");
4939 if (arg_action == ACTION_REBOOT && argc == optind + 1) {
4940 r = write_string_file(REBOOT_PARAM_FILE, argv[optind]);
4942 log_error("Failed to write reboot param to "
4943 REBOOT_PARAM_FILE": %s", strerror(-r));
4946 } else if (optind < argc) {
4947 log_error("Too many arguments.");
4954 static int parse_time_spec(const char *t, usec_t *_u) {
4958 if (streq(t, "now"))
4960 else if (!strchr(t, ':')) {
4963 if (safe_atou64(t, &u) < 0)
4966 *_u = now(CLOCK_REALTIME) + USEC_PER_MINUTE * u;
4975 hour = strtol(t, &e, 10);
4976 if (errno > 0 || *e != ':' || hour < 0 || hour > 23)
4979 minute = strtol(e+1, &e, 10);
4980 if (errno > 0 || *e != 0 || minute < 0 || minute > 59)
4983 n = now(CLOCK_REALTIME);
4984 s = (time_t) (n / USEC_PER_SEC);
4986 assert_se(localtime_r(&s, &tm));
4988 tm.tm_hour = (int) hour;
4989 tm.tm_min = (int) minute;
4992 assert_se(s = mktime(&tm));
4994 *_u = (usec_t) s * USEC_PER_SEC;
4997 *_u += USEC_PER_DAY;
5003 static int shutdown_parse_argv(int argc, char *argv[]) {
5010 static const struct option options[] = {
5011 { "help", no_argument, NULL, ARG_HELP },
5012 { "halt", no_argument, NULL, 'H' },
5013 { "poweroff", no_argument, NULL, 'P' },
5014 { "reboot", no_argument, NULL, 'r' },
5015 { "kexec", no_argument, NULL, 'K' }, /* not documented extension */
5016 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5025 while ((c = getopt_long(argc, argv, "HPrhkt:afFc", options, NULL)) >= 0) {
5029 return shutdown_help();
5032 arg_action = ACTION_HALT;
5036 arg_action = ACTION_POWEROFF;
5041 arg_action = ACTION_KEXEC;
5043 arg_action = ACTION_REBOOT;
5047 arg_action = ACTION_KEXEC;
5051 if (arg_action != ACTION_HALT)
5052 arg_action = ACTION_POWEROFF;
5065 /* Compatibility nops */
5069 arg_action = ACTION_CANCEL_SHUTDOWN;
5076 assert_not_reached("Unhandled option");
5080 if (argc > optind && arg_action != ACTION_CANCEL_SHUTDOWN) {
5081 r = parse_time_spec(argv[optind], &arg_when);
5083 log_error("Failed to parse time specification: %s", argv[optind]);
5087 arg_when = now(CLOCK_REALTIME) + USEC_PER_MINUTE;
5089 if (argc > optind && arg_action == ACTION_CANCEL_SHUTDOWN)
5090 /* No time argument for shutdown cancel */
5091 arg_wall = argv + optind;
5092 else if (argc > optind + 1)
5093 /* We skip the time argument */
5094 arg_wall = argv + optind + 1;
5101 static int telinit_parse_argv(int argc, char *argv[]) {
5108 static const struct option options[] = {
5109 { "help", no_argument, NULL, ARG_HELP },
5110 { "no-wall", no_argument, NULL, ARG_NO_WALL },
5114 static const struct {
5118 { '0', ACTION_POWEROFF },
5119 { '6', ACTION_REBOOT },
5120 { '1', ACTION_RESCUE },
5121 { '2', ACTION_RUNLEVEL2 },
5122 { '3', ACTION_RUNLEVEL3 },
5123 { '4', ACTION_RUNLEVEL4 },
5124 { '5', ACTION_RUNLEVEL5 },
5125 { 's', ACTION_RESCUE },
5126 { 'S', ACTION_RESCUE },
5127 { 'q', ACTION_RELOAD },
5128 { 'Q', ACTION_RELOAD },
5129 { 'u', ACTION_REEXEC },
5130 { 'U', ACTION_REEXEC }
5139 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5143 return telinit_help();
5153 assert_not_reached("Unhandled option");
5157 if (optind >= argc) {
5162 if (optind + 1 < argc) {
5163 log_error("Too many arguments.");
5167 if (strlen(argv[optind]) != 1) {
5168 log_error("Expected single character argument.");
5172 for (i = 0; i < ELEMENTSOF(table); i++)
5173 if (table[i].from == argv[optind][0])
5176 if (i >= ELEMENTSOF(table)) {
5177 log_error("Unknown command '%s'.", argv[optind]);
5181 arg_action = table[i].to;
5188 static int runlevel_parse_argv(int argc, char *argv[]) {
5194 static const struct option options[] = {
5195 { "help", no_argument, NULL, ARG_HELP },
5204 while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) {
5208 return runlevel_help();
5215 assert_not_reached("Unhandled option");
5219 if (optind < argc) {
5220 log_error("Too many arguments.");
5227 static int parse_argv(int argc, char *argv[]) {
5231 if (program_invocation_short_name) {
5233 if (strstr(program_invocation_short_name, "halt")) {
5234 arg_action = ACTION_HALT;
5235 return halt_parse_argv(argc, argv);
5236 } else if (strstr(program_invocation_short_name, "poweroff")) {
5237 arg_action = ACTION_POWEROFF;
5238 return halt_parse_argv(argc, argv);
5239 } else if (strstr(program_invocation_short_name, "reboot")) {
5241 arg_action = ACTION_KEXEC;
5243 arg_action = ACTION_REBOOT;
5244 return halt_parse_argv(argc, argv);
5245 } else if (strstr(program_invocation_short_name, "shutdown")) {
5246 arg_action = ACTION_POWEROFF;
5247 return shutdown_parse_argv(argc, argv);
5248 } else if (strstr(program_invocation_short_name, "init")) {
5250 if (sd_booted() > 0) {
5251 arg_action = _ACTION_INVALID;
5252 return telinit_parse_argv(argc, argv);
5254 /* Hmm, so some other init system is
5255 * running, we need to forward this
5256 * request to it. For now we simply
5257 * guess that it is Upstart. */
5259 execv(TELINIT, argv);
5261 log_error("Couldn't find an alternative telinit implementation to spawn.");
5265 } else if (strstr(program_invocation_short_name, "runlevel")) {
5266 arg_action = ACTION_RUNLEVEL;
5267 return runlevel_parse_argv(argc, argv);
5271 arg_action = ACTION_SYSTEMCTL;
5272 return systemctl_parse_argv(argc, argv);
5275 _pure_ static int action_to_runlevel(void) {
5277 static const char table[_ACTION_MAX] = {
5278 [ACTION_HALT] = '0',
5279 [ACTION_POWEROFF] = '0',
5280 [ACTION_REBOOT] = '6',
5281 [ACTION_RUNLEVEL2] = '2',
5282 [ACTION_RUNLEVEL3] = '3',
5283 [ACTION_RUNLEVEL4] = '4',
5284 [ACTION_RUNLEVEL5] = '5',
5285 [ACTION_RESCUE] = '1'
5288 assert(arg_action < _ACTION_MAX);
5290 return table[arg_action];
5293 static int talk_initctl(void) {
5294 struct init_request request = {};
5296 _cleanup_close_ int fd = -1;
5299 rl = action_to_runlevel();
5303 request.magic = INIT_MAGIC;
5304 request.sleeptime = 0;
5305 request.cmd = INIT_CMD_RUNLVL;
5306 request.runlevel = rl;
5308 fd = open(INIT_FIFO, O_WRONLY|O_NDELAY|O_CLOEXEC|O_NOCTTY);
5310 if (errno == ENOENT)
5313 log_error("Failed to open "INIT_FIFO": %m");
5318 r = loop_write(fd, &request, sizeof(request), false) != sizeof(request);
5320 log_error("Failed to write to "INIT_FIFO": %m");
5321 return errno > 0 ? -errno : -EIO;
5327 static int systemctl_main(sd_bus *bus, int argc, char *argv[], const int r) {
5329 static const struct {
5337 int (* const dispatch)(sd_bus *bus, char **args);
5339 { "list-units", LESS, 1, list_units },
5340 { "list-unit-files", EQUAL, 1, list_unit_files },
5341 { "list-sockets", LESS, 1, list_sockets },
5342 { "list-jobs", EQUAL, 1, list_jobs },
5343 { "clear-jobs", EQUAL, 1, daemon_reload },
5344 { "cancel", MORE, 2, cancel_job },
5345 { "start", MORE, 2, start_unit },
5346 { "stop", MORE, 2, start_unit },
5347 { "condstop", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5348 { "reload", MORE, 2, start_unit },
5349 { "restart", MORE, 2, start_unit },
5350 { "try-restart", MORE, 2, start_unit },
5351 { "reload-or-restart", MORE, 2, start_unit },
5352 { "reload-or-try-restart", MORE, 2, start_unit },
5353 { "force-reload", MORE, 2, start_unit }, /* For compatibility with SysV */
5354 { "condreload", MORE, 2, start_unit }, /* For compatibility with ALTLinux */
5355 { "condrestart", MORE, 2, start_unit }, /* For compatibility with RH */
5356 { "isolate", EQUAL, 2, start_unit },
5357 { "kill", MORE, 2, kill_unit },
5358 { "is-active", MORE, 2, check_unit_active },
5359 { "check", MORE, 2, check_unit_active },
5360 { "is-failed", MORE, 2, check_unit_failed },
5361 { "show", MORE, 1, show },
5362 { "status", MORE, 1, show },
5363 { "help", MORE, 2, show },
5364 { "snapshot", LESS, 2, snapshot },
5365 { "delete", MORE, 2, delete_snapshot },
5366 { "daemon-reload", EQUAL, 1, daemon_reload },
5367 { "daemon-reexec", EQUAL, 1, daemon_reload },
5368 { "show-environment", EQUAL, 1, show_environment },
5369 { "set-environment", MORE, 2, set_environment },
5370 { "unset-environment", MORE, 2, set_environment },
5371 { "halt", EQUAL, 1, start_special },
5372 { "poweroff", EQUAL, 1, start_special },
5373 { "reboot", EQUAL, 1, start_special },
5374 { "kexec", EQUAL, 1, start_special },
5375 { "suspend", EQUAL, 1, start_special },
5376 { "hibernate", EQUAL, 1, start_special },
5377 { "hybrid-sleep", EQUAL, 1, start_special },
5378 { "default", EQUAL, 1, start_special },
5379 { "rescue", EQUAL, 1, start_special },
5380 { "emergency", EQUAL, 1, start_special },
5381 { "exit", EQUAL, 1, start_special },
5382 { "reset-failed", MORE, 1, reset_failed },
5383 { "enable", MORE, 2, enable_unit },
5384 { "disable", MORE, 2, enable_unit },
5385 { "is-enabled", MORE, 2, unit_is_enabled },
5386 { "reenable", MORE, 2, enable_unit },
5387 { "preset", MORE, 2, enable_unit },
5388 { "mask", MORE, 2, enable_unit },
5389 { "unmask", MORE, 2, enable_unit },
5390 { "link", MORE, 2, enable_unit },
5391 { "switch-root", MORE, 2, switch_root },
5392 { "list-dependencies", LESS, 2, list_dependencies },
5393 { "set-default", EQUAL, 2, enable_unit },
5394 { "get-default", LESS, 1, get_default },
5395 { "set-property", MORE, 3, set_property },
5404 left = argc - optind;
5407 /* Special rule: no arguments means "list-units" */
5410 if (streq(argv[optind], "help") && !argv[optind+1]) {
5411 log_error("This command expects one or more "
5412 "unit names. Did you mean --help?");
5416 for (i = 0; i < ELEMENTSOF(verbs); i++)
5417 if (streq(argv[optind], verbs[i].verb))
5420 if (i >= ELEMENTSOF(verbs)) {
5421 log_error("Unknown operation '%s'.", argv[optind]);
5426 switch (verbs[i].argc_cmp) {
5429 if (left != verbs[i].argc) {
5430 log_error("Invalid number of arguments.");
5437 if (left < verbs[i].argc) {
5438 log_error("Too few arguments.");
5445 if (left > verbs[i].argc) {
5446 log_error("Too many arguments.");
5453 assert_not_reached("Unknown comparison operator.");
5456 /* Require a bus connection for all operations but
5458 if (!streq(verbs[i].verb, "enable") &&
5459 !streq(verbs[i].verb, "disable") &&
5460 !streq(verbs[i].verb, "is-enabled") &&
5461 !streq(verbs[i].verb, "list-unit-files") &&
5462 !streq(verbs[i].verb, "reenable") &&
5463 !streq(verbs[i].verb, "preset") &&
5464 !streq(verbs[i].verb, "mask") &&
5465 !streq(verbs[i].verb, "unmask") &&
5466 !streq(verbs[i].verb, "link") &&
5467 !streq(verbs[i].verb, "set-default") &&
5468 !streq(verbs[i].verb, "get-default")) {
5470 if (running_in_chroot() > 0) {
5471 log_info("Running in chroot, ignoring request.");
5475 if (((!streq(verbs[i].verb, "reboot") &&
5476 !streq(verbs[i].verb, "halt") &&
5477 !streq(verbs[i].verb, "poweroff")) || arg_force <= 0) && !bus) {
5478 log_error("Failed to get D-Bus connection: %s", strerror (-r));
5484 if (!bus && !avoid_bus()) {
5485 log_error("Failed to get D-Bus connection: %s", strerror (-r));
5490 return verbs[i].dispatch(bus, argv + optind);
5493 static int send_shutdownd(usec_t t, char mode, bool dry_run, bool warn, const char *message) {
5494 _cleanup_close_ int fd;
5495 struct sd_shutdown_command c = {
5501 union sockaddr_union sockaddr = {
5502 .un.sun_family = AF_UNIX,
5503 .un.sun_path = "/run/systemd/shutdownd",
5505 struct iovec iovec[2] = {
5506 {.iov_base = (char*) &c,
5507 .iov_len = offsetof(struct sd_shutdown_command, wall_message),
5510 struct msghdr msghdr = {
5511 .msg_name = &sockaddr,
5512 .msg_namelen = offsetof(struct sockaddr_un, sun_path)
5513 + sizeof("/run/systemd/shutdownd") - 1,
5518 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
5522 if (!isempty(message)) {
5523 iovec[1].iov_base = (char*) message;
5524 iovec[1].iov_len = strlen(message);
5525 msghdr.msg_iovlen++;
5528 if (sendmsg(fd, &msghdr, MSG_NOSIGNAL) < 0)
5534 static int reload_with_fallback(sd_bus *bus) {
5537 /* First, try systemd via D-Bus. */
5538 if (daemon_reload(bus, NULL) >= 0)
5542 /* Nothing else worked, so let's try signals */
5543 assert(arg_action == ACTION_RELOAD || arg_action == ACTION_REEXEC);
5545 if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) {
5546 log_error("kill() failed: %m");
5553 static int start_with_fallback(sd_bus *bus) {
5556 /* First, try systemd via D-Bus. */
5557 if (start_unit(bus, NULL) >= 0)
5561 /* Nothing else worked, so let's try
5563 if (talk_initctl() > 0)
5566 log_error("Failed to talk to init daemon.");
5570 warn_wall(arg_action);
5574 static _noreturn_ void halt_now(enum action a) {
5576 _cleanup_free_ char *param = NULL;
5578 /* Make sure C-A-D is handled by the kernel from this
5580 reboot(RB_ENABLE_CAD);
5585 log_info("Halting.");
5586 reboot(RB_HALT_SYSTEM);
5589 case ACTION_POWEROFF:
5590 log_info("Powering off.");
5591 reboot(RB_POWER_OFF);
5595 if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) == 0) {
5596 log_info("Rebooting with arg '%s'.", param);
5597 syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2,
5598 LINUX_REBOOT_CMD_RESTART2, param);
5600 log_info("Rebooting.");
5601 reboot(RB_AUTOBOOT);
5606 assert_not_reached("Unknown halt action.");
5609 assert_not_reached("Uh? This shouldn't happen.");
5612 static int halt_main(sd_bus *bus) {
5615 r = check_inhibitors(bus, arg_action);
5619 if (geteuid() != 0) {
5620 /* Try logind if we are a normal user and no special
5621 * mode applies. Maybe PolicyKit allows us to shutdown
5624 if (arg_when <= 0 &&
5627 (arg_action == ACTION_POWEROFF ||
5628 arg_action == ACTION_REBOOT)) {
5629 r = reboot_with_logind(bus, arg_action);
5634 log_error("Must be root.");
5639 _cleanup_free_ char *m;
5641 m = strv_join(arg_wall, " ");
5642 r = send_shutdownd(arg_when,
5643 arg_action == ACTION_HALT ? 'H' :
5644 arg_action == ACTION_POWEROFF ? 'P' :
5645 arg_action == ACTION_KEXEC ? 'K' :
5652 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r));
5654 char date[FORMAT_TIMESTAMP_MAX];
5656 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5657 format_timestamp(date, sizeof(date), arg_when));
5662 if (!arg_dry && !arg_force)
5663 return start_with_fallback(bus);
5666 if (sd_booted() > 0)
5667 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5669 r = utmp_put_shutdown();
5671 log_warning("Failed to write utmp record: %s", strerror(-r));
5678 halt_now(arg_action);
5679 /* We should never reach this. */
5683 static int runlevel_main(void) {
5684 int r, runlevel, previous;
5686 r = utmp_get_runlevel(&runlevel, &previous);
5693 previous <= 0 ? 'N' : previous,
5694 runlevel <= 0 ? 'N' : runlevel);
5699 int main(int argc, char*argv[]) {
5700 _cleanup_bus_unref_ sd_bus *bus = NULL;
5703 setlocale(LC_ALL, "");
5704 log_parse_environment();
5707 /* Explicitly not on_tty() to avoid setting cached value.
5708 * This becomes relevant for piping output which might be
5710 original_stdout_is_tty = isatty(STDOUT_FILENO);
5712 r = parse_argv(argc, argv);
5716 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5717 * let's shortcut this */
5718 if (arg_action == ACTION_RUNLEVEL) {
5719 r = runlevel_main();
5723 if (running_in_chroot() > 0 && arg_action != ACTION_SYSTEMCTL) {
5724 log_info("Running in chroot, ignoring request.");
5730 r = bus_open_transport(arg_transport, arg_host, arg_scope != UNIT_FILE_SYSTEM, &bus);
5732 log_error("Failed to create bus connection: %s", strerror(-r));
5737 switch (arg_action) {
5739 case ACTION_SYSTEMCTL:
5740 r = systemctl_main(bus, argc, argv, r);
5744 case ACTION_POWEROFF:
5750 case ACTION_RUNLEVEL2:
5751 case ACTION_RUNLEVEL3:
5752 case ACTION_RUNLEVEL4:
5753 case ACTION_RUNLEVEL5:
5755 case ACTION_EMERGENCY:
5756 case ACTION_DEFAULT:
5757 r = start_with_fallback(bus);
5762 r = reload_with_fallback(bus);
5765 case ACTION_CANCEL_SHUTDOWN: {
5766 _cleanup_free_ char *m = NULL;
5769 m = strv_join(arg_wall, " ");
5776 r = send_shutdownd(arg_when, SD_SHUTDOWN_NONE, false, !arg_no_wall, m);
5778 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r));
5782 case ACTION_RUNLEVEL:
5783 case _ACTION_INVALID:
5785 assert_not_reached("Unknown action");
5790 ask_password_agent_close();
5791 polkit_agent_close();
5793 strv_free(arg_types);
5794 strv_free(arg_states);
5795 strv_free(arg_properties);
5797 return r < 0 ? EXIT_FAILURE : r;