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 int 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
= sizeof("JOB")-1;
1208 unit_len
= sizeof("UNIT")-1;
1209 type_len
= sizeof("TYPE")-1;
1210 state_len
= sizeof("STATE")-1;
1212 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1213 uint32_t id
= j
->id
;
1214 assert(j
->name
&& j
->type
&& j
->state
);
1216 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
1217 unit_len
= MAX(unit_len
, strlen(j
->name
));
1218 type_len
= MAX(type_len
, strlen(j
->type
));
1219 state_len
= MAX(state_len
, strlen(j
->state
));
1222 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
1223 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
1227 printf("%*s %-*s %-*s %-*s\n",
1231 state_len
, "STATE");
1233 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1234 _cleanup_free_
char *e
= NULL
;
1236 if (streq(j
->state
, "running")) {
1237 on
= ansi_highlight();
1238 off
= ansi_highlight_off();
1242 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
1243 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1245 on
, unit_len
, e
? e
: j
->name
, off
,
1247 on
, state_len
, j
->state
, off
);
1250 on
= ansi_highlight();
1251 off
= ansi_highlight_off();
1253 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
1256 static int list_jobs(sd_bus
*bus
, char **args
) {
1257 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1258 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1259 const char *name
, *type
, *state
, *job_path
, *unit_path
;
1260 _cleanup_free_
struct job_info
*jobs
= NULL
;
1266 r
= sd_bus_call_method(
1268 "org.freedesktop.systemd1",
1269 "/org/freedesktop/systemd1",
1270 "org.freedesktop.systemd1.Manager",
1276 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
1280 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
1282 return bus_log_parse_error(r
);
1284 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
1286 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
1289 jobs
[c
++] = (struct job_info
) {
1297 return bus_log_parse_error(r
);
1299 r
= sd_bus_message_exit_container(reply
);
1301 return bus_log_parse_error(r
);
1303 output_jobs_list(jobs
, c
);
1307 static int cancel_job(sd_bus
*bus
, char **args
) {
1308 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1313 if (strv_length(args
) <= 1)
1314 return daemon_reload(bus
, args
);
1316 STRV_FOREACH(name
, args
+1) {
1320 r
= safe_atou32(*name
, &id
);
1322 log_error("Failed to parse job id \"%s\": %s", *name
, strerror(-r
));
1326 r
= sd_bus_call_method(
1328 "org.freedesktop.systemd1",
1329 "/org/freedesktop/systemd1",
1330 "org.freedesktop.systemd1.Manager",
1336 log_error("Failed to cancel job %u: %s", (unsigned) id
, bus_error_message(&error
, r
));
1344 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
1345 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1346 _cleanup_free_
char *n
= NULL
;
1350 /* We ignore all errors here, since this is used to show a
1353 n
= unit_name_mangle(unit
);
1357 /* We don't use unit_dbus_path_from_name() directly since we
1358 * don't want to load the unit if it isn't loaded. */
1360 r
= sd_bus_call_method(
1362 "org.freedesktop.systemd1",
1363 "/org/freedesktop/systemd1",
1364 "org.freedesktop.systemd1.Manager",
1372 r
= sd_bus_message_read(reply
, "o", &path
);
1376 r
= sd_bus_get_property_trivial(
1378 "org.freedesktop.systemd1",
1380 "org.freedesktop.systemd1.Unit",
1390 typedef struct WaitData
{
1397 static int wait_filter(sd_bus
*bus
, sd_bus_message
*m
, void *data
) {
1404 log_debug("Got D-Bus request: %s.%s() on %s",
1405 sd_bus_message_get_interface(m
),
1406 sd_bus_message_get_member(m
),
1407 sd_bus_message_get_path(m
));
1409 if (sd_bus_message_is_signal(m
, "org.freedesktop.DBus.Local", "Disconnected")) {
1410 log_error("Warning! D-Bus connection terminated.");
1412 } else if (sd_bus_message_is_signal(m
, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1414 const char *path
, *result
, *unit
;
1418 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1420 ret
= set_remove(d
->set
, (char*) path
);
1426 if (!isempty(result
))
1427 d
->result
= strdup(result
);
1430 d
->name
= strdup(unit
);
1435 r
= sd_bus_message_read(m
, "uos", &id
, &path
, &result
);
1437 ret
= set_remove(d
->set
, (char*) path
);
1444 d
->result
= strdup(result
);
1450 log_error("Failed to parse message.");
1456 static int enable_wait_for_jobs(sd_bus
*bus
) {
1461 r
= sd_bus_add_match(
1464 "sender='org.freedesktop.systemd1',"
1465 "interface='org.freedesktop.systemd1.Manager',"
1466 "member='JobRemoved',"
1467 "path='/org/freedesktop/systemd1'",
1470 log_error("Failed to add match");
1474 /* This is slightly dirty, since we don't undo the match registrations. */
1478 static int wait_for_jobs(sd_bus
*bus
, Set
*s
) {
1479 WaitData d
= { .set
= s
};
1485 r
= sd_bus_add_filter(bus
, wait_filter
, &d
);
1489 while (!set_isempty(s
)) {
1491 r
= sd_bus_process(bus
, NULL
);
1496 r
= sd_bus_wait(bus
, (uint64_t) -1);
1505 if (streq(d
.result
, "timeout"))
1506 log_error("Job for %s timed out.", strna(d
.name
));
1507 else if (streq(d
.result
, "canceled"))
1508 log_error("Job for %s canceled.", strna(d
.name
));
1509 else if (streq(d
.result
, "dependency"))
1510 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d
.name
));
1511 else if (!streq(d
.result
, "done") && !streq(d
.result
, "skipped"))
1512 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d
.name
), strna(d
.name
));
1515 if (streq_ptr(d
.result
, "timeout"))
1517 else if (streq_ptr(d
.result
, "canceled"))
1519 else if (!streq_ptr(d
.result
, "done") && !streq_ptr(d
.result
, "skipped"))
1530 return sd_bus_remove_filter(bus
, wait_filter
, &d
);
1533 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
1534 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1535 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
1541 n
= unit_name_mangle(name
);
1545 /* We don't use unit_dbus_path_from_name() directly since we
1546 * don't want to load the unit if it isn't loaded. */
1548 r
= sd_bus_call_method(
1550 "org.freedesktop.systemd1",
1551 "/org/freedesktop/systemd1",
1552 "org.freedesktop.systemd1.Manager",
1563 r
= sd_bus_message_read(reply
, "o", &path
);
1565 return bus_log_parse_error(r
);
1567 r
= sd_bus_get_property_string(
1569 "org.freedesktop.systemd1",
1571 "org.freedesktop.systemd1.Unit",
1584 return nulstr_contains(good_states
, state
);
1587 static int check_triggering_units(
1591 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1592 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
1593 _cleanup_strv_free_
char **triggered_by
= NULL
;
1594 bool print_warning_label
= true;
1598 n
= unit_name_mangle(name
);
1602 path
= unit_dbus_path_from_name(n
);
1606 r
= sd_bus_get_property_string(
1608 "org.freedesktop.systemd1",
1610 "org.freedesktop.systemd1.Unit",
1615 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
1619 if (streq(state
, "masked"))
1622 r
= sd_bus_get_property_strv(
1624 "org.freedesktop.systemd1",
1626 "org.freedesktop.systemd1.Unit",
1631 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
1635 STRV_FOREACH(i
, triggered_by
) {
1636 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
1638 log_error("Failed to check unit: %s", strerror(-r
));
1645 if (print_warning_label
) {
1646 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
1647 print_warning_label
= false;
1650 log_warning(" %s", *i
);
1656 static int start_unit_one(
1661 sd_bus_error
*error
,
1664 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1665 _cleanup_free_
char *n
;
1674 n
= unit_name_mangle(name
);
1678 r
= sd_bus_call_method(
1680 "org.freedesktop.systemd1",
1681 "/org/freedesktop/systemd1",
1682 "org.freedesktop.systemd1.Manager",
1688 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
1689 /* There's always a fallback possible for
1690 * legacy actions. */
1691 return -EADDRNOTAVAIL
;
1693 log_error("Failed to start %s: %s", name
, bus_error_message(error
, r
));
1697 r
= sd_bus_message_read(reply
, "o", &path
);
1699 return bus_log_parse_error(r
);
1701 if (need_daemon_reload(bus
, n
) > 0)
1702 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1703 n
, arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
1712 r
= set_consume(s
, p
);
1720 static const struct {
1724 } action_table
[_ACTION_MAX
] = {
1725 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
1726 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
1727 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
1728 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
1729 [ACTION_RUNLEVEL2
] = { SPECIAL_RUNLEVEL2_TARGET
, NULL
, "isolate" },
1730 [ACTION_RUNLEVEL3
] = { SPECIAL_RUNLEVEL3_TARGET
, NULL
, "isolate" },
1731 [ACTION_RUNLEVEL4
] = { SPECIAL_RUNLEVEL4_TARGET
, NULL
, "isolate" },
1732 [ACTION_RUNLEVEL5
] = { SPECIAL_RUNLEVEL5_TARGET
, NULL
, "isolate" },
1733 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
1734 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
1735 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
1736 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
1737 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
1738 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
1739 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
1742 static enum action
verb_to_action(const char *verb
) {
1745 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
1746 if (streq_ptr(action_table
[i
].verb
, verb
))
1749 return _ACTION_INVALID
;
1752 static int start_unit(sd_bus
*bus
, char **args
) {
1753 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1754 _cleanup_set_free_free_ Set
*s
= NULL
;
1755 const char *method
, *mode
, *one_name
;
1761 ask_password_agent_open_if_enabled();
1763 if (arg_action
== ACTION_SYSTEMCTL
) {
1766 streq(args
[0], "stop") ||
1767 streq(args
[0], "condstop") ? "StopUnit" :
1768 streq(args
[0], "reload") ? "ReloadUnit" :
1769 streq(args
[0], "restart") ? "RestartUnit" :
1771 streq(args
[0], "try-restart") ||
1772 streq(args
[0], "condrestart") ? "TryRestartUnit" :
1774 streq(args
[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1776 streq(args
[0], "reload-or-try-restart") ||
1777 streq(args
[0], "condreload") ||
1778 streq(args
[0], "force-reload") ? "ReloadOrTryRestartUnit" :
1780 action
= verb_to_action(args
[0]);
1782 mode
= streq(args
[0], "isolate") ? "isolate" :
1783 action_table
[action
].mode
?: arg_job_mode
;
1785 one_name
= action_table
[action
].target
;
1787 assert(arg_action
< ELEMENTSOF(action_table
));
1788 assert(action_table
[arg_action
].target
);
1790 method
= "StartUnit";
1792 mode
= action_table
[arg_action
].mode
;
1793 one_name
= action_table
[arg_action
].target
;
1796 if (!arg_no_block
) {
1797 r
= enable_wait_for_jobs(bus
);
1799 log_error("Could not watch jobs: %s", strerror(-r
));
1803 s
= set_new(string_hash_func
, string_compare_func
);
1809 r
= start_unit_one(bus
, method
, one_name
, mode
, &error
, s
);
1811 r
= translate_bus_error_to_exit_status(r
, &error
);
1815 STRV_FOREACH(name
, args
+1) {
1818 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, s
);
1820 r
= translate_bus_error_to_exit_status(r
, &error
);
1821 sd_bus_error_free(&error
);
1826 if (!arg_no_block
) {
1829 q
= wait_for_jobs(bus
, s
);
1833 /* When stopping units, warn if they can still be triggered by
1834 * another active unit (socket, path, timer) */
1835 if (!arg_quiet
&& streq(method
, "StopUnit")) {
1837 check_triggering_units(bus
, one_name
);
1839 STRV_FOREACH(name
, args
+1)
1840 check_triggering_units(bus
, *name
);
1847 /* Ask systemd-logind, which might grant access to unprivileged users
1848 * through PolicyKit */
1849 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
1851 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1858 polkit_agent_open_if_enabled();
1866 case ACTION_POWEROFF
:
1867 method
= "PowerOff";
1870 case ACTION_SUSPEND
:
1874 case ACTION_HIBERNATE
:
1875 method
= "Hibernate";
1878 case ACTION_HYBRID_SLEEP
:
1879 method
= "HybridSleep";
1886 r
= sd_bus_call_method(
1888 "org.freedesktop.login1",
1889 "/org/freedesktop/login1",
1890 "org.freedesktop.login1.Manager",
1896 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
1904 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
1906 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1907 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1908 _cleanup_strv_free_
char **sessions
= NULL
;
1909 const char *what
, *who
, *why
, *mode
;
1918 if (arg_ignore_inhibitors
|| arg_force
> 0)
1930 r
= sd_bus_call_method(
1932 "org.freedesktop.login1",
1933 "/org/freedesktop/login1",
1934 "org.freedesktop.login1.Manager",
1940 /* If logind is not around, then there are no inhibitors... */
1943 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
1945 return bus_log_parse_error(r
);
1947 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
1948 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
1949 _cleanup_strv_free_
char **sv
= NULL
;
1951 if (!streq(mode
, "block"))
1954 sv
= strv_split(what
, ":");
1958 if (!strv_contains(sv
,
1960 a
== ACTION_POWEROFF
||
1961 a
== ACTION_REBOOT
||
1962 a
== ACTION_KEXEC
? "shutdown" : "sleep"))
1965 get_process_comm(pid
, &comm
);
1966 user
= uid_to_name(uid
);
1968 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
1969 who
, (unsigned long) pid
, strna(comm
), strna(user
), why
);
1974 return bus_log_parse_error(r
);
1976 r
= sd_bus_message_exit_container(reply
);
1978 return bus_log_parse_error(r
);
1980 /* Check for current sessions */
1981 sd_get_sessions(&sessions
);
1982 STRV_FOREACH(s
, sessions
) {
1983 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
1985 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
1988 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
1991 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
1994 sd_session_get_tty(*s
, &tty
);
1995 sd_session_get_seat(*s
, &seat
);
1996 sd_session_get_service(*s
, &service
);
1997 user
= uid_to_name(uid
);
1999 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2006 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2007 action_table
[a
].verb
);
2015 static int start_special(sd_bus
*bus
, char **args
) {
2021 a
= verb_to_action(args
[0]);
2023 r
= check_inhibitors(bus
, a
);
2027 if (arg_force
>= 2 && geteuid() != 0) {
2028 log_error("Must be root.");
2032 if (arg_force
>= 2 &&
2033 (a
== ACTION_HALT
||
2034 a
== ACTION_POWEROFF
||
2035 a
== ACTION_REBOOT
))
2038 if (arg_force
>= 1 &&
2039 (a
== ACTION_HALT
||
2040 a
== ACTION_POWEROFF
||
2041 a
== ACTION_REBOOT
||
2042 a
== ACTION_KEXEC
||
2044 return daemon_reload(bus
, args
);
2046 /* first try logind, to allow authentication with polkit */
2047 if (geteuid() != 0 &&
2048 (a
== ACTION_POWEROFF
||
2049 a
== ACTION_REBOOT
||
2050 a
== ACTION_SUSPEND
||
2051 a
== ACTION_HIBERNATE
||
2052 a
== ACTION_HYBRID_SLEEP
)) {
2053 r
= reboot_with_logind(bus
, a
);
2058 r
= start_unit(bus
, args
);
2059 if (r
== EXIT_SUCCESS
)
2065 static int check_unit_active(sd_bus
*bus
, char **args
) {
2067 int r
= 3; /* According to LSB: "program is not running" */
2072 STRV_FOREACH(name
, args
+1) {
2075 state
= check_one_unit(bus
, *name
, "active\0reloading\0", arg_quiet
);
2085 static int check_unit_failed(sd_bus
*bus
, char **args
) {
2092 STRV_FOREACH(name
, args
+1) {
2095 state
= check_one_unit(bus
, *name
, "failed\0", arg_quiet
);
2105 static int kill_unit(sd_bus
*bus
, char **args
) {
2106 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2114 arg_kill_who
= "all";
2116 STRV_FOREACH(name
, args
+1) {
2117 _cleanup_free_
char *n
= NULL
;
2119 n
= unit_name_mangle(*name
);
2123 r
= sd_bus_call_method(
2125 "org.freedesktop.systemd1",
2126 "/org/freedesktop/systemd1",
2127 "org.freedesktop.systemd1.Manager",
2131 "ssi", n
, arg_kill_who
, arg_signal
);
2133 log_error("Failed to kill unit %s: %s", n
, bus_error_message(&error
, r
));
2141 typedef struct ExecStatusInfo
{
2149 usec_t start_timestamp
;
2150 usec_t exit_timestamp
;
2155 LIST_FIELDS(struct ExecStatusInfo
, exec
);
2158 static void exec_status_info_free(ExecStatusInfo
*i
) {
2167 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
2168 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
2171 int32_t code
, status
;
2177 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
2179 return bus_log_parse_error(r
);
2183 r
= sd_bus_message_read(m
, "s", &path
);
2185 return bus_log_parse_error(r
);
2187 i
->path
= strdup(path
);
2191 r
= sd_bus_message_read_strv(m
, &i
->argv
);
2193 return bus_log_parse_error(r
);
2195 r
= sd_bus_message_read(m
,
2198 &start_timestamp
, &start_timestamp_monotonic
,
2199 &exit_timestamp
, &exit_timestamp_monotonic
,
2203 return bus_log_parse_error(r
);
2206 i
->start_timestamp
= (usec_t
) start_timestamp
;
2207 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
2208 i
->pid
= (pid_t
) pid
;
2212 r
= sd_bus_message_exit_container(m
);
2214 return bus_log_parse_error(r
);
2219 typedef struct UnitStatusInfo
{
2221 const char *load_state
;
2222 const char *active_state
;
2223 const char *sub_state
;
2224 const char *unit_file_state
;
2226 const char *description
;
2227 const char *following
;
2229 char **documentation
;
2231 const char *fragment_path
;
2232 const char *source_path
;
2233 const char *control_group
;
2235 char **dropin_paths
;
2237 const char *load_error
;
2240 usec_t inactive_exit_timestamp
;
2241 usec_t inactive_exit_timestamp_monotonic
;
2242 usec_t active_enter_timestamp
;
2243 usec_t active_exit_timestamp
;
2244 usec_t inactive_enter_timestamp
;
2246 bool need_daemon_reload
;
2251 const char *status_text
;
2252 const char *pid_file
;
2255 usec_t start_timestamp
;
2256 usec_t exit_timestamp
;
2258 int exit_code
, exit_status
;
2260 usec_t condition_timestamp
;
2261 bool condition_result
;
2262 bool failed_condition_trigger
;
2263 bool failed_condition_negate
;
2264 const char *failed_condition
;
2265 const char *failed_condition_param
;
2268 unsigned n_accepted
;
2269 unsigned n_connections
;
2272 /* Pairs of type, path */
2276 const char *sysfs_path
;
2278 /* Mount, Automount */
2284 LIST_HEAD(ExecStatusInfo
, exec
);
2287 static void print_status_info(
2292 const char *on
, *off
, *ss
;
2294 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
2295 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
2298 arg_all
* OUTPUT_SHOW_ALL
|
2299 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
2300 on_tty() * OUTPUT_COLOR
|
2301 !arg_quiet
* OUTPUT_WARN_CUTOFF
|
2302 arg_full
* OUTPUT_FULL_WIDTH
;
2307 /* This shows pretty information about a unit. See
2308 * print_property() for a low-level property printer */
2310 printf("%s", strna(i
->id
));
2312 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
2313 printf(" - %s", i
->description
);
2318 printf(" Follow: unit currently follows state of %s\n", i
->following
);
2320 if (streq_ptr(i
->load_state
, "error")) {
2321 on
= ansi_highlight_red();
2322 off
= ansi_highlight_off();
2326 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
2329 printf(" Loaded: %s%s%s (Reason: %s)\n",
2330 on
, strna(i
->load_state
), off
, i
->load_error
);
2331 else if (path
&& i
->unit_file_state
)
2332 printf(" Loaded: %s%s%s (%s; %s)\n",
2333 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
2335 printf(" Loaded: %s%s%s (%s)\n",
2336 on
, strna(i
->load_state
), off
, path
);
2338 printf(" Loaded: %s%s%s\n",
2339 on
, strna(i
->load_state
), off
);
2341 if (!strv_isempty(i
->dropin_paths
)) {
2342 _cleanup_free_
char *dir
= NULL
;
2346 STRV_FOREACH(dropin
, i
->dropin_paths
) {
2347 if (! dir
|| last
) {
2348 printf(dir
? " " : " Drop-In: ");
2353 if (path_get_parent(*dropin
, &dir
) < 0) {
2358 printf("%s\n %s", dir
,
2359 draw_special_char(DRAW_TREE_RIGHT
));
2362 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
2364 printf("%s%s", path_get_file_name(*dropin
), last
? "\n" : ", ");
2368 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
2370 if (streq_ptr(i
->active_state
, "failed")) {
2371 on
= ansi_highlight_red();
2372 off
= ansi_highlight_off();
2373 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
2374 on
= ansi_highlight_green();
2375 off
= ansi_highlight_off();
2380 printf(" Active: %s%s (%s)%s",
2381 on
, strna(i
->active_state
), ss
, off
);
2383 printf(" Active: %s%s%s",
2384 on
, strna(i
->active_state
), off
);
2386 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
2387 printf(" (Result: %s)", i
->result
);
2389 timestamp
= (streq_ptr(i
->active_state
, "active") ||
2390 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
2391 (streq_ptr(i
->active_state
, "inactive") ||
2392 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
2393 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
2394 i
->active_exit_timestamp
;
2396 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
2397 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
2400 printf(" since %s; %s\n", s2
, s1
);
2402 printf(" since %s\n", s2
);
2406 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
2407 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
2408 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
2410 printf(" start condition failed at %s%s%s\n",
2411 s2
, s1
? "; " : "", s1
? s1
: "");
2412 if (i
->failed_condition_trigger
)
2413 printf(" none of the trigger conditions were met\n");
2414 else if (i
->failed_condition
)
2415 printf(" %s=%s%s was not met\n",
2416 i
->failed_condition
,
2417 i
->failed_condition_negate
? "!" : "",
2418 i
->failed_condition_param
);
2422 printf(" Device: %s\n", i
->sysfs_path
);
2424 printf(" Where: %s\n", i
->where
);
2426 printf(" What: %s\n", i
->what
);
2428 STRV_FOREACH(t
, i
->documentation
)
2429 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
2431 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
2432 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
2435 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
2437 LIST_FOREACH(exec
, p
, i
->exec
) {
2438 _cleanup_free_
char *argv
= NULL
;
2441 /* Only show exited processes here */
2445 argv
= strv_join(p
->argv
, " ");
2446 printf(" Process: %u %s=%s ", p
->pid
, p
->name
, strna(argv
));
2448 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
2450 on
= ansi_highlight_red();
2451 off
= ansi_highlight_off();
2455 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
2457 if (p
->code
== CLD_EXITED
) {
2460 printf("status=%i", p
->status
);
2462 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
2467 printf("signal=%s", signal_to_string(p
->status
));
2469 printf(")%s\n", off
);
2471 if (i
->main_pid
== p
->pid
&&
2472 i
->start_timestamp
== p
->start_timestamp
&&
2473 i
->exit_timestamp
== p
->start_timestamp
)
2474 /* Let's not show this twice */
2477 if (p
->pid
== i
->control_pid
)
2481 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
2482 if (i
->main_pid
> 0) {
2483 printf(" Main PID: %u", (unsigned) i
->main_pid
);
2486 _cleanup_free_
char *comm
= NULL
;
2487 get_process_comm(i
->main_pid
, &comm
);
2489 printf(" (%s)", comm
);
2490 } else if (i
->exit_code
> 0) {
2491 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
2493 if (i
->exit_code
== CLD_EXITED
) {
2496 printf("status=%i", i
->exit_status
);
2498 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
2503 printf("signal=%s", signal_to_string(i
->exit_status
));
2507 if (i
->control_pid
> 0)
2511 if (i
->control_pid
> 0) {
2512 _cleanup_free_
char *c
= NULL
;
2514 printf(" %8s: %u", i
->main_pid
? "" : " Control", (unsigned) i
->control_pid
);
2516 get_process_comm(i
->control_pid
, &c
);
2525 printf(" Status: \"%s\"\n", i
->status_text
);
2527 if (i
->control_group
&&
2528 (i
->main_pid
> 0 || i
->control_pid
> 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, false) == 0)) {
2531 printf(" CGroup: %s\n", i
->control_group
);
2533 if (arg_transport
== BUS_TRANSPORT_LOCAL
|| arg_transport
== BUS_TRANSPORT_CONTAINER
) {
2536 char prefix
[] = " ";
2539 if (c
> sizeof(prefix
) - 1)
2540 c
-= sizeof(prefix
) - 1;
2544 if (i
->main_pid
> 0)
2545 extra
[k
++] = i
->main_pid
;
2547 if (i
->control_pid
> 0)
2548 extra
[k
++] = i
->control_pid
;
2550 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
,
2551 c
, false, extra
, k
, flags
);
2555 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
) {
2557 show_journal_by_unit(stdout
,
2561 i
->inactive_exit_timestamp_monotonic
,
2565 arg_scope
== UNIT_FILE_SYSTEM
,
2569 if (i
->need_daemon_reload
)
2570 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2571 ansi_highlight_red(),
2572 ansi_highlight_off(),
2573 arg_scope
== UNIT_FILE_SYSTEM
? "" : "--user ");
2576 static void show_unit_help(UnitStatusInfo
*i
) {
2581 if (!i
->documentation
) {
2582 log_info("Documentation for %s not known.", i
->id
);
2586 STRV_FOREACH(p
, i
->documentation
) {
2588 if (startswith(*p
, "man:")) {
2589 const char *args
[4] = { "man", NULL
, NULL
, NULL
};
2590 _cleanup_free_
char *page
= NULL
, *section
= NULL
;
2597 if ((*p
)[k
-1] == ')')
2598 e
= strrchr(*p
, '(');
2601 page
= strndup((*p
) + 4, e
- *p
- 4);
2602 section
= strndup(e
+ 1, *p
+ k
- e
- 2);
2603 if (!page
|| !section
) {
2615 log_error("Failed to fork: %m");
2621 execvp(args
[0], (char**) args
);
2622 log_error("Failed to execute man: %m");
2623 _exit(EXIT_FAILURE
);
2626 wait_for_terminate(pid
, NULL
);
2628 log_info("Can't show: %s", *p
);
2632 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
2639 switch (contents
[0]) {
2641 case SD_BUS_TYPE_STRING
: {
2644 r
= sd_bus_message_read(m
, "s", &s
);
2646 return bus_log_parse_error(r
);
2649 if (streq(name
, "Id"))
2651 else if (streq(name
, "LoadState"))
2653 else if (streq(name
, "ActiveState"))
2654 i
->active_state
= s
;
2655 else if (streq(name
, "SubState"))
2657 else if (streq(name
, "Description"))
2659 else if (streq(name
, "FragmentPath"))
2660 i
->fragment_path
= s
;
2661 else if (streq(name
, "SourcePath"))
2664 else if (streq(name
, "DefaultControlGroup")) {
2666 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
2668 i
->control_group
= e
;
2671 else if (streq(name
, "ControlGroup"))
2672 i
->control_group
= s
;
2673 else if (streq(name
, "StatusText"))
2675 else if (streq(name
, "PIDFile"))
2677 else if (streq(name
, "SysFSPath"))
2679 else if (streq(name
, "Where"))
2681 else if (streq(name
, "What"))
2683 else if (streq(name
, "Following"))
2685 else if (streq(name
, "UnitFileState"))
2686 i
->unit_file_state
= s
;
2687 else if (streq(name
, "Result"))
2694 case SD_BUS_TYPE_BOOLEAN
: {
2697 r
= sd_bus_message_read(m
, "b", &b
);
2699 return bus_log_parse_error(r
);
2701 if (streq(name
, "Accept"))
2703 else if (streq(name
, "NeedDaemonReload"))
2704 i
->need_daemon_reload
= b
;
2705 else if (streq(name
, "ConditionResult"))
2706 i
->condition_result
= b
;
2711 case SD_BUS_TYPE_UINT32
: {
2714 r
= sd_bus_message_read(m
, "u", &u
);
2716 return bus_log_parse_error(r
);
2718 if (streq(name
, "MainPID")) {
2720 i
->main_pid
= (pid_t
) u
;
2723 } else if (streq(name
, "ControlPID"))
2724 i
->control_pid
= (pid_t
) u
;
2725 else if (streq(name
, "ExecMainPID")) {
2727 i
->main_pid
= (pid_t
) u
;
2728 } else if (streq(name
, "NAccepted"))
2730 else if (streq(name
, "NConnections"))
2731 i
->n_connections
= u
;
2736 case SD_BUS_TYPE_INT32
: {
2739 r
= sd_bus_message_read(m
, "i", &j
);
2741 return bus_log_parse_error(r
);
2743 if (streq(name
, "ExecMainCode"))
2744 i
->exit_code
= (int) j
;
2745 else if (streq(name
, "ExecMainStatus"))
2746 i
->exit_status
= (int) j
;
2751 case SD_BUS_TYPE_UINT64
: {
2754 r
= sd_bus_message_read(m
, "t", &u
);
2756 return bus_log_parse_error(r
);
2758 if (streq(name
, "ExecMainStartTimestamp"))
2759 i
->start_timestamp
= (usec_t
) u
;
2760 else if (streq(name
, "ExecMainExitTimestamp"))
2761 i
->exit_timestamp
= (usec_t
) u
;
2762 else if (streq(name
, "ActiveEnterTimestamp"))
2763 i
->active_enter_timestamp
= (usec_t
) u
;
2764 else if (streq(name
, "InactiveEnterTimestamp"))
2765 i
->inactive_enter_timestamp
= (usec_t
) u
;
2766 else if (streq(name
, "InactiveExitTimestamp"))
2767 i
->inactive_exit_timestamp
= (usec_t
) u
;
2768 else if (streq(name
, "InactiveExitTimestampMonotonic"))
2769 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
2770 else if (streq(name
, "ActiveExitTimestamp"))
2771 i
->active_exit_timestamp
= (usec_t
) u
;
2772 else if (streq(name
, "ConditionTimestamp"))
2773 i
->condition_timestamp
= (usec_t
) u
;
2778 case SD_BUS_TYPE_ARRAY
:
2780 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
2781 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
2783 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
2785 return bus_log_parse_error(r
);
2787 info
= new0(ExecStatusInfo
, 1);
2791 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
2793 info
->name
= strdup(name
);
2797 LIST_PREPEND(exec
, i
->exec
, info
);
2799 info
= new0(ExecStatusInfo
, 1);
2805 return bus_log_parse_error(r
);
2807 r
= sd_bus_message_exit_container(m
);
2809 return bus_log_parse_error(r
);
2813 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
2814 const char *type
, *path
;
2816 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
2818 return bus_log_parse_error(r
);
2820 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
2822 r
= strv_extend(&i
->listen
, type
);
2826 r
= strv_extend(&i
->listen
, path
);
2831 return bus_log_parse_error(r
);
2833 r
= sd_bus_message_exit_container(m
);
2835 return bus_log_parse_error(r
);
2839 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
2841 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
2843 return bus_log_parse_error(r
);
2845 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
2847 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
2849 return bus_log_parse_error(r
);
2851 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
2852 const char *cond
, *param
;
2853 int trigger
, negate
;
2856 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
2858 return bus_log_parse_error(r
);
2860 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
2861 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
2862 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
2863 i
->failed_condition
= cond
;
2864 i
->failed_condition_trigger
= trigger
;
2865 i
->failed_condition_negate
= negate
;
2866 i
->failed_condition_param
= param
;
2870 return bus_log_parse_error(r
);
2872 r
= sd_bus_message_exit_container(m
);
2874 return bus_log_parse_error(r
);
2881 case SD_BUS_TYPE_STRUCT_BEGIN
:
2883 if (streq(name
, "LoadError")) {
2884 const char *n
, *message
;
2886 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
2888 return bus_log_parse_error(r
);
2890 if (!isempty(message
))
2891 i
->load_error
= message
;
2904 r
= sd_bus_message_skip(m
, contents
);
2906 return bus_log_parse_error(r
);
2911 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
2917 /* This is a low-level property printer, see
2918 * print_status_info() for the nicer output */
2920 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
2921 /* skip what we didn't read */
2922 r
= sd_bus_message_skip(m
, contents
);
2926 switch (contents
[0]) {
2928 case SD_BUS_TYPE_STRUCT_BEGIN
:
2930 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
2933 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
2935 return bus_log_parse_error(r
);
2938 printf("%s=%u\n", name
, (unsigned) u
);
2940 printf("%s=\n", name
);
2944 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
2947 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
2949 return bus_log_parse_error(r
);
2951 if (arg_all
|| !isempty(s
))
2952 printf("%s=%s\n", name
, s
);
2956 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
2957 const char *a
= NULL
, *b
= NULL
;
2959 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
2961 return bus_log_parse_error(r
);
2963 if (arg_all
|| !isempty(a
) || !isempty(b
))
2964 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
2971 case SD_BUS_TYPE_ARRAY
:
2973 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
2977 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
2979 return bus_log_parse_error(r
);
2981 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
2982 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
2985 return bus_log_parse_error(r
);
2987 r
= sd_bus_message_exit_container(m
);
2989 return bus_log_parse_error(r
);
2993 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
2994 const char *type
, *path
;
2996 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
2998 return bus_log_parse_error(r
);
3000 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3001 printf("%s=%s\n", type
, path
);
3003 return bus_log_parse_error(r
);
3005 r
= sd_bus_message_exit_container(m
);
3007 return bus_log_parse_error(r
);
3011 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3012 const char *type
, *path
;
3014 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3016 return bus_log_parse_error(r
);
3018 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3019 printf("Listen%s=%s\n", type
, path
);
3021 return bus_log_parse_error(r
);
3023 r
= sd_bus_message_exit_container(m
);
3025 return bus_log_parse_error(r
);
3029 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
3031 uint64_t value
, next_elapse
;
3033 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
3035 return bus_log_parse_error(r
);
3037 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
3038 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
3040 printf("%s={ value=%s ; next_elapse=%s }\n",
3042 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
3043 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
3046 return bus_log_parse_error(r
);
3048 r
= sd_bus_message_exit_container(m
);
3050 return bus_log_parse_error(r
);
3054 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3055 ExecStatusInfo info
= {};
3057 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3059 return bus_log_parse_error(r
);
3061 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
3062 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
3063 _cleanup_free_
char *tt
;
3065 tt
= strv_join(info
.argv
, " ");
3067 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3071 yes_no(info
.ignore
),
3072 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
3073 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
3074 (unsigned) info
. pid
,
3075 sigchld_code_to_string(info
.code
),
3077 info
.code
== CLD_EXITED
? "" : "/",
3078 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
3081 strv_free(info
.argv
);
3085 r
= sd_bus_message_exit_container(m
);
3087 return bus_log_parse_error(r
);
3091 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
3092 const char *path
, *rwm
;
3094 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3096 return bus_log_parse_error(r
);
3098 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
3099 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
3101 return bus_log_parse_error(r
);
3103 r
= sd_bus_message_exit_container(m
);
3105 return bus_log_parse_error(r
);
3109 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
3113 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3115 return bus_log_parse_error(r
);
3117 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
3118 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
3120 return bus_log_parse_error(r
);
3122 r
= sd_bus_message_exit_container(m
);
3124 return bus_log_parse_error(r
);
3128 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
3132 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3134 return bus_log_parse_error(r
);
3136 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
3137 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
3139 return bus_log_parse_error(r
);
3141 r
= sd_bus_message_exit_container(m
);
3143 return bus_log_parse_error(r
);
3151 r
= bus_print_property(name
, m
, arg_all
);
3153 return bus_log_parse_error(r
);
3156 r
= sd_bus_message_skip(m
, contents
);
3158 return bus_log_parse_error(r
);
3161 printf("%s=[unprintable]\n", name
);
3167 static int show_one(
3171 bool show_properties
,
3175 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3176 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3177 UnitStatusInfo info
= {};
3184 r
= sd_bus_call_method(
3186 "org.freedesktop.systemd1",
3188 "org.freedesktop.DBus.Properties",
3194 log_error("Failed to get properties: %s", bus_error_message(&error
, r
));
3198 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
3200 return bus_log_parse_error(r
);
3207 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
3208 const char *name
, *contents
;
3210 r
= sd_bus_message_read(reply
, "s", &name
);
3212 return bus_log_parse_error(r
);
3214 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
3216 return bus_log_parse_error(r
);
3218 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
3220 return bus_log_parse_error(r
);
3222 if (show_properties
)
3223 r
= print_property(name
, reply
, contents
);
3225 r
= status_property(name
, reply
, &info
, contents
);
3229 r
= sd_bus_message_exit_container(reply
);
3231 return bus_log_parse_error(r
);
3233 r
= sd_bus_message_exit_container(reply
);
3235 return bus_log_parse_error(r
);
3238 return bus_log_parse_error(r
);
3240 r
= sd_bus_message_exit_container(reply
);
3242 return bus_log_parse_error(r
);
3246 if (!show_properties
) {
3247 if (streq(verb
, "help"))
3248 show_unit_help(&info
);
3250 print_status_info(&info
, ellipsized
);
3253 strv_free(info
.documentation
);
3254 strv_free(info
.dropin_paths
);
3255 strv_free(info
.listen
);
3257 if (!streq_ptr(info
.active_state
, "active") &&
3258 !streq_ptr(info
.active_state
, "reloading") &&
3259 streq(verb
, "status")) {
3260 /* According to LSB: "program not running" */
3261 /* 0: program is running or service is OK
3262 * 1: program is dead and /var/run pid file exists
3263 * 2: program is dead and /var/lock lock file exists
3264 * 3: program is not running
3265 * 4: program or service status is unknown
3267 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
3273 while ((p
= info
.exec
)) {
3274 LIST_REMOVE(exec
, info
.exec
, p
);
3275 exec_status_info_free(p
);
3281 static int show_one_by_pid(
3288 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3289 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3290 const char *path
= NULL
;
3293 r
= sd_bus_call_method(
3295 "org.freedesktop.systemd1",
3296 "/org/freedesktop/systemd1",
3297 "org.freedesktop.systemd1.Manager",
3303 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid
, bus_error_message(&error
, r
));
3307 r
= sd_bus_message_read(reply
, "o", &path
);
3309 return bus_log_parse_error(r
);
3311 return show_one(verb
, bus
, path
, false, new_line
, ellipsized
);
3314 static int show_all(
3317 bool show_properties
,
3321 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3322 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3323 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3328 r
= get_unit_list(bus
, &reply
, &unit_infos
);
3334 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
3336 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
3337 _cleanup_free_
char *p
= NULL
;
3339 if (!output_show_unit(u
))
3342 p
= unit_dbus_path_from_name(u
->id
);
3346 printf("%s -> '%s'\n", u
->id
, p
);
3348 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
3356 static int show(sd_bus
*bus
, char **args
) {
3358 bool show_properties
, show_status
, new_line
= false;
3360 bool ellipsized
= false;
3365 show_properties
= streq(args
[0], "show");
3366 show_status
= streq(args
[0], "status");
3368 if (show_properties
)
3369 pager_open_if_enabled();
3371 /* If no argument is specified inspect the manager itself */
3373 if (show_properties
&& strv_length(args
) <= 1)
3374 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
3376 if (show_status
&& strv_length(args
) <= 1)
3377 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
3379 STRV_FOREACH(name
, args
+1) {
3382 if (safe_atou32(*name
, &id
) < 0) {
3383 _cleanup_free_
char *p
= NULL
, *n
= NULL
;
3384 /* Interpret as unit name */
3386 n
= unit_name_mangle(*name
);
3390 p
= unit_dbus_path_from_name(n
);
3394 r
= show_one(args
[0], bus
, p
, show_properties
, &new_line
, &ellipsized
);
3398 } else if (show_properties
) {
3399 _cleanup_free_
char *p
= NULL
;
3401 /* Interpret as job id */
3402 if (asprintf(&p
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
3405 r
= show_one(args
[0], bus
, p
, show_properties
, &new_line
, &ellipsized
);
3410 /* Interpret as PID */
3411 r
= show_one_by_pid(args
[0], bus
, id
, &new_line
, &ellipsized
);
3417 if (ellipsized
&& !arg_quiet
)
3418 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3423 static int append_assignment(sd_bus_message
*m
, const char *assignment
) {
3431 eq
= strchr(assignment
, '=');
3433 log_error("Not an assignment: %s", assignment
);
3437 field
= strndupa(assignment
, eq
- assignment
);
3440 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, field
);
3442 return bus_log_create_error(r
);
3444 if (streq(field
, "CPUAccounting") ||
3445 streq(field
, "MemoryAccounting") ||
3446 streq(field
, "BlockIOAccounting")) {
3448 r
= parse_boolean(eq
);
3450 log_error("Failed to parse boolean assignment %s.", assignment
);
3454 r
= sd_bus_message_append(m
, "v", "b", r
);
3456 } else if (streq(field
, "MemoryLimit")) {
3459 r
= parse_bytes(eq
, &bytes
);
3461 log_error("Failed to parse bytes specification %s", assignment
);
3465 r
= sd_bus_message_append(m
, "v", "t", (uint64_t) bytes
);
3467 } else if (streq(field
, "CPUShares") || streq(field
, "BlockIOWeight")) {
3470 r
= safe_atou64(eq
, &u
);
3472 log_error("Failed to parse %s value %s.", field
, eq
);
3476 r
= sd_bus_message_append(m
, "v", "t", u
);
3478 } else if (streq(field
, "DevicePolicy"))
3479 r
= sd_bus_message_append(m
, "v", "s", eq
);
3481 else if (streq(field
, "DeviceAllow")) {
3484 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
3486 const char *path
, *rwm
;
3489 e
= strchr(eq
, ' ');
3491 path
= strndupa(eq
, e
- eq
);
3498 if (!path_startswith(path
, "/dev")) {
3499 log_error("%s is not a device file in /dev.", path
);
3503 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
3506 } else if (streq(field
, "BlockIOReadBandwidth") || streq(field
, "BlockIOWriteBandwidth")) {
3509 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
3511 const char *path
, *bandwidth
;
3515 e
= strchr(eq
, ' ');
3517 path
= strndupa(eq
, e
- eq
);
3520 log_error("Failed to parse %s value %s.", field
, eq
);
3524 if (!path_startswith(path
, "/dev")) {
3525 log_error("%s is not a device file in /dev.", path
);
3529 r
= parse_bytes(bandwidth
, &bytes
);
3531 log_error("Failed to parse byte value %s.", bandwidth
);
3535 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, (uint64_t) bytes
);
3538 } else if (streq(field
, "BlockIODeviceWeight")) {
3541 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
3543 const char *path
, *weight
;
3547 e
= strchr(eq
, ' ');
3549 path
= strndupa(eq
, e
- eq
);
3552 log_error("Failed to parse %s value %s.", field
, eq
);
3556 if (!path_startswith(path
, "/dev")) {
3557 log_error("%s is not a device file in /dev.", path
);
3561 r
= safe_atou64(weight
, &u
);
3563 log_error("Failed to parse %s value %s.", field
, weight
);
3566 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
3570 log_error("Unknown assignment %s.", assignment
);
3575 return bus_log_create_error(r
);
3580 static int set_property(sd_bus
*bus
, char **args
) {
3581 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
3582 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3583 _cleanup_free_
char *n
= NULL
;
3587 r
= sd_bus_message_new_method_call(
3589 "org.freedesktop.systemd1",
3590 "/org/freedesktop/systemd1",
3591 "org.freedesktop.systemd1.Manager",
3592 "SetUnitProperties",
3595 return bus_log_create_error(r
);
3597 n
= unit_name_mangle(args
[1]);
3601 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
3603 return bus_log_create_error(r
);
3605 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
3607 return bus_log_create_error(r
);
3609 STRV_FOREACH(i
, args
+ 2) {
3610 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
3612 return bus_log_create_error(r
);
3614 r
= append_assignment(m
, *i
);
3618 r
= sd_bus_message_close_container(m
);
3620 return bus_log_create_error(r
);
3623 r
= sd_bus_message_close_container(m
);
3625 return bus_log_create_error(r
);
3627 r
= sd_bus_send_with_reply_and_block(bus
, m
, -1, &error
, NULL
);
3629 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
3636 static int snapshot(sd_bus
*bus
, char **args
) {
3637 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3638 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3639 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
3643 if (strv_length(args
) > 1)
3644 n
= unit_name_mangle_with_suffix(args
[1], ".snapshot");
3650 r
= sd_bus_call_method(
3652 "org.freedesktop.systemd1",
3653 "/org/freedesktop/systemd1",
3654 "org.freedesktop.systemd1.Manager",
3660 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
3664 r
= sd_bus_message_read(reply
, "o", &path
);
3666 return bus_log_parse_error(r
);
3668 r
= sd_bus_get_property_string(
3670 "org.freedesktop.systemd1",
3672 "org.freedesktop.systemd1.Unit",
3677 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
3687 static int delete_snapshot(sd_bus
*bus
, char **args
) {
3688 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3694 STRV_FOREACH(name
, args
+1) {
3695 _cleanup_free_
char *n
= NULL
;
3697 n
= unit_name_mangle_with_suffix(*name
, ".snapshot");
3701 r
= sd_bus_call_method(
3703 "org.freedesktop.systemd1",
3704 "/org/freedesktop/systemd1",
3705 "org.freedesktop.systemd1.Manager",
3711 log_error("Failed to remove snapshot %s: %s", n
, bus_error_message(&error
, r
));
3719 static int daemon_reload(sd_bus
*bus
, char **args
) {
3720 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3724 if (arg_action
== ACTION_RELOAD
)
3726 else if (arg_action
== ACTION_REEXEC
)
3727 method
= "Reexecute";
3729 assert(arg_action
== ACTION_SYSTEMCTL
);
3732 streq(args
[0], "clear-jobs") ||
3733 streq(args
[0], "cancel") ? "ClearJobs" :
3734 streq(args
[0], "daemon-reexec") ? "Reexecute" :
3735 streq(args
[0], "reset-failed") ? "ResetFailed" :
3736 streq(args
[0], "halt") ? "Halt" :
3737 streq(args
[0], "poweroff") ? "PowerOff" :
3738 streq(args
[0], "reboot") ? "Reboot" :
3739 streq(args
[0], "kexec") ? "KExec" :
3740 streq(args
[0], "exit") ? "Exit" :
3741 /* "daemon-reload" */ "Reload";
3744 r
= sd_bus_call_method(
3746 "org.freedesktop.systemd1",
3747 "/org/freedesktop/systemd1",
3748 "org.freedesktop.systemd1.Manager",
3754 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
3755 /* There's always a fallback possible for
3756 * legacy actions. */
3758 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
3759 /* On reexecution, we expect a disconnect, not a
3763 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
3765 return r
< 0 ? r
: 0;
3768 static int reset_failed(sd_bus
*bus
, char **args
) {
3769 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3773 if (strv_length(args
) <= 1)
3774 return daemon_reload(bus
, args
);
3776 STRV_FOREACH(name
, args
+1) {
3777 _cleanup_free_
char *n
;
3779 n
= unit_name_mangle(*name
);
3783 r
= sd_bus_call_method(
3785 "org.freedesktop.systemd1",
3786 "/org/freedesktop/systemd1",
3787 "org.freedesktop.systemd1.Manager",
3793 log_error("Failed to reset failed state of unit %s: %s", n
, bus_error_message(&error
, r
));
3801 static int show_environment(sd_bus
*bus
, char **args
) {
3802 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3803 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3807 pager_open_if_enabled();
3809 r
= sd_bus_get_property(
3811 "org.freedesktop.systemd1",
3812 "/org/freedesktop/systemd1",
3813 "org.freedesktop.systemd1.Manager",
3819 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
3823 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
3825 return bus_log_parse_error(r
);
3827 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
3830 return bus_log_parse_error(r
);
3832 r
= sd_bus_message_exit_container(reply
);
3834 return bus_log_parse_error(r
);
3839 static int switch_root(sd_bus
*bus
, char **args
) {
3840 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3841 _cleanup_free_
char *init
= NULL
;
3846 l
= strv_length(args
);
3847 if (l
< 2 || l
> 3) {
3848 log_error("Wrong number of arguments.");
3855 init
= strdup(args
[2]);
3857 parse_env_file("/proc/cmdline", WHITESPACE
,
3868 log_debug("switching root - root: %s; init: %s", root
, init
);
3870 r
= sd_bus_call_method(
3872 "org.freedesktop.systemd1",
3873 "/org/freedesktop/systemd1",
3874 "org.freedesktop.systemd1.Manager",
3880 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
3887 static int set_environment(sd_bus
*bus
, char **args
) {
3888 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3889 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
3896 method
= streq(args
[0], "set-environment")
3898 : "UnsetEnvironment";
3900 r
= sd_bus_message_new_method_call(
3902 "org.freedesktop.systemd1",
3903 "/org/freedesktop/systemd1",
3904 "org.freedesktop.systemd1.Manager",
3908 return bus_log_create_error(r
);
3910 r
= sd_bus_message_append_strv(m
, args
+ 1);
3912 return bus_log_create_error(r
);
3914 r
= sd_bus_send_with_reply_and_block(bus
, m
, -1, &error
, NULL
);
3916 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
3923 static int enable_sysv_units(const char *verb
, char **args
) {
3926 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
3927 unsigned f
= 1, t
= 1;
3928 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
3930 if (arg_scope
!= UNIT_FILE_SYSTEM
)
3933 if (!streq(verb
, "enable") &&
3934 !streq(verb
, "disable") &&
3935 !streq(verb
, "is-enabled"))
3938 /* Processes all SysV units, and reshuffles the array so that
3939 * afterwards only the native units remain */
3941 r
= lookup_paths_init(&paths
, SYSTEMD_SYSTEM
, false, NULL
, NULL
, NULL
);
3946 for (f
= 0; args
[f
]; f
++) {
3948 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
3949 bool found_native
= false, found_sysv
;
3951 const char *argv
[6] = { "/sbin/chkconfig", NULL
, NULL
, NULL
, NULL
};
3959 if (!endswith(name
, ".service"))
3962 if (path_is_absolute(name
))
3965 STRV_FOREACH(k
, paths
.unit_path
) {
3966 if (!isempty(arg_root
))
3967 asprintf(&p
, "%s/%s/%s", arg_root
, *k
, name
);
3969 asprintf(&p
, "%s/%s", *k
, name
);
3976 found_native
= access(p
, F_OK
) >= 0;
3987 if (!isempty(arg_root
))
3988 asprintf(&p
, "%s/" SYSTEM_SYSVINIT_PATH
"/%s", arg_root
, name
);
3990 asprintf(&p
, SYSTEM_SYSVINIT_PATH
"/%s", name
);
3996 p
[strlen(p
) - sizeof(".service") + 1] = 0;
3997 found_sysv
= access(p
, F_OK
) >= 0;
4002 /* Mark this entry, so that we don't try enabling it as native unit */
4003 args
[f
] = (char*) "";
4005 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name
);
4007 if (!isempty(arg_root
))
4008 argv
[c
++] = q
= strappend("--root=", arg_root
);
4010 argv
[c
++] = path_get_file_name(p
);
4012 streq(verb
, "enable") ? "on" :
4013 streq(verb
, "disable") ? "off" : "--level=5";
4016 l
= strv_join((char**)argv
, " ");
4022 log_info("Executing %s", l
);
4027 log_error("Failed to fork: %m");
4030 } else if (pid
== 0) {
4033 execv(argv
[0], (char**) argv
);
4034 _exit(EXIT_FAILURE
);
4037 j
= wait_for_terminate(pid
, &status
);
4039 log_error("Failed to wait for child: %s", strerror(-r
));
4044 if (status
.si_code
== CLD_EXITED
) {
4045 if (streq(verb
, "is-enabled")) {
4046 if (status
.si_status
== 0) {
4055 } else if (status
.si_status
!= 0) {
4066 /* Drop all SysV units */
4067 for (f
= 0, t
= 0; args
[f
]; f
++) {
4069 if (isempty(args
[f
]))
4072 args
[t
++] = args
[f
];
4081 static int mangle_names(char **original_names
, char ***mangled_names
) {
4082 char **i
, **l
, **name
;
4084 l
= new(char*, strv_length(original_names
) + 1);
4089 STRV_FOREACH(name
, original_names
) {
4091 /* When enabling units qualified path names are OK,
4092 * too, hence allow them explicitly. */
4097 *i
= unit_name_mangle(*name
);
4113 static int enable_unit(sd_bus
*bus
, char **args
) {
4114 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
4115 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4116 _cleanup_strv_free_
char **mangled_names
= NULL
;
4117 const char *verb
= args
[0];
4118 UnitFileChange
*changes
= NULL
;
4119 unsigned n_changes
= 0, i
;
4120 int carries_install_info
= -1;
4126 r
= mangle_names(args
+1, &mangled_names
);
4130 r
= enable_sysv_units(verb
, mangled_names
);
4134 if (!bus
|| avoid_bus()) {
4135 if (streq(verb
, "enable")) {
4136 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4137 carries_install_info
= r
;
4138 } else if (streq(verb
, "disable"))
4139 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, &changes
, &n_changes
);
4140 else if (streq(verb
, "reenable")) {
4141 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4142 carries_install_info
= r
;
4143 } else if (streq(verb
, "link"))
4144 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4145 else if (streq(verb
, "preset")) {
4146 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4147 carries_install_info
= r
;
4148 } else if (streq(verb
, "mask"))
4149 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4150 else if (streq(verb
, "unmask"))
4151 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, mangled_names
, &changes
, &n_changes
);
4152 else if (streq(verb
, "set-default"))
4153 r
= unit_file_set_default(arg_scope
, arg_root
, args
[1], &changes
, &n_changes
);
4155 assert_not_reached("Unknown verb");
4158 log_error("Operation failed: %s", strerror(-r
));
4163 for (i
= 0; i
< n_changes
; i
++) {
4164 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
4165 log_info("ln -s '%s' '%s'", changes
[i
].source
, changes
[i
].path
);
4167 log_info("rm '%s'", changes
[i
].path
);
4173 const char *method
, *type
, *path
, *source
;
4174 int expect_carries_install_info
= false;
4175 bool send_force
= true;
4177 if (streq(verb
, "enable")) {
4178 method
= "EnableUnitFiles";
4179 expect_carries_install_info
= true;
4180 } else if (streq(verb
, "disable")) {
4181 method
= "DisableUnitFiles";
4183 } else if (streq(verb
, "reenable")) {
4184 method
= "ReenableUnitFiles";
4185 expect_carries_install_info
= true;
4186 } else if (streq(verb
, "link"))
4187 method
= "LinkUnitFiles";
4188 else if (streq(verb
, "preset")) {
4189 method
= "PresetUnitFiles";
4190 expect_carries_install_info
= true;
4191 } else if (streq(verb
, "mask"))
4192 method
= "MaskUnitFiles";
4193 else if (streq(verb
, "unmask")) {
4194 method
= "UnmaskUnitFiles";
4196 } else if (streq(verb
, "set-default")) {
4197 method
= "SetDefaultTarget";
4199 assert_not_reached("Unknown verb");
4201 r
= sd_bus_message_new_method_call(
4203 "org.freedesktop.systemd1",
4204 "/org/freedesktop/systemd1",
4205 "org.freedesktop.systemd1.Manager",
4209 return bus_log_create_error(r
);
4211 r
= sd_bus_message_append_strv(m
, mangled_names
);
4213 return bus_log_create_error(r
);
4215 r
= sd_bus_message_append(m
, "b", arg_runtime
);
4217 return bus_log_create_error(r
);
4220 r
= sd_bus_message_append(m
, "b", arg_force
);
4222 return bus_log_create_error(r
);
4225 r
= sd_bus_send_with_reply_and_block(bus
, m
, -0, &error
, &reply
);
4227 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4231 if (expect_carries_install_info
) {
4232 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
4234 return bus_log_parse_error(r
);
4237 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(sss)");
4239 return bus_log_parse_error(r
);
4241 while ((r
= sd_bus_message_read(reply
, "(sss)", &type
, &path
, &source
)) > 0) {
4243 if (streq(type
, "symlink"))
4244 log_info("ln -s '%s' '%s'", source
, path
);
4246 log_info("rm '%s'", path
);
4250 return bus_log_parse_error(r
);
4252 r
= sd_bus_message_exit_container(reply
);
4254 return bus_log_parse_error(r
);
4256 /* Try to reload if enabeld */
4258 r
= daemon_reload(bus
, args
);
4263 if (carries_install_info
== 0)
4264 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4265 "using systemctl.\n"
4266 "Possible reasons for having this kind of units are:\n"
4267 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4268 " .wants/ or .requires/ directory.\n"
4269 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4270 " a requirement dependency on it.\n"
4271 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4272 " D-Bus, udev, scripted systemctl call, ...).\n");
4275 unit_file_changes_free(changes
, n_changes
);
4280 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
4282 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4283 _cleanup_strv_free_
char **mangled_names
= NULL
;
4288 r
= mangle_names(args
+1, &mangled_names
);
4292 r
= enable_sysv_units(args
[0], mangled_names
);
4298 if (!bus
|| avoid_bus()) {
4300 STRV_FOREACH(name
, mangled_names
) {
4301 UnitFileState state
;
4303 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
4305 log_error("Failed to get unit file state for %s: %s", *name
, strerror(-state
));
4309 if (state
== UNIT_FILE_ENABLED
||
4310 state
== UNIT_FILE_ENABLED_RUNTIME
||
4311 state
== UNIT_FILE_STATIC
)
4315 puts(unit_file_state_to_string(state
));
4319 STRV_FOREACH(name
, mangled_names
) {
4320 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4323 r
= sd_bus_call_method(
4325 "org.freedesktop.systemd1",
4326 "/org/freedesktop/systemd1",
4327 "org.freedesktop.systemd1.Manager",
4333 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
4337 r
= sd_bus_message_read(reply
, "s", &s
);
4339 return bus_log_parse_error(r
);
4341 if (streq(s
, "enabled") ||
4342 streq(s
, "enabled-runtime") ||
4354 static int systemctl_help(void) {
4356 pager_open_if_enabled();
4358 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4359 "Query or send control commands to the systemd manager.\n\n"
4360 " -h --help Show this help\n"
4361 " --version Show package version\n"
4362 " --system Connect to system manager\n"
4363 " --user Connect to user service manager\n"
4364 " -H --host=[USER@]HOST\n"
4365 " Operate on remote host\n"
4366 " -M --machine=CONTAINER\n"
4367 " Operate on local container\n"
4368 " -t --type=TYPE List only units of a particular type\n"
4369 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4370 " -p --property=NAME Show only properties by this name\n"
4371 " -a --all Show all loaded units/properties, including dead/empty\n"
4372 " ones. To list all units installed on the system, use\n"
4373 " the 'list-unit-files' command instead.\n"
4374 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4375 " -l --full Don't ellipsize unit names on output\n"
4376 " --fail When queueing a new job, fail if conflicting jobs are\n"
4378 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4380 " --ignore-dependencies\n"
4381 " When queueing a new job, ignore all its dependencies\n"
4382 " --show-types When showing sockets, explicitly show their type\n"
4383 " -i --ignore-inhibitors\n"
4384 " When shutting down or sleeping, ignore inhibitors\n"
4385 " --kill-who=WHO Who to send signal to\n"
4386 " -s --signal=SIGNAL Which signal to send\n"
4387 " -q --quiet Suppress output\n"
4388 " --no-block Do not wait until operation finished\n"
4389 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4390 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4392 " --no-legend Do not print a legend (column headers and hints)\n"
4393 " --no-pager Do not pipe output into a pager\n"
4394 " --no-ask-password\n"
4395 " Do not ask for system passwords\n"
4396 " --global Enable/disable unit files globally\n"
4397 " --runtime Enable unit files only temporarily until next reboot\n"
4398 " -f --force When enabling unit files, override existing symlinks\n"
4399 " When shutting down, execute action immediately\n"
4400 " --root=PATH Enable unit files in the specified root directory\n"
4401 " -n --lines=INTEGER Number of journal entries to show\n"
4402 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4403 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4405 " list-units List loaded units\n"
4406 " list-sockets List loaded sockets ordered by address\n"
4407 " start [NAME...] Start (activate) one or more units\n"
4408 " stop [NAME...] Stop (deactivate) one or more units\n"
4409 " reload [NAME...] Reload one or more units\n"
4410 " restart [NAME...] Start or restart one or more units\n"
4411 " try-restart [NAME...] Restart one or more units if active\n"
4412 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4413 " otherwise start or restart\n"
4414 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4415 " otherwise restart if active\n"
4416 " isolate [NAME] Start one unit and stop all others\n"
4417 " kill [NAME...] Send signal to processes of a unit\n"
4418 " is-active [NAME...] Check whether units are active\n"
4419 " is-failed [NAME...] Check whether units are failed\n"
4420 " status [NAME...|PID...] Show runtime status of one or more units\n"
4421 " show [NAME...|JOB...] Show properties of one or more\n"
4422 " units/jobs or the manager\n"
4423 " set-property [NAME] [ASSIGNMENT...]\n"
4424 " Sets one or more properties of a unit\n"
4425 " help [NAME...|PID...] Show manual for one or more units\n"
4426 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4428 " list-dependencies [NAME] Recursively show units which are required\n"
4429 " or wanted by this unit or by which this\n"
4430 " unit is required or wanted\n\n"
4431 "Unit File Commands:\n"
4432 " list-unit-files List installed unit files\n"
4433 " enable [NAME...] Enable one or more unit files\n"
4434 " disable [NAME...] Disable one or more unit files\n"
4435 " reenable [NAME...] Reenable one or more unit files\n"
4436 " preset [NAME...] Enable/disable one or more unit files\n"
4437 " based on preset configuration\n"
4438 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4439 " mask [NAME...] Mask one or more units\n"
4440 " unmask [NAME...] Unmask one or more units\n"
4441 " link [PATH...] Link one or more units files into\n"
4442 " the search path\n"
4443 " get-default Get the name of the default target\n"
4444 " set-default NAME Set the default target\n\n"
4446 " list-jobs List jobs\n"
4447 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4448 "Snapshot Commands:\n"
4449 " snapshot [NAME] Create a snapshot\n"
4450 " delete [NAME...] Remove one or more snapshots\n\n"
4451 "Environment Commands:\n"
4452 " show-environment Dump environment\n"
4453 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4454 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4455 "Manager Lifecycle Commands:\n"
4456 " daemon-reload Reload systemd manager configuration\n"
4457 " daemon-reexec Reexecute systemd manager\n\n"
4458 "System Commands:\n"
4459 " default Enter system default mode\n"
4460 " rescue Enter system rescue mode\n"
4461 " emergency Enter system emergency mode\n"
4462 " halt Shut down and halt the system\n"
4463 " poweroff Shut down and power-off the system\n"
4464 " reboot [ARG] Shut down and reboot the system\n"
4465 " kexec Shut down and reboot the system with kexec\n"
4466 " exit Request user instance exit\n"
4467 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4468 " suspend Suspend the system\n"
4469 " hibernate Hibernate the system\n"
4470 " hybrid-sleep Hibernate and suspend the system\n",
4471 program_invocation_short_name
);
4476 static int halt_help(void) {
4478 printf("%s [OPTIONS...]%s\n\n"
4479 "%s the system.\n\n"
4480 " --help Show this help\n"
4481 " --halt Halt the machine\n"
4482 " -p --poweroff Switch off the machine\n"
4483 " --reboot Reboot the machine\n"
4484 " -f --force Force immediate halt/power-off/reboot\n"
4485 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4486 " -d --no-wtmp Don't write wtmp record\n"
4487 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4488 program_invocation_short_name
,
4489 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
4490 arg_action
== ACTION_REBOOT
? "Reboot" :
4491 arg_action
== ACTION_POWEROFF
? "Power off" :
4497 static int shutdown_help(void) {
4499 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4500 "Shut down the system.\n\n"
4501 " --help Show this help\n"
4502 " -H --halt Halt the machine\n"
4503 " -P --poweroff Power-off the machine\n"
4504 " -r --reboot Reboot the machine\n"
4505 " -h Equivalent to --poweroff, overridden by --halt\n"
4506 " -k Don't halt/power-off/reboot, just send warnings\n"
4507 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4508 " -c Cancel a pending shutdown\n",
4509 program_invocation_short_name
);
4514 static int telinit_help(void) {
4516 printf("%s [OPTIONS...] {COMMAND}\n\n"
4517 "Send control commands to the init daemon.\n\n"
4518 " --help Show this help\n"
4519 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4521 " 0 Power-off the machine\n"
4522 " 6 Reboot the machine\n"
4523 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4524 " 1, s, S Enter rescue mode\n"
4525 " q, Q Reload init daemon configuration\n"
4526 " u, U Reexecute init daemon\n",
4527 program_invocation_short_name
);
4532 static int runlevel_help(void) {
4534 printf("%s [OPTIONS...]\n\n"
4535 "Prints the previous and current runlevel of the init system.\n\n"
4536 " --help Show this help\n",
4537 program_invocation_short_name
);
4542 static int help_types(void) {
4546 puts("Available unit types:");
4547 for(i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
4548 t
= unit_type_to_string(i
);
4556 static int systemctl_parse_argv(int argc
, char *argv
[]) {
4565 ARG_IGNORE_DEPENDENCIES
,
4577 ARG_NO_ASK_PASSWORD
,
4585 static const struct option options
[] = {
4586 { "help", no_argument
, NULL
, 'h' },
4587 { "version", no_argument
, NULL
, ARG_VERSION
},
4588 { "type", required_argument
, NULL
, 't' },
4589 { "property", required_argument
, NULL
, 'p' },
4590 { "all", no_argument
, NULL
, 'a' },
4591 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
4592 { "after", no_argument
, NULL
, ARG_AFTER
},
4593 { "before", no_argument
, NULL
, ARG_BEFORE
},
4594 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
4595 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
4596 { "full", no_argument
, NULL
, 'l' },
4597 { "fail", no_argument
, NULL
, ARG_FAIL
},
4598 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
},
4599 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
},
4600 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
4601 { "user", no_argument
, NULL
, ARG_USER
},
4602 { "system", no_argument
, NULL
, ARG_SYSTEM
},
4603 { "global", no_argument
, NULL
, ARG_GLOBAL
},
4604 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
4605 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
4606 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
4607 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
4608 { "quiet", no_argument
, NULL
, 'q' },
4609 { "root", required_argument
, NULL
, ARG_ROOT
},
4610 { "force", no_argument
, NULL
, ARG_FORCE
},
4611 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
4612 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
4613 { "signal", required_argument
, NULL
, 's' },
4614 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
4615 { "host", required_argument
, NULL
, 'H' },
4616 { "machine", required_argument
, NULL
, 'M' },
4617 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
4618 { "lines", required_argument
, NULL
, 'n' },
4619 { "output", required_argument
, NULL
, 'o' },
4620 { "plain", no_argument
, NULL
, ARG_PLAIN
},
4621 { "state", required_argument
, NULL
, ARG_STATE
},
4630 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:i", options
, NULL
)) >= 0) {
4635 return systemctl_help();
4638 puts(PACKAGE_STRING
);
4639 puts(SYSTEMD_FEATURES
);
4646 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
4647 _cleanup_free_
char *type
;
4649 type
= strndup(word
, size
);
4653 if (streq(type
, "help")) {
4658 if (unit_type_from_string(type
) >= 0) {
4659 if (strv_push(&arg_types
, type
))
4665 /* It's much nicer to use --state= for
4666 * load states, but let's support this
4667 * in --types= too for compatibility
4668 * with old versions */
4669 if (unit_load_state_from_string(optarg
) >= 0) {
4670 if (strv_push(&arg_states
, type
) < 0)
4676 log_error("Unknown unit type or load state '%s'.", type
);
4677 log_info("Use -t help to see a list of allowed values.");
4685 /* Make sure that if the empty property list
4686 was specified, we won't show any properties. */
4687 if (isempty(optarg
) && !arg_properties
) {
4688 arg_properties
= new0(char*, 1);
4689 if (!arg_properties
)
4695 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
4698 prop
= strndup(word
, size
);
4702 if (strv_push(&arg_properties
, prop
) < 0) {
4709 /* If the user asked for a particular
4710 * property, show it to him, even if it is
4722 arg_dependency
= DEPENDENCY_REVERSE
;
4726 arg_dependency
= DEPENDENCY_AFTER
;
4730 arg_dependency
= DEPENDENCY_BEFORE
;
4733 case ARG_SHOW_TYPES
:
4734 arg_show_types
= true;
4738 arg_job_mode
= "fail";
4741 case ARG_IRREVERSIBLE
:
4742 arg_job_mode
= "replace-irreversibly";
4745 case ARG_IGNORE_DEPENDENCIES
:
4746 arg_job_mode
= "ignore-dependencies";
4750 arg_scope
= UNIT_FILE_USER
;
4754 arg_scope
= UNIT_FILE_SYSTEM
;
4758 arg_scope
= UNIT_FILE_GLOBAL
;
4762 arg_no_block
= true;
4766 arg_no_legend
= true;
4770 arg_no_pager
= true;
4786 if (strv_extend(&arg_states
, "failed") < 0)
4804 arg_no_reload
= true;
4808 arg_kill_who
= optarg
;
4812 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
4813 log_error("Failed to parse signal string %s.", optarg
);
4818 case ARG_NO_ASK_PASSWORD
:
4819 arg_ask_password
= false;
4823 arg_transport
= BUS_TRANSPORT_REMOTE
;
4828 arg_transport
= BUS_TRANSPORT_CONTAINER
;
4837 if (safe_atou(optarg
, &arg_lines
) < 0) {
4838 log_error("Failed to parse lines '%s'", optarg
);
4844 arg_output
= output_mode_from_string(optarg
);
4845 if (arg_output
< 0) {
4846 log_error("Unknown output '%s'.", optarg
);
4852 arg_ignore_inhibitors
= true;
4863 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
4866 s
= strndup(word
, size
);
4870 if (strv_push(&arg_states
, s
) < 0) {
4882 assert_not_reached("Unhandled option");
4886 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
4887 log_error("Cannot access user instance remotely.");
4894 static int halt_parse_argv(int argc
, char *argv
[]) {
4903 static const struct option options
[] = {
4904 { "help", no_argument
, NULL
, ARG_HELP
},
4905 { "halt", no_argument
, NULL
, ARG_HALT
},
4906 { "poweroff", no_argument
, NULL
, 'p' },
4907 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
4908 { "force", no_argument
, NULL
, 'f' },
4909 { "wtmp-only", no_argument
, NULL
, 'w' },
4910 { "no-wtmp", no_argument
, NULL
, 'd' },
4911 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
4920 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
4921 if (runlevel
== '0' || runlevel
== '6')
4924 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0) {
4931 arg_action
= ACTION_HALT
;
4935 if (arg_action
!= ACTION_REBOOT
)
4936 arg_action
= ACTION_POWEROFF
;
4940 arg_action
= ACTION_REBOOT
;
4962 /* Compatibility nops */
4969 assert_not_reached("Unhandled option");
4973 if (arg_action
== ACTION_REBOOT
&& argc
== optind
+ 1) {
4974 r
= write_string_file(REBOOT_PARAM_FILE
, argv
[optind
]);
4976 log_error("Failed to write reboot param to "
4977 REBOOT_PARAM_FILE
": %s", strerror(-r
));
4980 } else if (optind
< argc
) {
4981 log_error("Too many arguments.");
4988 static int parse_time_spec(const char *t
, usec_t
*_u
) {
4992 if (streq(t
, "now"))
4994 else if (!strchr(t
, ':')) {
4997 if (safe_atou64(t
, &u
) < 0)
5000 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
5009 hour
= strtol(t
, &e
, 10);
5010 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
5013 minute
= strtol(e
+1, &e
, 10);
5014 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
5017 n
= now(CLOCK_REALTIME
);
5018 s
= (time_t) (n
/ USEC_PER_SEC
);
5020 assert_se(localtime_r(&s
, &tm
));
5022 tm
.tm_hour
= (int) hour
;
5023 tm
.tm_min
= (int) minute
;
5026 assert_se(s
= mktime(&tm
));
5028 *_u
= (usec_t
) s
* USEC_PER_SEC
;
5031 *_u
+= USEC_PER_DAY
;
5037 static int shutdown_parse_argv(int argc
, char *argv
[]) {
5044 static const struct option options
[] = {
5045 { "help", no_argument
, NULL
, ARG_HELP
},
5046 { "halt", no_argument
, NULL
, 'H' },
5047 { "poweroff", no_argument
, NULL
, 'P' },
5048 { "reboot", no_argument
, NULL
, 'r' },
5049 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
5050 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5059 while ((c
= getopt_long(argc
, argv
, "HPrhkt:afFc", options
, NULL
)) >= 0) {
5063 return shutdown_help();
5066 arg_action
= ACTION_HALT
;
5070 arg_action
= ACTION_POWEROFF
;
5075 arg_action
= ACTION_KEXEC
;
5077 arg_action
= ACTION_REBOOT
;
5081 arg_action
= ACTION_KEXEC
;
5085 if (arg_action
!= ACTION_HALT
)
5086 arg_action
= ACTION_POWEROFF
;
5099 /* Compatibility nops */
5103 arg_action
= ACTION_CANCEL_SHUTDOWN
;
5110 assert_not_reached("Unhandled option");
5114 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
5115 r
= parse_time_spec(argv
[optind
], &arg_when
);
5117 log_error("Failed to parse time specification: %s", argv
[optind
]);
5121 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
5123 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
5124 /* No time argument for shutdown cancel */
5125 arg_wall
= argv
+ optind
;
5126 else if (argc
> optind
+ 1)
5127 /* We skip the time argument */
5128 arg_wall
= argv
+ optind
+ 1;
5135 static int telinit_parse_argv(int argc
, char *argv
[]) {
5142 static const struct option options
[] = {
5143 { "help", no_argument
, NULL
, ARG_HELP
},
5144 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5148 static const struct {
5152 { '0', ACTION_POWEROFF
},
5153 { '6', ACTION_REBOOT
},
5154 { '1', ACTION_RESCUE
},
5155 { '2', ACTION_RUNLEVEL2
},
5156 { '3', ACTION_RUNLEVEL3
},
5157 { '4', ACTION_RUNLEVEL4
},
5158 { '5', ACTION_RUNLEVEL5
},
5159 { 's', ACTION_RESCUE
},
5160 { 'S', ACTION_RESCUE
},
5161 { 'q', ACTION_RELOAD
},
5162 { 'Q', ACTION_RELOAD
},
5163 { 'u', ACTION_REEXEC
},
5164 { 'U', ACTION_REEXEC
}
5173 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5177 return telinit_help();
5187 assert_not_reached("Unhandled option");
5191 if (optind
>= argc
) {
5196 if (optind
+ 1 < argc
) {
5197 log_error("Too many arguments.");
5201 if (strlen(argv
[optind
]) != 1) {
5202 log_error("Expected single character argument.");
5206 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
5207 if (table
[i
].from
== argv
[optind
][0])
5210 if (i
>= ELEMENTSOF(table
)) {
5211 log_error("Unknown command '%s'.", argv
[optind
]);
5215 arg_action
= table
[i
].to
;
5222 static int runlevel_parse_argv(int argc
, char *argv
[]) {
5228 static const struct option options
[] = {
5229 { "help", no_argument
, NULL
, ARG_HELP
},
5238 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5242 return runlevel_help();
5249 assert_not_reached("Unhandled option");
5253 if (optind
< argc
) {
5254 log_error("Too many arguments.");
5261 static int parse_argv(int argc
, char *argv
[]) {
5265 if (program_invocation_short_name
) {
5267 if (strstr(program_invocation_short_name
, "halt")) {
5268 arg_action
= ACTION_HALT
;
5269 return halt_parse_argv(argc
, argv
);
5270 } else if (strstr(program_invocation_short_name
, "poweroff")) {
5271 arg_action
= ACTION_POWEROFF
;
5272 return halt_parse_argv(argc
, argv
);
5273 } else if (strstr(program_invocation_short_name
, "reboot")) {
5275 arg_action
= ACTION_KEXEC
;
5277 arg_action
= ACTION_REBOOT
;
5278 return halt_parse_argv(argc
, argv
);
5279 } else if (strstr(program_invocation_short_name
, "shutdown")) {
5280 arg_action
= ACTION_POWEROFF
;
5281 return shutdown_parse_argv(argc
, argv
);
5282 } else if (strstr(program_invocation_short_name
, "init")) {
5284 if (sd_booted() > 0) {
5285 arg_action
= _ACTION_INVALID
;
5286 return telinit_parse_argv(argc
, argv
);
5288 /* Hmm, so some other init system is
5289 * running, we need to forward this
5290 * request to it. For now we simply
5291 * guess that it is Upstart. */
5293 execv(TELINIT
, argv
);
5295 log_error("Couldn't find an alternative telinit implementation to spawn.");
5299 } else if (strstr(program_invocation_short_name
, "runlevel")) {
5300 arg_action
= ACTION_RUNLEVEL
;
5301 return runlevel_parse_argv(argc
, argv
);
5305 arg_action
= ACTION_SYSTEMCTL
;
5306 return systemctl_parse_argv(argc
, argv
);
5309 _pure_
static int action_to_runlevel(void) {
5311 static const char table
[_ACTION_MAX
] = {
5312 [ACTION_HALT
] = '0',
5313 [ACTION_POWEROFF
] = '0',
5314 [ACTION_REBOOT
] = '6',
5315 [ACTION_RUNLEVEL2
] = '2',
5316 [ACTION_RUNLEVEL3
] = '3',
5317 [ACTION_RUNLEVEL4
] = '4',
5318 [ACTION_RUNLEVEL5
] = '5',
5319 [ACTION_RESCUE
] = '1'
5322 assert(arg_action
< _ACTION_MAX
);
5324 return table
[arg_action
];
5327 static int talk_initctl(void) {
5329 struct init_request request
= {
5330 .magic
= INIT_MAGIC
,
5332 .cmd
= INIT_CMD_RUNLVL
5335 _cleanup_close_
int fd
= -1;
5339 rl
= action_to_runlevel();
5343 request
.runlevel
= rl
;
5345 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
5347 if (errno
== ENOENT
)
5350 log_error("Failed to open "INIT_FIFO
": %m");
5355 r
= loop_write(fd
, &request
, sizeof(request
), false) != sizeof(request
);
5357 log_error("Failed to write to "INIT_FIFO
": %m");
5358 return errno
> 0 ? -errno
: -EIO
;
5364 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
5366 static const struct {
5374 int (* const dispatch
)(sd_bus
*bus
, char **args
);
5376 { "list-units", LESS
, 1, list_units
},
5377 { "list-unit-files", EQUAL
, 1, list_unit_files
},
5378 { "list-sockets", LESS
, 1, list_sockets
},
5379 { "list-jobs", EQUAL
, 1, list_jobs
},
5380 { "clear-jobs", EQUAL
, 1, daemon_reload
},
5381 { "cancel", MORE
, 2, cancel_job
},
5382 { "start", MORE
, 2, start_unit
},
5383 { "stop", MORE
, 2, start_unit
},
5384 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5385 { "reload", MORE
, 2, start_unit
},
5386 { "restart", MORE
, 2, start_unit
},
5387 { "try-restart", MORE
, 2, start_unit
},
5388 { "reload-or-restart", MORE
, 2, start_unit
},
5389 { "reload-or-try-restart", MORE
, 2, start_unit
},
5390 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
5391 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5392 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
5393 { "isolate", EQUAL
, 2, start_unit
},
5394 { "kill", MORE
, 2, kill_unit
},
5395 { "is-active", MORE
, 2, check_unit_active
},
5396 { "check", MORE
, 2, check_unit_active
},
5397 { "is-failed", MORE
, 2, check_unit_failed
},
5398 { "show", MORE
, 1, show
},
5399 { "status", MORE
, 1, show
},
5400 { "help", MORE
, 2, show
},
5401 { "snapshot", LESS
, 2, snapshot
},
5402 { "delete", MORE
, 2, delete_snapshot
},
5403 { "daemon-reload", EQUAL
, 1, daemon_reload
},
5404 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
5405 { "show-environment", EQUAL
, 1, show_environment
},
5406 { "set-environment", MORE
, 2, set_environment
},
5407 { "unset-environment", MORE
, 2, set_environment
},
5408 { "halt", EQUAL
, 1, start_special
},
5409 { "poweroff", EQUAL
, 1, start_special
},
5410 { "reboot", EQUAL
, 1, start_special
},
5411 { "kexec", EQUAL
, 1, start_special
},
5412 { "suspend", EQUAL
, 1, start_special
},
5413 { "hibernate", EQUAL
, 1, start_special
},
5414 { "hybrid-sleep", EQUAL
, 1, start_special
},
5415 { "default", EQUAL
, 1, start_special
},
5416 { "rescue", EQUAL
, 1, start_special
},
5417 { "emergency", EQUAL
, 1, start_special
},
5418 { "exit", EQUAL
, 1, start_special
},
5419 { "reset-failed", MORE
, 1, reset_failed
},
5420 { "enable", MORE
, 2, enable_unit
},
5421 { "disable", MORE
, 2, enable_unit
},
5422 { "is-enabled", MORE
, 2, unit_is_enabled
},
5423 { "reenable", MORE
, 2, enable_unit
},
5424 { "preset", MORE
, 2, enable_unit
},
5425 { "mask", MORE
, 2, enable_unit
},
5426 { "unmask", MORE
, 2, enable_unit
},
5427 { "link", MORE
, 2, enable_unit
},
5428 { "switch-root", MORE
, 2, switch_root
},
5429 { "list-dependencies", LESS
, 2, list_dependencies
},
5430 { "set-default", EQUAL
, 2, enable_unit
},
5431 { "get-default", LESS
, 1, get_default
},
5432 { "set-property", MORE
, 3, set_property
},
5441 left
= argc
- optind
;
5444 /* Special rule: no arguments means "list-units" */
5447 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
5448 log_error("This command expects one or more "
5449 "unit names. Did you mean --help?");
5453 for (i
= 0; i
< ELEMENTSOF(verbs
); i
++)
5454 if (streq(argv
[optind
], verbs
[i
].verb
))
5457 if (i
>= ELEMENTSOF(verbs
)) {
5458 log_error("Unknown operation '%s'.", argv
[optind
]);
5463 switch (verbs
[i
].argc_cmp
) {
5466 if (left
!= verbs
[i
].argc
) {
5467 log_error("Invalid number of arguments.");
5474 if (left
< verbs
[i
].argc
) {
5475 log_error("Too few arguments.");
5482 if (left
> verbs
[i
].argc
) {
5483 log_error("Too many arguments.");
5490 assert_not_reached("Unknown comparison operator.");
5493 /* Require a bus connection for all operations but
5495 if (!streq(verbs
[i
].verb
, "enable") &&
5496 !streq(verbs
[i
].verb
, "disable") &&
5497 !streq(verbs
[i
].verb
, "is-enabled") &&
5498 !streq(verbs
[i
].verb
, "list-unit-files") &&
5499 !streq(verbs
[i
].verb
, "reenable") &&
5500 !streq(verbs
[i
].verb
, "preset") &&
5501 !streq(verbs
[i
].verb
, "mask") &&
5502 !streq(verbs
[i
].verb
, "unmask") &&
5503 !streq(verbs
[i
].verb
, "link") &&
5504 !streq(verbs
[i
].verb
, "set-default") &&
5505 !streq(verbs
[i
].verb
, "get-default")) {
5507 if (running_in_chroot() > 0) {
5508 log_info("Running in chroot, ignoring request.");
5512 if (((!streq(verbs
[i
].verb
, "reboot") &&
5513 !streq(verbs
[i
].verb
, "halt") &&
5514 !streq(verbs
[i
].verb
, "poweroff")) || arg_force
<= 0) && !bus
) {
5515 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error
));
5521 if (!bus
&& !avoid_bus()) {
5522 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error
));
5527 return verbs
[i
].dispatch(bus
, argv
+ optind
);
5530 static int send_shutdownd(usec_t t
, char mode
, bool dry_run
, bool warn
, const char *message
) {
5532 struct sd_shutdown_command c
= {
5539 union sockaddr_union sockaddr
= {
5540 .un
.sun_family
= AF_UNIX
,
5541 .un
.sun_path
= "/run/systemd/shutdownd",
5544 struct iovec iovec
[2] = {{
5545 .iov_base
= (char*) &c
,
5546 .iov_len
= offsetof(struct sd_shutdown_command
, wall_message
),
5549 struct msghdr msghdr
= {
5550 .msg_name
= &sockaddr
,
5551 .msg_namelen
= offsetof(struct sockaddr_un
, sun_path
)
5552 + sizeof("/run/systemd/shutdownd") - 1,
5557 _cleanup_close_
int fd
;
5559 fd
= socket(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0);
5563 if (!isempty(message
)) {
5564 iovec
[1].iov_base
= (char*) message
;
5565 iovec
[1].iov_len
= strlen(message
);
5566 msghdr
.msg_iovlen
++;
5569 if (sendmsg(fd
, &msghdr
, MSG_NOSIGNAL
) < 0)
5575 static int reload_with_fallback(sd_bus
*bus
) {
5578 /* First, try systemd via D-Bus. */
5579 if (daemon_reload(bus
, NULL
) >= 0)
5583 /* Nothing else worked, so let's try signals */
5584 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
5586 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0) {
5587 log_error("kill() failed: %m");
5594 static int start_with_fallback(sd_bus
*bus
) {
5597 /* First, try systemd via D-Bus. */
5598 if (start_unit(bus
, NULL
) >= 0)
5602 /* Nothing else worked, so let's try
5604 if (talk_initctl() > 0)
5607 log_error("Failed to talk to init daemon.");
5611 warn_wall(arg_action
);
5615 static int halt_now(enum action a
) {
5617 /* Make sure C-A-D is handled by the kernel from this
5619 reboot(RB_ENABLE_CAD
);
5624 log_info("Halting.");
5625 reboot(RB_HALT_SYSTEM
);
5628 case ACTION_POWEROFF
:
5629 log_info("Powering off.");
5630 reboot(RB_POWER_OFF
);
5633 case ACTION_REBOOT
: {
5634 _cleanup_free_
char *param
= NULL
;
5636 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
5637 log_info("Rebooting with argument '%s'.", param
);
5638 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
5639 LINUX_REBOOT_CMD_RESTART2
, param
);
5642 log_info("Rebooting.");
5643 reboot(RB_AUTOBOOT
);
5648 assert_not_reached("Unknown action.");
5652 static int halt_main(sd_bus
*bus
) {
5655 r
= check_inhibitors(bus
, arg_action
);
5659 if (geteuid() != 0) {
5660 /* Try logind if we are a normal user and no special
5661 * mode applies. Maybe PolicyKit allows us to shutdown
5664 if (arg_when
<= 0 &&
5667 (arg_action
== ACTION_POWEROFF
||
5668 arg_action
== ACTION_REBOOT
)) {
5669 r
= reboot_with_logind(bus
, arg_action
);
5674 log_error("Must be root.");
5679 _cleanup_free_
char *m
;
5681 m
= strv_join(arg_wall
, " ");
5685 r
= send_shutdownd(arg_when
,
5686 arg_action
== ACTION_HALT
? 'H' :
5687 arg_action
== ACTION_POWEROFF
? 'P' :
5688 arg_action
== ACTION_KEXEC
? 'K' :
5695 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r
));
5697 char date
[FORMAT_TIMESTAMP_MAX
];
5699 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5700 format_timestamp(date
, sizeof(date
), arg_when
));
5705 if (!arg_dry
&& !arg_force
)
5706 return start_with_fallback(bus
);
5709 if (sd_booted() > 0)
5710 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5712 r
= utmp_put_shutdown();
5714 log_warning("Failed to write utmp record: %s", strerror(-r
));
5721 r
= halt_now(arg_action
);
5722 log_error("Failed to reboot: %s", strerror(-r
));
5727 static int runlevel_main(void) {
5728 int r
, runlevel
, previous
;
5730 r
= utmp_get_runlevel(&runlevel
, &previous
);
5737 previous
<= 0 ? 'N' : previous
,
5738 runlevel
<= 0 ? 'N' : runlevel
);
5743 int main(int argc
, char*argv
[]) {
5744 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
5747 setlocale(LC_ALL
, "");
5748 log_parse_environment();
5751 /* Explicitly not on_tty() to avoid setting cached value.
5752 * This becomes relevant for piping output which might be
5754 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
5756 r
= parse_argv(argc
, argv
);
5760 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5761 * let's shortcut this */
5762 if (arg_action
== ACTION_RUNLEVEL
) {
5763 r
= runlevel_main();
5767 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
5768 log_info("Running in chroot, ignoring request.");
5774 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
5776 /* systemctl_main() will print an error message for the bus
5777 * connection, but only if it needs to */
5779 switch (arg_action
) {
5781 case ACTION_SYSTEMCTL
:
5782 r
= systemctl_main(bus
, argc
, argv
, r
);
5786 case ACTION_POWEROFF
:
5792 case ACTION_RUNLEVEL2
:
5793 case ACTION_RUNLEVEL3
:
5794 case ACTION_RUNLEVEL4
:
5795 case ACTION_RUNLEVEL5
:
5797 case ACTION_EMERGENCY
:
5798 case ACTION_DEFAULT
:
5799 r
= start_with_fallback(bus
);
5804 r
= reload_with_fallback(bus
);
5807 case ACTION_CANCEL_SHUTDOWN
: {
5808 _cleanup_free_
char *m
= NULL
;
5811 m
= strv_join(arg_wall
, " ");
5818 r
= send_shutdownd(arg_when
, SD_SHUTDOWN_NONE
, false, !arg_no_wall
, m
);
5820 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r
));
5824 case ACTION_RUNLEVEL
:
5825 case _ACTION_INVALID
:
5827 assert_not_reached("Unknown action");
5832 ask_password_agent_close();
5833 polkit_agent_close();
5835 strv_free(arg_types
);
5836 strv_free(arg_states
);
5837 strv_free(arg_properties
);
5839 return r
< 0 ? EXIT_FAILURE
: r
;