1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
25 #include <sys/syscall.h>
32 #include <sys/ioctl.h>
36 #include <sys/socket.h>
39 #include <sys/prctl.h>
41 #include "sd-daemon.h"
42 #include "sd-shutdown.h"
49 #include "utmp-wtmp.h"
52 #include "path-util.h"
54 #include "cgroup-show.h"
55 #include "cgroup-util.h"
57 #include "path-lookup.h"
58 #include "conf-parser.h"
59 #include "exit-status.h"
60 #include "bus-errors.h"
62 #include "unit-name.h"
64 #include "spawn-ask-password-agent.h"
65 #include "spawn-polkit-agent.h"
67 #include "logs-show.h"
68 #include "path-util.h"
69 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
75 static char **arg_types = NULL;
76 static char **arg_states = NULL;
77 static char **arg_properties = NULL;
78 static bool arg_all = false;
79 static bool original_stdout_is_tty;
80 static enum dependency {
85 } arg_dependency = DEPENDENCY_FORWARD;
86 static const char *arg_job_mode = "replace";
87 static UnitFileScope arg_scope = UNIT_FILE_SYSTEM;
88 static bool arg_no_block = false;
89 static bool arg_no_legend = false;
90 static bool arg_no_pager = false;
91 static bool arg_no_wtmp = false;
92 static bool arg_no_wall = false;
93 static bool arg_no_reload = false;
94 static bool arg_show_types = false;
95 static bool arg_ignore_inhibitors = false;
96 static bool arg_dry = false;
97 static bool arg_quiet = false;
98 static bool arg_full = false;
99 static int arg_force = 0;
100 static bool arg_ask_password = true;
101 static bool arg_runtime = false;
102 static char **arg_wall = NULL;
103 static const char *arg_kill_who = NULL;
104 static int arg_signal = SIGTERM;
105 static const char *arg_root = NULL;
106 static usec_t arg_when = 0;
128 ACTION_CANCEL_SHUTDOWN,
130 } arg_action = ACTION_SYSTEMCTL;
131 static BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
132 static char *arg_host = NULL;
133 static unsigned arg_lines = 10;
134 static OutputMode arg_output = OUTPUT_SHORT;
135 static bool arg_plain = false;
137 static int daemon_reload(sd_bus *bus, char **args);
138 static void halt_now(enum action a);
140 static void pager_open_if_enabled(void) {
148 static void ask_password_agent_open_if_enabled(void) {
150 /* Open the password agent as a child process if necessary */
152 if (!arg_ask_password)
155 if (arg_scope != UNIT_FILE_SYSTEM)
158 if (arg_transport != BUS_TRANSPORT_LOCAL)
161 ask_password_agent_open();
165 static void polkit_agent_open_if_enabled(void) {
167 /* Open the polkit agent as a child process if necessary */
169 if (!arg_ask_password)
172 if (arg_scope != UNIT_FILE_SYSTEM)
175 if (arg_transport != BUS_TRANSPORT_LOCAL)
182 static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error) {
185 if (!sd_bus_error_is_set(error))
188 if (sd_bus_error_has_name(error, SD_BUS_ERROR_ACCESS_DENIED) ||
189 sd_bus_error_has_name(error, BUS_ERROR_ONLY_BY_DEPENDENCY) ||
190 sd_bus_error_has_name(error, BUS_ERROR_NO_ISOLATION) ||
191 sd_bus_error_has_name(error, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE))
192 return EXIT_NOPERMISSION;
194 if (sd_bus_error_has_name(error, BUS_ERROR_NO_SUCH_UNIT))
195 return EXIT_NOTINSTALLED;
197 if (sd_bus_error_has_name(error, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE) ||
198 sd_bus_error_has_name(error, BUS_ERROR_NOT_SUPPORTED))
199 return EXIT_NOTIMPLEMENTED;
201 if (sd_bus_error_has_name(error, BUS_ERROR_LOAD_FAILED))
202 return EXIT_NOTCONFIGURED;
210 static void warn_wall(enum action a) {
211 static const char *table[_ACTION_MAX] = {
212 [ACTION_HALT] = "The system is going down for system halt NOW!",
213 [ACTION_REBOOT] = "The system is going down for reboot NOW!",
214 [ACTION_POWEROFF] = "The system is going down for power-off NOW!",
215 [ACTION_KEXEC] = "The system is going down for kexec reboot NOW!",
216 [ACTION_RESCUE] = "The system is going down to rescue mode NOW!",
217 [ACTION_EMERGENCY] = "The system is going down to emergency mode NOW!",
218 [ACTION_CANCEL_SHUTDOWN] = "The system shutdown has been cancelled NOW!"
225 _cleanup_free_ char *p;
227 p = strv_join(arg_wall, " ");
242 utmp_wall(table[a], NULL);
245 static bool avoid_bus(void) {
247 if (running_in_chroot() > 0)
250 if (sd_booted() <= 0)
253 if (!isempty(arg_root))
256 if (arg_scope == UNIT_FILE_GLOBAL)
262 static int compare_unit_info(const void *a, const void *b) {
263 const UnitInfo *u = a, *v = b;
266 d1 = strrchr(u->id, '.');
267 d2 = strrchr(v->id, '.');
272 r = strcasecmp(d1, d2);
277 return strcasecmp(u->id, v->id);
280 static bool output_show_unit(const UnitInfo *u) {
283 if (!strv_isempty(arg_states))
285 strv_contains(arg_states, u->load_state) ||
286 strv_contains(arg_states, u->sub_state) ||
287 strv_contains(arg_states, u->active_state);
289 return (!arg_types || ((dot = strrchr(u->id, '.')) &&
290 strv_find(arg_types, dot+1))) &&
291 (arg_all || !(streq(u->active_state, "inactive")
292 || u->following[0]) || u->job_id > 0);
295 static void output_units_list(const UnitInfo *unit_infos, unsigned c) {
296 unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
298 unsigned n_shown = 0;
301 max_id_len = sizeof("UNIT")-1;
302 load_len = sizeof("LOAD")-1;
303 active_len = sizeof("ACTIVE")-1;
304 sub_len = sizeof("SUB")-1;
305 job_len = sizeof("JOB")-1;
308 for (u = unit_infos; u < unit_infos + c; u++) {
309 if (!output_show_unit(u))
312 max_id_len = MAX(max_id_len, strlen(u->id));
313 load_len = MAX(load_len, strlen(u->load_state));
314 active_len = MAX(active_len, strlen(u->active_state));
315 sub_len = MAX(sub_len, strlen(u->sub_state));
317 if (u->job_id != 0) {
318 job_len = MAX(job_len, strlen(u->job_type));
323 if (!arg_full && original_stdout_is_tty) {
326 id_len = MIN(max_id_len, 25u);
327 basic_len = 5 + id_len + 5 + active_len + sub_len;
330 basic_len += job_len + 1;
332 if (basic_len < (unsigned) columns()) {
333 unsigned extra_len, incr;
334 extra_len = columns() - basic_len;
336 /* Either UNIT already got 25, or is fully satisfied.
337 * Grant up to 25 to DESC now. */
338 incr = MIN(extra_len, 25u);
342 /* split the remaining space between UNIT and DESC,
343 * but do not give UNIT more than it needs. */
345 incr = MIN(extra_len / 2, max_id_len - id_len);
347 desc_len += extra_len - incr;
353 for (u = unit_infos; u < unit_infos + c; u++) {
354 _cleanup_free_ char *e = NULL;
355 const char *on_loaded, *off_loaded, *on = "";
356 const char *on_active, *off_active, *off = "";
358 if (!output_show_unit(u))
361 if (!n_shown && !arg_no_legend) {
362 printf("%-*s %-*s %-*s %-*s ",
365 active_len, "ACTIVE",
369 printf("%-*s ", job_len, "JOB");
371 if (!arg_full && arg_no_pager)
372 printf("%.*s\n", desc_len, "DESCRIPTION");
374 printf("%s\n", "DESCRIPTION");
379 if (streq(u->load_state, "error") ||
380 streq(u->load_state, "not-found")) {
381 on_loaded = on = ansi_highlight_red();
382 off_loaded = off = ansi_highlight_off();
384 on_loaded = off_loaded = "";
386 if (streq(u->active_state, "failed")) {
387 on_active = on = ansi_highlight_red();
388 off_active = off = ansi_highlight_off();
390 on_active = off_active = "";
392 e = arg_full ? NULL : ellipsize(u->id, id_len, 33);
394 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
395 on, id_len, e ? e : u->id, off,
396 on_loaded, load_len, u->load_state, off_loaded,
397 on_active, active_len, u->active_state,
398 sub_len, u->sub_state, off_active,
399 job_count ? job_len + 1 : 0, u->job_id ? u->job_type : "");
402 printf("%.*s\n", desc_len, u->description);
404 printf("%s\n", u->description);
407 if (!arg_no_legend) {
408 const char *on, *off;
411 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
412 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
413 "SUB = The low-level unit activation state, values depend on unit type.\n");
415 printf("JOB = Pending job for the unit.\n");
417 on = ansi_highlight();
418 off = ansi_highlight_off();
420 on = ansi_highlight_red();
421 off = ansi_highlight_off();
425 printf("%s%u loaded units listed.%s\n"
426 "To show all installed unit files use 'systemctl list-unit-files'.\n",
429 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
430 "To show all installed unit files use 'systemctl list-unit-files'.\n",
435 static int get_unit_list(
437 sd_bus_message **_reply,
438 UnitInfo **_unit_infos) {
440 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
441 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
442 _cleanup_free_ UnitInfo *unit_infos = NULL;
451 r = sd_bus_call_method(
453 "org.freedesktop.systemd1",
454 "/org/freedesktop/systemd1",
455 "org.freedesktop.systemd1.Manager",
461 log_error("Failed to list units: %s", bus_error_message(&error, r));
465 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssssouso)");
467 return bus_log_parse_error(r);
469 while ((r = bus_parse_unit_info(reply, &u)) > 0) {
471 if (!GREEDY_REALLOC(unit_infos, size, c+1))
477 return bus_log_parse_error(r);
479 r = sd_bus_message_exit_container(reply);
481 return bus_log_parse_error(r);
486 *_unit_infos = unit_infos;
492 static int list_units(sd_bus *bus, char **args) {
493 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
494 _cleanup_free_ UnitInfo *unit_infos = NULL;
497 pager_open_if_enabled();
499 r = get_unit_list(bus, &reply, &unit_infos);
503 qsort_safe(unit_infos, r, sizeof(UnitInfo), compare_unit_info);
504 output_units_list(unit_infos, r);
509 static int get_triggered_units(
514 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
517 r = sd_bus_get_property_strv(
519 "org.freedesktop.systemd1",
521 "org.freedesktop.systemd1.Unit",
527 log_error("Failed to determine triggers: %s", bus_error_message(&error, r));
532 static int get_listening(
534 const char* unit_path,
538 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
539 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
540 const char *type, *path;
543 r = sd_bus_get_property(
545 "org.freedesktop.systemd1",
547 "org.freedesktop.systemd1.Socket",
553 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error, r));
557 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
559 return bus_log_parse_error(r);
561 while ((r = sd_bus_message_read(reply, "(ss)", &type, &path)) > 0) {
563 r = strv_extend(listening, type);
567 r = strv_extend(listening, path);
574 return bus_log_parse_error(r);
576 r = sd_bus_message_exit_container(reply);
578 return bus_log_parse_error(r);
589 /* Note: triggered is a list here, although it almost certainly
590 * will always be one unit. Nevertheless, dbus API allows for multiple
591 * values, so let's follow that.*/
594 /* The strv above is shared. free is set only in the first one. */
598 static int socket_info_compare(struct socket_info *a, struct socket_info *b) {
601 o = strcmp(a->path, b->path);
603 o = strcmp(a->type, b->type);
608 static int output_sockets_list(struct socket_info *socket_infos, unsigned cs) {
609 struct socket_info *s;
610 unsigned pathlen = sizeof("LISTEN") - 1,
611 typelen = (sizeof("TYPE") - 1) * arg_show_types,
612 socklen = sizeof("UNIT") - 1,
613 servlen = sizeof("ACTIVATES") - 1;
614 const char *on, *off;
616 for (s = socket_infos; s < socket_infos + cs; s++) {
620 socklen = MAX(socklen, strlen(s->id));
622 typelen = MAX(typelen, strlen(s->type));
623 pathlen = MAX(pathlen, strlen(s->path));
625 STRV_FOREACH(a, s->triggered)
626 tmp += strlen(*a) + 2*(a != s->triggered);
627 servlen = MAX(servlen, tmp);
632 printf("%-*s %-*.*s%-*s %s\n",
634 typelen + arg_show_types, typelen + arg_show_types, "TYPE ",
638 for (s = socket_infos; s < socket_infos + cs; s++) {
642 printf("%-*s %-*s %-*s",
643 pathlen, s->path, typelen, s->type, socklen, s->id);
646 pathlen, s->path, socklen, s->id);
647 STRV_FOREACH(a, s->triggered)
649 a == s->triggered ? "" : ",", *a);
653 on = ansi_highlight();
654 off = ansi_highlight_off();
658 on = ansi_highlight_red();
659 off = ansi_highlight_off();
662 if (!arg_no_legend) {
663 printf("%s%u sockets listed.%s\n", on, cs, off);
665 printf("Pass --all to see loaded but inactive sockets, too.\n");
671 static int list_sockets(sd_bus *bus, char **args) {
672 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
673 _cleanup_free_ UnitInfo *unit_infos = NULL;
674 struct socket_info *socket_infos = NULL;
676 struct socket_info *s;
677 unsigned cu = 0, cs = 0;
681 pager_open_if_enabled();
683 r = get_unit_list(bus, &reply, &unit_infos);
689 for (u = unit_infos; u < unit_infos + cu; u++) {
690 _cleanup_strv_free_ char **listening = NULL, **triggered = NULL;
693 if (!output_show_unit(u))
696 if (!endswith(u->id, ".socket"))
699 r = get_triggered_units(bus, u->unit_path, &triggered);
703 r = get_listening(bus, u->unit_path, &listening, &c);
707 if (!GREEDY_REALLOC(socket_infos, size, cs + c)) {
712 for (i = 0; i < c; i++)
713 socket_infos[cs + i] = (struct socket_info) {
715 .type = listening[i*2],
716 .path = listening[i*2 + 1],
717 .triggered = triggered,
718 .own_triggered = i==0,
721 /* from this point on we will cleanup those socket_infos */
724 listening = triggered = NULL; /* avoid cleanup */
727 qsort_safe(socket_infos, cs, sizeof(struct socket_info),
728 (__compar_fn_t) socket_info_compare);
730 output_sockets_list(socket_infos, cs);
733 assert(cs == 0 || socket_infos);
734 for (s = socket_infos; s < socket_infos + cs; s++) {
737 if (s->own_triggered)
738 strv_free(s->triggered);
745 static int compare_unit_file_list(const void *a, const void *b) {
747 const UnitFileList *u = a, *v = b;
749 d1 = strrchr(u->path, '.');
750 d2 = strrchr(v->path, '.');
755 r = strcasecmp(d1, d2);
760 return strcasecmp(path_get_file_name(u->path), path_get_file_name(v->path));
763 static bool output_show_unit_file(const UnitFileList *u) {
766 return !arg_types || ((dot = strrchr(u->path, '.')) && strv_find(arg_types, dot+1));
769 static void output_unit_file_list(const UnitFileList *units, unsigned c) {
770 unsigned max_id_len, id_cols, state_cols, n_shown = 0;
771 const UnitFileList *u;
773 max_id_len = sizeof("UNIT FILE")-1;
774 state_cols = sizeof("STATE")-1;
776 for (u = units; u < units + c; u++) {
777 if (!output_show_unit_file(u))
780 max_id_len = MAX(max_id_len, strlen(path_get_file_name(u->path)));
781 state_cols = MAX(state_cols, strlen(unit_file_state_to_string(u->state)));
787 id_cols = MIN(max_id_len, 25u);
788 basic_cols = 1 + id_cols + state_cols;
789 if (basic_cols < (unsigned) columns())
790 id_cols += MIN(columns() - basic_cols, max_id_len - id_cols);
792 id_cols = max_id_len;
795 printf("%-*s %-*s\n",
796 id_cols, "UNIT FILE",
797 state_cols, "STATE");
799 for (u = units; u < units + c; u++) {
800 _cleanup_free_ char *e = NULL;
801 const char *on, *off;
804 if (!output_show_unit_file(u))
809 if (u->state == UNIT_FILE_MASKED ||
810 u->state == UNIT_FILE_MASKED_RUNTIME ||
811 u->state == UNIT_FILE_DISABLED ||
812 u->state == UNIT_FILE_INVALID) {
813 on = ansi_highlight_red();
814 off = ansi_highlight_off();
815 } else if (u->state == UNIT_FILE_ENABLED) {
816 on = ansi_highlight_green();
817 off = ansi_highlight_off();
821 id = path_get_file_name(u->path);
823 e = arg_full ? NULL : ellipsize(id, id_cols, 33);
825 printf("%-*s %s%-*s%s\n",
827 on, state_cols, unit_file_state_to_string(u->state), off);
831 printf("\n%u unit files listed.\n", n_shown);
834 static int list_unit_files(sd_bus *bus, char **args) {
835 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
836 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
837 _cleanup_free_ UnitFileList *units = NULL;
843 pager_open_if_enabled();
851 h = hashmap_new(string_hash_func, string_compare_func);
855 r = unit_file_get_list(arg_scope, arg_root, h);
857 unit_file_list_free(h);
858 log_error("Failed to get unit file list: %s", strerror(-r));
862 n_units = hashmap_size(h);
863 units = new(UnitFileList, n_units);
865 unit_file_list_free(h);
869 HASHMAP_FOREACH(u, h, i) {
870 memcpy(units + c++, u, sizeof(UnitFileList));
874 assert(c == n_units);
879 r = sd_bus_call_method(
881 "org.freedesktop.systemd1",
882 "/org/freedesktop/systemd1",
883 "org.freedesktop.systemd1.Manager",
889 log_error("Failed to list unit files: %s", bus_error_message(&error, r));
893 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ss)");
895 return bus_log_parse_error(r);
897 while ((r = sd_bus_message_read(reply, "(ss)", &path, &state)) > 0) {
899 if (!GREEDY_REALLOC(units, size, c + 1))
902 units[c++] = (struct UnitFileList) {
904 unit_file_state_from_string(state)
908 return bus_log_parse_error(r);
910 r = sd_bus_message_exit_container(reply);
912 return bus_log_parse_error(r);
916 qsort(units, c, sizeof(UnitFileList), compare_unit_file_list);
917 output_unit_file_list(units, c);
923 static int list_dependencies_print(const char *name, int level, unsigned int branches, bool last) {
924 _cleanup_free_ char *n = NULL;
925 size_t max_len = MAX(columns(),20u);
931 for (i = level - 1; i >= 0; i--) {
933 if(len > max_len - 3 && !arg_full) {
934 printf("%s...\n",max_len % 2 ? "" : " ");
937 printf("%s", draw_special_char(branches & (1 << i) ? DRAW_TREE_VERT : DRAW_TREE_SPACE));
941 if(len > max_len - 3 && !arg_full) {
942 printf("%s...\n",max_len % 2 ? "" : " ");
946 printf("%s", draw_special_char(last ? DRAW_TREE_RIGHT : DRAW_TREE_BRANCH));
950 printf("%s\n", name);
954 n = ellipsize(name, max_len-len, 100);
962 static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
964 static const char *dependencies[] = {
965 [DEPENDENCY_FORWARD] = "Requires\0"
966 "RequiresOverridable\0"
968 "RequisiteOverridable\0"
970 [DEPENDENCY_REVERSE] = "RequiredBy\0"
971 "RequiredByOverridable\0"
974 [DEPENDENCY_AFTER] = "After\0",
975 [DEPENDENCY_BEFORE] = "Before\0",
978 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
979 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
980 _cleanup_strv_free_ char **ret = NULL;
981 _cleanup_free_ char *path = NULL;
987 assert(arg_dependency < ELEMENTSOF(dependencies));
989 path = unit_dbus_path_from_name(name);
993 r = sd_bus_call_method(
995 "org.freedesktop.systemd1",
997 "org.freedesktop.DBus.Properties",
1001 "s", "org.freedesktop.systemd1.Unit");
1003 log_error("Failed to get properties of %s: %s", name, bus_error_message(&error, r));
1007 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "{sv}");
1009 return bus_log_parse_error(r);
1011 while ((r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_DICT_ENTRY, "sv")) > 0) {
1014 r = sd_bus_message_read(reply, "s", &prop);
1016 return bus_log_parse_error(r);
1018 if (!nulstr_contains(dependencies[arg_dependency], prop)) {
1019 r = sd_bus_message_skip(reply, "v");
1021 return bus_log_parse_error(r);
1024 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_VARIANT, "as");
1026 return bus_log_parse_error(r);
1028 r = bus_message_read_strv_extend(reply, &ret);
1030 return bus_log_parse_error(r);
1032 r = sd_bus_message_exit_container(reply);
1034 return bus_log_parse_error(r);
1037 r = sd_bus_message_exit_container(reply);
1039 return bus_log_parse_error(r);
1043 return bus_log_parse_error(r);
1045 r = sd_bus_message_exit_container(reply);
1047 return bus_log_parse_error(r);
1055 static int list_dependencies_compare(const void *_a, const void *_b) {
1056 const char **a = (const char**) _a, **b = (const char**) _b;
1058 if (unit_name_to_type(*a) == UNIT_TARGET && unit_name_to_type(*b) != UNIT_TARGET)
1060 if (unit_name_to_type(*a) != UNIT_TARGET && unit_name_to_type(*b) == UNIT_TARGET)
1063 return strcasecmp(*a, *b);
1066 static int list_dependencies_one(
1071 unsigned int branches) {
1073 _cleanup_strv_free_ char **deps = NULL, **u;
1081 u = strv_append(*units, name);
1085 r = list_dependencies_get_dependencies(bus, name, &deps);
1089 qsort_safe(deps, strv_length(deps), sizeof (char*), list_dependencies_compare);
1091 STRV_FOREACH(c, deps) {
1092 if (strv_contains(u, *c)) {
1094 r = list_dependencies_print("...", level + 1, (branches << 1) | (c[1] == NULL ? 0 : 1), 1);
1101 r = list_dependencies_print(*c, level, branches, c[1] == NULL);
1105 if (arg_all || unit_name_to_type(*c) == UNIT_TARGET) {
1106 r = list_dependencies_one(bus, *c, level + 1, &u, (branches << 1) | (c[1] == NULL ? 0 : 1));
1121 static int list_dependencies(sd_bus *bus, char **args) {
1122 _cleanup_strv_free_ char **units = NULL;
1123 _cleanup_free_ char *unit = NULL;
1129 unit = unit_name_mangle(args[1]);
1134 u = SPECIAL_DEFAULT_TARGET;
1136 pager_open_if_enabled();
1140 return list_dependencies_one(bus, u, 0, &units, 0);
1143 static int get_default(sd_bus *bus, char **args) {
1144 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1145 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1146 _cleanup_free_ char *_path = NULL;
1150 if (!bus || avoid_bus()) {
1151 r = unit_file_get_default(arg_scope, arg_root, &_path);
1153 log_error("Failed to get default target: %s", strerror(-r));
1159 r = sd_bus_call_method(
1161 "org.freedesktop.systemd1",
1162 "/org/freedesktop/systemd1",
1163 "org.freedesktop.systemd1.Manager",
1169 log_error("Failed to get default target: %s", bus_error_message(&error, -r));
1173 r = sd_bus_message_read(reply, "s", &path);
1175 return bus_log_parse_error(r);
1179 printf("%s\n", path);
1186 const char *name, *type, *state;
1189 static void output_jobs_list(const struct job_info* jobs, unsigned n) {
1190 unsigned id_len, unit_len, type_len, state_len;
1191 const struct job_info *j;
1192 const char *on, *off;
1193 bool shorten = false;
1195 assert(n == 0 || jobs);
1198 on = ansi_highlight_green();
1199 off = ansi_highlight_off();
1201 printf("%sNo jobs running.%s\n", on, off);
1205 pager_open_if_enabled();
1207 id_len = unit_len = type_len = state_len = 0;
1208 for (j = jobs; j < jobs + n; j++) {
1209 uint32_t id = j->id;
1210 assert(j->name && j->type && j->state);
1212 id_len = MAX(id_len, DECIMAL_STR_WIDTH(id));
1213 unit_len = MAX(unit_len, strlen(j->name));
1214 type_len = MAX(type_len, strlen(j->type));
1215 state_len = MAX(state_len, strlen(j->state));
1218 if (!arg_full && id_len + 1 + unit_len + type_len + 1 + state_len > columns()) {
1219 unit_len = MAX(33u, columns() - id_len - type_len - state_len - 3);
1223 printf("%*s %-*s %-*s %-*s\n",
1227 state_len, "STATE");
1229 for (j = jobs; j < jobs + n; j++) {
1230 _cleanup_free_ char *e = NULL;
1232 if (streq(j->state, "running")) {
1233 on = ansi_highlight();
1234 off = ansi_highlight_off();
1238 e = shorten ? ellipsize(j->name, unit_len, 33) : NULL;
1239 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1241 on, unit_len, e ? e : j->name, off,
1243 on, state_len, j->state, off);
1246 on = ansi_highlight();
1247 off = ansi_highlight_off();
1249 printf("\n%s%u jobs listed%s.\n", on, n, off);
1252 static int list_jobs(sd_bus *bus, char **args) {
1253 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1254 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1255 const char *name, *type, *state, *job_path, *unit_path;
1256 _cleanup_free_ struct job_info *jobs = NULL;
1262 r = sd_bus_call_method(
1264 "org.freedesktop.systemd1",
1265 "/org/freedesktop/systemd1",
1266 "org.freedesktop.systemd1.Manager",
1272 log_error("Failed to list jobs: %s", bus_error_message(&error, r));
1276 r = sd_bus_message_enter_container(reply, 'a', "(usssoo)");
1278 return bus_log_parse_error(r);
1280 while ((r = sd_bus_message_read(reply, "(usssoo)", &id, &name, &type, &state, &job_path, &unit_path)) > 0) {
1282 if (!GREEDY_REALLOC(jobs, size, c + 1))
1285 jobs[c++] = (struct job_info) {
1293 return bus_log_parse_error(r);
1295 r = sd_bus_message_exit_container(reply);
1297 return bus_log_parse_error(r);
1299 output_jobs_list(jobs, c);
1303 static int cancel_job(sd_bus *bus, char **args) {
1304 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1309 if (strv_length(args) <= 1)
1310 return daemon_reload(bus, args);
1312 STRV_FOREACH(name, args+1) {
1316 r = safe_atou32(*name, &id);
1318 log_error("Failed to parse job id \"%s\": %s", *name, strerror(-r));
1322 r = sd_bus_call_method(
1324 "org.freedesktop.systemd1",
1325 "/org/freedesktop/systemd1",
1326 "org.freedesktop.systemd1.Manager",
1332 log_error("Failed to cancel job %u: %s", (unsigned) id, bus_error_message(&error, r));
1340 static int need_daemon_reload(sd_bus *bus, const char *unit) {
1341 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1342 _cleanup_free_ char *n = NULL;
1346 /* We ignore all errors here, since this is used to show a
1349 n = unit_name_mangle(unit);
1353 /* We don't use unit_dbus_path_from_name() directly since we
1354 * don't want to load the unit if it isn't loaded. */
1356 r = sd_bus_call_method(
1358 "org.freedesktop.systemd1",
1359 "/org/freedesktop/systemd1",
1360 "org.freedesktop.systemd1.Manager",
1368 r = sd_bus_message_read(reply, "o", &path);
1372 r = sd_bus_get_property_trivial(
1374 "org.freedesktop.systemd1",
1376 "org.freedesktop.systemd1.Unit",
1386 typedef struct WaitData {
1393 static int wait_filter(sd_bus *bus, sd_bus_message *m, void *data) {
1400 log_debug("Got D-Bus request: %s.%s() on %s",
1401 sd_bus_message_get_interface(m),
1402 sd_bus_message_get_member(m),
1403 sd_bus_message_get_path(m));
1405 if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected")) {
1406 log_error("Warning! D-Bus connection terminated.");
1408 } else if (sd_bus_message_is_signal(m, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1410 const char *path, *result, *unit;
1414 r = sd_bus_message_read(m, "uoss", &id, &path, &unit, &result);
1416 ret = set_remove(d->set, (char*) path);
1422 if (!isempty(result))
1423 d->result = strdup(result);
1426 d->name = strdup(unit);
1431 r = sd_bus_message_read(m, "uos", &id, &path, &result);
1433 ret = set_remove(d->set, (char*) path);
1440 d->result = strdup(result);
1446 log_error("Failed to parse message.");
1452 static int enable_wait_for_jobs(sd_bus *bus) {
1457 r = sd_bus_add_match(
1460 "sender='org.freedesktop.systemd1',"
1461 "interface='org.freedesktop.systemd1.Manager',"
1462 "member='JobRemoved',"
1463 "path='/org/freedesktop/systemd1'",
1466 log_error("Failed to add match");
1470 /* This is slightly dirty, since we don't undo the match registrations. */
1474 static int wait_for_jobs(sd_bus *bus, Set *s) {
1475 WaitData d = { .set = s };
1481 r = sd_bus_add_filter(bus, wait_filter, &d);
1485 while (!set_isempty(s)) {
1487 r = sd_bus_process(bus, NULL);
1492 r = sd_bus_wait(bus, (uint64_t) -1);
1501 if (streq(d.result, "timeout"))
1502 log_error("Job for %s timed out.", strna(d.name));
1503 else if (streq(d.result, "canceled"))
1504 log_error("Job for %s canceled.", strna(d.name));
1505 else if (streq(d.result, "dependency"))
1506 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d.name));
1507 else if (!streq(d.result, "done") && !streq(d.result, "skipped"))
1508 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d.name), strna(d.name));
1511 if (streq_ptr(d.result, "timeout"))
1513 else if (streq_ptr(d.result, "canceled"))
1515 else if (!streq_ptr(d.result, "done") && !streq_ptr(d.result, "skipped"))
1526 return sd_bus_remove_filter(bus, wait_filter, &d);
1529 static int check_one_unit(sd_bus *bus, const char *name, const char *good_states, bool quiet) {
1530 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1531 _cleanup_free_ char *n = NULL, *state = NULL;
1537 n = unit_name_mangle(name);
1541 /* We don't use unit_dbus_path_from_name() directly since we
1542 * don't want to load the unit if it isn't loaded. */
1544 r = sd_bus_call_method(
1546 "org.freedesktop.systemd1",
1547 "/org/freedesktop/systemd1",
1548 "org.freedesktop.systemd1.Manager",
1559 r = sd_bus_message_read(reply, "o", &path);
1561 return bus_log_parse_error(r);
1563 r = sd_bus_get_property_string(
1565 "org.freedesktop.systemd1",
1567 "org.freedesktop.systemd1.Unit",
1580 return nulstr_contains(good_states, state);
1583 static int check_triggering_units(
1587 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1588 _cleanup_free_ char *path = NULL, *n = NULL, *state = NULL;
1589 _cleanup_strv_free_ char **triggered_by = NULL;
1590 bool print_warning_label = true;
1594 n = unit_name_mangle(name);
1598 path = unit_dbus_path_from_name(n);
1602 r = sd_bus_get_property_string(
1604 "org.freedesktop.systemd1",
1606 "org.freedesktop.systemd1.Unit",
1611 log_error("Failed to get load state of %s: %s", n, bus_error_message(&error, r));
1615 if (streq(state, "masked"))
1618 r = sd_bus_get_property_strv(
1620 "org.freedesktop.systemd1",
1622 "org.freedesktop.systemd1.Unit",
1627 log_error("Failed to get triggered by array of %s: %s", n, bus_error_message(&error, r));
1631 STRV_FOREACH(i, triggered_by) {
1632 r = check_one_unit(bus, *i, "active\0reloading\0", true);
1634 log_error("Failed to check unit: %s", strerror(-r));
1641 if (print_warning_label) {
1642 log_warning("Warning: Stopping %s, but it can still be activated by:", n);
1643 print_warning_label = false;
1646 log_warning(" %s", *i);
1652 static int start_unit_one(
1657 sd_bus_error *error,
1660 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1661 _cleanup_free_ char *n;
1670 n = unit_name_mangle(name);
1674 r = sd_bus_call_method(
1676 "org.freedesktop.systemd1",
1677 "/org/freedesktop/systemd1",
1678 "org.freedesktop.systemd1.Manager",
1684 if (r == -ENOENT && arg_action != ACTION_SYSTEMCTL)
1685 /* There's always a fallback possible for
1686 * legacy actions. */
1687 return -EADDRNOTAVAIL;
1689 log_error("Failed to start %s: %s", name, bus_error_message(error, r));
1693 r = sd_bus_message_read(reply, "o", &path);
1695 return bus_log_parse_error(r);
1697 if (need_daemon_reload(bus, n) > 0)
1698 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1699 n, arg_scope == UNIT_FILE_SYSTEM ? "" : " --user");
1708 r = set_consume(s, p);
1716 static const struct {
1720 } action_table[_ACTION_MAX] = {
1721 [ACTION_HALT] = { SPECIAL_HALT_TARGET, "halt", "replace-irreversibly" },
1722 [ACTION_POWEROFF] = { SPECIAL_POWEROFF_TARGET, "poweroff", "replace-irreversibly" },
1723 [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" },
1724 [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" },
1725 [ACTION_RUNLEVEL2] = { SPECIAL_RUNLEVEL2_TARGET, NULL, "isolate" },
1726 [ACTION_RUNLEVEL3] = { SPECIAL_RUNLEVEL3_TARGET, NULL, "isolate" },
1727 [ACTION_RUNLEVEL4] = { SPECIAL_RUNLEVEL4_TARGET, NULL, "isolate" },
1728 [ACTION_RUNLEVEL5] = { SPECIAL_RUNLEVEL5_TARGET, NULL, "isolate" },
1729 [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" },
1730 [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" },
1731 [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" },
1732 [ACTION_EXIT] = { SPECIAL_EXIT_TARGET, "exit", "replace-irreversibly" },
1733 [ACTION_SUSPEND] = { SPECIAL_SUSPEND_TARGET, "suspend", "replace-irreversibly" },
1734 [ACTION_HIBERNATE] = { SPECIAL_HIBERNATE_TARGET, "hibernate", "replace-irreversibly" },
1735 [ACTION_HYBRID_SLEEP] = { SPECIAL_HYBRID_SLEEP_TARGET, "hybrid-sleep", "replace-irreversibly" },
1738 static enum action verb_to_action(const char *verb) {
1741 for (i = _ACTION_INVALID; i < _ACTION_MAX; i++)
1742 if (streq_ptr(action_table[i].verb, verb))
1745 return _ACTION_INVALID;
1748 static int start_unit(sd_bus *bus, char **args) {
1749 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1750 _cleanup_set_free_free_ Set *s = NULL;
1751 const char *method, *mode, *one_name;
1757 ask_password_agent_open_if_enabled();
1759 if (arg_action == ACTION_SYSTEMCTL) {
1762 streq(args[0], "stop") ||
1763 streq(args[0], "condstop") ? "StopUnit" :
1764 streq(args[0], "reload") ? "ReloadUnit" :
1765 streq(args[0], "restart") ? "RestartUnit" :
1767 streq(args[0], "try-restart") ||
1768 streq(args[0], "condrestart") ? "TryRestartUnit" :
1770 streq(args[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1772 streq(args[0], "reload-or-try-restart") ||
1773 streq(args[0], "condreload") ||
1774 streq(args[0], "force-reload") ? "ReloadOrTryRestartUnit" :
1776 action = verb_to_action(args[0]);
1778 mode = streq(args[0], "isolate") ? "isolate" :
1779 action_table[action].mode ?: arg_job_mode;
1781 one_name = action_table[action].target;
1783 assert(arg_action < ELEMENTSOF(action_table));
1784 assert(action_table[arg_action].target);
1786 method = "StartUnit";
1788 mode = action_table[arg_action].mode;
1789 one_name = action_table[arg_action].target;
1792 if (!arg_no_block) {
1793 r = enable_wait_for_jobs(bus);
1795 log_error("Could not watch jobs: %s", strerror(-r));
1799 s = set_new(string_hash_func, string_compare_func);
1805 r = start_unit_one(bus, method, one_name, mode, &error, s);
1807 r = translate_bus_error_to_exit_status(r, &error);
1811 STRV_FOREACH(name, args+1) {
1814 q = start_unit_one(bus, method, *name, mode, &error, s);
1816 r = translate_bus_error_to_exit_status(r, &error);
1817 sd_bus_error_free(&error);
1822 if (!arg_no_block) {
1825 q = wait_for_jobs(bus, s);
1829 /* When stopping units, warn if they can still be triggered by
1830 * another active unit (socket, path, timer) */
1831 if (!arg_quiet && streq(method, "StopUnit")) {
1833 check_triggering_units(bus, one_name);
1835 STRV_FOREACH(name, args+1)
1836 check_triggering_units(bus, *name);
1843 /* Ask systemd-logind, which might grant access to unprivileged users
1844 * through PolicyKit */
1845 static int reboot_with_logind(sd_bus *bus, enum action a) {
1847 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1854 polkit_agent_open_if_enabled();
1862 case ACTION_POWEROFF:
1863 method = "PowerOff";
1866 case ACTION_SUSPEND:
1870 case ACTION_HIBERNATE:
1871 method = "Hibernate";
1874 case ACTION_HYBRID_SLEEP:
1875 method = "HybridSleep";
1882 r = sd_bus_call_method(
1884 "org.freedesktop.login1",
1885 "/org/freedesktop/login1",
1886 "org.freedesktop.login1.Manager",
1892 log_error("Failed to execute operation: %s", bus_error_message(&error, r));
1900 static int check_inhibitors(sd_bus *bus, enum action a) {
1902 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1903 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1904 _cleanup_strv_free_ char **sessions = NULL;
1905 const char *what, *who, *why, *mode;
1914 if (arg_ignore_inhibitors || arg_force > 0)
1926 r = sd_bus_call_method(
1928 "org.freedesktop.login1",
1929 "/org/freedesktop/login1",
1930 "org.freedesktop.login1.Manager",
1936 /* If logind is not around, then there are no inhibitors... */
1939 r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssssuu)");
1941 return bus_log_parse_error(r);
1943 while ((r = sd_bus_message_read(reply, "(ssssuu)", &what, &who, &why, &mode, &uid, &pid)) > 0) {
1944 _cleanup_free_ char *comm = NULL, *user = NULL;
1945 _cleanup_strv_free_ char **sv = NULL;
1947 if (!streq(mode, "block"))
1950 sv = strv_split(what, ":");
1954 if (!strv_contains(sv,
1956 a == ACTION_POWEROFF ||
1957 a == ACTION_REBOOT ||
1958 a == ACTION_KEXEC ? "shutdown" : "sleep"))
1961 get_process_comm(pid, &comm);
1962 user = uid_to_name(uid);
1964 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
1965 who, (unsigned long) pid, strna(comm), strna(user), why);
1970 return bus_log_parse_error(r);
1972 r = sd_bus_message_exit_container(reply);
1974 return bus_log_parse_error(r);
1976 /* Check for current sessions */
1977 sd_get_sessions(&sessions);
1978 STRV_FOREACH(s, sessions) {
1979 _cleanup_free_ char *type = NULL, *tty = NULL, *seat = NULL, *user = NULL, *service = NULL, *class = NULL;
1981 if (sd_session_get_uid(*s, &uid) < 0 || uid == getuid())
1984 if (sd_session_get_class(*s, &class) < 0 || !streq(class, "user"))
1987 if (sd_session_get_type(*s, &type) < 0 || (!streq(type, "x11") && !streq(type, "tty")))
1990 sd_session_get_tty(*s, &tty);
1991 sd_session_get_seat(*s, &seat);
1992 sd_session_get_service(*s, &service);
1993 user = uid_to_name(uid);
1995 log_warning("User %s is logged in on %s.", strna(user), isempty(tty) ? (isempty(seat) ? strna(service) : seat) : tty);
2002 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2003 action_table[a].verb);
2011 static int start_special(sd_bus *bus, char **args) {
2017 a = verb_to_action(args[0]);
2019 r = check_inhibitors(bus, a);
2023 if (arg_force >= 2 && geteuid() != 0) {
2024 log_error("Must be root.");
2028 if (arg_force >= 2 &&
2029 (a == ACTION_HALT ||
2030 a == ACTION_POWEROFF ||
2031 a == ACTION_REBOOT))
2034 if (arg_force >= 1 &&
2035 (a == ACTION_HALT ||
2036 a == ACTION_POWEROFF ||
2037 a == ACTION_REBOOT ||
2038 a == ACTION_KEXEC ||
2040 return daemon_reload(bus, args);
2042 /* first try logind, to allow authentication with polkit */
2043 if (geteuid() != 0 &&
2044 (a == ACTION_POWEROFF ||
2045 a == ACTION_REBOOT ||
2046 a == ACTION_SUSPEND ||
2047 a == ACTION_HIBERNATE ||
2048 a == ACTION_HYBRID_SLEEP)) {
2049 r = reboot_with_logind(bus, a);
2054 r = start_unit(bus, args);
2055 if (r == EXIT_SUCCESS)
2061 static int check_unit_active(sd_bus *bus, char **args) {
2063 int r = 3; /* According to LSB: "program is not running" */
2068 STRV_FOREACH(name, args+1) {
2071 state = check_one_unit(bus, *name, "active\0reloading\0", arg_quiet);
2081 static int check_unit_failed(sd_bus *bus, char **args) {
2088 STRV_FOREACH(name, args+1) {
2091 state = check_one_unit(bus, *name, "failed\0", arg_quiet);
2101 static int kill_unit(sd_bus *bus, char **args) {
2102 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
2110 arg_kill_who = "all";
2112 STRV_FOREACH(name, args+1) {
2113 _cleanup_free_ char *n = NULL;
2115 n = unit_name_mangle(*name);
2119 r = sd_bus_call_method(
2121 "org.freedesktop.systemd1",
2122 "/org/freedesktop/systemd1",
2123 "org.freedesktop.systemd1.Manager",
2127 "ssi", n, arg_kill_who, arg_signal);
2129 log_error("Failed to kill unit %s: %s", n, bus_error_message(&error, r));
2137 typedef struct ExecStatusInfo {
2145 usec_t start_timestamp;
2146 usec_t exit_timestamp;
2151 LIST_FIELDS(struct ExecStatusInfo, exec);
2154 static void exec_status_info_free(ExecStatusInfo *i) {
2163 static int exec_status_info_deserialize(sd_bus_message *m, ExecStatusInfo *i) {
2164 uint64_t start_timestamp, exit_timestamp, start_timestamp_monotonic, exit_timestamp_monotonic;
2167 int32_t code, status;
2173 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_STRUCT, "sasbttttuii");
2175 return bus_log_parse_error(r);
2179 r = sd_bus_message_read(m, "s", &path);
2181 return bus_log_parse_error(r);
2183 i->path = strdup(path);
2187 r = sd_bus_message_read_strv(m, &i->argv);
2189 return bus_log_parse_error(r);
2191 r = sd_bus_message_read(m,
2194 &start_timestamp, &start_timestamp_monotonic,
2195 &exit_timestamp, &exit_timestamp_monotonic,
2199 return bus_log_parse_error(r);
2202 i->start_timestamp = (usec_t) start_timestamp;
2203 i->exit_timestamp = (usec_t) exit_timestamp;
2204 i->pid = (pid_t) pid;
2208 r = sd_bus_message_exit_container(m);
2210 return bus_log_parse_error(r);
2215 typedef struct UnitStatusInfo {
2217 const char *load_state;
2218 const char *active_state;
2219 const char *sub_state;
2220 const char *unit_file_state;
2222 const char *description;
2223 const char *following;
2225 char **documentation;
2227 const char *fragment_path;
2228 const char *source_path;
2229 const char *control_group;
2231 char **dropin_paths;
2233 const char *load_error;
2236 usec_t inactive_exit_timestamp;
2237 usec_t inactive_exit_timestamp_monotonic;
2238 usec_t active_enter_timestamp;
2239 usec_t active_exit_timestamp;
2240 usec_t inactive_enter_timestamp;
2242 bool need_daemon_reload;
2247 const char *status_text;
2248 const char *pid_file;
2251 usec_t start_timestamp;
2252 usec_t exit_timestamp;
2254 int exit_code, exit_status;
2256 usec_t condition_timestamp;
2257 bool condition_result;
2258 bool failed_condition_trigger;
2259 bool failed_condition_negate;
2260 const char *failed_condition;
2261 const char *failed_condition_param;
2264 unsigned n_accepted;
2265 unsigned n_connections;
2268 /* Pairs of type, path */
2272 const char *sysfs_path;
2274 /* Mount, Automount */
2280 LIST_HEAD(ExecStatusInfo, exec);
2283 static void print_status_info(
2288 const char *on, *off, *ss;
2290 char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
2291 char since2[FORMAT_TIMESTAMP_MAX], *s2;
2294 arg_all * OUTPUT_SHOW_ALL |
2295 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
2296 on_tty() * OUTPUT_COLOR |
2297 !arg_quiet * OUTPUT_WARN_CUTOFF |
2298 arg_full * OUTPUT_FULL_WIDTH;
2303 /* This shows pretty information about a unit. See
2304 * print_property() for a low-level property printer */
2306 printf("%s", strna(i->id));
2308 if (i->description && !streq_ptr(i->id, i->description))
2309 printf(" - %s", i->description);
2314 printf(" Follow: unit currently follows state of %s\n", i->following);
2316 if (streq_ptr(i->load_state, "error")) {
2317 on = ansi_highlight_red();
2318 off = ansi_highlight_off();
2322 path = i->source_path ? i->source_path : i->fragment_path;
2325 printf(" Loaded: %s%s%s (Reason: %s)\n",
2326 on, strna(i->load_state), off, i->load_error);
2327 else if (path && i->unit_file_state)
2328 printf(" Loaded: %s%s%s (%s; %s)\n",
2329 on, strna(i->load_state), off, path, i->unit_file_state);
2331 printf(" Loaded: %s%s%s (%s)\n",
2332 on, strna(i->load_state), off, path);
2334 printf(" Loaded: %s%s%s\n",
2335 on, strna(i->load_state), off);
2337 if (!strv_isempty(i->dropin_paths)) {
2338 _cleanup_free_ char *dir = NULL;
2342 STRV_FOREACH(dropin, i->dropin_paths) {
2343 if (! dir || last) {
2344 printf(dir ? " " : " Drop-In: ");
2349 if (path_get_parent(*dropin, &dir) < 0) {
2354 printf("%s\n %s", dir,
2355 draw_special_char(DRAW_TREE_RIGHT));
2358 last = ! (*(dropin + 1) && startswith(*(dropin + 1), dir));
2360 printf("%s%s", path_get_file_name(*dropin), last ? "\n" : ", ");
2364 ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
2366 if (streq_ptr(i->active_state, "failed")) {
2367 on = ansi_highlight_red();
2368 off = ansi_highlight_off();
2369 } else if (streq_ptr(i->active_state, "active") || streq_ptr(i->active_state, "reloading")) {
2370 on = ansi_highlight_green();
2371 off = ansi_highlight_off();
2376 printf(" Active: %s%s (%s)%s",
2377 on, strna(i->active_state), ss, off);
2379 printf(" Active: %s%s%s",
2380 on, strna(i->active_state), off);
2382 if (!isempty(i->result) && !streq(i->result, "success"))
2383 printf(" (Result: %s)", i->result);
2385 timestamp = (streq_ptr(i->active_state, "active") ||
2386 streq_ptr(i->active_state, "reloading")) ? i->active_enter_timestamp :
2387 (streq_ptr(i->active_state, "inactive") ||
2388 streq_ptr(i->active_state, "failed")) ? i->inactive_enter_timestamp :
2389 streq_ptr(i->active_state, "activating") ? i->inactive_exit_timestamp :
2390 i->active_exit_timestamp;
2392 s1 = format_timestamp_relative(since1, sizeof(since1), timestamp);
2393 s2 = format_timestamp(since2, sizeof(since2), timestamp);
2396 printf(" since %s; %s\n", s2, s1);
2398 printf(" since %s\n", s2);
2402 if (!i->condition_result && i->condition_timestamp > 0) {
2403 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
2404 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
2406 printf(" start condition failed at %s%s%s\n",
2407 s2, s1 ? "; " : "", s1 ? s1 : "");
2408 if (i->failed_condition_trigger)
2409 printf(" none of the trigger conditions were met\n");
2410 else if (i->failed_condition)
2411 printf(" %s=%s%s was not met\n",
2412 i->failed_condition,
2413 i->failed_condition_negate ? "!" : "",
2414 i->failed_condition_param);
2418 printf(" Device: %s\n", i->sysfs_path);
2420 printf(" Where: %s\n", i->where);
2422 printf(" What: %s\n", i->what);
2424 STRV_FOREACH(t, i->documentation)
2425 printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", *t);
2427 STRV_FOREACH_PAIR(t, t2, i->listen)
2428 printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
2431 printf(" Accepted: %u; Connected: %u\n", i->n_accepted, i->n_connections);
2433 LIST_FOREACH(exec, p, i->exec) {
2434 _cleanup_free_ char *argv = NULL;
2437 /* Only show exited processes here */
2441 argv = strv_join(p->argv, " ");
2442 printf(" Process: %u %s=%s ", p->pid, p->name, strna(argv));
2444 good = is_clean_exit_lsb(p->code, p->status, NULL);
2446 on = ansi_highlight_red();
2447 off = ansi_highlight_off();
2451 printf("%s(code=%s, ", on, sigchld_code_to_string(p->code));
2453 if (p->code == CLD_EXITED) {
2456 printf("status=%i", p->status);
2458 c = exit_status_to_string(p->status, EXIT_STATUS_SYSTEMD);
2463 printf("signal=%s", signal_to_string(p->status));
2465 printf(")%s\n", off);
2467 if (i->main_pid == p->pid &&
2468 i->start_timestamp == p->start_timestamp &&
2469 i->exit_timestamp == p->start_timestamp)
2470 /* Let's not show this twice */
2473 if (p->pid == i->control_pid)
2477 if (i->main_pid > 0 || i->control_pid > 0) {
2478 if (i->main_pid > 0) {
2479 printf(" Main PID: %u", (unsigned) i->main_pid);
2482 _cleanup_free_ char *comm = NULL;
2483 get_process_comm(i->main_pid, &comm);
2485 printf(" (%s)", comm);
2486 } else if (i->exit_code > 0) {
2487 printf(" (code=%s, ", sigchld_code_to_string(i->exit_code));
2489 if (i->exit_code == CLD_EXITED) {
2492 printf("status=%i", i->exit_status);
2494 c = exit_status_to_string(i->exit_status, EXIT_STATUS_SYSTEMD);
2499 printf("signal=%s", signal_to_string(i->exit_status));
2503 if (i->control_pid > 0)
2507 if (i->control_pid > 0) {
2508 _cleanup_free_ char *c = NULL;
2510 printf(" %8s: %u", i->main_pid ? "" : " Control", (unsigned) i->control_pid);
2512 get_process_comm(i->control_pid, &c);
2521 printf(" Status: \"%s\"\n", i->status_text);
2523 if (i->control_group &&
2524 (i->main_pid > 0 || i->control_pid > 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, i->control_group, false) == 0)) {
2527 printf(" CGroup: %s\n", i->control_group);
2529 if (arg_transport == BUS_TRANSPORT_LOCAL || arg_transport == BUS_TRANSPORT_CONTAINER) {
2532 char prefix[] = " ";
2535 if (c > sizeof(prefix) - 1)
2536 c -= sizeof(prefix) - 1;
2540 if (i->main_pid > 0)
2541 extra[k++] = i->main_pid;
2543 if (i->control_pid > 0)
2544 extra[k++] = i->control_pid;
2546 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, i->control_group, prefix,
2547 c, false, extra, k, flags);
2551 if (i->id && arg_transport == BUS_TRANSPORT_LOCAL) {
2553 show_journal_by_unit(stdout,
2557 i->inactive_exit_timestamp_monotonic,
2561 arg_scope == UNIT_FILE_SYSTEM,
2565 if (i->need_daemon_reload)
2566 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2567 ansi_highlight_red(),
2568 ansi_highlight_off(),
2569 arg_scope == UNIT_FILE_SYSTEM ? "" : "--user ");
2572 static void show_unit_help(UnitStatusInfo *i) {
2577 if (!i->documentation) {
2578 log_info("Documentation for %s not known.", i->id);
2582 STRV_FOREACH(p, i->documentation) {
2584 if (startswith(*p, "man:")) {
2585 const char *args[4] = { "man", NULL, NULL, NULL };
2586 _cleanup_free_ char *page = NULL, *section = NULL;
2593 if ((*p)[k-1] == ')')
2594 e = strrchr(*p, '(');
2597 page = strndup((*p) + 4, e - *p - 4);
2598 section = strndup(e + 1, *p + k - e - 2);
2599 if (!page || !section) {
2611 log_error("Failed to fork: %m");
2617 execvp(args[0], (char**) args);
2618 log_error("Failed to execute man: %m");
2619 _exit(EXIT_FAILURE);
2622 wait_for_terminate(pid, NULL);
2624 log_info("Can't show: %s", *p);
2628 static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *i, const char *contents) {
2635 switch (contents[0]) {
2637 case SD_BUS_TYPE_STRING: {
2640 r = sd_bus_message_read(m, "s", &s);
2642 return bus_log_parse_error(r);
2645 if (streq(name, "Id"))
2647 else if (streq(name, "LoadState"))
2649 else if (streq(name, "ActiveState"))
2650 i->active_state = s;
2651 else if (streq(name, "SubState"))
2653 else if (streq(name, "Description"))
2655 else if (streq(name, "FragmentPath"))
2656 i->fragment_path = s;
2657 else if (streq(name, "SourcePath"))
2660 else if (streq(name, "DefaultControlGroup")) {
2662 e = startswith(s, SYSTEMD_CGROUP_CONTROLLER ":");
2664 i->control_group = e;
2667 else if (streq(name, "ControlGroup"))
2668 i->control_group = s;
2669 else if (streq(name, "StatusText"))
2671 else if (streq(name, "PIDFile"))
2673 else if (streq(name, "SysFSPath"))
2675 else if (streq(name, "Where"))
2677 else if (streq(name, "What"))
2679 else if (streq(name, "Following"))
2681 else if (streq(name, "UnitFileState"))
2682 i->unit_file_state = s;
2683 else if (streq(name, "Result"))
2690 case SD_BUS_TYPE_BOOLEAN: {
2693 r = sd_bus_message_read(m, "b", &b);
2695 return bus_log_parse_error(r);
2697 if (streq(name, "Accept"))
2699 else if (streq(name, "NeedDaemonReload"))
2700 i->need_daemon_reload = b;
2701 else if (streq(name, "ConditionResult"))
2702 i->condition_result = b;
2707 case SD_BUS_TYPE_UINT32: {
2710 r = sd_bus_message_read(m, "u", &u);
2712 return bus_log_parse_error(r);
2714 if (streq(name, "MainPID")) {
2716 i->main_pid = (pid_t) u;
2719 } else if (streq(name, "ControlPID"))
2720 i->control_pid = (pid_t) u;
2721 else if (streq(name, "ExecMainPID")) {
2723 i->main_pid = (pid_t) u;
2724 } else if (streq(name, "NAccepted"))
2726 else if (streq(name, "NConnections"))
2727 i->n_connections = u;
2732 case SD_BUS_TYPE_INT32: {
2735 r = sd_bus_message_read(m, "i", &j);
2737 return bus_log_parse_error(r);
2739 if (streq(name, "ExecMainCode"))
2740 i->exit_code = (int) j;
2741 else if (streq(name, "ExecMainStatus"))
2742 i->exit_status = (int) j;
2747 case SD_BUS_TYPE_UINT64: {
2750 r = sd_bus_message_read(m, "t", &u);
2752 return bus_log_parse_error(r);
2754 if (streq(name, "ExecMainStartTimestamp"))
2755 i->start_timestamp = (usec_t) u;
2756 else if (streq(name, "ExecMainExitTimestamp"))
2757 i->exit_timestamp = (usec_t) u;
2758 else if (streq(name, "ActiveEnterTimestamp"))
2759 i->active_enter_timestamp = (usec_t) u;
2760 else if (streq(name, "InactiveEnterTimestamp"))
2761 i->inactive_enter_timestamp = (usec_t) u;
2762 else if (streq(name, "InactiveExitTimestamp"))
2763 i->inactive_exit_timestamp = (usec_t) u;
2764 else if (streq(name, "InactiveExitTimestampMonotonic"))
2765 i->inactive_exit_timestamp_monotonic = (usec_t) u;
2766 else if (streq(name, "ActiveExitTimestamp"))
2767 i->active_exit_timestamp = (usec_t) u;
2768 else if (streq(name, "ConditionTimestamp"))
2769 i->condition_timestamp = (usec_t) u;
2774 case SD_BUS_TYPE_ARRAY:
2776 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
2777 _cleanup_free_ ExecStatusInfo *info = NULL;
2779 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
2781 return bus_log_parse_error(r);
2783 info = new0(ExecStatusInfo, 1);
2787 while ((r = exec_status_info_deserialize(m, info)) > 0) {
2789 info->name = strdup(name);
2793 LIST_PREPEND(exec, i->exec, info);
2795 info = new0(ExecStatusInfo, 1);
2801 return bus_log_parse_error(r);
2803 r = sd_bus_message_exit_container(m);
2805 return bus_log_parse_error(r);
2809 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
2810 const char *type, *path;
2812 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2814 return bus_log_parse_error(r);
2816 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0) {
2818 r = strv_extend(&i->listen, type);
2822 r = strv_extend(&i->listen, path);
2827 return bus_log_parse_error(r);
2829 r = sd_bus_message_exit_container(m);
2831 return bus_log_parse_error(r);
2835 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "DropInPaths")) {
2837 r = sd_bus_message_read_strv(m, &i->dropin_paths);
2839 return bus_log_parse_error(r);
2841 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Documentation")) {
2843 r = sd_bus_message_read_strv(m, &i->documentation);
2845 return bus_log_parse_error(r);
2847 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Conditions")) {
2848 const char *cond, *param;
2849 int trigger, negate;
2852 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sbbsi)");
2854 return bus_log_parse_error(r);
2856 while ((r = sd_bus_message_read(m, "(sbbsi)", &cond, &trigger, &negate, ¶m, &state)) > 0) {
2857 log_debug("%s %d %d %s %d", cond, trigger, negate, param, state);
2858 if (state < 0 && (!trigger || !i->failed_condition)) {
2859 i->failed_condition = cond;
2860 i->failed_condition_trigger = trigger;
2861 i->failed_condition_negate = negate;
2862 i->failed_condition_param = param;
2866 return bus_log_parse_error(r);
2868 r = sd_bus_message_exit_container(m);
2870 return bus_log_parse_error(r);
2877 case SD_BUS_TYPE_STRUCT_BEGIN:
2879 if (streq(name, "LoadError")) {
2880 const char *n, *message;
2882 r = sd_bus_message_read(m, "(ss)", &n, &message);
2884 return bus_log_parse_error(r);
2886 if (!isempty(message))
2887 i->load_error = message;
2900 r = sd_bus_message_skip(m, contents);
2902 return bus_log_parse_error(r);
2907 static int print_property(const char *name, sd_bus_message *m, const char *contents) {
2913 /* This is a low-level property printer, see
2914 * print_status_info() for the nicer output */
2916 if (arg_properties && !strv_find(arg_properties, name))
2919 switch (contents[0]) {
2921 case SD_BUS_TYPE_STRUCT_BEGIN:
2923 if (contents[1] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) {
2926 r = sd_bus_message_read(m, "(uo)", &u, NULL);
2928 return bus_log_parse_error(r);
2931 printf("%s=%u\n", name, (unsigned) u);
2933 printf("%s=\n", name);
2937 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "Unit")) {
2940 r = sd_bus_message_read(m, "(so)", &s, NULL);
2942 return bus_log_parse_error(r);
2944 if (arg_all || !isempty(s))
2945 printf("%s=%s\n", name, s);
2949 } else if (contents[1] == SD_BUS_TYPE_STRING && streq(name, "LoadError")) {
2950 const char *a = NULL, *b = NULL;
2952 r = sd_bus_message_read(m, "(ss)", &a, &b);
2954 return bus_log_parse_error(r);
2956 if (arg_all || !isempty(a) || !isempty(b))
2957 printf("%s=%s \"%s\"\n", name, strempty(a), strempty(b));
2964 case SD_BUS_TYPE_ARRAY:
2966 if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "EnvironmentFiles")) {
2970 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sb)");
2972 return bus_log_parse_error(r);
2974 while ((r = sd_bus_message_read(m, "(sb)", &path, &ignore)) > 0)
2975 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path, yes_no(ignore));
2978 return bus_log_parse_error(r);
2980 r = sd_bus_message_exit_container(m);
2982 return bus_log_parse_error(r);
2986 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Paths")) {
2987 const char *type, *path;
2989 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
2991 return bus_log_parse_error(r);
2993 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
2994 printf("%s=%s\n", type, path);
2996 return bus_log_parse_error(r);
2998 r = sd_bus_message_exit_container(m);
3000 return bus_log_parse_error(r);
3004 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Listen")) {
3005 const char *type, *path;
3007 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(ss)");
3009 return bus_log_parse_error(r);
3011 while ((r = sd_bus_message_read(m, "(ss)", &type, &path)) > 0)
3012 printf("Listen%s=%s\n", type, path);
3014 return bus_log_parse_error(r);
3016 r = sd_bus_message_exit_container(m);
3018 return bus_log_parse_error(r);
3022 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && streq(name, "Timers")) {
3024 uint64_t value, next_elapse;
3026 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(stt)");
3028 return bus_log_parse_error(r);
3030 while ((r = sd_bus_message_read(m, "(stt)", &base, &value, &next_elapse)) > 0) {
3031 char timespan1[FORMAT_TIMESPAN_MAX], timespan2[FORMAT_TIMESPAN_MAX];
3033 printf("%s={ value=%s ; next_elapse=%s }\n",
3035 format_timespan(timespan1, sizeof(timespan1), value, 0),
3036 format_timespan(timespan2, sizeof(timespan2), next_elapse, 0));
3039 return bus_log_parse_error(r);
3041 r = sd_bus_message_exit_container(m);
3043 return bus_log_parse_error(r);
3047 } else if (contents[1] == SD_BUS_TYPE_STRUCT_BEGIN && startswith(name, "Exec")) {
3048 ExecStatusInfo info = {};
3050 r = sd_bus_message_enter_container(m, SD_BUS_TYPE_ARRAY, "(sasbttttuii)");
3052 return bus_log_parse_error(r);
3054 while ((r = exec_status_info_deserialize(m, &info)) > 0) {
3055 char timestamp1[FORMAT_TIMESTAMP_MAX], timestamp2[FORMAT_TIMESTAMP_MAX];
3056 _cleanup_free_ char *tt;
3058 tt = strv_join(info.argv, " ");
3060 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3064 yes_no(info.ignore),
3065 strna(format_timestamp(timestamp1, sizeof(timestamp1), info.start_timestamp)),
3066 strna(format_timestamp(timestamp2, sizeof(timestamp2), info.exit_timestamp)),
3067 (unsigned) info. pid,
3068 sigchld_code_to_string(info.code),
3070 info.code == CLD_EXITED ? "" : "/",
3071 strempty(info.code == CLD_EXITED ? NULL : signal_to_string(info.status)));
3074 strv_free(info.argv);
3078 r = sd_bus_message_exit_container(m);
3080 return bus_log_parse_error(r);