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
,
537 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
538 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
539 const char *type
, *path
;
542 r
= sd_bus_get_property(
544 "org.freedesktop.systemd1",
546 "org.freedesktop.systemd1.Socket",
552 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
556 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
558 return bus_log_parse_error(r
);
560 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
562 r
= strv_extend(listening
, type
);
566 r
= strv_extend(listening
, path
);
573 return bus_log_parse_error(r
);
575 r
= sd_bus_message_exit_container(reply
);
577 return bus_log_parse_error(r
);
588 /* Note: triggered is a list here, although it almost certainly
589 * will always be one unit. Nevertheless, dbus API allows for multiple
590 * values, so let's follow that.*/
593 /* The strv above is shared. free is set only in the first one. */
597 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
603 o
= strcmp(a
->path
, b
->path
);
605 o
= strcmp(a
->type
, b
->type
);
610 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
611 struct socket_info
*s
;
612 unsigned pathlen
= sizeof("LISTEN") - 1,
613 typelen
= (sizeof("TYPE") - 1) * arg_show_types
,
614 socklen
= sizeof("UNIT") - 1,
615 servlen
= sizeof("ACTIVATES") - 1;
616 const char *on
, *off
;
618 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
622 socklen
= MAX(socklen
, strlen(s
->id
));
624 typelen
= MAX(typelen
, strlen(s
->type
));
625 pathlen
= MAX(pathlen
, strlen(s
->path
));
627 STRV_FOREACH(a
, s
->triggered
)
628 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
629 servlen
= MAX(servlen
, tmp
);
634 printf("%-*s %-*.*s%-*s %s\n",
636 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
640 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
644 printf("%-*s %-*s %-*s",
645 pathlen
, s
->path
, typelen
, s
->type
, socklen
, s
->id
);
648 pathlen
, s
->path
, socklen
, s
->id
);
649 STRV_FOREACH(a
, s
->triggered
)
651 a
== s
->triggered
? "" : ",", *a
);
655 on
= ansi_highlight();
656 off
= ansi_highlight_off();
660 on
= ansi_highlight_red();
661 off
= ansi_highlight_off();
664 if (!arg_no_legend
) {
665 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
667 printf("Pass --all to see loaded but inactive sockets, too.\n");
673 static int list_sockets(sd_bus
*bus
, char **args
) {
674 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
675 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
676 struct socket_info
*socket_infos
= NULL
;
678 struct socket_info
*s
;
683 pager_open_if_enabled();
685 n
= get_unit_list(bus
, &reply
, &unit_infos
);
689 for (u
= unit_infos
; u
< unit_infos
+ n
; 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 c
= get_listening(bus
, u
->unit_path
, &listening
);
709 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
714 for (i
= 0; i
< c
; i
++)
715 socket_infos
[cs
+ i
] = (struct socket_info
) {
717 .type
= listening
[i
*2],
718 .path
= listening
[i
*2 + 1],
719 .triggered
= triggered
,
720 .own_triggered
= i
==0,
723 /* from this point on we will cleanup those socket_infos */
726 listening
= triggered
= NULL
; /* avoid cleanup */
729 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
730 (__compar_fn_t
) socket_info_compare
);
732 output_sockets_list(socket_infos
, cs
);
735 assert(cs
== 0 || socket_infos
);
736 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
739 if (s
->own_triggered
)
740 strv_free(s
->triggered
);
747 static int get_next_elapse(
750 dual_timestamp
*next
) {
752 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
753 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
761 r
= sd_bus_get_property_trivial(
763 "org.freedesktop.systemd1",
765 "org.freedesktop.systemd1.Timer",
766 "NextElapseUSecMonotonic",
771 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
775 r
= sd_bus_get_property_trivial(
777 "org.freedesktop.systemd1",
779 "org.freedesktop.systemd1.Timer",
780 "NextElapseUSecRealtime",
785 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
799 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
803 if (a
->next_elapse
< b
->next_elapse
)
805 if (a
->next_elapse
> b
->next_elapse
)
808 return strcmp(a
->id
, b
->id
);
811 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
812 struct timer_info
*t
;
814 nextlen
= sizeof("NEXT") - 1,
815 leftlen
= sizeof("LEFT") - 1,
816 unitlen
= sizeof("UNIT") - 1,
817 activatelen
= sizeof("ACTIVATES") - 1;
819 const char *on
, *off
;
821 assert(timer_infos
|| n
== 0);
823 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
827 if (t
->next_elapse
> 0) {
828 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
830 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
831 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
833 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
834 leftlen
= MAX(leftlen
, strlen(trel
));
837 unitlen
= MAX(unitlen
, strlen(t
->id
));
839 STRV_FOREACH(a
, t
->triggered
)
840 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
841 activatelen
= MAX(activatelen
, ul
);
846 printf("%-*s %-*s %-*s %s\n",
852 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
853 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
856 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
857 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
859 printf("%-*s %-*s %-*s",
860 nextlen
, tstamp
, leftlen
, trel
, unitlen
, t
->id
);
862 STRV_FOREACH(a
, t
->triggered
)
864 a
== t
->triggered
? "" : ",", *a
);
868 on
= ansi_highlight();
869 off
= ansi_highlight_off();
873 on
= ansi_highlight_red();
874 off
= ansi_highlight_off();
877 if (!arg_no_legend
) {
878 printf("%s%u timers listed.%s\n", on
, n
, off
);
880 printf("Pass --all to see loaded but inactive timers, too.\n");
886 static int list_timers(sd_bus
*bus
, char **args
) {
888 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
889 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
890 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
891 struct timer_info
*t
;
898 pager_open_if_enabled();
900 n
= get_unit_list(bus
, &reply
, &unit_infos
);
904 dual_timestamp_get(&nw
);
906 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
907 _cleanup_strv_free_
char **triggered
= NULL
;
911 if (!output_show_unit(u
))
914 if (!endswith(u
->id
, ".timer"))
917 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
921 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
925 if (next
.monotonic
!= (usec_t
) -1 && next
.monotonic
> 0) {
928 if (next
.monotonic
> nw
.monotonic
)
929 converted
= nw
.realtime
+ (next
.monotonic
- nw
.monotonic
);
931 converted
= nw
.realtime
- (nw
.monotonic
- next
.monotonic
);
933 if (next
.realtime
!= (usec_t
) -1 && next
.realtime
> 0)
934 m
= MIN(converted
, next
.realtime
);
940 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
945 timer_infos
[c
++] = (struct timer_info
) {
948 .triggered
= triggered
,
951 triggered
= NULL
; /* avoid cleanup */
954 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
955 (__compar_fn_t
) timer_info_compare
);
957 output_timers_list(timer_infos
, c
);
960 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
961 strv_free(t
->triggered
);
966 static int compare_unit_file_list(const void *a
, const void *b
) {
968 const UnitFileList
*u
= a
, *v
= b
;
970 d1
= strrchr(u
->path
, '.');
971 d2
= strrchr(v
->path
, '.');
976 r
= strcasecmp(d1
, d2
);
981 return strcasecmp(path_get_file_name(u
->path
), path_get_file_name(v
->path
));
984 static bool output_show_unit_file(const UnitFileList
*u
) {
987 return !arg_types
|| ((dot
= strrchr(u
->path
, '.')) && strv_find(arg_types
, dot
+1));
990 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
991 unsigned max_id_len
, id_cols
, state_cols
, n_shown
= 0;
992 const UnitFileList
*u
;
994 max_id_len
= sizeof("UNIT FILE")-1;
995 state_cols
= sizeof("STATE")-1;
997 for (u
= units
; u
< units
+ c
; u
++) {
998 if (!output_show_unit_file(u
))
1001 max_id_len
= MAX(max_id_len
, strlen(path_get_file_name(u
->path
)));
1002 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1006 unsigned basic_cols
;
1008 id_cols
= MIN(max_id_len
, 25u);
1009 basic_cols
= 1 + id_cols
+ state_cols
;
1010 if (basic_cols
< (unsigned) columns())
1011 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1013 id_cols
= max_id_len
;
1016 printf("%-*s %-*s\n",
1017 id_cols
, "UNIT FILE",
1018 state_cols
, "STATE");
1020 for (u
= units
; u
< units
+ c
; u
++) {
1021 _cleanup_free_
char *e
= NULL
;
1022 const char *on
, *off
;
1025 if (!output_show_unit_file(u
))
1030 if (u
->state
== UNIT_FILE_MASKED
||
1031 u
->state
== UNIT_FILE_MASKED_RUNTIME
||
1032 u
->state
== UNIT_FILE_DISABLED
||
1033 u
->state
== UNIT_FILE_INVALID
) {
1034 on
= ansi_highlight_red();
1035 off
= ansi_highlight_off();
1036 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1037 on
= ansi_highlight_green();
1038 off
= ansi_highlight_off();
1042 id
= path_get_file_name(u
->path
);
1044 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1046 printf("%-*s %s%-*s%s\n",
1047 id_cols
, e
? e
: id
,
1048 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1052 printf("\n%u unit files listed.\n", n_shown
);
1055 static int list_unit_files(sd_bus
*bus
, char **args
) {
1056 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1057 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1058 _cleanup_free_ UnitFileList
*units
= NULL
;
1064 pager_open_if_enabled();
1072 h
= hashmap_new(string_hash_func
, string_compare_func
);
1076 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1078 unit_file_list_free(h
);
1079 log_error("Failed to get unit file list: %s", strerror(-r
));
1083 n_units
= hashmap_size(h
);
1084 units
= new(UnitFileList
, n_units
);
1086 unit_file_list_free(h
);
1090 HASHMAP_FOREACH(u
, h
, i
) {
1091 memcpy(units
+ c
++, u
, sizeof(UnitFileList
));
1095 assert(c
== n_units
);
1100 r
= sd_bus_call_method(
1102 "org.freedesktop.systemd1",
1103 "/org/freedesktop/systemd1",
1104 "org.freedesktop.systemd1.Manager",
1110 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1114 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1116 return bus_log_parse_error(r
);
1118 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1120 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1123 units
[c
++] = (struct UnitFileList
) {
1125 unit_file_state_from_string(state
)
1129 return bus_log_parse_error(r
);
1131 r
= sd_bus_message_exit_container(reply
);
1133 return bus_log_parse_error(r
);
1137 qsort(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1138 output_unit_file_list(units
, c
);
1144 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1145 _cleanup_free_
char *n
= NULL
;
1146 size_t max_len
= MAX(columns(),20u);
1152 for (i
= level
- 1; i
>= 0; i
--) {
1154 if(len
> max_len
- 3 && !arg_full
) {
1155 printf("%s...\n",max_len
% 2 ? "" : " ");
1158 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERT
: DRAW_TREE_SPACE
));
1162 if(len
> max_len
- 3 && !arg_full
) {
1163 printf("%s...\n",max_len
% 2 ? "" : " ");
1167 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1171 printf("%s\n", name
);
1175 n
= ellipsize(name
, max_len
-len
, 100);
1183 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1185 static const char *dependencies
[] = {
1186 [DEPENDENCY_FORWARD
] = "Requires\0"
1187 "RequiresOverridable\0"
1189 "RequisiteOverridable\0"
1191 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1192 "RequiredByOverridable\0"
1195 [DEPENDENCY_AFTER
] = "After\0",
1196 [DEPENDENCY_BEFORE
] = "Before\0",
1199 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1200 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1201 _cleanup_strv_free_
char **ret
= NULL
;
1202 _cleanup_free_
char *path
= NULL
;
1208 assert(arg_dependency
< ELEMENTSOF(dependencies
));
1210 path
= unit_dbus_path_from_name(name
);
1214 r
= sd_bus_call_method(
1216 "org.freedesktop.systemd1",
1218 "org.freedesktop.DBus.Properties",
1222 "s", "org.freedesktop.systemd1.Unit");
1224 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1228 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1230 return bus_log_parse_error(r
);
1232 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1235 r
= sd_bus_message_read(reply
, "s", &prop
);
1237 return bus_log_parse_error(r
);
1239 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1240 r
= sd_bus_message_skip(reply
, "v");
1242 return bus_log_parse_error(r
);
1245 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1247 return bus_log_parse_error(r
);
1249 r
= bus_message_read_strv_extend(reply
, &ret
);
1251 return bus_log_parse_error(r
);
1253 r
= sd_bus_message_exit_container(reply
);
1255 return bus_log_parse_error(r
);
1258 r
= sd_bus_message_exit_container(reply
);
1260 return bus_log_parse_error(r
);
1264 return bus_log_parse_error(r
);
1266 r
= sd_bus_message_exit_container(reply
);
1268 return bus_log_parse_error(r
);
1276 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1277 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1279 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1281 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1284 return strcasecmp(*a
, *b
);
1287 static int list_dependencies_one(
1292 unsigned int branches
) {
1294 _cleanup_strv_free_
char **deps
= NULL
, **u
;
1302 u
= strv_append(*units
, name
);
1306 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1310 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1312 STRV_FOREACH(c
, deps
) {
1313 if (strv_contains(u
, *c
)) {
1315 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1322 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1326 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1327 r
= list_dependencies_one(bus
, *c
, level
+ 1, &u
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1342 static int list_dependencies(sd_bus
*bus
, char **args
) {
1343 _cleanup_strv_free_
char **units
= NULL
;
1344 _cleanup_free_
char *unit
= NULL
;
1350 unit
= unit_name_mangle(args
[1]);
1355 u
= SPECIAL_DEFAULT_TARGET
;
1357 pager_open_if_enabled();
1361 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1364 static int get_default(sd_bus
*bus
, char **args
) {
1365 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1366 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1367 _cleanup_free_
char *_path
= NULL
;
1371 if (!bus
|| avoid_bus()) {
1372 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1374 log_error("Failed to get default target: %s", strerror(-r
));
1380 r
= sd_bus_call_method(
1382 "org.freedesktop.systemd1",
1383 "/org/freedesktop/systemd1",
1384 "org.freedesktop.systemd1.Manager",
1390 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1394 r
= sd_bus_message_read(reply
, "s", &path
);
1396 return bus_log_parse_error(r
);
1400 printf("%s\n", path
);
1407 const char *name
, *type
, *state
;
1410 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
) {
1411 unsigned id_len
, unit_len
, type_len
, state_len
;
1412 const struct job_info
*j
;
1413 const char *on
, *off
;
1414 bool shorten
= false;
1416 assert(n
== 0 || jobs
);
1419 on
= ansi_highlight_green();
1420 off
= ansi_highlight_off();
1422 printf("%sNo jobs running.%s\n", on
, off
);
1426 pager_open_if_enabled();
1428 id_len
= sizeof("JOB")-1;
1429 unit_len
= sizeof("UNIT")-1;
1430 type_len
= sizeof("TYPE")-1;
1431 state_len
= sizeof("STATE")-1;
1433 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1434 uint32_t id
= j
->id
;
1435 assert(j
->name
&& j
->type
&& j
->state
);
1437 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
1438 unit_len
= MAX(unit_len
, strlen(j
->name
));
1439 type_len
= MAX(type_len
, strlen(j
->type
));
1440 state_len
= MAX(state_len
, strlen(j
->state
));
1443 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
1444 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
1448 printf("%*s %-*s %-*s %-*s\n",
1452 state_len
, "STATE");
1454 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1455 _cleanup_free_
char *e
= NULL
;
1457 if (streq(j
->state
, "running")) {
1458 on
= ansi_highlight();
1459 off
= ansi_highlight_off();
1463 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
1464 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1466 on
, unit_len
, e
? e
: j
->name
, off
,
1468 on
, state_len
, j
->state
, off
);
1471 on
= ansi_highlight();
1472 off
= ansi_highlight_off();
1474 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
1477 static int list_jobs(sd_bus
*bus
, char **args
) {
1478 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1479 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1480 const char *name
, *type
, *state
, *job_path
, *unit_path
;
1481 _cleanup_free_
struct job_info
*jobs
= NULL
;
1487 r
= sd_bus_call_method(
1489 "org.freedesktop.systemd1",
1490 "/org/freedesktop/systemd1",
1491 "org.freedesktop.systemd1.Manager",
1497 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
1501 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
1503 return bus_log_parse_error(r
);
1505 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
1507 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
1510 jobs
[c
++] = (struct job_info
) {
1518 return bus_log_parse_error(r
);
1520 r
= sd_bus_message_exit_container(reply
);
1522 return bus_log_parse_error(r
);
1524 output_jobs_list(jobs
, c
);
1528 static int cancel_job(sd_bus
*bus
, char **args
) {
1529 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1534 if (strv_length(args
) <= 1)
1535 return daemon_reload(bus
, args
);
1537 STRV_FOREACH(name
, args
+1) {
1541 r
= safe_atou32(*name
, &id
);
1543 log_error("Failed to parse job id \"%s\": %s", *name
, strerror(-r
));
1547 r
= sd_bus_call_method(
1549 "org.freedesktop.systemd1",
1550 "/org/freedesktop/systemd1",
1551 "org.freedesktop.systemd1.Manager",
1557 log_error("Failed to cancel job %u: %s", (unsigned) id
, bus_error_message(&error
, r
));
1565 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
1566 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1567 _cleanup_free_
char *n
= NULL
;
1571 /* We ignore all errors here, since this is used to show a
1574 n
= unit_name_mangle(unit
);
1578 /* We don't use unit_dbus_path_from_name() directly since we
1579 * don't want to load the unit if it isn't loaded. */
1581 r
= sd_bus_call_method(
1583 "org.freedesktop.systemd1",
1584 "/org/freedesktop/systemd1",
1585 "org.freedesktop.systemd1.Manager",
1593 r
= sd_bus_message_read(reply
, "o", &path
);
1597 r
= sd_bus_get_property_trivial(
1599 "org.freedesktop.systemd1",
1601 "org.freedesktop.systemd1.Unit",
1611 typedef struct WaitData
{
1618 static int wait_filter(sd_bus
*bus
, sd_bus_message
*m
, void *data
) {
1625 log_debug("Got D-Bus request: %s.%s() on %s",
1626 sd_bus_message_get_interface(m
),
1627 sd_bus_message_get_member(m
),
1628 sd_bus_message_get_path(m
));
1630 if (sd_bus_message_is_signal(m
, "org.freedesktop.DBus.Local", "Disconnected")) {
1631 log_error("Warning! D-Bus connection terminated.");
1633 } else if (sd_bus_message_is_signal(m
, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1635 const char *path
, *result
, *unit
;
1639 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1641 ret
= set_remove(d
->set
, (char*) path
);
1647 if (!isempty(result
))
1648 d
->result
= strdup(result
);
1651 d
->name
= strdup(unit
);
1656 r
= sd_bus_message_read(m
, "uos", &id
, &path
, &result
);
1658 ret
= set_remove(d
->set
, (char*) path
);
1665 d
->result
= strdup(result
);
1671 log_error("Failed to parse message.");
1677 static int enable_wait_for_jobs(sd_bus
*bus
) {
1682 r
= sd_bus_add_match(
1685 "sender='org.freedesktop.systemd1',"
1686 "interface='org.freedesktop.systemd1.Manager',"
1687 "member='JobRemoved',"
1688 "path='/org/freedesktop/systemd1'",
1691 log_error("Failed to add match");
1695 /* This is slightly dirty, since we don't undo the match registrations. */
1699 static int wait_for_jobs(sd_bus
*bus
, Set
*s
) {
1700 WaitData d
= { .set
= s
};
1706 r
= sd_bus_add_filter(bus
, wait_filter
, &d
);
1710 while (!set_isempty(s
)) {
1712 r
= sd_bus_process(bus
, NULL
);
1717 r
= sd_bus_wait(bus
, (uint64_t) -1);
1726 if (streq(d
.result
, "timeout"))
1727 log_error("Job for %s timed out.", strna(d
.name
));
1728 else if (streq(d
.result
, "canceled"))
1729 log_error("Job for %s canceled.", strna(d
.name
));
1730 else if (streq(d
.result
, "dependency"))
1731 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d
.name
));
1732 else if (!streq(d
.result
, "done") && !streq(d
.result
, "skipped"))
1733 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d
.name
), strna(d
.name
));
1736 if (streq_ptr(d
.result
, "timeout"))
1738 else if (streq_ptr(d
.result
, "canceled"))
1740 else if (!streq_ptr(d
.result
, "done") && !streq_ptr(d
.result
, "skipped"))
1751 return sd_bus_remove_filter(bus
, wait_filter
, &d
);
1754 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
1755 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1756 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
1762 n
= unit_name_mangle(name
);
1766 /* We don't use unit_dbus_path_from_name() directly since we
1767 * don't want to load the unit if it isn't loaded. */
1769 r
= sd_bus_call_method(
1771 "org.freedesktop.systemd1",
1772 "/org/freedesktop/systemd1",
1773 "org.freedesktop.systemd1.Manager",
1784 r
= sd_bus_message_read(reply
, "o", &path
);
1786 return bus_log_parse_error(r
);
1788 r
= sd_bus_get_property_string(
1790 "org.freedesktop.systemd1",
1792 "org.freedesktop.systemd1.Unit",
1805 return nulstr_contains(good_states
, state
);
1808 static int check_triggering_units(
1812 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1813 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
1814 _cleanup_strv_free_
char **triggered_by
= NULL
;
1815 bool print_warning_label
= true;
1819 n
= unit_name_mangle(name
);
1823 path
= unit_dbus_path_from_name(n
);
1827 r
= sd_bus_get_property_string(
1829 "org.freedesktop.systemd1",
1831 "org.freedesktop.systemd1.Unit",
1836 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
1840 if (streq(state
, "masked"))
1843 r
= sd_bus_get_property_strv(
1845 "org.freedesktop.systemd1",
1847 "org.freedesktop.systemd1.Unit",
1852 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
1856 STRV_FOREACH(i
, triggered_by
) {
1857 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
1859 log_error("Failed to check unit: %s", strerror(-r
));
1866 if (print_warning_label
) {
1867 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
1868 print_warning_label
= false;
1871 log_warning(" %s", *i
);
1877 static int start_unit_one(
1882 sd_bus_error
*error
,
1885 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1886 _cleanup_free_
char *n
;
1895 n
= unit_name_mangle(name
);
1899 r
= sd_bus_call_method(
1901 "org.freedesktop.systemd1",
1902 "/org/freedesktop/systemd1",
1903 "org.freedesktop.systemd1.Manager",
1909 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
1910 /* There's always a fallback possible for
1911 * legacy actions. */
1912 return -EADDRNOTAVAIL
;
1914 log_error("Failed to start %s: %s", name
, bus_error_message(error
, r
));
1918 r
= sd_bus_message_read(reply
, "o", &path
);
1920 return bus_log_parse_error(r
);
1922 if (need_daemon_reload(bus
, n
) > 0)
1923 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
1924 n
, arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
1933 r
= set_consume(s
, p
);
1941 static const struct {
1945 } action_table
[_ACTION_MAX
] = {
1946 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
1947 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
1948 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
1949 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
1950 [ACTION_RUNLEVEL2
] = { SPECIAL_RUNLEVEL2_TARGET
, NULL
, "isolate" },
1951 [ACTION_RUNLEVEL3
] = { SPECIAL_RUNLEVEL3_TARGET
, NULL
, "isolate" },
1952 [ACTION_RUNLEVEL4
] = { SPECIAL_RUNLEVEL4_TARGET
, NULL
, "isolate" },
1953 [ACTION_RUNLEVEL5
] = { SPECIAL_RUNLEVEL5_TARGET
, NULL
, "isolate" },
1954 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
1955 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
1956 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
1957 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
1958 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
1959 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
1960 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
1963 static enum action
verb_to_action(const char *verb
) {
1966 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
1967 if (streq_ptr(action_table
[i
].verb
, verb
))
1970 return _ACTION_INVALID
;
1973 static int start_unit(sd_bus
*bus
, char **args
) {
1974 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1975 _cleanup_set_free_free_ Set
*s
= NULL
;
1976 const char *method
, *mode
, *one_name
;
1982 ask_password_agent_open_if_enabled();
1984 if (arg_action
== ACTION_SYSTEMCTL
) {
1987 streq(args
[0], "stop") ||
1988 streq(args
[0], "condstop") ? "StopUnit" :
1989 streq(args
[0], "reload") ? "ReloadUnit" :
1990 streq(args
[0], "restart") ? "RestartUnit" :
1992 streq(args
[0], "try-restart") ||
1993 streq(args
[0], "condrestart") ? "TryRestartUnit" :
1995 streq(args
[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
1997 streq(args
[0], "reload-or-try-restart") ||
1998 streq(args
[0], "condreload") ||
1999 streq(args
[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2001 action
= verb_to_action(args
[0]);
2003 mode
= streq(args
[0], "isolate") ? "isolate" :
2004 action_table
[action
].mode
?: arg_job_mode
;
2006 one_name
= action_table
[action
].target
;
2008 assert(arg_action
< ELEMENTSOF(action_table
));
2009 assert(action_table
[arg_action
].target
);
2011 method
= "StartUnit";
2013 mode
= action_table
[arg_action
].mode
;
2014 one_name
= action_table
[arg_action
].target
;
2017 if (!arg_no_block
) {
2018 r
= enable_wait_for_jobs(bus
);
2020 log_error("Could not watch jobs: %s", strerror(-r
));
2024 s
= set_new(string_hash_func
, string_compare_func
);
2030 r
= start_unit_one(bus
, method
, one_name
, mode
, &error
, s
);
2032 r
= translate_bus_error_to_exit_status(r
, &error
);
2036 STRV_FOREACH(name
, args
+1) {
2039 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, s
);
2041 r
= translate_bus_error_to_exit_status(r
, &error
);
2042 sd_bus_error_free(&error
);
2047 if (!arg_no_block
) {
2050 q
= wait_for_jobs(bus
, s
);
2054 /* When stopping units, warn if they can still be triggered by
2055 * another active unit (socket, path, timer) */
2056 if (!arg_quiet
&& streq(method
, "StopUnit")) {
2058 check_triggering_units(bus
, one_name
);
2060 STRV_FOREACH(name
, args
+1)
2061 check_triggering_units(bus
, *name
);
2068 /* Ask systemd-logind, which might grant access to unprivileged users
2069 * through PolicyKit */
2070 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
2072 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2079 polkit_agent_open_if_enabled();
2087 case ACTION_POWEROFF
:
2088 method
= "PowerOff";
2091 case ACTION_SUSPEND
:
2095 case ACTION_HIBERNATE
:
2096 method
= "Hibernate";
2099 case ACTION_HYBRID_SLEEP
:
2100 method
= "HybridSleep";
2107 r
= sd_bus_call_method(
2109 "org.freedesktop.login1",
2110 "/org/freedesktop/login1",
2111 "org.freedesktop.login1.Manager",
2117 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
2125 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
2127 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2128 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2129 _cleanup_strv_free_
char **sessions
= NULL
;
2130 const char *what
, *who
, *why
, *mode
;
2139 if (arg_ignore_inhibitors
|| arg_force
> 0)
2151 r
= sd_bus_call_method(
2153 "org.freedesktop.login1",
2154 "/org/freedesktop/login1",
2155 "org.freedesktop.login1.Manager",
2161 /* If logind is not around, then there are no inhibitors... */
2164 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2166 return bus_log_parse_error(r
);
2168 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2169 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2170 _cleanup_strv_free_
char **sv
= NULL
;
2172 if (!streq(mode
, "block"))
2175 sv
= strv_split(what
, ":");
2179 if (!strv_contains(sv
,
2181 a
== ACTION_POWEROFF
||
2182 a
== ACTION_REBOOT
||
2183 a
== ACTION_KEXEC
? "shutdown" : "sleep"))
2186 get_process_comm(pid
, &comm
);
2187 user
= uid_to_name(uid
);
2189 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2190 who
, (unsigned long) pid
, strna(comm
), strna(user
), why
);
2195 return bus_log_parse_error(r
);
2197 r
= sd_bus_message_exit_container(reply
);
2199 return bus_log_parse_error(r
);
2201 /* Check for current sessions */
2202 sd_get_sessions(&sessions
);
2203 STRV_FOREACH(s
, sessions
) {
2204 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2206 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2209 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2212 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2215 sd_session_get_tty(*s
, &tty
);
2216 sd_session_get_seat(*s
, &seat
);
2217 sd_session_get_service(*s
, &service
);
2218 user
= uid_to_name(uid
);
2220 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2227 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2228 action_table
[a
].verb
);
2236 static int start_special(sd_bus
*bus
, char **args
) {
2242 a
= verb_to_action(args
[0]);
2244 r
= check_inhibitors(bus
, a
);
2248 if (arg_force
>= 2 && geteuid() != 0) {
2249 log_error("Must be root.");
2253 if (arg_force
>= 2 &&
2254 (a
== ACTION_HALT
||
2255 a
== ACTION_POWEROFF
||
2256 a
== ACTION_REBOOT
))
2259 if (arg_force
>= 1 &&
2260 (a
== ACTION_HALT
||
2261 a
== ACTION_POWEROFF
||
2262 a
== ACTION_REBOOT
||
2263 a
== ACTION_KEXEC
||
2265 return daemon_reload(bus
, args
);
2267 /* first try logind, to allow authentication with polkit */
2268 if (geteuid() != 0 &&
2269 (a
== ACTION_POWEROFF
||
2270 a
== ACTION_REBOOT
||
2271 a
== ACTION_SUSPEND
||
2272 a
== ACTION_HIBERNATE
||
2273 a
== ACTION_HYBRID_SLEEP
)) {
2274 r
= reboot_with_logind(bus
, a
);
2279 r
= start_unit(bus
, args
);
2280 if (r
== EXIT_SUCCESS
)
2286 static int check_unit_active(sd_bus
*bus
, char **args
) {
2288 int r
= 3; /* According to LSB: "program is not running" */
2293 STRV_FOREACH(name
, args
+1) {
2296 state
= check_one_unit(bus
, *name
, "active\0reloading\0", arg_quiet
);
2306 static int check_unit_failed(sd_bus
*bus
, char **args
) {
2313 STRV_FOREACH(name
, args
+1) {
2316 state
= check_one_unit(bus
, *name
, "failed\0", arg_quiet
);
2326 static int kill_unit(sd_bus
*bus
, char **args
) {
2327 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2335 arg_kill_who
= "all";
2337 STRV_FOREACH(name
, args
+1) {
2338 _cleanup_free_
char *n
= NULL
;
2340 n
= unit_name_mangle(*name
);
2344 r
= sd_bus_call_method(
2346 "org.freedesktop.systemd1",
2347 "/org/freedesktop/systemd1",
2348 "org.freedesktop.systemd1.Manager",
2352 "ssi", n
, arg_kill_who
, arg_signal
);
2354 log_error("Failed to kill unit %s: %s", n
, bus_error_message(&error
, r
));
2362 typedef struct ExecStatusInfo
{
2370 usec_t start_timestamp
;
2371 usec_t exit_timestamp
;
2376 LIST_FIELDS(struct ExecStatusInfo
, exec
);
2379 static void exec_status_info_free(ExecStatusInfo
*i
) {
2388 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
2389 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
2392 int32_t code
, status
;
2398 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
2400 return bus_log_parse_error(r
);
2404 r
= sd_bus_message_read(m
, "s", &path
);
2406 return bus_log_parse_error(r
);
2408 i
->path
= strdup(path
);
2412 r
= sd_bus_message_read_strv(m
, &i
->argv
);
2414 return bus_log_parse_error(r
);
2416 r
= sd_bus_message_read(m
,
2419 &start_timestamp
, &start_timestamp_monotonic
,
2420 &exit_timestamp
, &exit_timestamp_monotonic
,
2424 return bus_log_parse_error(r
);
2427 i
->start_timestamp
= (usec_t
) start_timestamp
;
2428 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
2429 i
->pid
= (pid_t
) pid
;
2433 r
= sd_bus_message_exit_container(m
);
2435 return bus_log_parse_error(r
);
2440 typedef struct UnitStatusInfo
{
2442 const char *load_state
;
2443 const char *active_state
;
2444 const char *sub_state
;
2445 const char *unit_file_state
;
2447 const char *description
;
2448 const char *following
;
2450 char **documentation
;
2452 const char *fragment_path
;
2453 const char *source_path
;
2454 const char *control_group
;
2456 char **dropin_paths
;
2458 const char *load_error
;
2461 usec_t inactive_exit_timestamp
;
2462 usec_t inactive_exit_timestamp_monotonic
;
2463 usec_t active_enter_timestamp
;
2464 usec_t active_exit_timestamp
;
2465 usec_t inactive_enter_timestamp
;
2467 bool need_daemon_reload
;
2472 const char *status_text
;
2473 const char *pid_file
;
2476 usec_t start_timestamp
;
2477 usec_t exit_timestamp
;
2479 int exit_code
, exit_status
;
2481 usec_t condition_timestamp
;
2482 bool condition_result
;
2483 bool failed_condition_trigger
;
2484 bool failed_condition_negate
;
2485 const char *failed_condition
;
2486 const char *failed_condition_param
;
2489 unsigned n_accepted
;
2490 unsigned n_connections
;
2493 /* Pairs of type, path */
2497 const char *sysfs_path
;
2499 /* Mount, Automount */
2505 LIST_HEAD(ExecStatusInfo
, exec
);
2508 static void print_status_info(
2513 const char *on
, *off
, *ss
;
2515 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
2516 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
2519 arg_all
* OUTPUT_SHOW_ALL
|
2520 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
2521 on_tty() * OUTPUT_COLOR
|
2522 !arg_quiet
* OUTPUT_WARN_CUTOFF
|
2523 arg_full
* OUTPUT_FULL_WIDTH
;
2528 /* This shows pretty information about a unit. See
2529 * print_property() for a low-level property printer */
2531 printf("%s", strna(i
->id
));
2533 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
2534 printf(" - %s", i
->description
);
2539 printf(" Follow: unit currently follows state of %s\n", i
->following
);
2541 if (streq_ptr(i
->load_state
, "error")) {
2542 on
= ansi_highlight_red();
2543 off
= ansi_highlight_off();
2547 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
2550 printf(" Loaded: %s%s%s (Reason: %s)\n",
2551 on
, strna(i
->load_state
), off
, i
->load_error
);
2552 else if (path
&& i
->unit_file_state
)
2553 printf(" Loaded: %s%s%s (%s; %s)\n",
2554 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
2556 printf(" Loaded: %s%s%s (%s)\n",
2557 on
, strna(i
->load_state
), off
, path
);
2559 printf(" Loaded: %s%s%s\n",
2560 on
, strna(i
->load_state
), off
);
2562 if (!strv_isempty(i
->dropin_paths
)) {
2563 _cleanup_free_
char *dir
= NULL
;
2567 STRV_FOREACH(dropin
, i
->dropin_paths
) {
2568 if (! dir
|| last
) {
2569 printf(dir
? " " : " Drop-In: ");
2574 if (path_get_parent(*dropin
, &dir
) < 0) {
2579 printf("%s\n %s", dir
,
2580 draw_special_char(DRAW_TREE_RIGHT
));
2583 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
2585 printf("%s%s", path_get_file_name(*dropin
), last
? "\n" : ", ");
2589 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
2591 if (streq_ptr(i
->active_state
, "failed")) {
2592 on
= ansi_highlight_red();
2593 off
= ansi_highlight_off();
2594 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
2595 on
= ansi_highlight_green();
2596 off
= ansi_highlight_off();
2601 printf(" Active: %s%s (%s)%s",
2602 on
, strna(i
->active_state
), ss
, off
);
2604 printf(" Active: %s%s%s",
2605 on
, strna(i
->active_state
), off
);
2607 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
2608 printf(" (Result: %s)", i
->result
);
2610 timestamp
= (streq_ptr(i
->active_state
, "active") ||
2611 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
2612 (streq_ptr(i
->active_state
, "inactive") ||
2613 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
2614 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
2615 i
->active_exit_timestamp
;
2617 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
2618 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
2621 printf(" since %s; %s\n", s2
, s1
);
2623 printf(" since %s\n", s2
);
2627 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
2628 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
2629 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
2631 printf(" start condition failed at %s%s%s\n",
2632 s2
, s1
? "; " : "", s1
? s1
: "");
2633 if (i
->failed_condition_trigger
)
2634 printf(" none of the trigger conditions were met\n");
2635 else if (i
->failed_condition
)
2636 printf(" %s=%s%s was not met\n",
2637 i
->failed_condition
,
2638 i
->failed_condition_negate
? "!" : "",
2639 i
->failed_condition_param
);
2643 printf(" Device: %s\n", i
->sysfs_path
);
2645 printf(" Where: %s\n", i
->where
);
2647 printf(" What: %s\n", i
->what
);
2649 STRV_FOREACH(t
, i
->documentation
)
2650 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
2652 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
2653 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
2656 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
2658 LIST_FOREACH(exec
, p
, i
->exec
) {
2659 _cleanup_free_
char *argv
= NULL
;
2662 /* Only show exited processes here */
2666 argv
= strv_join(p
->argv
, " ");
2667 printf(" Process: %u %s=%s ", p
->pid
, p
->name
, strna(argv
));
2669 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
2671 on
= ansi_highlight_red();
2672 off
= ansi_highlight_off();
2676 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
2678 if (p
->code
== CLD_EXITED
) {
2681 printf("status=%i", p
->status
);
2683 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
2688 printf("signal=%s", signal_to_string(p
->status
));
2690 printf(")%s\n", off
);
2692 if (i
->main_pid
== p
->pid
&&
2693 i
->start_timestamp
== p
->start_timestamp
&&
2694 i
->exit_timestamp
== p
->start_timestamp
)
2695 /* Let's not show this twice */
2698 if (p
->pid
== i
->control_pid
)
2702 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
2703 if (i
->main_pid
> 0) {
2704 printf(" Main PID: %u", (unsigned) i
->main_pid
);
2707 _cleanup_free_
char *comm
= NULL
;
2708 get_process_comm(i
->main_pid
, &comm
);
2710 printf(" (%s)", comm
);
2711 } else if (i
->exit_code
> 0) {
2712 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
2714 if (i
->exit_code
== CLD_EXITED
) {
2717 printf("status=%i", i
->exit_status
);
2719 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
2724 printf("signal=%s", signal_to_string(i
->exit_status
));
2728 if (i
->control_pid
> 0)
2732 if (i
->control_pid
> 0) {
2733 _cleanup_free_
char *c
= NULL
;
2735 printf(" %8s: %u", i
->main_pid
? "" : " Control", (unsigned) i
->control_pid
);
2737 get_process_comm(i
->control_pid
, &c
);
2746 printf(" Status: \"%s\"\n", i
->status_text
);
2748 if (i
->control_group
&&
2749 (i
->main_pid
> 0 || i
->control_pid
> 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, false) == 0)) {
2752 printf(" CGroup: %s\n", i
->control_group
);
2754 if (arg_transport
== BUS_TRANSPORT_LOCAL
|| arg_transport
== BUS_TRANSPORT_CONTAINER
) {
2757 char prefix
[] = " ";
2760 if (c
> sizeof(prefix
) - 1)
2761 c
-= sizeof(prefix
) - 1;
2765 if (i
->main_pid
> 0)
2766 extra
[k
++] = i
->main_pid
;
2768 if (i
->control_pid
> 0)
2769 extra
[k
++] = i
->control_pid
;
2771 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
,
2772 c
, false, extra
, k
, flags
);
2776 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
) {
2778 show_journal_by_unit(stdout
,
2782 i
->inactive_exit_timestamp_monotonic
,
2786 arg_scope
== UNIT_FILE_SYSTEM
,
2790 if (i
->need_daemon_reload
)
2791 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2792 ansi_highlight_red(),
2793 ansi_highlight_off(),
2794 arg_scope
== UNIT_FILE_SYSTEM
? "" : "--user ");
2797 static void show_unit_help(UnitStatusInfo
*i
) {
2802 if (!i
->documentation
) {
2803 log_info("Documentation for %s not known.", i
->id
);
2807 STRV_FOREACH(p
, i
->documentation
) {
2809 if (startswith(*p
, "man:")) {
2810 const char *args
[4] = { "man", NULL
, NULL
, NULL
};
2811 _cleanup_free_
char *page
= NULL
, *section
= NULL
;
2818 if ((*p
)[k
-1] == ')')
2819 e
= strrchr(*p
, '(');
2822 page
= strndup((*p
) + 4, e
- *p
- 4);
2823 section
= strndup(e
+ 1, *p
+ k
- e
- 2);
2824 if (!page
|| !section
) {
2836 log_error("Failed to fork: %m");
2842 execvp(args
[0], (char**) args
);
2843 log_error("Failed to execute man: %m");
2844 _exit(EXIT_FAILURE
);
2847 wait_for_terminate(pid
, NULL
);
2849 log_info("Can't show: %s", *p
);
2853 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
2860 switch (contents
[0]) {
2862 case SD_BUS_TYPE_STRING
: {
2865 r
= sd_bus_message_read(m
, "s", &s
);
2867 return bus_log_parse_error(r
);
2870 if (streq(name
, "Id"))
2872 else if (streq(name
, "LoadState"))
2874 else if (streq(name
, "ActiveState"))
2875 i
->active_state
= s
;
2876 else if (streq(name
, "SubState"))
2878 else if (streq(name
, "Description"))
2880 else if (streq(name
, "FragmentPath"))
2881 i
->fragment_path
= s
;
2882 else if (streq(name
, "SourcePath"))
2885 else if (streq(name
, "DefaultControlGroup")) {
2887 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
2889 i
->control_group
= e
;
2892 else if (streq(name
, "ControlGroup"))
2893 i
->control_group
= s
;
2894 else if (streq(name
, "StatusText"))
2896 else if (streq(name
, "PIDFile"))
2898 else if (streq(name
, "SysFSPath"))
2900 else if (streq(name
, "Where"))
2902 else if (streq(name
, "What"))
2904 else if (streq(name
, "Following"))
2906 else if (streq(name
, "UnitFileState"))
2907 i
->unit_file_state
= s
;
2908 else if (streq(name
, "Result"))
2915 case SD_BUS_TYPE_BOOLEAN
: {
2918 r
= sd_bus_message_read(m
, "b", &b
);
2920 return bus_log_parse_error(r
);
2922 if (streq(name
, "Accept"))
2924 else if (streq(name
, "NeedDaemonReload"))
2925 i
->need_daemon_reload
= b
;
2926 else if (streq(name
, "ConditionResult"))
2927 i
->condition_result
= b
;
2932 case SD_BUS_TYPE_UINT32
: {
2935 r
= sd_bus_message_read(m
, "u", &u
);
2937 return bus_log_parse_error(r
);
2939 if (streq(name
, "MainPID")) {
2941 i
->main_pid
= (pid_t
) u
;
2944 } else if (streq(name
, "ControlPID"))
2945 i
->control_pid
= (pid_t
) u
;
2946 else if (streq(name
, "ExecMainPID")) {
2948 i
->main_pid
= (pid_t
) u
;
2949 } else if (streq(name
, "NAccepted"))
2951 else if (streq(name
, "NConnections"))
2952 i
->n_connections
= u
;
2957 case SD_BUS_TYPE_INT32
: {
2960 r
= sd_bus_message_read(m
, "i", &j
);
2962 return bus_log_parse_error(r
);
2964 if (streq(name
, "ExecMainCode"))
2965 i
->exit_code
= (int) j
;
2966 else if (streq(name
, "ExecMainStatus"))
2967 i
->exit_status
= (int) j
;
2972 case SD_BUS_TYPE_UINT64
: {
2975 r
= sd_bus_message_read(m
, "t", &u
);
2977 return bus_log_parse_error(r
);
2979 if (streq(name
, "ExecMainStartTimestamp"))
2980 i
->start_timestamp
= (usec_t
) u
;
2981 else if (streq(name
, "ExecMainExitTimestamp"))
2982 i
->exit_timestamp
= (usec_t
) u
;
2983 else if (streq(name
, "ActiveEnterTimestamp"))
2984 i
->active_enter_timestamp
= (usec_t
) u
;
2985 else if (streq(name
, "InactiveEnterTimestamp"))
2986 i
->inactive_enter_timestamp
= (usec_t
) u
;
2987 else if (streq(name
, "InactiveExitTimestamp"))
2988 i
->inactive_exit_timestamp
= (usec_t
) u
;
2989 else if (streq(name
, "InactiveExitTimestampMonotonic"))
2990 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
2991 else if (streq(name
, "ActiveExitTimestamp"))
2992 i
->active_exit_timestamp
= (usec_t
) u
;
2993 else if (streq(name
, "ConditionTimestamp"))
2994 i
->condition_timestamp
= (usec_t
) u
;
2999 case SD_BUS_TYPE_ARRAY
:
3001 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3002 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3004 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3006 return bus_log_parse_error(r
);
3008 info
= new0(ExecStatusInfo
, 1);
3012 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3014 info
->name
= strdup(name
);
3018 LIST_PREPEND(exec
, i
->exec
, info
);
3020 info
= new0(ExecStatusInfo
, 1);
3026 return bus_log_parse_error(r
);
3028 r
= sd_bus_message_exit_container(m
);
3030 return bus_log_parse_error(r
);
3034 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3035 const char *type
, *path
;
3037 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3039 return bus_log_parse_error(r
);
3041 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3043 r
= strv_extend(&i
->listen
, type
);
3047 r
= strv_extend(&i
->listen
, path
);
3052 return bus_log_parse_error(r
);
3054 r
= sd_bus_message_exit_container(m
);
3056 return bus_log_parse_error(r
);
3060 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3062 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3064 return bus_log_parse_error(r
);
3066 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3068 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3070 return bus_log_parse_error(r
);
3072 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3073 const char *cond
, *param
;
3074 int trigger
, negate
;
3077 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3079 return bus_log_parse_error(r
);
3081 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3082 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3083 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3084 i
->failed_condition
= cond
;
3085 i
->failed_condition_trigger
= trigger
;
3086 i
->failed_condition_negate
= negate
;
3087 i
->failed_condition_param
= param
;
3091 return bus_log_parse_error(r
);
3093 r
= sd_bus_message_exit_container(m
);
3095 return bus_log_parse_error(r
);
3102 case SD_BUS_TYPE_STRUCT_BEGIN
:
3104 if (streq(name
, "LoadError")) {
3105 const char *n
, *message
;
3107 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3109 return bus_log_parse_error(r
);
3111 if (!isempty(message
))
3112 i
->load_error
= message
;
3125 r
= sd_bus_message_skip(m
, contents
);
3127 return bus_log_parse_error(r
);
3132 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
3138 /* This is a low-level property printer, see
3139 * print_status_info() for the nicer output */
3141 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
3142 /* skip what we didn't read */
3143 r
= sd_bus_message_skip(m
, contents
);
3147 switch (contents
[0]) {
3149 case SD_BUS_TYPE_STRUCT_BEGIN
:
3151 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
3154 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
3156 return bus_log_parse_error(r
);
3159 printf("%s=%u\n", name
, (unsigned) u
);
3161 printf("%s=\n", name
);
3165 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
3168 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
3170 return bus_log_parse_error(r
);
3172 if (arg_all
|| !isempty(s
))
3173 printf("%s=%s\n", name
, s
);
3177 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
3178 const char *a
= NULL
, *b
= NULL
;
3180 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
3182 return bus_log_parse_error(r
);
3184 if (arg_all
|| !isempty(a
) || !isempty(b
))
3185 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
3192 case SD_BUS_TYPE_ARRAY
:
3194 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
3198 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
3200 return bus_log_parse_error(r
);
3202 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
3203 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
3206 return bus_log_parse_error(r
);
3208 r
= sd_bus_message_exit_container(m
);
3210 return bus_log_parse_error(r
);
3214 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
3215 const char *type
, *path
;
3217 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3219 return bus_log_parse_error(r
);
3221 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3222 printf("%s=%s\n", type
, path
);
3224 return bus_log_parse_error(r
);
3226 r
= sd_bus_message_exit_container(m
);
3228 return bus_log_parse_error(r
);
3232 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3233 const char *type
, *path
;
3235 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3237 return bus_log_parse_error(r
);
3239 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3240 printf("Listen%s=%s\n", type
, path
);
3242 return bus_log_parse_error(r
);
3244 r
= sd_bus_message_exit_container(m
);
3246 return bus_log_parse_error(r
);
3250 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
3252 uint64_t value
, next_elapse
;
3254 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
3256 return bus_log_parse_error(r
);
3258 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
3259 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
3261 printf("%s={ value=%s ; next_elapse=%s }\n",
3263 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
3264 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
3267 return bus_log_parse_error(r
);
3269 r
= sd_bus_message_exit_container(m
);
3271 return bus_log_parse_error(r
);
3275 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3276 ExecStatusInfo info
= {};
3278 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3280 return bus_log_parse_error(r
);
3282 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
3283 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
3284 _cleanup_free_
char *tt
;
3286 tt
= strv_join(info
.argv
, " ");
3288 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3292 yes_no(info
.ignore
),
3293 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
3294 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
3295 (unsigned) info
. pid
,
3296 sigchld_code_to_string(info
.code
),
3298 info
.code
== CLD_EXITED
? "" : "/",
3299 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
3302 strv_free(info
.argv
);
3306 r
= sd_bus_message_exit_container(m
);
3308 return bus_log_parse_error(r
);
3312 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
3313 const char *path
, *rwm
;
3315 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3317 return bus_log_parse_error(r
);
3319 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
3320 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
3322 return bus_log_parse_error(r
);
3324 r
= sd_bus_message_exit_container(m
);
3326 return bus_log_parse_error(r
);
3330 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
3334 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3336 return bus_log_parse_error(r
);
3338 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
3339 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
3341 return bus_log_parse_error(r
);
3343 r
= sd_bus_message_exit_container(m
);
3345 return bus_log_parse_error(r
);
3349 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
3353 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3355 return bus_log_parse_error(r
);
3357 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
3358 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
3360 return bus_log_parse_error(r
);
3362 r
= sd_bus_message_exit_container(m
);
3364 return bus_log_parse_error(r
);
3372 r
= bus_print_property(name
, m
, arg_all
);
3374 return bus_log_parse_error(r
);
3377 r
= sd_bus_message_skip(m
, contents
);
3379 return bus_log_parse_error(r
);
3382 printf("%s=[unprintable]\n", name
);
3388 static int show_one(
3392 bool show_properties
,
3396 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3397 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3398 UnitStatusInfo info
= {};
3405 r
= sd_bus_call_method(
3407 "org.freedesktop.systemd1",
3409 "org.freedesktop.DBus.Properties",
3415 log_error("Failed to get properties: %s", bus_error_message(&error
, r
));
3419 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
3421 return bus_log_parse_error(r
);
3428 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
3429 const char *name
, *contents
;
3431 r
= sd_bus_message_read(reply
, "s", &name
);
3433 return bus_log_parse_error(r
);
3435 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
3437 return bus_log_parse_error(r
);
3439 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
3441 return bus_log_parse_error(r
);
3443 if (show_properties
)
3444 r
= print_property(name
, reply
, contents
);
3446 r
= status_property(name
, reply
, &info
, contents
);
3450 r
= sd_bus_message_exit_container(reply
);
3452 return bus_log_parse_error(r
);
3454 r
= sd_bus_message_exit_container(reply
);
3456 return bus_log_parse_error(r
);
3459 return bus_log_parse_error(r
);
3461 r
= sd_bus_message_exit_container(reply
);
3463 return bus_log_parse_error(r
);
3467 if (!show_properties
) {
3468 if (streq(verb
, "help"))
3469 show_unit_help(&info
);
3471 print_status_info(&info
, ellipsized
);
3474 strv_free(info
.documentation
);
3475 strv_free(info
.dropin_paths
);
3476 strv_free(info
.listen
);
3478 if (!streq_ptr(info
.active_state
, "active") &&
3479 !streq_ptr(info
.active_state
, "reloading") &&
3480 streq(verb
, "status")) {
3481 /* According to LSB: "program not running" */
3482 /* 0: program is running or service is OK
3483 * 1: program is dead and /var/run pid file exists
3484 * 2: program is dead and /var/lock lock file exists
3485 * 3: program is not running
3486 * 4: program or service status is unknown
3488 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
3494 while ((p
= info
.exec
)) {
3495 LIST_REMOVE(exec
, info
.exec
, p
);
3496 exec_status_info_free(p
);
3502 static int show_one_by_pid(
3509 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3510 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3511 const char *path
= NULL
;
3514 r
= sd_bus_call_method(
3516 "org.freedesktop.systemd1",
3517 "/org/freedesktop/systemd1",
3518 "org.freedesktop.systemd1.Manager",
3524 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid
, bus_error_message(&error
, r
));
3528 r
= sd_bus_message_read(reply
, "o", &path
);
3530 return bus_log_parse_error(r
);
3532 return show_one(verb
, bus
, path
, false, new_line
, ellipsized
);
3535 static int show_all(
3538 bool show_properties
,
3542 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3543 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3544 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3549 r
= get_unit_list(bus
, &reply
, &unit_infos
);
3555 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
3557 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
3558 _cleanup_free_
char *p
= NULL
;
3560 if (!output_show_unit(u
))
3563 p
= unit_dbus_path_from_name(u
->id
);
3567 printf("%s -> '%s'\n", u
->id
, p
);
3569 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
3577 static int show(sd_bus
*bus
, char **args
) {
3579 bool show_properties
, show_status
, new_line
= false;
3581 bool ellipsized
= false;
3586 show_properties
= streq(args
[0], "show");
3587 show_status
= streq(args
[0], "status");
3589 if (show_properties
)
3590 pager_open_if_enabled();
3592 /* If no argument is specified inspect the manager itself */
3594 if (show_properties
&& strv_length(args
) <= 1)
3595 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
3597 if (show_status
&& strv_length(args
) <= 1)
3598 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
3600 STRV_FOREACH(name
, args
+1) {
3603 if (safe_atou32(*name
, &id
) < 0) {
3604 _cleanup_free_
char *p
= NULL
, *n
= NULL
;
3605 /* Interpret as unit name */
3607 n
= unit_name_mangle(*name
);
3611 p
= unit_dbus_path_from_name(n
);
3615 r
= show_one(args
[0], bus
, p
, show_properties
, &new_line
, &ellipsized
);
3619 } else if (show_properties
) {
3620 _cleanup_free_
char *p
= NULL
;
3622 /* Interpret as job id */
3623 if (asprintf(&p
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
3626 r
= show_one(args
[0], bus
, p
, show_properties
, &new_line
, &ellipsized
);
3631 /* Interpret as PID */
3632 r
= show_one_by_pid(args
[0], bus
, id
, &new_line
, &ellipsized
);
3638 if (ellipsized
&& !arg_quiet
)
3639 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3644 static int append_assignment(sd_bus_message
*m
, const char *assignment
) {
3652 eq
= strchr(assignment
, '=');
3654 log_error("Not an assignment: %s", assignment
);
3658 field
= strndupa(assignment
, eq
- assignment
);
3661 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, field
);
3663 return bus_log_create_error(r
);
3665 if (streq(field
, "CPUAccounting") ||
3666 streq(field
, "MemoryAccounting") ||
3667 streq(field
, "BlockIOAccounting")) {
3669 r
= parse_boolean(eq
);
3671 log_error("Failed to parse boolean assignment %s.", assignment
);
3675 r
= sd_bus_message_append(m
, "v", "b", r
);
3677 } else if (streq(field
, "MemoryLimit")) {
3680 r
= parse_bytes(eq
, &bytes
);
3682 log_error("Failed to parse bytes specification %s", assignment
);
3686 r
= sd_bus_message_append(m
, "v", "t", (uint64_t) bytes
);
3688 } else if (streq(field
, "CPUShares") || streq(field
, "BlockIOWeight")) {
3691 r
= safe_atou64(eq
, &u
);
3693 log_error("Failed to parse %s value %s.", field
, eq
);
3697 r
= sd_bus_message_append(m
, "v", "t", u
);
3699 } else if (streq(field
, "DevicePolicy"))
3700 r
= sd_bus_message_append(m
, "v", "s", eq
);
3702 else if (streq(field
, "DeviceAllow")) {
3705 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
3707 const char *path
, *rwm
;
3710 e
= strchr(eq
, ' ');
3712 path
= strndupa(eq
, e
- eq
);
3719 if (!path_startswith(path
, "/dev")) {
3720 log_error("%s is not a device file in /dev.", path
);
3724 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
3727 } else if (streq(field
, "BlockIOReadBandwidth") || streq(field
, "BlockIOWriteBandwidth")) {
3730 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
3732 const char *path
, *bandwidth
;
3736 e
= strchr(eq
, ' ');
3738 path
= strndupa(eq
, e
- eq
);
3741 log_error("Failed to parse %s value %s.", field
, eq
);
3745 if (!path_startswith(path
, "/dev")) {
3746 log_error("%s is not a device file in /dev.", path
);
3750 r
= parse_bytes(bandwidth
, &bytes
);
3752 log_error("Failed to parse byte value %s.", bandwidth
);
3756 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, (uint64_t) bytes
);
3759 } else if (streq(field
, "BlockIODeviceWeight")) {
3762 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
3764 const char *path
, *weight
;
3768 e
= strchr(eq
, ' ');
3770 path
= strndupa(eq
, e
- eq
);
3773 log_error("Failed to parse %s value %s.", field
, eq
);
3777 if (!path_startswith(path
, "/dev")) {
3778 log_error("%s is not a device file in /dev.", path
);
3782 r
= safe_atou64(weight
, &u
);
3784 log_error("Failed to parse %s value %s.", field
, weight
);
3787 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
3791 log_error("Unknown assignment %s.", assignment
);
3796 return bus_log_create_error(r
);
3801 static int set_property(sd_bus
*bus
, char **args
) {
3802 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
3803 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3804 _cleanup_free_
char *n
= NULL
;
3808 r
= sd_bus_message_new_method_call(
3810 "org.freedesktop.systemd1",
3811 "/org/freedesktop/systemd1",
3812 "org.freedesktop.systemd1.Manager",
3813 "SetUnitProperties",
3816 return bus_log_create_error(r
);
3818 n
= unit_name_mangle(args
[1]);
3822 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
3824 return bus_log_create_error(r
);
3826 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
3828 return bus_log_create_error(r
);
3830 STRV_FOREACH(i
, args
+ 2) {
3831 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
3833 return bus_log_create_error(r
);
3835 r
= append_assignment(m
, *i
);
3839 r
= sd_bus_message_close_container(m
);
3841 return bus_log_create_error(r
);
3844 r
= sd_bus_message_close_container(m
);
3846 return bus_log_create_error(r
);
3848 r
= sd_bus_send_with_reply_and_block(bus
, m
, -1, &error
, NULL
);
3850 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
3857 static int snapshot(sd_bus
*bus
, char **args
) {
3858 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3859 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3860 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
3864 if (strv_length(args
) > 1)
3865 n
= unit_name_mangle_with_suffix(args
[1], ".snapshot");
3871 r
= sd_bus_call_method(
3873 "org.freedesktop.systemd1",
3874 "/org/freedesktop/systemd1",
3875 "org.freedesktop.systemd1.Manager",
3881 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
3885 r
= sd_bus_message_read(reply
, "o", &path
);
3887 return bus_log_parse_error(r
);
3889 r
= sd_bus_get_property_string(
3891 "org.freedesktop.systemd1",
3893 "org.freedesktop.systemd1.Unit",
3898 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
3908 static int delete_snapshot(sd_bus
*bus
, char **args
) {
3909 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3915 STRV_FOREACH(name
, args
+1) {
3916 _cleanup_free_
char *n
= NULL
;
3918 n
= unit_name_mangle_with_suffix(*name
, ".snapshot");
3922 r
= sd_bus_call_method(
3924 "org.freedesktop.systemd1",
3925 "/org/freedesktop/systemd1",
3926 "org.freedesktop.systemd1.Manager",
3932 log_error("Failed to remove snapshot %s: %s", n
, bus_error_message(&error
, r
));
3940 static int daemon_reload(sd_bus
*bus
, char **args
) {
3941 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3945 if (arg_action
== ACTION_RELOAD
)
3947 else if (arg_action
== ACTION_REEXEC
)
3948 method
= "Reexecute";
3950 assert(arg_action
== ACTION_SYSTEMCTL
);
3953 streq(args
[0], "clear-jobs") ||
3954 streq(args
[0], "cancel") ? "ClearJobs" :
3955 streq(args
[0], "daemon-reexec") ? "Reexecute" :
3956 streq(args
[0], "reset-failed") ? "ResetFailed" :
3957 streq(args
[0], "halt") ? "Halt" :
3958 streq(args
[0], "poweroff") ? "PowerOff" :
3959 streq(args
[0], "reboot") ? "Reboot" :
3960 streq(args
[0], "kexec") ? "KExec" :
3961 streq(args
[0], "exit") ? "Exit" :
3962 /* "daemon-reload" */ "Reload";
3965 r
= sd_bus_call_method(
3967 "org.freedesktop.systemd1",
3968 "/org/freedesktop/systemd1",
3969 "org.freedesktop.systemd1.Manager",
3975 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
3976 /* There's always a fallback possible for
3977 * legacy actions. */
3979 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
3980 /* On reexecution, we expect a disconnect, not a
3984 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
3986 return r
< 0 ? r
: 0;
3989 static int reset_failed(sd_bus
*bus
, char **args
) {
3990 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3994 if (strv_length(args
) <= 1)
3995 return daemon_reload(bus
, args
);
3997 STRV_FOREACH(name
, args
+1) {
3998 _cleanup_free_
char *n
;
4000 n
= unit_name_mangle(*name
);
4004 r
= sd_bus_call_method(
4006 "org.freedesktop.systemd1",
4007 "/org/freedesktop/systemd1",
4008 "org.freedesktop.systemd1.Manager",
4014 log_error("Failed to reset failed state of unit %s: %s", n
, bus_error_message(&error
, r
));
4022 static int show_environment(sd_bus
*bus
, char **args
) {
4023 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4024 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4028 pager_open_if_enabled();
4030 r
= sd_bus_get_property(
4032 "org.freedesktop.systemd1",
4033 "/org/freedesktop/systemd1",
4034 "org.freedesktop.systemd1.Manager",
4040 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
4044 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
4046 return bus_log_parse_error(r
);
4048 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
4051 return bus_log_parse_error(r
);
4053 r
= sd_bus_message_exit_container(reply
);
4055 return bus_log_parse_error(r
);
4060 static int switch_root(sd_bus
*bus
, char **args
) {
4061 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4062 _cleanup_free_
char *init
= NULL
;
4067 l
= strv_length(args
);
4068 if (l
< 2 || l
> 3) {
4069 log_error("Wrong number of arguments.");
4076 init
= strdup(args
[2]);
4078 parse_env_file("/proc/cmdline", WHITESPACE
,
4089 log_debug("switching root - root: %s; init: %s", root
, init
);
4091 r
= sd_bus_call_method(
4093 "org.freedesktop.systemd1",
4094 "/org/freedesktop/systemd1",
4095 "org.freedesktop.systemd1.Manager",
4101 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
4108 static int set_environment(sd_bus
*bus
, char **args
) {
4109 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4110 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4117 method
= streq(args
[0], "set-environment")
4119 : "UnsetEnvironment";
4121 r
= sd_bus_message_new_method_call(
4123 "org.freedesktop.systemd1",
4124 "/org/freedesktop/systemd1",
4125 "org.freedesktop.systemd1.Manager",
4129 return bus_log_create_error(r
);
4131 r
= sd_bus_message_append_strv(m
, args
+ 1);
4133 return bus_log_create_error(r
);
4135 r
= sd_bus_send_with_reply_and_block(bus
, m
, -1, &error
, NULL
);
4137 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
4144 static int enable_sysv_units(const char *verb
, char **args
) {
4147 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4148 unsigned f
= 1, t
= 1;
4149 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
4151 if (arg_scope
!= UNIT_FILE_SYSTEM
)
4154 if (!streq(verb
, "enable") &&
4155 !streq(verb
, "disable") &&
4156 !streq(verb
, "is-enabled"))
4159 /* Processes all SysV units, and reshuffles the array so that
4160 * afterwards only the native units remain */
4162 r
= lookup_paths_init(&paths
, SYSTEMD_SYSTEM
, false, NULL
, NULL
, NULL
);
4167 for (f
= 0; args
[f
]; f
++) {
4169 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
4170 bool found_native
= false, found_sysv
;
4172 const char *argv
[6] = { "/sbin/chkconfig", NULL
, NULL
, NULL
, NULL
};
4180 if (!endswith(name
, ".service"))
4183 if (path_is_absolute(name
))
4186 STRV_FOREACH(k
, paths
.unit_path
) {
4187 if (!isempty(arg_root
))
4188 asprintf(&p
, "%s/%s/%s", arg_root
, *k
, name
);
4190 asprintf(&p
, "%s/%s", *k
, name
);
4197 found_native
= access(p
, F_OK
) >= 0;
4208 if (!isempty(arg_root
))
4209 asprintf(&p
, "%s/" SYSTEM_SYSVINIT_PATH
"/%s", arg_root
, name
);
4211 asprintf(&p
, SYSTEM_SYSVINIT_PATH
"/%s", name
);
4217 p
[strlen(p
) - sizeof(".service") + 1] = 0;
4218 found_sysv
= access(p
, F_OK
) >= 0;
4223 /* Mark this entry, so that we don't try enabling it as native unit */
4224 args
[f
] = (char*) "";
4226 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name
);
4228 if (!isempty(arg_root
))
4229 argv
[c
++] = q
= strappend("--root=", arg_root
);
4231 argv
[c
++] = path_get_file_name(p
);
4233 streq(verb
, "enable") ? "on" :
4234 streq(verb
, "disable") ? "off" : "--level=5";
4237 l
= strv_join((char**)argv
, " ");
4243 log_info("Executing %s", l
);
4248 log_error("Failed to fork: %m");
4251 } else if (pid
== 0) {
4254 execv(argv
[0], (char**) argv
);
4255 _exit(EXIT_FAILURE
);
4258 j
= wait_for_terminate(pid
, &status
);
4260 log_error("Failed to wait for child: %s", strerror(-r
));
4265 if (status
.si_code
== CLD_EXITED
) {
4266 if (streq(verb
, "is-enabled")) {
4267 if (status
.si_status
== 0) {
4276 } else if (status
.si_status
!= 0) {
4287 /* Drop all SysV units */
4288 for (f
= 0, t
= 0; args
[f
]; f
++) {
4290 if (isempty(args
[f
]))
4293 args
[t
++] = args
[f
];
4302 static int mangle_names(char **original_names
, char ***mangled_names
) {
4303 char **i
, **l
, **name
;
4305 l
= new(char*, strv_length(original_names
) + 1);
4310 STRV_FOREACH(name
, original_names
) {
4312 /* When enabling units qualified path names are OK,
4313 * too, hence allow them explicitly. */
4318 *i
= unit_name_mangle(*name
);
4334 static int enable_unit(sd_bus
*bus
, char **args
) {
4335 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
4336 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4337 _cleanup_strv_free_
char **mangled_names
= NULL
;
4338 const char *verb
= args
[0];
4339 UnitFileChange
*changes
= NULL
;
4340 unsigned n_changes
= 0, i
;
4341 int carries_install_info
= -1;
4347 r
= mangle_names(args
+1, &mangled_names
);
4351 r
= enable_sysv_units(verb
, mangled_names
);
4355 if (!bus
|| avoid_bus()) {
4356 if (streq(verb
, "enable")) {
4357 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4358 carries_install_info
= r
;
4359 } else if (streq(verb
, "disable"))
4360 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, &changes
, &n_changes
);
4361 else if (streq(verb
, "reenable")) {
4362 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4363 carries_install_info
= r
;
4364 } else if (streq(verb
, "link"))
4365 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4366 else if (streq(verb
, "preset")) {
4367 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4368 carries_install_info
= r
;
4369 } else if (streq(verb
, "mask"))
4370 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4371 else if (streq(verb
, "unmask"))
4372 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, mangled_names
, &changes
, &n_changes
);
4373 else if (streq(verb
, "set-default"))
4374 r
= unit_file_set_default(arg_scope
, arg_root
, args
[1], &changes
, &n_changes
);
4376 assert_not_reached("Unknown verb");
4379 log_error("Operation failed: %s", strerror(-r
));
4384 for (i
= 0; i
< n_changes
; i
++) {
4385 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
4386 log_info("ln -s '%s' '%s'", changes
[i
].source
, changes
[i
].path
);
4388 log_info("rm '%s'", changes
[i
].path
);
4394 const char *method
, *type
, *path
, *source
;
4395 int expect_carries_install_info
= false;
4396 bool send_force
= true;
4398 if (streq(verb
, "enable")) {
4399 method
= "EnableUnitFiles";
4400 expect_carries_install_info
= true;
4401 } else if (streq(verb
, "disable")) {
4402 method
= "DisableUnitFiles";
4404 } else if (streq(verb
, "reenable")) {
4405 method
= "ReenableUnitFiles";
4406 expect_carries_install_info
= true;
4407 } else if (streq(verb
, "link"))
4408 method
= "LinkUnitFiles";
4409 else if (streq(verb
, "preset")) {
4410 method
= "PresetUnitFiles";
4411 expect_carries_install_info
= true;
4412 } else if (streq(verb
, "mask"))
4413 method
= "MaskUnitFiles";
4414 else if (streq(verb
, "unmask")) {
4415 method
= "UnmaskUnitFiles";
4417 } else if (streq(verb
, "set-default")) {
4418 method
= "SetDefaultTarget";
4420 assert_not_reached("Unknown verb");
4422 r
= sd_bus_message_new_method_call(
4424 "org.freedesktop.systemd1",
4425 "/org/freedesktop/systemd1",
4426 "org.freedesktop.systemd1.Manager",
4430 return bus_log_create_error(r
);
4432 r
= sd_bus_message_append_strv(m
, mangled_names
);
4434 return bus_log_create_error(r
);
4436 r
= sd_bus_message_append(m
, "b", arg_runtime
);
4438 return bus_log_create_error(r
);
4441 r
= sd_bus_message_append(m
, "b", arg_force
);
4443 return bus_log_create_error(r
);
4446 r
= sd_bus_send_with_reply_and_block(bus
, m
, -0, &error
, &reply
);
4448 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4452 if (expect_carries_install_info
) {
4453 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
4455 return bus_log_parse_error(r
);
4458 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(sss)");
4460 return bus_log_parse_error(r
);
4462 while ((r
= sd_bus_message_read(reply
, "(sss)", &type
, &path
, &source
)) > 0) {
4464 if (streq(type
, "symlink"))
4465 log_info("ln -s '%s' '%s'", source
, path
);
4467 log_info("rm '%s'", path
);
4471 return bus_log_parse_error(r
);
4473 r
= sd_bus_message_exit_container(reply
);
4475 return bus_log_parse_error(r
);
4477 /* Try to reload if enabeld */
4479 r
= daemon_reload(bus
, args
);
4484 if (carries_install_info
== 0)
4485 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4486 "using systemctl.\n"
4487 "Possible reasons for having this kind of units are:\n"
4488 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4489 " .wants/ or .requires/ directory.\n"
4490 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4491 " a requirement dependency on it.\n"
4492 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4493 " D-Bus, udev, scripted systemctl call, ...).\n");
4496 unit_file_changes_free(changes
, n_changes
);
4501 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
4503 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4504 _cleanup_strv_free_
char **mangled_names
= NULL
;
4509 r
= mangle_names(args
+1, &mangled_names
);
4513 r
= enable_sysv_units(args
[0], mangled_names
);
4519 if (!bus
|| avoid_bus()) {
4521 STRV_FOREACH(name
, mangled_names
) {
4522 UnitFileState state
;
4524 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
4526 log_error("Failed to get unit file state for %s: %s", *name
, strerror(-state
));
4530 if (state
== UNIT_FILE_ENABLED
||
4531 state
== UNIT_FILE_ENABLED_RUNTIME
||
4532 state
== UNIT_FILE_STATIC
)
4536 puts(unit_file_state_to_string(state
));
4540 STRV_FOREACH(name
, mangled_names
) {
4541 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4544 r
= sd_bus_call_method(
4546 "org.freedesktop.systemd1",
4547 "/org/freedesktop/systemd1",
4548 "org.freedesktop.systemd1.Manager",
4554 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
4558 r
= sd_bus_message_read(reply
, "s", &s
);
4560 return bus_log_parse_error(r
);
4562 if (streq(s
, "enabled") ||
4563 streq(s
, "enabled-runtime") ||
4575 static int systemctl_help(void) {
4577 pager_open_if_enabled();
4579 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4580 "Query or send control commands to the systemd manager.\n\n"
4581 " -h --help Show this help\n"
4582 " --version Show package version\n"
4583 " --system Connect to system manager\n"
4584 " --user Connect to user service manager\n"
4585 " -H --host=[USER@]HOST\n"
4586 " Operate on remote host\n"
4587 " -M --machine=CONTAINER\n"
4588 " Operate on local container\n"
4589 " -t --type=TYPE List only units of a particular type\n"
4590 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4591 " -p --property=NAME Show only properties by this name\n"
4592 " -a --all Show all loaded units/properties, including dead/empty\n"
4593 " ones. To list all units installed on the system, use\n"
4594 " the 'list-unit-files' command instead.\n"
4595 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4596 " -l --full Don't ellipsize unit names on output\n"
4597 " --fail When queueing a new job, fail if conflicting jobs are\n"
4599 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4601 " --ignore-dependencies\n"
4602 " When queueing a new job, ignore all its dependencies\n"
4603 " --show-types When showing sockets, explicitly show their type\n"
4604 " -i --ignore-inhibitors\n"
4605 " When shutting down or sleeping, ignore inhibitors\n"
4606 " --kill-who=WHO Who to send signal to\n"
4607 " -s --signal=SIGNAL Which signal to send\n"
4608 " -q --quiet Suppress output\n"
4609 " --no-block Do not wait until operation finished\n"
4610 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4611 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4613 " --no-legend Do not print a legend (column headers and hints)\n"
4614 " --no-pager Do not pipe output into a pager\n"
4615 " --no-ask-password\n"
4616 " Do not ask for system passwords\n"
4617 " --global Enable/disable unit files globally\n"
4618 " --runtime Enable unit files only temporarily until next reboot\n"
4619 " -f --force When enabling unit files, override existing symlinks\n"
4620 " When shutting down, execute action immediately\n"
4621 " --root=PATH Enable unit files in the specified root directory\n"
4622 " -n --lines=INTEGER Number of journal entries to show\n"
4623 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4624 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4626 " list-units List loaded units\n"
4627 " list-sockets List loaded sockets ordered by address\n"
4628 " list-timers List loaded timers ordered by next elapse\n"
4629 " start [NAME...] Start (activate) one or more units\n"
4630 " stop [NAME...] Stop (deactivate) one or more units\n"
4631 " reload [NAME...] Reload one or more units\n"
4632 " restart [NAME...] Start or restart one or more units\n"
4633 " try-restart [NAME...] Restart one or more units if active\n"
4634 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4635 " otherwise start or restart\n"
4636 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4637 " otherwise restart if active\n"
4638 " isolate [NAME] Start one unit and stop all others\n"
4639 " kill [NAME...] Send signal to processes of a unit\n"
4640 " is-active [NAME...] Check whether units are active\n"
4641 " is-failed [NAME...] Check whether units are failed\n"
4642 " status [NAME...|PID...] Show runtime status of one or more units\n"
4643 " show [NAME...|JOB...] Show properties of one or more\n"
4644 " units/jobs or the manager\n"
4645 " set-property [NAME] [ASSIGNMENT...]\n"
4646 " Sets one or more properties of a unit\n"
4647 " help [NAME...|PID...] Show manual for one or more units\n"
4648 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4650 " list-dependencies [NAME] Recursively show units which are required\n"
4651 " or wanted by this unit or by which this\n"
4652 " unit is required or wanted\n\n"
4653 "Unit File Commands:\n"
4654 " list-unit-files List installed unit files\n"
4655 " enable [NAME...] Enable one or more unit files\n"
4656 " disable [NAME...] Disable one or more unit files\n"
4657 " reenable [NAME...] Reenable one or more unit files\n"
4658 " preset [NAME...] Enable/disable one or more unit files\n"
4659 " based on preset configuration\n"
4660 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4661 " mask [NAME...] Mask one or more units\n"
4662 " unmask [NAME...] Unmask one or more units\n"
4663 " link [PATH...] Link one or more units files into\n"
4664 " the search path\n"
4665 " get-default Get the name of the default target\n"
4666 " set-default NAME Set the default target\n\n"
4668 " list-jobs List jobs\n"
4669 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4670 "Snapshot Commands:\n"
4671 " snapshot [NAME] Create a snapshot\n"
4672 " delete [NAME...] Remove one or more snapshots\n\n"
4673 "Environment Commands:\n"
4674 " show-environment Dump environment\n"
4675 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4676 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4677 "Manager Lifecycle Commands:\n"
4678 " daemon-reload Reload systemd manager configuration\n"
4679 " daemon-reexec Reexecute systemd manager\n\n"
4680 "System Commands:\n"
4681 " default Enter system default mode\n"
4682 " rescue Enter system rescue mode\n"
4683 " emergency Enter system emergency mode\n"
4684 " halt Shut down and halt the system\n"
4685 " poweroff Shut down and power-off the system\n"
4686 " reboot [ARG] Shut down and reboot the system\n"
4687 " kexec Shut down and reboot the system with kexec\n"
4688 " exit Request user instance exit\n"
4689 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4690 " suspend Suspend the system\n"
4691 " hibernate Hibernate the system\n"
4692 " hybrid-sleep Hibernate and suspend the system\n",
4693 program_invocation_short_name
);
4698 static int halt_help(void) {
4700 printf("%s [OPTIONS...]%s\n\n"
4701 "%s the system.\n\n"
4702 " --help Show this help\n"
4703 " --halt Halt the machine\n"
4704 " -p --poweroff Switch off the machine\n"
4705 " --reboot Reboot the machine\n"
4706 " -f --force Force immediate halt/power-off/reboot\n"
4707 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4708 " -d --no-wtmp Don't write wtmp record\n"
4709 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4710 program_invocation_short_name
,
4711 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
4712 arg_action
== ACTION_REBOOT
? "Reboot" :
4713 arg_action
== ACTION_POWEROFF
? "Power off" :
4719 static int shutdown_help(void) {
4721 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4722 "Shut down the system.\n\n"
4723 " --help Show this help\n"
4724 " -H --halt Halt the machine\n"
4725 " -P --poweroff Power-off the machine\n"
4726 " -r --reboot Reboot the machine\n"
4727 " -h Equivalent to --poweroff, overridden by --halt\n"
4728 " -k Don't halt/power-off/reboot, just send warnings\n"
4729 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4730 " -c Cancel a pending shutdown\n",
4731 program_invocation_short_name
);
4736 static int telinit_help(void) {
4738 printf("%s [OPTIONS...] {COMMAND}\n\n"
4739 "Send control commands to the init daemon.\n\n"
4740 " --help Show this help\n"
4741 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4743 " 0 Power-off the machine\n"
4744 " 6 Reboot the machine\n"
4745 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4746 " 1, s, S Enter rescue mode\n"
4747 " q, Q Reload init daemon configuration\n"
4748 " u, U Reexecute init daemon\n",
4749 program_invocation_short_name
);
4754 static int runlevel_help(void) {
4756 printf("%s [OPTIONS...]\n\n"
4757 "Prints the previous and current runlevel of the init system.\n\n"
4758 " --help Show this help\n",
4759 program_invocation_short_name
);
4764 static int help_types(void) {
4768 puts("Available unit types:");
4769 for(i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
4770 t
= unit_type_to_string(i
);
4778 static int systemctl_parse_argv(int argc
, char *argv
[]) {
4787 ARG_IGNORE_DEPENDENCIES
,
4799 ARG_NO_ASK_PASSWORD
,
4807 static const struct option options
[] = {
4808 { "help", no_argument
, NULL
, 'h' },
4809 { "version", no_argument
, NULL
, ARG_VERSION
},
4810 { "type", required_argument
, NULL
, 't' },
4811 { "property", required_argument
, NULL
, 'p' },
4812 { "all", no_argument
, NULL
, 'a' },
4813 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
4814 { "after", no_argument
, NULL
, ARG_AFTER
},
4815 { "before", no_argument
, NULL
, ARG_BEFORE
},
4816 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
4817 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
4818 { "full", no_argument
, NULL
, 'l' },
4819 { "fail", no_argument
, NULL
, ARG_FAIL
},
4820 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
},
4821 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
},
4822 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
4823 { "user", no_argument
, NULL
, ARG_USER
},
4824 { "system", no_argument
, NULL
, ARG_SYSTEM
},
4825 { "global", no_argument
, NULL
, ARG_GLOBAL
},
4826 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
4827 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
4828 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
4829 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
4830 { "quiet", no_argument
, NULL
, 'q' },
4831 { "root", required_argument
, NULL
, ARG_ROOT
},
4832 { "force", no_argument
, NULL
, ARG_FORCE
},
4833 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
4834 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
4835 { "signal", required_argument
, NULL
, 's' },
4836 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
4837 { "host", required_argument
, NULL
, 'H' },
4838 { "machine", required_argument
, NULL
, 'M' },
4839 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
4840 { "lines", required_argument
, NULL
, 'n' },
4841 { "output", required_argument
, NULL
, 'o' },
4842 { "plain", no_argument
, NULL
, ARG_PLAIN
},
4843 { "state", required_argument
, NULL
, ARG_STATE
},
4852 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:i", options
, NULL
)) >= 0) {
4857 return systemctl_help();
4860 puts(PACKAGE_STRING
);
4861 puts(SYSTEMD_FEATURES
);
4868 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
4869 _cleanup_free_
char *type
;
4871 type
= strndup(word
, size
);
4875 if (streq(type
, "help")) {
4880 if (unit_type_from_string(type
) >= 0) {
4881 if (strv_push(&arg_types
, type
))
4887 /* It's much nicer to use --state= for
4888 * load states, but let's support this
4889 * in --types= too for compatibility
4890 * with old versions */
4891 if (unit_load_state_from_string(optarg
) >= 0) {
4892 if (strv_push(&arg_states
, type
) < 0)
4898 log_error("Unknown unit type or load state '%s'.", type
);
4899 log_info("Use -t help to see a list of allowed values.");
4907 /* Make sure that if the empty property list
4908 was specified, we won't show any properties. */
4909 if (isempty(optarg
) && !arg_properties
) {
4910 arg_properties
= new0(char*, 1);
4911 if (!arg_properties
)
4917 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
4920 prop
= strndup(word
, size
);
4924 if (strv_push(&arg_properties
, prop
) < 0) {
4931 /* If the user asked for a particular
4932 * property, show it to him, even if it is
4944 arg_dependency
= DEPENDENCY_REVERSE
;
4948 arg_dependency
= DEPENDENCY_AFTER
;
4952 arg_dependency
= DEPENDENCY_BEFORE
;
4955 case ARG_SHOW_TYPES
:
4956 arg_show_types
= true;
4960 arg_job_mode
= "fail";
4963 case ARG_IRREVERSIBLE
:
4964 arg_job_mode
= "replace-irreversibly";
4967 case ARG_IGNORE_DEPENDENCIES
:
4968 arg_job_mode
= "ignore-dependencies";
4972 arg_scope
= UNIT_FILE_USER
;
4976 arg_scope
= UNIT_FILE_SYSTEM
;
4980 arg_scope
= UNIT_FILE_GLOBAL
;
4984 arg_no_block
= true;
4988 arg_no_legend
= true;
4992 arg_no_pager
= true;
5008 if (strv_extend(&arg_states
, "failed") < 0)
5026 arg_no_reload
= true;
5030 arg_kill_who
= optarg
;
5034 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
5035 log_error("Failed to parse signal string %s.", optarg
);
5040 case ARG_NO_ASK_PASSWORD
:
5041 arg_ask_password
= false;
5045 arg_transport
= BUS_TRANSPORT_REMOTE
;
5050 arg_transport
= BUS_TRANSPORT_CONTAINER
;
5059 if (safe_atou(optarg
, &arg_lines
) < 0) {
5060 log_error("Failed to parse lines '%s'", optarg
);
5066 arg_output
= output_mode_from_string(optarg
);
5067 if (arg_output
< 0) {
5068 log_error("Unknown output '%s'.", optarg
);
5074 arg_ignore_inhibitors
= true;
5085 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
5088 s
= strndup(word
, size
);
5092 if (strv_push(&arg_states
, s
) < 0) {
5104 assert_not_reached("Unhandled option");
5108 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
5109 log_error("Cannot access user instance remotely.");
5116 static int halt_parse_argv(int argc
, char *argv
[]) {
5125 static const struct option options
[] = {
5126 { "help", no_argument
, NULL
, ARG_HELP
},
5127 { "halt", no_argument
, NULL
, ARG_HALT
},
5128 { "poweroff", no_argument
, NULL
, 'p' },
5129 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
5130 { "force", no_argument
, NULL
, 'f' },
5131 { "wtmp-only", no_argument
, NULL
, 'w' },
5132 { "no-wtmp", no_argument
, NULL
, 'd' },
5133 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5142 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
5143 if (runlevel
== '0' || runlevel
== '6')
5146 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0) {
5153 arg_action
= ACTION_HALT
;
5157 if (arg_action
!= ACTION_REBOOT
)
5158 arg_action
= ACTION_POWEROFF
;
5162 arg_action
= ACTION_REBOOT
;
5184 /* Compatibility nops */
5191 assert_not_reached("Unhandled option");
5195 if (arg_action
== ACTION_REBOOT
&& argc
== optind
+ 1) {
5196 r
= write_string_file(REBOOT_PARAM_FILE
, argv
[optind
]);
5198 log_error("Failed to write reboot param to "
5199 REBOOT_PARAM_FILE
": %s", strerror(-r
));
5202 } else if (optind
< argc
) {
5203 log_error("Too many arguments.");
5210 static int parse_time_spec(const char *t
, usec_t
*_u
) {
5214 if (streq(t
, "now"))
5216 else if (!strchr(t
, ':')) {
5219 if (safe_atou64(t
, &u
) < 0)
5222 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
5231 hour
= strtol(t
, &e
, 10);
5232 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
5235 minute
= strtol(e
+1, &e
, 10);
5236 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
5239 n
= now(CLOCK_REALTIME
);
5240 s
= (time_t) (n
/ USEC_PER_SEC
);
5242 assert_se(localtime_r(&s
, &tm
));
5244 tm
.tm_hour
= (int) hour
;
5245 tm
.tm_min
= (int) minute
;
5248 assert_se(s
= mktime(&tm
));
5250 *_u
= (usec_t
) s
* USEC_PER_SEC
;
5253 *_u
+= USEC_PER_DAY
;
5259 static int shutdown_parse_argv(int argc
, char *argv
[]) {
5266 static const struct option options
[] = {
5267 { "help", no_argument
, NULL
, ARG_HELP
},
5268 { "halt", no_argument
, NULL
, 'H' },
5269 { "poweroff", no_argument
, NULL
, 'P' },
5270 { "reboot", no_argument
, NULL
, 'r' },
5271 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
5272 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5281 while ((c
= getopt_long(argc
, argv
, "HPrhkt:afFc", options
, NULL
)) >= 0) {
5285 return shutdown_help();
5288 arg_action
= ACTION_HALT
;
5292 arg_action
= ACTION_POWEROFF
;
5297 arg_action
= ACTION_KEXEC
;
5299 arg_action
= ACTION_REBOOT
;
5303 arg_action
= ACTION_KEXEC
;
5307 if (arg_action
!= ACTION_HALT
)
5308 arg_action
= ACTION_POWEROFF
;
5321 /* Compatibility nops */
5325 arg_action
= ACTION_CANCEL_SHUTDOWN
;
5332 assert_not_reached("Unhandled option");
5336 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
5337 r
= parse_time_spec(argv
[optind
], &arg_when
);
5339 log_error("Failed to parse time specification: %s", argv
[optind
]);
5343 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
5345 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
5346 /* No time argument for shutdown cancel */
5347 arg_wall
= argv
+ optind
;
5348 else if (argc
> optind
+ 1)
5349 /* We skip the time argument */
5350 arg_wall
= argv
+ optind
+ 1;
5357 static int telinit_parse_argv(int argc
, char *argv
[]) {
5364 static const struct option options
[] = {
5365 { "help", no_argument
, NULL
, ARG_HELP
},
5366 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5370 static const struct {
5374 { '0', ACTION_POWEROFF
},
5375 { '6', ACTION_REBOOT
},
5376 { '1', ACTION_RESCUE
},
5377 { '2', ACTION_RUNLEVEL2
},
5378 { '3', ACTION_RUNLEVEL3
},
5379 { '4', ACTION_RUNLEVEL4
},
5380 { '5', ACTION_RUNLEVEL5
},
5381 { 's', ACTION_RESCUE
},
5382 { 'S', ACTION_RESCUE
},
5383 { 'q', ACTION_RELOAD
},
5384 { 'Q', ACTION_RELOAD
},
5385 { 'u', ACTION_REEXEC
},
5386 { 'U', ACTION_REEXEC
}
5395 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5399 return telinit_help();
5409 assert_not_reached("Unhandled option");
5413 if (optind
>= argc
) {
5418 if (optind
+ 1 < argc
) {
5419 log_error("Too many arguments.");
5423 if (strlen(argv
[optind
]) != 1) {
5424 log_error("Expected single character argument.");
5428 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
5429 if (table
[i
].from
== argv
[optind
][0])
5432 if (i
>= ELEMENTSOF(table
)) {
5433 log_error("Unknown command '%s'.", argv
[optind
]);
5437 arg_action
= table
[i
].to
;
5444 static int runlevel_parse_argv(int argc
, char *argv
[]) {
5450 static const struct option options
[] = {
5451 { "help", no_argument
, NULL
, ARG_HELP
},
5460 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5464 return runlevel_help();
5471 assert_not_reached("Unhandled option");
5475 if (optind
< argc
) {
5476 log_error("Too many arguments.");
5483 static int parse_argv(int argc
, char *argv
[]) {
5487 if (program_invocation_short_name
) {
5489 if (strstr(program_invocation_short_name
, "halt")) {
5490 arg_action
= ACTION_HALT
;
5491 return halt_parse_argv(argc
, argv
);
5492 } else if (strstr(program_invocation_short_name
, "poweroff")) {
5493 arg_action
= ACTION_POWEROFF
;
5494 return halt_parse_argv(argc
, argv
);
5495 } else if (strstr(program_invocation_short_name
, "reboot")) {
5497 arg_action
= ACTION_KEXEC
;
5499 arg_action
= ACTION_REBOOT
;
5500 return halt_parse_argv(argc
, argv
);
5501 } else if (strstr(program_invocation_short_name
, "shutdown")) {
5502 arg_action
= ACTION_POWEROFF
;
5503 return shutdown_parse_argv(argc
, argv
);
5504 } else if (strstr(program_invocation_short_name
, "init")) {
5506 if (sd_booted() > 0) {
5507 arg_action
= _ACTION_INVALID
;
5508 return telinit_parse_argv(argc
, argv
);
5510 /* Hmm, so some other init system is
5511 * running, we need to forward this
5512 * request to it. For now we simply
5513 * guess that it is Upstart. */
5515 execv(TELINIT
, argv
);
5517 log_error("Couldn't find an alternative telinit implementation to spawn.");
5521 } else if (strstr(program_invocation_short_name
, "runlevel")) {
5522 arg_action
= ACTION_RUNLEVEL
;
5523 return runlevel_parse_argv(argc
, argv
);
5527 arg_action
= ACTION_SYSTEMCTL
;
5528 return systemctl_parse_argv(argc
, argv
);
5531 _pure_
static int action_to_runlevel(void) {
5533 static const char table
[_ACTION_MAX
] = {
5534 [ACTION_HALT
] = '0',
5535 [ACTION_POWEROFF
] = '0',
5536 [ACTION_REBOOT
] = '6',
5537 [ACTION_RUNLEVEL2
] = '2',
5538 [ACTION_RUNLEVEL3
] = '3',
5539 [ACTION_RUNLEVEL4
] = '4',
5540 [ACTION_RUNLEVEL5
] = '5',
5541 [ACTION_RESCUE
] = '1'
5544 assert(arg_action
< _ACTION_MAX
);
5546 return table
[arg_action
];
5549 static int talk_initctl(void) {
5551 struct init_request request
= {
5552 .magic
= INIT_MAGIC
,
5554 .cmd
= INIT_CMD_RUNLVL
5557 _cleanup_close_
int fd
= -1;
5561 rl
= action_to_runlevel();
5565 request
.runlevel
= rl
;
5567 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
5569 if (errno
== ENOENT
)
5572 log_error("Failed to open "INIT_FIFO
": %m");
5577 r
= loop_write(fd
, &request
, sizeof(request
), false) != sizeof(request
);
5579 log_error("Failed to write to "INIT_FIFO
": %m");
5580 return errno
> 0 ? -errno
: -EIO
;
5586 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
5588 static const struct {
5596 int (* const dispatch
)(sd_bus
*bus
, char **args
);
5598 { "list-units", LESS
, 1, list_units
},
5599 { "list-unit-files", EQUAL
, 1, list_unit_files
},
5600 { "list-sockets", LESS
, 1, list_sockets
},
5601 { "list-timers", LESS
, 1, list_timers
},
5602 { "list-jobs", EQUAL
, 1, list_jobs
},
5603 { "clear-jobs", EQUAL
, 1, daemon_reload
},
5604 { "cancel", MORE
, 2, cancel_job
},
5605 { "start", MORE
, 2, start_unit
},
5606 { "stop", MORE
, 2, start_unit
},
5607 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5608 { "reload", MORE
, 2, start_unit
},
5609 { "restart", MORE
, 2, start_unit
},
5610 { "try-restart", MORE
, 2, start_unit
},
5611 { "reload-or-restart", MORE
, 2, start_unit
},
5612 { "reload-or-try-restart", MORE
, 2, start_unit
},
5613 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
5614 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5615 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
5616 { "isolate", EQUAL
, 2, start_unit
},
5617 { "kill", MORE
, 2, kill_unit
},
5618 { "is-active", MORE
, 2, check_unit_active
},
5619 { "check", MORE
, 2, check_unit_active
},
5620 { "is-failed", MORE
, 2, check_unit_failed
},
5621 { "show", MORE
, 1, show
},
5622 { "status", MORE
, 1, show
},
5623 { "help", MORE
, 2, show
},
5624 { "snapshot", LESS
, 2, snapshot
},
5625 { "delete", MORE
, 2, delete_snapshot
},
5626 { "daemon-reload", EQUAL
, 1, daemon_reload
},
5627 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
5628 { "show-environment", EQUAL
, 1, show_environment
},
5629 { "set-environment", MORE
, 2, set_environment
},
5630 { "unset-environment", MORE
, 2, set_environment
},
5631 { "halt", EQUAL
, 1, start_special
},
5632 { "poweroff", EQUAL
, 1, start_special
},
5633 { "reboot", EQUAL
, 1, start_special
},
5634 { "kexec", EQUAL
, 1, start_special
},
5635 { "suspend", EQUAL
, 1, start_special
},
5636 { "hibernate", EQUAL
, 1, start_special
},
5637 { "hybrid-sleep", EQUAL
, 1, start_special
},
5638 { "default", EQUAL
, 1, start_special
},
5639 { "rescue", EQUAL
, 1, start_special
},
5640 { "emergency", EQUAL
, 1, start_special
},
5641 { "exit", EQUAL
, 1, start_special
},
5642 { "reset-failed", MORE
, 1, reset_failed
},
5643 { "enable", MORE
, 2, enable_unit
},
5644 { "disable", MORE
, 2, enable_unit
},
5645 { "is-enabled", MORE
, 2, unit_is_enabled
},
5646 { "reenable", MORE
, 2, enable_unit
},
5647 { "preset", MORE
, 2, enable_unit
},
5648 { "mask", MORE
, 2, enable_unit
},
5649 { "unmask", MORE
, 2, enable_unit
},
5650 { "link", MORE
, 2, enable_unit
},
5651 { "switch-root", MORE
, 2, switch_root
},
5652 { "list-dependencies", LESS
, 2, list_dependencies
},
5653 { "set-default", EQUAL
, 2, enable_unit
},
5654 { "get-default", LESS
, 1, get_default
},
5655 { "set-property", MORE
, 3, set_property
},
5664 left
= argc
- optind
;
5667 /* Special rule: no arguments means "list-units" */
5670 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
5671 log_error("This command expects one or more "
5672 "unit names. Did you mean --help?");
5676 for (i
= 0; i
< ELEMENTSOF(verbs
); i
++)
5677 if (streq(argv
[optind
], verbs
[i
].verb
))
5680 if (i
>= ELEMENTSOF(verbs
)) {
5681 log_error("Unknown operation '%s'.", argv
[optind
]);
5686 switch (verbs
[i
].argc_cmp
) {
5689 if (left
!= verbs
[i
].argc
) {
5690 log_error("Invalid number of arguments.");
5697 if (left
< verbs
[i
].argc
) {
5698 log_error("Too few arguments.");
5705 if (left
> verbs
[i
].argc
) {
5706 log_error("Too many arguments.");
5713 assert_not_reached("Unknown comparison operator.");
5716 /* Require a bus connection for all operations but
5718 if (!streq(verbs
[i
].verb
, "enable") &&
5719 !streq(verbs
[i
].verb
, "disable") &&
5720 !streq(verbs
[i
].verb
, "is-enabled") &&
5721 !streq(verbs
[i
].verb
, "list-unit-files") &&
5722 !streq(verbs
[i
].verb
, "reenable") &&
5723 !streq(verbs
[i
].verb
, "preset") &&
5724 !streq(verbs
[i
].verb
, "mask") &&
5725 !streq(verbs
[i
].verb
, "unmask") &&
5726 !streq(verbs
[i
].verb
, "link") &&
5727 !streq(verbs
[i
].verb
, "set-default") &&
5728 !streq(verbs
[i
].verb
, "get-default")) {
5730 if (running_in_chroot() > 0) {
5731 log_info("Running in chroot, ignoring request.");
5735 if (((!streq(verbs
[i
].verb
, "reboot") &&
5736 !streq(verbs
[i
].verb
, "halt") &&
5737 !streq(verbs
[i
].verb
, "poweroff")) || arg_force
<= 0) && !bus
) {
5738 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error
));
5744 if (!bus
&& !avoid_bus()) {
5745 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error
));
5750 return verbs
[i
].dispatch(bus
, argv
+ optind
);
5753 static int send_shutdownd(usec_t t
, char mode
, bool dry_run
, bool warn
, const char *message
) {
5755 struct sd_shutdown_command c
= {
5762 union sockaddr_union sockaddr
= {
5763 .un
.sun_family
= AF_UNIX
,
5764 .un
.sun_path
= "/run/systemd/shutdownd",
5767 struct iovec iovec
[2] = {{
5768 .iov_base
= (char*) &c
,
5769 .iov_len
= offsetof(struct sd_shutdown_command
, wall_message
),
5772 struct msghdr msghdr
= {
5773 .msg_name
= &sockaddr
,
5774 .msg_namelen
= offsetof(struct sockaddr_un
, sun_path
)
5775 + sizeof("/run/systemd/shutdownd") - 1,
5780 _cleanup_close_
int fd
;
5782 fd
= socket(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0);
5786 if (!isempty(message
)) {
5787 iovec
[1].iov_base
= (char*) message
;
5788 iovec
[1].iov_len
= strlen(message
);
5789 msghdr
.msg_iovlen
++;
5792 if (sendmsg(fd
, &msghdr
, MSG_NOSIGNAL
) < 0)
5798 static int reload_with_fallback(sd_bus
*bus
) {
5801 /* First, try systemd via D-Bus. */
5802 if (daemon_reload(bus
, NULL
) >= 0)
5806 /* Nothing else worked, so let's try signals */
5807 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
5809 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0) {
5810 log_error("kill() failed: %m");
5817 static int start_with_fallback(sd_bus
*bus
) {
5820 /* First, try systemd via D-Bus. */
5821 if (start_unit(bus
, NULL
) >= 0)
5825 /* Nothing else worked, so let's try
5827 if (talk_initctl() > 0)
5830 log_error("Failed to talk to init daemon.");
5834 warn_wall(arg_action
);
5838 static int halt_now(enum action a
) {
5840 /* Make sure C-A-D is handled by the kernel from this
5842 reboot(RB_ENABLE_CAD
);
5847 log_info("Halting.");
5848 reboot(RB_HALT_SYSTEM
);
5851 case ACTION_POWEROFF
:
5852 log_info("Powering off.");
5853 reboot(RB_POWER_OFF
);
5856 case ACTION_REBOOT
: {
5857 _cleanup_free_
char *param
= NULL
;
5859 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
5860 log_info("Rebooting with argument '%s'.", param
);
5861 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
5862 LINUX_REBOOT_CMD_RESTART2
, param
);
5865 log_info("Rebooting.");
5866 reboot(RB_AUTOBOOT
);
5871 assert_not_reached("Unknown action.");
5875 static int halt_main(sd_bus
*bus
) {
5878 r
= check_inhibitors(bus
, arg_action
);
5882 if (geteuid() != 0) {
5883 /* Try logind if we are a normal user and no special
5884 * mode applies. Maybe PolicyKit allows us to shutdown
5887 if (arg_when
<= 0 &&
5890 (arg_action
== ACTION_POWEROFF
||
5891 arg_action
== ACTION_REBOOT
)) {
5892 r
= reboot_with_logind(bus
, arg_action
);
5897 log_error("Must be root.");
5902 _cleanup_free_
char *m
;
5904 m
= strv_join(arg_wall
, " ");
5908 r
= send_shutdownd(arg_when
,
5909 arg_action
== ACTION_HALT
? 'H' :
5910 arg_action
== ACTION_POWEROFF
? 'P' :
5911 arg_action
== ACTION_KEXEC
? 'K' :
5918 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r
));
5920 char date
[FORMAT_TIMESTAMP_MAX
];
5922 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
5923 format_timestamp(date
, sizeof(date
), arg_when
));
5928 if (!arg_dry
&& !arg_force
)
5929 return start_with_fallback(bus
);
5932 if (sd_booted() > 0)
5933 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
5935 r
= utmp_put_shutdown();
5937 log_warning("Failed to write utmp record: %s", strerror(-r
));
5944 r
= halt_now(arg_action
);
5945 log_error("Failed to reboot: %s", strerror(-r
));
5950 static int runlevel_main(void) {
5951 int r
, runlevel
, previous
;
5953 r
= utmp_get_runlevel(&runlevel
, &previous
);
5960 previous
<= 0 ? 'N' : previous
,
5961 runlevel
<= 0 ? 'N' : runlevel
);
5966 int main(int argc
, char*argv
[]) {
5967 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
5970 setlocale(LC_ALL
, "");
5971 log_parse_environment();
5974 /* Explicitly not on_tty() to avoid setting cached value.
5975 * This becomes relevant for piping output which might be
5977 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
5979 r
= parse_argv(argc
, argv
);
5983 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
5984 * let's shortcut this */
5985 if (arg_action
== ACTION_RUNLEVEL
) {
5986 r
= runlevel_main();
5990 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
5991 log_info("Running in chroot, ignoring request.");
5997 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
5999 /* systemctl_main() will print an error message for the bus
6000 * connection, but only if it needs to */
6002 switch (arg_action
) {
6004 case ACTION_SYSTEMCTL
:
6005 r
= systemctl_main(bus
, argc
, argv
, r
);
6009 case ACTION_POWEROFF
:
6015 case ACTION_RUNLEVEL2
:
6016 case ACTION_RUNLEVEL3
:
6017 case ACTION_RUNLEVEL4
:
6018 case ACTION_RUNLEVEL5
:
6020 case ACTION_EMERGENCY
:
6021 case ACTION_DEFAULT
:
6022 r
= start_with_fallback(bus
);
6027 r
= reload_with_fallback(bus
);
6030 case ACTION_CANCEL_SHUTDOWN
: {
6031 _cleanup_free_
char *m
= NULL
;
6034 m
= strv_join(arg_wall
, " ");
6041 r
= send_shutdownd(arg_when
, SD_SHUTDOWN_NONE
, false, !arg_no_wall
, m
);
6043 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r
));
6047 case ACTION_RUNLEVEL
:
6048 case _ACTION_INVALID
:
6050 assert_not_reached("Unknown action");
6055 ask_password_agent_close();
6056 polkit_agent_close();
6058 strv_free(arg_types
);
6059 strv_free(arg_states
);
6060 strv_free(arg_properties
);
6062 return r
< 0 ? EXIT_FAILURE
: r
;