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 "socket-util.h"
71 #include "bus-message.h"
72 #include "bus-error.h"
73 #include "bus-errors.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 int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
142 static void pager_open_if_enabled(void) {
150 static void ask_password_agent_open_if_enabled(void) {
152 /* Open the password agent as a child process if necessary */
154 if (!arg_ask_password
)
157 if (arg_scope
!= UNIT_FILE_SYSTEM
)
160 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
163 ask_password_agent_open();
167 static void polkit_agent_open_if_enabled(void) {
169 /* Open the polkit agent as a child process if necessary */
171 if (!arg_ask_password
)
174 if (arg_scope
!= UNIT_FILE_SYSTEM
)
177 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
184 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
187 if (!sd_bus_error_is_set(error
))
190 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
191 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
192 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
193 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
194 return EXIT_NOPERMISSION
;
196 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
197 return EXIT_NOTINSTALLED
;
199 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
200 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
201 return EXIT_NOTIMPLEMENTED
;
203 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
204 return EXIT_NOTCONFIGURED
;
212 static void warn_wall(enum action a
) {
213 static const char *table
[_ACTION_MAX
] = {
214 [ACTION_HALT
] = "The system is going down for system halt NOW!",
215 [ACTION_REBOOT
] = "The system is going down for reboot NOW!",
216 [ACTION_POWEROFF
] = "The system is going down for power-off NOW!",
217 [ACTION_KEXEC
] = "The system is going down for kexec reboot NOW!",
218 [ACTION_RESCUE
] = "The system is going down to rescue mode NOW!",
219 [ACTION_EMERGENCY
] = "The system is going down to emergency mode NOW!",
220 [ACTION_CANCEL_SHUTDOWN
] = "The system shutdown has been cancelled NOW!"
227 _cleanup_free_
char *p
;
229 p
= strv_join(arg_wall
, " ");
244 utmp_wall(table
[a
], NULL
);
247 static bool avoid_bus(void) {
249 if (running_in_chroot() > 0)
252 if (sd_booted() <= 0)
255 if (!isempty(arg_root
))
258 if (arg_scope
== UNIT_FILE_GLOBAL
)
264 static int compare_unit_info(const void *a
, const void *b
) {
265 const UnitInfo
*u
= a
, *v
= b
;
268 d1
= strrchr(u
->id
, '.');
269 d2
= strrchr(v
->id
, '.');
274 r
= strcasecmp(d1
, d2
);
279 return strcasecmp(u
->id
, v
->id
);
282 static bool output_show_unit(const UnitInfo
*u
) {
285 if (!strv_isempty(arg_states
))
287 strv_contains(arg_states
, u
->load_state
) ||
288 strv_contains(arg_states
, u
->sub_state
) ||
289 strv_contains(arg_states
, u
->active_state
);
291 return (!arg_types
|| ((dot
= strrchr(u
->id
, '.')) &&
292 strv_find(arg_types
, dot
+1))) &&
293 (arg_all
|| !(streq(u
->active_state
, "inactive")
294 || u
->following
[0]) || u
->job_id
> 0);
297 static void output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
298 unsigned id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
300 unsigned n_shown
= 0;
303 max_id_len
= sizeof("UNIT")-1;
304 load_len
= sizeof("LOAD")-1;
305 active_len
= sizeof("ACTIVE")-1;
306 sub_len
= sizeof("SUB")-1;
307 job_len
= sizeof("JOB")-1;
310 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
311 if (!output_show_unit(u
))
314 max_id_len
= MAX(max_id_len
, strlen(u
->id
));
315 load_len
= MAX(load_len
, strlen(u
->load_state
));
316 active_len
= MAX(active_len
, strlen(u
->active_state
));
317 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
319 if (u
->job_id
!= 0) {
320 job_len
= MAX(job_len
, strlen(u
->job_type
));
325 if (!arg_full
&& original_stdout_is_tty
) {
328 id_len
= MIN(max_id_len
, 25u);
329 basic_len
= 5 + id_len
+ 5 + active_len
+ sub_len
;
332 basic_len
+= job_len
+ 1;
334 if (basic_len
< (unsigned) columns()) {
335 unsigned extra_len
, incr
;
336 extra_len
= columns() - basic_len
;
338 /* Either UNIT already got 25, or is fully satisfied.
339 * Grant up to 25 to DESC now. */
340 incr
= MIN(extra_len
, 25u);
344 /* split the remaining space between UNIT and DESC,
345 * but do not give UNIT more than it needs. */
347 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
349 desc_len
+= extra_len
- incr
;
355 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
356 _cleanup_free_
char *e
= NULL
;
357 const char *on_loaded
, *off_loaded
, *on
= "";
358 const char *on_active
, *off_active
, *off
= "";
360 if (!output_show_unit(u
))
363 if (!n_shown
&& !arg_no_legend
) {
364 printf("%-*s %-*s %-*s %-*s ",
367 active_len
, "ACTIVE",
371 printf("%-*s ", job_len
, "JOB");
373 if (!arg_full
&& arg_no_pager
)
374 printf("%.*s\n", desc_len
, "DESCRIPTION");
376 printf("%s\n", "DESCRIPTION");
381 if (streq(u
->load_state
, "error") ||
382 streq(u
->load_state
, "not-found")) {
383 on_loaded
= on
= ansi_highlight_red();
384 off_loaded
= off
= ansi_highlight_off();
386 on_loaded
= off_loaded
= "";
388 if (streq(u
->active_state
, "failed")) {
389 on_active
= on
= ansi_highlight_red();
390 off_active
= off
= ansi_highlight_off();
392 on_active
= off_active
= "";
394 e
= arg_full
? NULL
: ellipsize(u
->id
, id_len
, 33);
396 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
397 on
, id_len
, e
? e
: u
->id
, off
,
398 on_loaded
, load_len
, u
->load_state
, off_loaded
,
399 on_active
, active_len
, u
->active_state
,
400 sub_len
, u
->sub_state
, off_active
,
401 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
404 printf("%.*s\n", desc_len
, u
->description
);
406 printf("%s\n", u
->description
);
409 if (!arg_no_legend
) {
410 const char *on
, *off
;
413 printf("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
414 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
415 "SUB = The low-level unit activation state, values depend on unit type.\n");
417 printf("JOB = Pending job for the unit.\n");
419 on
= ansi_highlight();
420 off
= ansi_highlight_off();
422 on
= ansi_highlight_red();
423 off
= ansi_highlight_off();
427 printf("%s%u loaded units listed.%s\n"
428 "To show all installed unit files use 'systemctl list-unit-files'.\n",
431 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
432 "To show all installed unit files use 'systemctl list-unit-files'.\n",
437 static int get_unit_list(
439 sd_bus_message
**_reply
,
440 UnitInfo
**_unit_infos
) {
442 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
443 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
444 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
453 r
= sd_bus_call_method(
455 "org.freedesktop.systemd1",
456 "/org/freedesktop/systemd1",
457 "org.freedesktop.systemd1.Manager",
463 log_error("Failed to list units: %s", bus_error_message(&error
, r
));
467 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
469 return bus_log_parse_error(r
);
471 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
473 if (!GREEDY_REALLOC(unit_infos
, size
, c
+1))
479 return bus_log_parse_error(r
);
481 r
= sd_bus_message_exit_container(reply
);
483 return bus_log_parse_error(r
);
488 *_unit_infos
= unit_infos
;
494 static int list_units(sd_bus
*bus
, char **args
) {
495 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
496 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
499 pager_open_if_enabled();
501 r
= get_unit_list(bus
, &reply
, &unit_infos
);
505 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
506 output_units_list(unit_infos
, r
);
511 static int get_triggered_units(
516 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
519 r
= sd_bus_get_property_strv(
521 "org.freedesktop.systemd1",
523 "org.freedesktop.systemd1.Unit",
529 log_error("Failed to determine triggers: %s", bus_error_message(&error
, r
));
534 static int get_listening(
536 const char* unit_path
,
539 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
540 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
541 const char *type
, *path
;
544 r
= sd_bus_get_property(
546 "org.freedesktop.systemd1",
548 "org.freedesktop.systemd1.Socket",
554 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
558 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
560 return bus_log_parse_error(r
);
562 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
564 r
= strv_extend(listening
, type
);
568 r
= strv_extend(listening
, path
);
575 return bus_log_parse_error(r
);
577 r
= sd_bus_message_exit_container(reply
);
579 return bus_log_parse_error(r
);
590 /* Note: triggered is a list here, although it almost certainly
591 * will always be one unit. Nevertheless, dbus API allows for multiple
592 * values, so let's follow that.*/
595 /* The strv above is shared. free is set only in the first one. */
599 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
605 o
= strcmp(a
->path
, b
->path
);
607 o
= strcmp(a
->type
, b
->type
);
612 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
613 struct socket_info
*s
;
614 unsigned pathlen
= sizeof("LISTEN") - 1,
615 typelen
= (sizeof("TYPE") - 1) * arg_show_types
,
616 socklen
= sizeof("UNIT") - 1,
617 servlen
= sizeof("ACTIVATES") - 1;
618 const char *on
, *off
;
620 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
624 socklen
= MAX(socklen
, strlen(s
->id
));
626 typelen
= MAX(typelen
, strlen(s
->type
));
627 pathlen
= MAX(pathlen
, strlen(s
->path
));
629 STRV_FOREACH(a
, s
->triggered
)
630 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
631 servlen
= MAX(servlen
, tmp
);
636 printf("%-*s %-*.*s%-*s %s\n",
638 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
642 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
646 printf("%-*s %-*s %-*s",
647 pathlen
, s
->path
, typelen
, s
->type
, socklen
, s
->id
);
650 pathlen
, s
->path
, socklen
, s
->id
);
651 STRV_FOREACH(a
, s
->triggered
)
653 a
== s
->triggered
? "" : ",", *a
);
657 on
= ansi_highlight();
658 off
= ansi_highlight_off();
662 on
= ansi_highlight_red();
663 off
= ansi_highlight_off();
666 if (!arg_no_legend
) {
667 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
669 printf("Pass --all to see loaded but inactive sockets, too.\n");
675 static int list_sockets(sd_bus
*bus
, char **args
) {
676 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
677 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
678 struct socket_info
*socket_infos
= NULL
;
680 struct socket_info
*s
;
685 pager_open_if_enabled();
687 n
= get_unit_list(bus
, &reply
, &unit_infos
);
691 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
692 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
695 if (!output_show_unit(u
))
698 if (!endswith(u
->id
, ".socket"))
701 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
705 c
= get_listening(bus
, u
->unit_path
, &listening
);
711 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
716 for (i
= 0; i
< c
; i
++)
717 socket_infos
[cs
+ i
] = (struct socket_info
) {
719 .type
= listening
[i
*2],
720 .path
= listening
[i
*2 + 1],
721 .triggered
= triggered
,
722 .own_triggered
= i
==0,
725 /* from this point on we will cleanup those socket_infos */
728 listening
= triggered
= NULL
; /* avoid cleanup */
731 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
732 (__compar_fn_t
) socket_info_compare
);
734 output_sockets_list(socket_infos
, cs
);
737 assert(cs
== 0 || socket_infos
);
738 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
741 if (s
->own_triggered
)
742 strv_free(s
->triggered
);
749 static int get_next_elapse(
752 dual_timestamp
*next
) {
754 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
762 r
= sd_bus_get_property_trivial(
764 "org.freedesktop.systemd1",
766 "org.freedesktop.systemd1.Timer",
767 "NextElapseUSecMonotonic",
772 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
776 r
= sd_bus_get_property_trivial(
778 "org.freedesktop.systemd1",
780 "org.freedesktop.systemd1.Timer",
781 "NextElapseUSecRealtime",
786 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
800 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
804 if (a
->next_elapse
< b
->next_elapse
)
806 if (a
->next_elapse
> b
->next_elapse
)
809 return strcmp(a
->id
, b
->id
);
812 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
813 struct timer_info
*t
;
815 nextlen
= sizeof("NEXT") - 1,
816 leftlen
= sizeof("LEFT") - 1,
817 unitlen
= sizeof("UNIT") - 1,
818 activatelen
= sizeof("ACTIVATES") - 1;
820 const char *on
, *off
;
822 assert(timer_infos
|| n
== 0);
824 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
828 if (t
->next_elapse
> 0) {
829 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
831 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
832 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
834 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
835 leftlen
= MAX(leftlen
, strlen(trel
));
838 unitlen
= MAX(unitlen
, strlen(t
->id
));
840 STRV_FOREACH(a
, t
->triggered
)
841 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
842 activatelen
= MAX(activatelen
, ul
);
847 printf("%-*s %-*s %-*s %s\n",
853 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
854 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
857 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
858 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
860 printf("%-*s %-*s %-*s",
861 nextlen
, tstamp
, leftlen
, trel
, unitlen
, t
->id
);
863 STRV_FOREACH(a
, t
->triggered
)
865 a
== t
->triggered
? "" : ",", *a
);
869 on
= ansi_highlight();
870 off
= ansi_highlight_off();
874 on
= ansi_highlight_red();
875 off
= ansi_highlight_off();
878 if (!arg_no_legend
) {
879 printf("%s%u timers listed.%s\n", on
, n
, off
);
881 printf("Pass --all to see loaded but inactive timers, too.\n");
887 static int list_timers(sd_bus
*bus
, char **args
) {
889 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
890 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
891 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
892 struct timer_info
*t
;
899 pager_open_if_enabled();
901 n
= get_unit_list(bus
, &reply
, &unit_infos
);
905 dual_timestamp_get(&nw
);
907 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
908 _cleanup_strv_free_
char **triggered
= NULL
;
912 if (!output_show_unit(u
))
915 if (!endswith(u
->id
, ".timer"))
918 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
922 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
926 if (next
.monotonic
!= (usec_t
) -1 && next
.monotonic
> 0) {
929 if (next
.monotonic
> nw
.monotonic
)
930 converted
= nw
.realtime
+ (next
.monotonic
- nw
.monotonic
);
932 converted
= nw
.realtime
- (nw
.monotonic
- next
.monotonic
);
934 if (next
.realtime
!= (usec_t
) -1 && next
.realtime
> 0)
935 m
= MIN(converted
, next
.realtime
);
941 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
946 timer_infos
[c
++] = (struct timer_info
) {
949 .triggered
= triggered
,
952 triggered
= NULL
; /* avoid cleanup */
955 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
956 (__compar_fn_t
) timer_info_compare
);
958 output_timers_list(timer_infos
, c
);
961 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
962 strv_free(t
->triggered
);
967 static int compare_unit_file_list(const void *a
, const void *b
) {
969 const UnitFileList
*u
= a
, *v
= b
;
971 d1
= strrchr(u
->path
, '.');
972 d2
= strrchr(v
->path
, '.');
977 r
= strcasecmp(d1
, d2
);
982 return strcasecmp(path_get_file_name(u
->path
), path_get_file_name(v
->path
));
985 static bool output_show_unit_file(const UnitFileList
*u
) {
988 return !arg_types
|| ((dot
= strrchr(u
->path
, '.')) && strv_find(arg_types
, dot
+1));
991 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
992 unsigned max_id_len
, id_cols
, state_cols
, n_shown
= 0;
993 const UnitFileList
*u
;
995 max_id_len
= sizeof("UNIT FILE")-1;
996 state_cols
= sizeof("STATE")-1;
998 for (u
= units
; u
< units
+ c
; u
++) {
999 if (!output_show_unit_file(u
))
1002 max_id_len
= MAX(max_id_len
, strlen(path_get_file_name(u
->path
)));
1003 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1007 unsigned basic_cols
;
1009 id_cols
= MIN(max_id_len
, 25u);
1010 basic_cols
= 1 + id_cols
+ state_cols
;
1011 if (basic_cols
< (unsigned) columns())
1012 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1014 id_cols
= max_id_len
;
1017 printf("%-*s %-*s\n",
1018 id_cols
, "UNIT FILE",
1019 state_cols
, "STATE");
1021 for (u
= units
; u
< units
+ c
; u
++) {
1022 _cleanup_free_
char *e
= NULL
;
1023 const char *on
, *off
;
1026 if (!output_show_unit_file(u
))
1031 if (u
->state
== UNIT_FILE_MASKED
||
1032 u
->state
== UNIT_FILE_MASKED_RUNTIME
||
1033 u
->state
== UNIT_FILE_DISABLED
||
1034 u
->state
== UNIT_FILE_INVALID
) {
1035 on
= ansi_highlight_red();
1036 off
= ansi_highlight_off();
1037 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1038 on
= ansi_highlight_green();
1039 off
= ansi_highlight_off();
1043 id
= path_get_file_name(u
->path
);
1045 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1047 printf("%-*s %s%-*s%s\n",
1048 id_cols
, e
? e
: id
,
1049 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1053 printf("\n%u unit files listed.\n", n_shown
);
1056 static int list_unit_files(sd_bus
*bus
, char **args
) {
1057 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1058 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1059 _cleanup_free_ UnitFileList
*units
= NULL
;
1065 pager_open_if_enabled();
1073 h
= hashmap_new(string_hash_func
, string_compare_func
);
1077 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1079 unit_file_list_free(h
);
1080 log_error("Failed to get unit file list: %s", strerror(-r
));
1084 n_units
= hashmap_size(h
);
1085 units
= new(UnitFileList
, n_units
);
1087 unit_file_list_free(h
);
1091 HASHMAP_FOREACH(u
, h
, i
) {
1092 memcpy(units
+ c
++, u
, sizeof(UnitFileList
));
1096 assert(c
== n_units
);
1101 r
= sd_bus_call_method(
1103 "org.freedesktop.systemd1",
1104 "/org/freedesktop/systemd1",
1105 "org.freedesktop.systemd1.Manager",
1111 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1115 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1117 return bus_log_parse_error(r
);
1119 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1121 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1124 units
[c
++] = (struct UnitFileList
) {
1126 unit_file_state_from_string(state
)
1130 return bus_log_parse_error(r
);
1132 r
= sd_bus_message_exit_container(reply
);
1134 return bus_log_parse_error(r
);
1138 qsort(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1139 output_unit_file_list(units
, c
);
1145 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1146 _cleanup_free_
char *n
= NULL
;
1147 size_t max_len
= MAX(columns(),20u);
1153 for (i
= level
- 1; i
>= 0; i
--) {
1155 if(len
> max_len
- 3 && !arg_full
) {
1156 printf("%s...\n",max_len
% 2 ? "" : " ");
1159 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERT
: DRAW_TREE_SPACE
));
1163 if(len
> max_len
- 3 && !arg_full
) {
1164 printf("%s...\n",max_len
% 2 ? "" : " ");
1168 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1172 printf("%s\n", name
);
1176 n
= ellipsize(name
, max_len
-len
, 100);
1184 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1186 static const char *dependencies
[] = {
1187 [DEPENDENCY_FORWARD
] = "Requires\0"
1188 "RequiresOverridable\0"
1190 "RequisiteOverridable\0"
1192 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1193 "RequiredByOverridable\0"
1196 [DEPENDENCY_AFTER
] = "After\0",
1197 [DEPENDENCY_BEFORE
] = "Before\0",
1200 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1201 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1202 _cleanup_strv_free_
char **ret
= NULL
;
1203 _cleanup_free_
char *path
= NULL
;
1209 assert(arg_dependency
< ELEMENTSOF(dependencies
));
1211 path
= unit_dbus_path_from_name(name
);
1215 r
= sd_bus_call_method(
1217 "org.freedesktop.systemd1",
1219 "org.freedesktop.DBus.Properties",
1223 "s", "org.freedesktop.systemd1.Unit");
1225 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1229 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1231 return bus_log_parse_error(r
);
1233 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1236 r
= sd_bus_message_read(reply
, "s", &prop
);
1238 return bus_log_parse_error(r
);
1240 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1241 r
= sd_bus_message_skip(reply
, "v");
1243 return bus_log_parse_error(r
);
1246 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1248 return bus_log_parse_error(r
);
1250 r
= bus_message_read_strv_extend(reply
, &ret
);
1252 return bus_log_parse_error(r
);
1254 r
= sd_bus_message_exit_container(reply
);
1256 return bus_log_parse_error(r
);
1259 r
= sd_bus_message_exit_container(reply
);
1261 return bus_log_parse_error(r
);
1265 return bus_log_parse_error(r
);
1267 r
= sd_bus_message_exit_container(reply
);
1269 return bus_log_parse_error(r
);
1277 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1278 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1280 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1282 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1285 return strcasecmp(*a
, *b
);
1288 static int list_dependencies_one(
1293 unsigned int branches
) {
1295 _cleanup_strv_free_
char **deps
= NULL
, **u
;
1303 u
= strv_append(*units
, name
);
1307 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1311 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1313 STRV_FOREACH(c
, deps
) {
1316 if (strv_contains(u
, *c
)) {
1318 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1325 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1327 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE
), ansi_highlight_off());
1329 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE
), ansi_highlight_off());
1331 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1335 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1336 r
= list_dependencies_one(bus
, *c
, level
+ 1, &u
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1351 static int list_dependencies(sd_bus
*bus
, char **args
) {
1352 _cleanup_strv_free_
char **units
= NULL
;
1353 _cleanup_free_
char *unit
= NULL
;
1359 unit
= unit_name_mangle(args
[1]);
1364 u
= SPECIAL_DEFAULT_TARGET
;
1366 pager_open_if_enabled();
1370 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1373 static int get_default(sd_bus
*bus
, char **args
) {
1374 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1375 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1376 _cleanup_free_
char *_path
= NULL
;
1380 if (!bus
|| avoid_bus()) {
1381 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1383 log_error("Failed to get default target: %s", strerror(-r
));
1389 r
= sd_bus_call_method(
1391 "org.freedesktop.systemd1",
1392 "/org/freedesktop/systemd1",
1393 "org.freedesktop.systemd1.Manager",
1399 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1403 r
= sd_bus_message_read(reply
, "s", &path
);
1405 return bus_log_parse_error(r
);
1409 printf("%s\n", path
);
1414 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1417 assert(changes
|| n_changes
== 0);
1419 for (i
= 0; i
< n_changes
; i
++) {
1420 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1421 log_info("ln -s '%s' '%s'", changes
[i
].source
, changes
[i
].path
);
1423 log_info("rm '%s'", changes
[i
].path
);
1427 static int deserialize_and_dump_unit_file_changes(sd_bus_message
*m
) {
1428 const char *type
, *path
, *source
;
1431 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
1433 return bus_log_parse_error(r
);
1435 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
1437 if (streq(type
, "symlink"))
1438 log_info("ln -s '%s' '%s'", source
, path
);
1440 log_info("rm '%s'", path
);
1444 return bus_log_parse_error(r
);
1446 r
= sd_bus_message_exit_container(m
);
1448 return bus_log_parse_error(r
);
1453 static int set_default(sd_bus
*bus
, char **args
) {
1454 _cleanup_free_
char *unit
= NULL
;
1455 UnitFileChange
*changes
= NULL
;
1456 unsigned n_changes
= 0;
1459 unit
= unit_name_mangle_with_suffix(args
[1], ".target");
1463 if (!bus
|| avoid_bus()) {
1464 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, arg_force
, &changes
, &n_changes
);
1466 log_error("Failed to set default target: %s", strerror(-r
));
1471 dump_unit_file_changes(changes
, n_changes
);
1475 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1476 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1478 r
= sd_bus_call_method(
1480 "org.freedesktop.systemd1",
1481 "/org/freedesktop/systemd1",
1482 "org.freedesktop.systemd1.Manager",
1486 "sb", unit
, arg_force
);
1488 log_error("Failed to set default target: %s", bus_error_message(&error
, -r
));
1492 r
= deserialize_and_dump_unit_file_changes(reply
);
1496 /* Try to reload if enabeld */
1498 r
= daemon_reload(bus
, args
);
1503 unit_file_changes_free(changes
, n_changes
);
1510 const char *name
, *type
, *state
;
1513 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
) {
1514 unsigned id_len
, unit_len
, type_len
, state_len
;
1515 const struct job_info
*j
;
1516 const char *on
, *off
;
1517 bool shorten
= false;
1519 assert(n
== 0 || jobs
);
1522 on
= ansi_highlight_green();
1523 off
= ansi_highlight_off();
1525 printf("%sNo jobs running.%s\n", on
, off
);
1529 pager_open_if_enabled();
1531 id_len
= sizeof("JOB")-1;
1532 unit_len
= sizeof("UNIT")-1;
1533 type_len
= sizeof("TYPE")-1;
1534 state_len
= sizeof("STATE")-1;
1536 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1537 uint32_t id
= j
->id
;
1538 assert(j
->name
&& j
->type
&& j
->state
);
1540 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
1541 unit_len
= MAX(unit_len
, strlen(j
->name
));
1542 type_len
= MAX(type_len
, strlen(j
->type
));
1543 state_len
= MAX(state_len
, strlen(j
->state
));
1546 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
1547 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
1552 printf("%*s %-*s %-*s %-*s\n",
1556 state_len
, "STATE");
1558 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1559 _cleanup_free_
char *e
= NULL
;
1561 if (streq(j
->state
, "running")) {
1562 on
= ansi_highlight();
1563 off
= ansi_highlight_off();
1567 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
1568 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1570 on
, unit_len
, e
? e
: j
->name
, off
,
1572 on
, state_len
, j
->state
, off
);
1575 if (!arg_no_legend
) {
1576 on
= ansi_highlight();
1577 off
= ansi_highlight_off();
1579 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
1583 static int list_jobs(sd_bus
*bus
, char **args
) {
1584 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1585 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1586 const char *name
, *type
, *state
, *job_path
, *unit_path
;
1587 _cleanup_free_
struct job_info
*jobs
= NULL
;
1593 r
= sd_bus_call_method(
1595 "org.freedesktop.systemd1",
1596 "/org/freedesktop/systemd1",
1597 "org.freedesktop.systemd1.Manager",
1603 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
1607 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
1609 return bus_log_parse_error(r
);
1611 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
1613 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
1616 jobs
[c
++] = (struct job_info
) {
1624 return bus_log_parse_error(r
);
1626 r
= sd_bus_message_exit_container(reply
);
1628 return bus_log_parse_error(r
);
1630 output_jobs_list(jobs
, c
);
1634 static int cancel_job(sd_bus
*bus
, char **args
) {
1635 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1640 if (strv_length(args
) <= 1)
1641 return daemon_reload(bus
, args
);
1643 STRV_FOREACH(name
, args
+1) {
1647 r
= safe_atou32(*name
, &id
);
1649 log_error("Failed to parse job id \"%s\": %s", *name
, strerror(-r
));
1653 r
= sd_bus_call_method(
1655 "org.freedesktop.systemd1",
1656 "/org/freedesktop/systemd1",
1657 "org.freedesktop.systemd1.Manager",
1663 log_error("Failed to cancel job %u: %s", (unsigned) id
, bus_error_message(&error
, r
));
1671 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
1672 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1673 _cleanup_free_
char *n
= NULL
;
1677 /* We ignore all errors here, since this is used to show a
1680 n
= unit_name_mangle(unit
);
1684 /* We don't use unit_dbus_path_from_name() directly since we
1685 * don't want to load the unit if it isn't loaded. */
1687 r
= sd_bus_call_method(
1689 "org.freedesktop.systemd1",
1690 "/org/freedesktop/systemd1",
1691 "org.freedesktop.systemd1.Manager",
1699 r
= sd_bus_message_read(reply
, "o", &path
);
1703 r
= sd_bus_get_property_trivial(
1705 "org.freedesktop.systemd1",
1707 "org.freedesktop.systemd1.Unit",
1717 typedef struct WaitData
{
1724 static int wait_filter(sd_bus
*bus
, sd_bus_message
*m
, void *data
, sd_bus_error
*error
) {
1731 log_debug("Got D-Bus request: %s.%s() on %s",
1732 sd_bus_message_get_interface(m
),
1733 sd_bus_message_get_member(m
),
1734 sd_bus_message_get_path(m
));
1736 if (sd_bus_message_is_signal(m
, "org.freedesktop.DBus.Local", "Disconnected")) {
1737 log_error("Warning! D-Bus connection terminated.");
1739 } else if (sd_bus_message_is_signal(m
, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1741 const char *path
, *result
, *unit
;
1745 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1747 ret
= set_remove(d
->set
, (char*) path
);
1753 if (!isempty(result
))
1754 d
->result
= strdup(result
);
1757 d
->name
= strdup(unit
);
1762 r
= sd_bus_message_read(m
, "uos", &id
, &path
, &result
);
1764 ret
= set_remove(d
->set
, (char*) path
);
1771 d
->result
= strdup(result
);
1777 bus_log_parse_error(r
);
1783 static int enable_wait_for_jobs(sd_bus
*bus
) {
1788 r
= sd_bus_add_match(
1791 "sender='org.freedesktop.systemd1',"
1792 "interface='org.freedesktop.systemd1.Manager',"
1793 "member='JobRemoved',"
1794 "path='/org/freedesktop/systemd1'",
1797 log_error("Failed to add match");
1801 /* This is slightly dirty, since we don't undo the match registrations. */
1805 static int wait_for_jobs(sd_bus
*bus
, Set
*s
) {
1806 WaitData d
= { .set
= s
};
1812 r
= sd_bus_add_filter(bus
, wait_filter
, &d
);
1816 while (!set_isempty(s
)) {
1818 r
= sd_bus_process(bus
, NULL
);
1823 r
= sd_bus_wait(bus
, (uint64_t) -1);
1832 if (streq(d
.result
, "timeout"))
1833 log_error("Job for %s timed out.", strna(d
.name
));
1834 else if (streq(d
.result
, "canceled"))
1835 log_error("Job for %s canceled.", strna(d
.name
));
1836 else if (streq(d
.result
, "dependency"))
1837 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d
.name
));
1838 else if (!streq(d
.result
, "done") && !streq(d
.result
, "skipped"))
1839 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d
.name
), strna(d
.name
));
1842 if (streq_ptr(d
.result
, "timeout"))
1844 else if (streq_ptr(d
.result
, "canceled"))
1846 else if (!streq_ptr(d
.result
, "done") && !streq_ptr(d
.result
, "skipped"))
1857 return sd_bus_remove_filter(bus
, wait_filter
, &d
);
1860 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
1861 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1862 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
1868 n
= unit_name_mangle(name
);
1872 /* We don't use unit_dbus_path_from_name() directly since we
1873 * don't want to load the unit if it isn't loaded. */
1875 r
= sd_bus_call_method(
1877 "org.freedesktop.systemd1",
1878 "/org/freedesktop/systemd1",
1879 "org.freedesktop.systemd1.Manager",
1890 r
= sd_bus_message_read(reply
, "o", &path
);
1892 return bus_log_parse_error(r
);
1894 r
= sd_bus_get_property_string(
1896 "org.freedesktop.systemd1",
1898 "org.freedesktop.systemd1.Unit",
1911 return nulstr_contains(good_states
, state
);
1914 static int check_triggering_units(
1918 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1919 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
1920 _cleanup_strv_free_
char **triggered_by
= NULL
;
1921 bool print_warning_label
= true;
1925 n
= unit_name_mangle(name
);
1929 path
= unit_dbus_path_from_name(n
);
1933 r
= sd_bus_get_property_string(
1935 "org.freedesktop.systemd1",
1937 "org.freedesktop.systemd1.Unit",
1942 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
1946 if (streq(state
, "masked"))
1949 r
= sd_bus_get_property_strv(
1951 "org.freedesktop.systemd1",
1953 "org.freedesktop.systemd1.Unit",
1958 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
1962 STRV_FOREACH(i
, triggered_by
) {
1963 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
1965 log_error("Failed to check unit: %s", strerror(-r
));
1972 if (print_warning_label
) {
1973 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
1974 print_warning_label
= false;
1977 log_warning(" %s", *i
);
1983 static int start_unit_one(
1988 sd_bus_error
*error
,
1991 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1992 _cleanup_free_
char *n
;
2001 n
= unit_name_mangle(name
);
2005 r
= sd_bus_call_method(
2007 "org.freedesktop.systemd1",
2008 "/org/freedesktop/systemd1",
2009 "org.freedesktop.systemd1.Manager",
2015 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2016 /* There's always a fallback possible for
2017 * legacy actions. */
2018 return -EADDRNOTAVAIL
;
2020 log_error("Failed to start %s: %s", name
, bus_error_message(error
, r
));
2024 r
= sd_bus_message_read(reply
, "o", &path
);
2026 return bus_log_parse_error(r
);
2028 if (need_daemon_reload(bus
, n
) > 0)
2029 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2030 n
, arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2039 r
= set_consume(s
, p
);
2047 static const struct {
2051 } action_table
[_ACTION_MAX
] = {
2052 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2053 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2054 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2055 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2056 [ACTION_RUNLEVEL2
] = { SPECIAL_RUNLEVEL2_TARGET
, NULL
, "isolate" },
2057 [ACTION_RUNLEVEL3
] = { SPECIAL_RUNLEVEL3_TARGET
, NULL
, "isolate" },
2058 [ACTION_RUNLEVEL4
] = { SPECIAL_RUNLEVEL4_TARGET
, NULL
, "isolate" },
2059 [ACTION_RUNLEVEL5
] = { SPECIAL_RUNLEVEL5_TARGET
, NULL
, "isolate" },
2060 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2061 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2062 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2063 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2064 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2065 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2066 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2069 static enum action
verb_to_action(const char *verb
) {
2072 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2073 if (streq_ptr(action_table
[i
].verb
, verb
))
2076 return _ACTION_INVALID
;
2079 static int start_unit(sd_bus
*bus
, char **args
) {
2080 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2081 _cleanup_set_free_free_ Set
*s
= NULL
;
2082 const char *method
, *mode
, *one_name
;
2088 ask_password_agent_open_if_enabled();
2090 if (arg_action
== ACTION_SYSTEMCTL
) {
2093 streq(args
[0], "stop") ||
2094 streq(args
[0], "condstop") ? "StopUnit" :
2095 streq(args
[0], "reload") ? "ReloadUnit" :
2096 streq(args
[0], "restart") ? "RestartUnit" :
2098 streq(args
[0], "try-restart") ||
2099 streq(args
[0], "condrestart") ? "TryRestartUnit" :
2101 streq(args
[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2103 streq(args
[0], "reload-or-try-restart") ||
2104 streq(args
[0], "condreload") ||
2105 streq(args
[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2107 action
= verb_to_action(args
[0]);
2109 mode
= streq(args
[0], "isolate") ? "isolate" :
2110 action_table
[action
].mode
?: arg_job_mode
;
2112 one_name
= action_table
[action
].target
;
2114 assert(arg_action
< ELEMENTSOF(action_table
));
2115 assert(action_table
[arg_action
].target
);
2117 method
= "StartUnit";
2119 mode
= action_table
[arg_action
].mode
;
2120 one_name
= action_table
[arg_action
].target
;
2123 if (!arg_no_block
) {
2124 r
= enable_wait_for_jobs(bus
);
2126 log_error("Could not watch jobs: %s", strerror(-r
));
2130 s
= set_new(string_hash_func
, string_compare_func
);
2136 r
= start_unit_one(bus
, method
, one_name
, mode
, &error
, s
);
2138 r
= translate_bus_error_to_exit_status(r
, &error
);
2142 STRV_FOREACH(name
, args
+1) {
2145 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, s
);
2147 r
= translate_bus_error_to_exit_status(r
, &error
);
2148 sd_bus_error_free(&error
);
2153 if (!arg_no_block
) {
2156 q
= wait_for_jobs(bus
, s
);
2160 /* When stopping units, warn if they can still be triggered by
2161 * another active unit (socket, path, timer) */
2162 if (!arg_quiet
&& streq(method
, "StopUnit")) {
2164 check_triggering_units(bus
, one_name
);
2166 STRV_FOREACH(name
, args
+1)
2167 check_triggering_units(bus
, *name
);
2174 /* Ask systemd-logind, which might grant access to unprivileged users
2175 * through PolicyKit */
2176 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
2178 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2185 polkit_agent_open_if_enabled();
2193 case ACTION_POWEROFF
:
2194 method
= "PowerOff";
2197 case ACTION_SUSPEND
:
2201 case ACTION_HIBERNATE
:
2202 method
= "Hibernate";
2205 case ACTION_HYBRID_SLEEP
:
2206 method
= "HybridSleep";
2213 r
= sd_bus_call_method(
2215 "org.freedesktop.login1",
2216 "/org/freedesktop/login1",
2217 "org.freedesktop.login1.Manager",
2223 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
2231 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
2233 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2234 _cleanup_strv_free_
char **sessions
= NULL
;
2235 const char *what
, *who
, *why
, *mode
;
2244 if (arg_ignore_inhibitors
|| arg_force
> 0)
2256 r
= sd_bus_call_method(
2258 "org.freedesktop.login1",
2259 "/org/freedesktop/login1",
2260 "org.freedesktop.login1.Manager",
2266 /* If logind is not around, then there are no inhibitors... */
2269 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2271 return bus_log_parse_error(r
);
2273 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2274 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2275 _cleanup_strv_free_
char **sv
= NULL
;
2277 if (!streq(mode
, "block"))
2280 sv
= strv_split(what
, ":");
2284 if (!strv_contains(sv
,
2286 a
== ACTION_POWEROFF
||
2287 a
== ACTION_REBOOT
||
2288 a
== ACTION_KEXEC
? "shutdown" : "sleep"))
2291 get_process_comm(pid
, &comm
);
2292 user
= uid_to_name(uid
);
2294 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2295 who
, (unsigned long) pid
, strna(comm
), strna(user
), why
);
2300 return bus_log_parse_error(r
);
2302 r
= sd_bus_message_exit_container(reply
);
2304 return bus_log_parse_error(r
);
2306 /* Check for current sessions */
2307 sd_get_sessions(&sessions
);
2308 STRV_FOREACH(s
, sessions
) {
2309 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2311 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2314 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2317 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2320 sd_session_get_tty(*s
, &tty
);
2321 sd_session_get_seat(*s
, &seat
);
2322 sd_session_get_service(*s
, &service
);
2323 user
= uid_to_name(uid
);
2325 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2332 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2333 action_table
[a
].verb
);
2341 static int start_special(sd_bus
*bus
, char **args
) {
2347 a
= verb_to_action(args
[0]);
2349 r
= check_inhibitors(bus
, a
);
2353 if (arg_force
>= 2 && geteuid() != 0) {
2354 log_error("Must be root.");
2358 if (arg_force
>= 2 &&
2359 (a
== ACTION_HALT
||
2360 a
== ACTION_POWEROFF
||
2361 a
== ACTION_REBOOT
))
2364 if (arg_force
>= 1 &&
2365 (a
== ACTION_HALT
||
2366 a
== ACTION_POWEROFF
||
2367 a
== ACTION_REBOOT
||
2368 a
== ACTION_KEXEC
||
2370 return daemon_reload(bus
, args
);
2372 /* first try logind, to allow authentication with polkit */
2373 if (geteuid() != 0 &&
2374 (a
== ACTION_POWEROFF
||
2375 a
== ACTION_REBOOT
||
2376 a
== ACTION_SUSPEND
||
2377 a
== ACTION_HIBERNATE
||
2378 a
== ACTION_HYBRID_SLEEP
)) {
2379 r
= reboot_with_logind(bus
, a
);
2384 r
= start_unit(bus
, args
);
2385 if (r
== EXIT_SUCCESS
)
2391 static int check_unit_active(sd_bus
*bus
, char **args
) {
2393 int r
= 3; /* According to LSB: "program is not running" */
2398 STRV_FOREACH(name
, args
+1) {
2401 state
= check_one_unit(bus
, *name
, "active\0reloading\0", arg_quiet
);
2411 static int check_unit_failed(sd_bus
*bus
, char **args
) {
2418 STRV_FOREACH(name
, args
+1) {
2421 state
= check_one_unit(bus
, *name
, "failed\0", arg_quiet
);
2431 static int kill_unit(sd_bus
*bus
, char **args
) {
2432 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2440 arg_kill_who
= "all";
2442 STRV_FOREACH(name
, args
+1) {
2443 _cleanup_free_
char *n
= NULL
;
2445 n
= unit_name_mangle(*name
);
2449 r
= sd_bus_call_method(
2451 "org.freedesktop.systemd1",
2452 "/org/freedesktop/systemd1",
2453 "org.freedesktop.systemd1.Manager",
2457 "ssi", n
, arg_kill_who
, arg_signal
);
2459 log_error("Failed to kill unit %s: %s", n
, bus_error_message(&error
, r
));
2467 typedef struct ExecStatusInfo
{
2475 usec_t start_timestamp
;
2476 usec_t exit_timestamp
;
2481 LIST_FIELDS(struct ExecStatusInfo
, exec
);
2484 static void exec_status_info_free(ExecStatusInfo
*i
) {
2493 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
2494 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
2497 int32_t code
, status
;
2503 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
2505 return bus_log_parse_error(r
);
2509 r
= sd_bus_message_read(m
, "s", &path
);
2511 return bus_log_parse_error(r
);
2513 i
->path
= strdup(path
);
2517 r
= sd_bus_message_read_strv(m
, &i
->argv
);
2519 return bus_log_parse_error(r
);
2521 r
= sd_bus_message_read(m
,
2524 &start_timestamp
, &start_timestamp_monotonic
,
2525 &exit_timestamp
, &exit_timestamp_monotonic
,
2529 return bus_log_parse_error(r
);
2532 i
->start_timestamp
= (usec_t
) start_timestamp
;
2533 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
2534 i
->pid
= (pid_t
) pid
;
2538 r
= sd_bus_message_exit_container(m
);
2540 return bus_log_parse_error(r
);
2545 typedef struct UnitStatusInfo
{
2547 const char *load_state
;
2548 const char *active_state
;
2549 const char *sub_state
;
2550 const char *unit_file_state
;
2552 const char *description
;
2553 const char *following
;
2555 char **documentation
;
2557 const char *fragment_path
;
2558 const char *source_path
;
2559 const char *control_group
;
2561 char **dropin_paths
;
2563 const char *load_error
;
2566 usec_t inactive_exit_timestamp
;
2567 usec_t inactive_exit_timestamp_monotonic
;
2568 usec_t active_enter_timestamp
;
2569 usec_t active_exit_timestamp
;
2570 usec_t inactive_enter_timestamp
;
2572 bool need_daemon_reload
;
2577 const char *status_text
;
2578 const char *pid_file
;
2581 usec_t start_timestamp
;
2582 usec_t exit_timestamp
;
2584 int exit_code
, exit_status
;
2586 usec_t condition_timestamp
;
2587 bool condition_result
;
2588 bool failed_condition_trigger
;
2589 bool failed_condition_negate
;
2590 const char *failed_condition
;
2591 const char *failed_condition_param
;
2594 unsigned n_accepted
;
2595 unsigned n_connections
;
2598 /* Pairs of type, path */
2602 const char *sysfs_path
;
2604 /* Mount, Automount */
2610 LIST_HEAD(ExecStatusInfo
, exec
);
2613 static void print_status_info(
2618 const char *on
, *off
, *ss
;
2620 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
2621 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
2624 arg_all
* OUTPUT_SHOW_ALL
|
2625 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
2626 on_tty() * OUTPUT_COLOR
|
2627 !arg_quiet
* OUTPUT_WARN_CUTOFF
|
2628 arg_full
* OUTPUT_FULL_WIDTH
;
2633 /* This shows pretty information about a unit. See
2634 * print_property() for a low-level property printer */
2636 printf("%s", strna(i
->id
));
2638 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
2639 printf(" - %s", i
->description
);
2644 printf(" Follow: unit currently follows state of %s\n", i
->following
);
2646 if (streq_ptr(i
->load_state
, "error")) {
2647 on
= ansi_highlight_red();
2648 off
= ansi_highlight_off();
2652 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
2655 printf(" Loaded: %s%s%s (Reason: %s)\n",
2656 on
, strna(i
->load_state
), off
, i
->load_error
);
2657 else if (path
&& i
->unit_file_state
)
2658 printf(" Loaded: %s%s%s (%s; %s)\n",
2659 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
2661 printf(" Loaded: %s%s%s (%s)\n",
2662 on
, strna(i
->load_state
), off
, path
);
2664 printf(" Loaded: %s%s%s\n",
2665 on
, strna(i
->load_state
), off
);
2667 if (!strv_isempty(i
->dropin_paths
)) {
2668 _cleanup_free_
char *dir
= NULL
;
2672 STRV_FOREACH(dropin
, i
->dropin_paths
) {
2673 if (! dir
|| last
) {
2674 printf(dir
? " " : " Drop-In: ");
2679 if (path_get_parent(*dropin
, &dir
) < 0) {
2684 printf("%s\n %s", dir
,
2685 draw_special_char(DRAW_TREE_RIGHT
));
2688 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
2690 printf("%s%s", path_get_file_name(*dropin
), last
? "\n" : ", ");
2694 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
2696 if (streq_ptr(i
->active_state
, "failed")) {
2697 on
= ansi_highlight_red();
2698 off
= ansi_highlight_off();
2699 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
2700 on
= ansi_highlight_green();
2701 off
= ansi_highlight_off();
2706 printf(" Active: %s%s (%s)%s",
2707 on
, strna(i
->active_state
), ss
, off
);
2709 printf(" Active: %s%s%s",
2710 on
, strna(i
->active_state
), off
);
2712 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
2713 printf(" (Result: %s)", i
->result
);
2715 timestamp
= (streq_ptr(i
->active_state
, "active") ||
2716 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
2717 (streq_ptr(i
->active_state
, "inactive") ||
2718 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
2719 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
2720 i
->active_exit_timestamp
;
2722 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
2723 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
2726 printf(" since %s; %s\n", s2
, s1
);
2728 printf(" since %s\n", s2
);
2732 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
2733 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
2734 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
2736 printf(" start condition failed at %s%s%s\n",
2737 s2
, s1
? "; " : "", s1
? s1
: "");
2738 if (i
->failed_condition_trigger
)
2739 printf(" none of the trigger conditions were met\n");
2740 else if (i
->failed_condition
)
2741 printf(" %s=%s%s was not met\n",
2742 i
->failed_condition
,
2743 i
->failed_condition_negate
? "!" : "",
2744 i
->failed_condition_param
);
2748 printf(" Device: %s\n", i
->sysfs_path
);
2750 printf(" Where: %s\n", i
->where
);
2752 printf(" What: %s\n", i
->what
);
2754 STRV_FOREACH(t
, i
->documentation
)
2755 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
2757 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
2758 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
2761 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
2763 LIST_FOREACH(exec
, p
, i
->exec
) {
2764 _cleanup_free_
char *argv
= NULL
;
2767 /* Only show exited processes here */
2771 argv
= strv_join(p
->argv
, " ");
2772 printf(" Process: %u %s=%s ", p
->pid
, p
->name
, strna(argv
));
2774 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
2776 on
= ansi_highlight_red();
2777 off
= ansi_highlight_off();
2781 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
2783 if (p
->code
== CLD_EXITED
) {
2786 printf("status=%i", p
->status
);
2788 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
2793 printf("signal=%s", signal_to_string(p
->status
));
2795 printf(")%s\n", off
);
2797 if (i
->main_pid
== p
->pid
&&
2798 i
->start_timestamp
== p
->start_timestamp
&&
2799 i
->exit_timestamp
== p
->start_timestamp
)
2800 /* Let's not show this twice */
2803 if (p
->pid
== i
->control_pid
)
2807 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
2808 if (i
->main_pid
> 0) {
2809 printf(" Main PID: %u", (unsigned) i
->main_pid
);
2812 _cleanup_free_
char *comm
= NULL
;
2813 get_process_comm(i
->main_pid
, &comm
);
2815 printf(" (%s)", comm
);
2816 } else if (i
->exit_code
> 0) {
2817 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
2819 if (i
->exit_code
== CLD_EXITED
) {
2822 printf("status=%i", i
->exit_status
);
2824 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
2829 printf("signal=%s", signal_to_string(i
->exit_status
));
2833 if (i
->control_pid
> 0)
2837 if (i
->control_pid
> 0) {
2838 _cleanup_free_
char *c
= NULL
;
2840 printf(" %8s: %u", i
->main_pid
? "" : " Control", (unsigned) i
->control_pid
);
2842 get_process_comm(i
->control_pid
, &c
);
2851 printf(" Status: \"%s\"\n", i
->status_text
);
2853 if (i
->control_group
&&
2854 (i
->main_pid
> 0 || i
->control_pid
> 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, false) == 0)) {
2857 printf(" CGroup: %s\n", i
->control_group
);
2859 if (arg_transport
== BUS_TRANSPORT_LOCAL
|| arg_transport
== BUS_TRANSPORT_CONTAINER
) {
2862 char prefix
[] = " ";
2865 if (c
> sizeof(prefix
) - 1)
2866 c
-= sizeof(prefix
) - 1;
2870 if (i
->main_pid
> 0)
2871 extra
[k
++] = i
->main_pid
;
2873 if (i
->control_pid
> 0)
2874 extra
[k
++] = i
->control_pid
;
2876 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
,
2877 c
, false, extra
, k
, flags
);
2881 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
) {
2883 show_journal_by_unit(stdout
,
2887 i
->inactive_exit_timestamp_monotonic
,
2891 arg_scope
== UNIT_FILE_SYSTEM
,
2895 if (i
->need_daemon_reload
)
2896 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2897 ansi_highlight_red(),
2898 ansi_highlight_off(),
2899 arg_scope
== UNIT_FILE_SYSTEM
? "" : "--user ");
2902 static void show_unit_help(UnitStatusInfo
*i
) {
2907 if (!i
->documentation
) {
2908 log_info("Documentation for %s not known.", i
->id
);
2912 STRV_FOREACH(p
, i
->documentation
) {
2914 if (startswith(*p
, "man:")) {
2915 const char *args
[4] = { "man", NULL
, NULL
, NULL
};
2916 _cleanup_free_
char *page
= NULL
, *section
= NULL
;
2923 if ((*p
)[k
-1] == ')')
2924 e
= strrchr(*p
, '(');
2927 page
= strndup((*p
) + 4, e
- *p
- 4);
2928 section
= strndup(e
+ 1, *p
+ k
- e
- 2);
2929 if (!page
|| !section
) {
2941 log_error("Failed to fork: %m");
2947 execvp(args
[0], (char**) args
);
2948 log_error("Failed to execute man: %m");
2949 _exit(EXIT_FAILURE
);
2952 wait_for_terminate(pid
, NULL
);
2954 log_info("Can't show: %s", *p
);
2958 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
2965 switch (contents
[0]) {
2967 case SD_BUS_TYPE_STRING
: {
2970 r
= sd_bus_message_read(m
, "s", &s
);
2972 return bus_log_parse_error(r
);
2975 if (streq(name
, "Id"))
2977 else if (streq(name
, "LoadState"))
2979 else if (streq(name
, "ActiveState"))
2980 i
->active_state
= s
;
2981 else if (streq(name
, "SubState"))
2983 else if (streq(name
, "Description"))
2985 else if (streq(name
, "FragmentPath"))
2986 i
->fragment_path
= s
;
2987 else if (streq(name
, "SourcePath"))
2990 else if (streq(name
, "DefaultControlGroup")) {
2992 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
2994 i
->control_group
= e
;
2997 else if (streq(name
, "ControlGroup"))
2998 i
->control_group
= s
;
2999 else if (streq(name
, "StatusText"))
3001 else if (streq(name
, "PIDFile"))
3003 else if (streq(name
, "SysFSPath"))
3005 else if (streq(name
, "Where"))
3007 else if (streq(name
, "What"))
3009 else if (streq(name
, "Following"))
3011 else if (streq(name
, "UnitFileState"))
3012 i
->unit_file_state
= s
;
3013 else if (streq(name
, "Result"))
3020 case SD_BUS_TYPE_BOOLEAN
: {
3023 r
= sd_bus_message_read(m
, "b", &b
);
3025 return bus_log_parse_error(r
);
3027 if (streq(name
, "Accept"))
3029 else if (streq(name
, "NeedDaemonReload"))
3030 i
->need_daemon_reload
= b
;
3031 else if (streq(name
, "ConditionResult"))
3032 i
->condition_result
= b
;
3037 case SD_BUS_TYPE_UINT32
: {
3040 r
= sd_bus_message_read(m
, "u", &u
);
3042 return bus_log_parse_error(r
);
3044 if (streq(name
, "MainPID")) {
3046 i
->main_pid
= (pid_t
) u
;
3049 } else if (streq(name
, "ControlPID"))
3050 i
->control_pid
= (pid_t
) u
;
3051 else if (streq(name
, "ExecMainPID")) {
3053 i
->main_pid
= (pid_t
) u
;
3054 } else if (streq(name
, "NAccepted"))
3056 else if (streq(name
, "NConnections"))
3057 i
->n_connections
= u
;
3062 case SD_BUS_TYPE_INT32
: {
3065 r
= sd_bus_message_read(m
, "i", &j
);
3067 return bus_log_parse_error(r
);
3069 if (streq(name
, "ExecMainCode"))
3070 i
->exit_code
= (int) j
;
3071 else if (streq(name
, "ExecMainStatus"))
3072 i
->exit_status
= (int) j
;
3077 case SD_BUS_TYPE_UINT64
: {
3080 r
= sd_bus_message_read(m
, "t", &u
);
3082 return bus_log_parse_error(r
);
3084 if (streq(name
, "ExecMainStartTimestamp"))
3085 i
->start_timestamp
= (usec_t
) u
;
3086 else if (streq(name
, "ExecMainExitTimestamp"))
3087 i
->exit_timestamp
= (usec_t
) u
;
3088 else if (streq(name
, "ActiveEnterTimestamp"))
3089 i
->active_enter_timestamp
= (usec_t
) u
;
3090 else if (streq(name
, "InactiveEnterTimestamp"))
3091 i
->inactive_enter_timestamp
= (usec_t
) u
;
3092 else if (streq(name
, "InactiveExitTimestamp"))
3093 i
->inactive_exit_timestamp
= (usec_t
) u
;
3094 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3095 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3096 else if (streq(name
, "ActiveExitTimestamp"))
3097 i
->active_exit_timestamp
= (usec_t
) u
;
3098 else if (streq(name
, "ConditionTimestamp"))
3099 i
->condition_timestamp
= (usec_t
) u
;
3104 case SD_BUS_TYPE_ARRAY
:
3106 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3107 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3109 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3111 return bus_log_parse_error(r
);
3113 info
= new0(ExecStatusInfo
, 1);
3117 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3119 info
->name
= strdup(name
);
3123 LIST_PREPEND(exec
, i
->exec
, info
);
3125 info
= new0(ExecStatusInfo
, 1);
3131 return bus_log_parse_error(r
);
3133 r
= sd_bus_message_exit_container(m
);
3135 return bus_log_parse_error(r
);
3139 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3140 const char *type
, *path
;
3142 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3144 return bus_log_parse_error(r
);
3146 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3148 r
= strv_extend(&i
->listen
, type
);
3152 r
= strv_extend(&i
->listen
, path
);
3157 return bus_log_parse_error(r
);
3159 r
= sd_bus_message_exit_container(m
);
3161 return bus_log_parse_error(r
);
3165 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3167 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3169 return bus_log_parse_error(r
);
3171 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3173 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3175 return bus_log_parse_error(r
);
3177 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3178 const char *cond
, *param
;
3179 int trigger
, negate
;
3182 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3184 return bus_log_parse_error(r
);
3186 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3187 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3188 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3189 i
->failed_condition
= cond
;
3190 i
->failed_condition_trigger
= trigger
;
3191 i
->failed_condition_negate
= negate
;
3192 i
->failed_condition_param
= param
;
3196 return bus_log_parse_error(r
);
3198 r
= sd_bus_message_exit_container(m
);
3200 return bus_log_parse_error(r
);
3207 case SD_BUS_TYPE_STRUCT_BEGIN
:
3209 if (streq(name
, "LoadError")) {
3210 const char *n
, *message
;
3212 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3214 return bus_log_parse_error(r
);
3216 if (!isempty(message
))
3217 i
->load_error
= message
;
3230 r
= sd_bus_message_skip(m
, contents
);
3232 return bus_log_parse_error(r
);
3237 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
3243 /* This is a low-level property printer, see
3244 * print_status_info() for the nicer output */
3246 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
3247 /* skip what we didn't read */
3248 r
= sd_bus_message_skip(m
, contents
);
3252 switch (contents
[0]) {
3254 case SD_BUS_TYPE_STRUCT_BEGIN
:
3256 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
3259 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
3261 return bus_log_parse_error(r
);
3264 printf("%s=%u\n", name
, (unsigned) u
);
3266 printf("%s=\n", name
);
3270 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
3273 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
3275 return bus_log_parse_error(r
);
3277 if (arg_all
|| !isempty(s
))
3278 printf("%s=%s\n", name
, s
);
3282 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
3283 const char *a
= NULL
, *b
= NULL
;
3285 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
3287 return bus_log_parse_error(r
);
3289 if (arg_all
|| !isempty(a
) || !isempty(b
))
3290 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
3297 case SD_BUS_TYPE_ARRAY
:
3299 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
3303 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
3305 return bus_log_parse_error(r
);
3307 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
3308 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
3311 return bus_log_parse_error(r
);
3313 r
= sd_bus_message_exit_container(m
);
3315 return bus_log_parse_error(r
);
3319 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
3320 const char *type
, *path
;
3322 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3324 return bus_log_parse_error(r
);
3326 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3327 printf("%s=%s\n", type
, path
);
3329 return bus_log_parse_error(r
);
3331 r
= sd_bus_message_exit_container(m
);
3333 return bus_log_parse_error(r
);
3337 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3338 const char *type
, *path
;
3340 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3342 return bus_log_parse_error(r
);
3344 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3345 printf("Listen%s=%s\n", type
, path
);
3347 return bus_log_parse_error(r
);
3349 r
= sd_bus_message_exit_container(m
);
3351 return bus_log_parse_error(r
);
3355 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
3357 uint64_t value
, next_elapse
;
3359 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
3361 return bus_log_parse_error(r
);
3363 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
3364 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
3366 printf("%s={ value=%s ; next_elapse=%s }\n",
3368 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
3369 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
3372 return bus_log_parse_error(r
);
3374 r
= sd_bus_message_exit_container(m
);
3376 return bus_log_parse_error(r
);
3380 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3381 ExecStatusInfo info
= {};
3383 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3385 return bus_log_parse_error(r
);
3387 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
3388 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
3389 _cleanup_free_
char *tt
;
3391 tt
= strv_join(info
.argv
, " ");
3393 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3397 yes_no(info
.ignore
),
3398 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
3399 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
3400 (unsigned) info
. pid
,
3401 sigchld_code_to_string(info
.code
),
3403 info
.code
== CLD_EXITED
? "" : "/",
3404 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
3407 strv_free(info
.argv
);
3411 r
= sd_bus_message_exit_container(m
);
3413 return bus_log_parse_error(r
);
3417 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
3418 const char *path
, *rwm
;
3420 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3422 return bus_log_parse_error(r
);
3424 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
3425 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
3427 return bus_log_parse_error(r
);
3429 r
= sd_bus_message_exit_container(m
);
3431 return bus_log_parse_error(r
);
3435 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
3439 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3441 return bus_log_parse_error(r
);
3443 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
3444 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
3446 return bus_log_parse_error(r
);
3448 r
= sd_bus_message_exit_container(m
);
3450 return bus_log_parse_error(r
);
3454 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
3458 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3460 return bus_log_parse_error(r
);
3462 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
3463 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
3465 return bus_log_parse_error(r
);
3467 r
= sd_bus_message_exit_container(m
);
3469 return bus_log_parse_error(r
);
3477 r
= bus_print_property(name
, m
, arg_all
);
3479 return bus_log_parse_error(r
);
3482 r
= sd_bus_message_skip(m
, contents
);
3484 return bus_log_parse_error(r
);
3487 printf("%s=[unprintable]\n", name
);
3493 static int show_one(
3497 bool show_properties
,
3501 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3502 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3503 UnitStatusInfo info
= {};
3510 r
= sd_bus_call_method(
3512 "org.freedesktop.systemd1",
3514 "org.freedesktop.DBus.Properties",
3520 log_error("Failed to get properties: %s", bus_error_message(&error
, r
));
3524 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
3526 return bus_log_parse_error(r
);
3533 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
3534 const char *name
, *contents
;
3536 r
= sd_bus_message_read(reply
, "s", &name
);
3538 return bus_log_parse_error(r
);
3540 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
3542 return bus_log_parse_error(r
);
3544 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
3546 return bus_log_parse_error(r
);
3548 if (show_properties
)
3549 r
= print_property(name
, reply
, contents
);
3551 r
= status_property(name
, reply
, &info
, contents
);
3555 r
= sd_bus_message_exit_container(reply
);
3557 return bus_log_parse_error(r
);
3559 r
= sd_bus_message_exit_container(reply
);
3561 return bus_log_parse_error(r
);
3564 return bus_log_parse_error(r
);
3566 r
= sd_bus_message_exit_container(reply
);
3568 return bus_log_parse_error(r
);
3572 if (!show_properties
) {
3573 if (streq(verb
, "help"))
3574 show_unit_help(&info
);
3576 print_status_info(&info
, ellipsized
);
3579 strv_free(info
.documentation
);
3580 strv_free(info
.dropin_paths
);
3581 strv_free(info
.listen
);
3583 if (!streq_ptr(info
.active_state
, "active") &&
3584 !streq_ptr(info
.active_state
, "reloading") &&
3585 streq(verb
, "status")) {
3586 /* According to LSB: "program not running" */
3587 /* 0: program is running or service is OK
3588 * 1: program is dead and /var/run pid file exists
3589 * 2: program is dead and /var/lock lock file exists
3590 * 3: program is not running
3591 * 4: program or service status is unknown
3593 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
3599 while ((p
= info
.exec
)) {
3600 LIST_REMOVE(exec
, info
.exec
, p
);
3601 exec_status_info_free(p
);
3607 static int show_one_by_pid(
3614 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3615 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3616 const char *path
= NULL
;
3619 r
= sd_bus_call_method(
3621 "org.freedesktop.systemd1",
3622 "/org/freedesktop/systemd1",
3623 "org.freedesktop.systemd1.Manager",
3629 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid
, bus_error_message(&error
, r
));
3633 r
= sd_bus_message_read(reply
, "o", &path
);
3635 return bus_log_parse_error(r
);
3637 return show_one(verb
, bus
, path
, false, new_line
, ellipsized
);
3640 static int show_all(
3643 bool show_properties
,
3647 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3648 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3653 r
= get_unit_list(bus
, &reply
, &unit_infos
);
3657 pager_open_if_enabled();
3661 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
3663 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
3664 _cleanup_free_
char *p
= NULL
;
3666 if (!output_show_unit(u
))
3669 p
= unit_dbus_path_from_name(u
->id
);
3673 printf("%s -> '%s'\n", u
->id
, p
);
3675 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
3683 static int show(sd_bus
*bus
, char **args
) {
3685 bool show_properties
, show_status
, new_line
= false;
3687 bool ellipsized
= false;
3692 show_properties
= streq(args
[0], "show");
3693 show_status
= streq(args
[0], "status");
3695 if (show_properties
)
3696 pager_open_if_enabled();
3698 /* If no argument is specified inspect the manager itself */
3700 if (show_properties
&& strv_length(args
) <= 1)
3701 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
3703 if (show_status
&& strv_length(args
) <= 1)
3704 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
3706 STRV_FOREACH(name
, args
+1) {
3709 if (safe_atou32(*name
, &id
) < 0) {
3710 _cleanup_free_
char *p
= NULL
, *n
= NULL
;
3711 /* Interpret as unit name */
3713 n
= unit_name_mangle(*name
);
3717 p
= unit_dbus_path_from_name(n
);
3721 r
= show_one(args
[0], bus
, p
, show_properties
, &new_line
, &ellipsized
);
3725 } else if (show_properties
) {
3726 _cleanup_free_
char *p
= NULL
;
3728 /* Interpret as job id */
3729 if (asprintf(&p
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
3732 r
= show_one(args
[0], bus
, p
, show_properties
, &new_line
, &ellipsized
);
3737 /* Interpret as PID */
3738 r
= show_one_by_pid(args
[0], bus
, id
, &new_line
, &ellipsized
);
3744 if (ellipsized
&& !arg_quiet
)
3745 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3750 static int append_assignment(sd_bus_message
*m
, const char *assignment
) {
3758 eq
= strchr(assignment
, '=');
3760 log_error("Not an assignment: %s", assignment
);
3764 field
= strndupa(assignment
, eq
- assignment
);
3767 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, field
);
3769 return bus_log_create_error(r
);
3771 if (streq(field
, "CPUAccounting") ||
3772 streq(field
, "MemoryAccounting") ||
3773 streq(field
, "BlockIOAccounting")) {
3775 r
= parse_boolean(eq
);
3777 log_error("Failed to parse boolean assignment %s.", assignment
);
3781 r
= sd_bus_message_append(m
, "v", "b", r
);
3783 } else if (streq(field
, "MemoryLimit")) {
3786 r
= parse_bytes(eq
, &bytes
);
3788 log_error("Failed to parse bytes specification %s", assignment
);
3792 r
= sd_bus_message_append(m
, "v", "t", (uint64_t) bytes
);
3794 } else if (streq(field
, "CPUShares") || streq(field
, "BlockIOWeight")) {
3797 r
= safe_atou64(eq
, &u
);
3799 log_error("Failed to parse %s value %s.", field
, eq
);
3803 r
= sd_bus_message_append(m
, "v", "t", u
);
3805 } else if (streq(field
, "DevicePolicy"))
3806 r
= sd_bus_message_append(m
, "v", "s", eq
);
3808 else if (streq(field
, "DeviceAllow")) {
3811 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
3813 const char *path
, *rwm
;
3816 e
= strchr(eq
, ' ');
3818 path
= strndupa(eq
, e
- eq
);
3825 if (!path_startswith(path
, "/dev")) {
3826 log_error("%s is not a device file in /dev.", path
);
3830 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
3833 } else if (streq(field
, "BlockIOReadBandwidth") || streq(field
, "BlockIOWriteBandwidth")) {
3836 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
3838 const char *path
, *bandwidth
;
3842 e
= strchr(eq
, ' ');
3844 path
= strndupa(eq
, e
- eq
);
3847 log_error("Failed to parse %s value %s.", field
, eq
);
3851 if (!path_startswith(path
, "/dev")) {
3852 log_error("%s is not a device file in /dev.", path
);
3856 r
= parse_bytes(bandwidth
, &bytes
);
3858 log_error("Failed to parse byte value %s.", bandwidth
);
3862 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, (uint64_t) bytes
);
3865 } else if (streq(field
, "BlockIODeviceWeight")) {
3868 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
3870 const char *path
, *weight
;
3874 e
= strchr(eq
, ' ');
3876 path
= strndupa(eq
, e
- eq
);
3879 log_error("Failed to parse %s value %s.", field
, eq
);
3883 if (!path_startswith(path
, "/dev")) {
3884 log_error("%s is not a device file in /dev.", path
);
3888 r
= safe_atou64(weight
, &u
);
3890 log_error("Failed to parse %s value %s.", field
, weight
);
3893 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
3897 log_error("Unknown assignment %s.", assignment
);
3902 return bus_log_create_error(r
);
3907 static int set_property(sd_bus
*bus
, char **args
) {
3908 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
3909 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3910 _cleanup_free_
char *n
= NULL
;
3914 r
= sd_bus_message_new_method_call(
3916 "org.freedesktop.systemd1",
3917 "/org/freedesktop/systemd1",
3918 "org.freedesktop.systemd1.Manager",
3919 "SetUnitProperties",
3922 return bus_log_create_error(r
);
3924 n
= unit_name_mangle(args
[1]);
3928 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
3930 return bus_log_create_error(r
);
3932 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
3934 return bus_log_create_error(r
);
3936 STRV_FOREACH(i
, args
+ 2) {
3937 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
3939 return bus_log_create_error(r
);
3941 r
= append_assignment(m
, *i
);
3945 r
= sd_bus_message_close_container(m
);
3947 return bus_log_create_error(r
);
3950 r
= sd_bus_message_close_container(m
);
3952 return bus_log_create_error(r
);
3954 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
3956 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
3963 static int snapshot(sd_bus
*bus
, char **args
) {
3964 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3965 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3966 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
3970 if (strv_length(args
) > 1)
3971 n
= unit_name_mangle_with_suffix(args
[1], ".snapshot");
3977 r
= sd_bus_call_method(
3979 "org.freedesktop.systemd1",
3980 "/org/freedesktop/systemd1",
3981 "org.freedesktop.systemd1.Manager",
3987 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
3991 r
= sd_bus_message_read(reply
, "o", &path
);
3993 return bus_log_parse_error(r
);
3995 r
= sd_bus_get_property_string(
3997 "org.freedesktop.systemd1",
3999 "org.freedesktop.systemd1.Unit",
4004 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4014 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4015 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4021 STRV_FOREACH(name
, args
+1) {
4022 _cleanup_free_
char *n
= NULL
;
4024 n
= unit_name_mangle_with_suffix(*name
, ".snapshot");
4028 r
= sd_bus_call_method(
4030 "org.freedesktop.systemd1",
4031 "/org/freedesktop/systemd1",
4032 "org.freedesktop.systemd1.Manager",
4038 log_error("Failed to remove snapshot %s: %s", n
, bus_error_message(&error
, r
));
4046 static int daemon_reload(sd_bus
*bus
, char **args
) {
4047 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4051 if (arg_action
== ACTION_RELOAD
)
4053 else if (arg_action
== ACTION_REEXEC
)
4054 method
= "Reexecute";
4056 assert(arg_action
== ACTION_SYSTEMCTL
);
4059 streq(args
[0], "clear-jobs") ||
4060 streq(args
[0], "cancel") ? "ClearJobs" :
4061 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4062 streq(args
[0], "reset-failed") ? "ResetFailed" :
4063 streq(args
[0], "halt") ? "Halt" :
4064 streq(args
[0], "poweroff") ? "PowerOff" :
4065 streq(args
[0], "reboot") ? "Reboot" :
4066 streq(args
[0], "kexec") ? "KExec" :
4067 streq(args
[0], "exit") ? "Exit" :
4068 /* "daemon-reload" */ "Reload";
4071 r
= sd_bus_call_method(
4073 "org.freedesktop.systemd1",
4074 "/org/freedesktop/systemd1",
4075 "org.freedesktop.systemd1.Manager",
4081 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4082 /* There's always a fallback possible for
4083 * legacy actions. */
4085 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4086 /* On reexecution, we expect a disconnect, not a
4090 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4092 return r
< 0 ? r
: 0;
4095 static int reset_failed(sd_bus
*bus
, char **args
) {
4096 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4100 if (strv_length(args
) <= 1)
4101 return daemon_reload(bus
, args
);
4103 STRV_FOREACH(name
, args
+1) {
4104 _cleanup_free_
char *n
;
4106 n
= unit_name_mangle(*name
);
4110 r
= sd_bus_call_method(
4112 "org.freedesktop.systemd1",
4113 "/org/freedesktop/systemd1",
4114 "org.freedesktop.systemd1.Manager",
4120 log_error("Failed to reset failed state of unit %s: %s", n
, bus_error_message(&error
, r
));
4128 static int show_environment(sd_bus
*bus
, char **args
) {
4129 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4130 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4134 pager_open_if_enabled();
4136 r
= sd_bus_get_property(
4138 "org.freedesktop.systemd1",
4139 "/org/freedesktop/systemd1",
4140 "org.freedesktop.systemd1.Manager",
4146 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
4150 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
4152 return bus_log_parse_error(r
);
4154 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
4157 return bus_log_parse_error(r
);
4159 r
= sd_bus_message_exit_container(reply
);
4161 return bus_log_parse_error(r
);
4166 static int switch_root(sd_bus
*bus
, char **args
) {
4167 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4168 _cleanup_free_
char *init
= NULL
;
4173 l
= strv_length(args
);
4174 if (l
< 2 || l
> 3) {
4175 log_error("Wrong number of arguments.");
4182 init
= strdup(args
[2]);
4184 parse_env_file("/proc/cmdline", WHITESPACE
,
4195 log_debug("switching root - root: %s; init: %s", root
, init
);
4197 r
= sd_bus_call_method(
4199 "org.freedesktop.systemd1",
4200 "/org/freedesktop/systemd1",
4201 "org.freedesktop.systemd1.Manager",
4207 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
4214 static int set_environment(sd_bus
*bus
, char **args
) {
4215 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4216 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4223 method
= streq(args
[0], "set-environment")
4225 : "UnsetEnvironment";
4227 r
= sd_bus_message_new_method_call(
4229 "org.freedesktop.systemd1",
4230 "/org/freedesktop/systemd1",
4231 "org.freedesktop.systemd1.Manager",
4235 return bus_log_create_error(r
);
4237 r
= sd_bus_message_append_strv(m
, args
+ 1);
4239 return bus_log_create_error(r
);
4241 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4243 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
4250 static int enable_sysv_units(const char *verb
, char **args
) {
4253 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4254 unsigned f
= 1, t
= 1;
4255 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
4257 if (arg_scope
!= UNIT_FILE_SYSTEM
)
4260 if (!streq(verb
, "enable") &&
4261 !streq(verb
, "disable") &&
4262 !streq(verb
, "is-enabled"))
4265 /* Processes all SysV units, and reshuffles the array so that
4266 * afterwards only the native units remain */
4268 r
= lookup_paths_init(&paths
, SYSTEMD_SYSTEM
, false, NULL
, NULL
, NULL
);
4273 for (f
= 0; args
[f
]; f
++) {
4275 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
4276 bool found_native
= false, found_sysv
;
4278 const char *argv
[6] = { "/sbin/chkconfig", NULL
, NULL
, NULL
, NULL
};
4286 if (!endswith(name
, ".service"))
4289 if (path_is_absolute(name
))
4292 STRV_FOREACH(k
, paths
.unit_path
) {
4293 if (!isempty(arg_root
))
4294 asprintf(&p
, "%s/%s/%s", arg_root
, *k
, name
);
4296 asprintf(&p
, "%s/%s", *k
, name
);
4303 found_native
= access(p
, F_OK
) >= 0;
4314 if (!isempty(arg_root
))
4315 asprintf(&p
, "%s/" SYSTEM_SYSVINIT_PATH
"/%s", arg_root
, name
);
4317 asprintf(&p
, SYSTEM_SYSVINIT_PATH
"/%s", name
);
4323 p
[strlen(p
) - sizeof(".service") + 1] = 0;
4324 found_sysv
= access(p
, F_OK
) >= 0;
4329 /* Mark this entry, so that we don't try enabling it as native unit */
4330 args
[f
] = (char*) "";
4332 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name
);
4334 if (!isempty(arg_root
))
4335 argv
[c
++] = q
= strappend("--root=", arg_root
);
4337 argv
[c
++] = path_get_file_name(p
);
4339 streq(verb
, "enable") ? "on" :
4340 streq(verb
, "disable") ? "off" : "--level=5";
4343 l
= strv_join((char**)argv
, " ");
4349 log_info("Executing %s", l
);
4354 log_error("Failed to fork: %m");
4357 } else if (pid
== 0) {
4360 execv(argv
[0], (char**) argv
);
4361 _exit(EXIT_FAILURE
);
4364 j
= wait_for_terminate(pid
, &status
);
4366 log_error("Failed to wait for child: %s", strerror(-r
));
4371 if (status
.si_code
== CLD_EXITED
) {
4372 if (streq(verb
, "is-enabled")) {
4373 if (status
.si_status
== 0) {
4382 } else if (status
.si_status
!= 0) {
4393 /* Drop all SysV units */
4394 for (f
= 0, t
= 0; args
[f
]; f
++) {
4396 if (isempty(args
[f
]))
4399 args
[t
++] = args
[f
];
4408 static int mangle_names(char **original_names
, char ***mangled_names
) {
4409 char **i
, **l
, **name
;
4411 l
= new(char*, strv_length(original_names
) + 1);
4416 STRV_FOREACH(name
, original_names
) {
4418 /* When enabling units qualified path names are OK,
4419 * too, hence allow them explicitly. */
4424 *i
= unit_name_mangle(*name
);
4440 static int enable_unit(sd_bus
*bus
, char **args
) {
4441 _cleanup_strv_free_
char **mangled_names
= NULL
;
4442 const char *verb
= args
[0];
4443 UnitFileChange
*changes
= NULL
;
4444 unsigned n_changes
= 0;
4445 int carries_install_info
= -1;
4451 r
= mangle_names(args
+1, &mangled_names
);
4455 r
= enable_sysv_units(verb
, mangled_names
);
4459 if (!bus
|| avoid_bus()) {
4460 if (streq(verb
, "enable")) {
4461 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4462 carries_install_info
= r
;
4463 } else if (streq(verb
, "disable"))
4464 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, &changes
, &n_changes
);
4465 else if (streq(verb
, "reenable")) {
4466 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4467 carries_install_info
= r
;
4468 } else if (streq(verb
, "link"))
4469 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4470 else if (streq(verb
, "preset")) {
4471 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4472 carries_install_info
= r
;
4473 } else if (streq(verb
, "mask"))
4474 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, mangled_names
, arg_force
, &changes
, &n_changes
);
4475 else if (streq(verb
, "unmask"))
4476 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, mangled_names
, &changes
, &n_changes
);
4478 assert_not_reached("Unknown verb");
4481 log_error("Operation failed: %s", strerror(-r
));
4486 dump_unit_file_changes(changes
, n_changes
);
4490 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
4491 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4492 int expect_carries_install_info
= false;
4493 bool send_force
= true;
4496 if (streq(verb
, "enable")) {
4497 method
= "EnableUnitFiles";
4498 expect_carries_install_info
= true;
4499 } else if (streq(verb
, "disable")) {
4500 method
= "DisableUnitFiles";
4502 } else if (streq(verb
, "reenable")) {
4503 method
= "ReenableUnitFiles";
4504 expect_carries_install_info
= true;
4505 } else if (streq(verb
, "link"))
4506 method
= "LinkUnitFiles";
4507 else if (streq(verb
, "preset")) {
4508 method
= "PresetUnitFiles";
4509 expect_carries_install_info
= true;
4510 } else if (streq(verb
, "mask"))
4511 method
= "MaskUnitFiles";
4512 else if (streq(verb
, "unmask")) {
4513 method
= "UnmaskUnitFiles";
4516 assert_not_reached("Unknown verb");
4518 r
= sd_bus_message_new_method_call(
4520 "org.freedesktop.systemd1",
4521 "/org/freedesktop/systemd1",
4522 "org.freedesktop.systemd1.Manager",
4526 return bus_log_create_error(r
);
4528 r
= sd_bus_message_append_strv(m
, mangled_names
);
4530 return bus_log_create_error(r
);
4532 r
= sd_bus_message_append(m
, "b", arg_runtime
);
4534 return bus_log_create_error(r
);
4537 r
= sd_bus_message_append(m
, "b", arg_force
);
4539 return bus_log_create_error(r
);
4542 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
4544 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4548 if (expect_carries_install_info
) {
4549 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
4551 return bus_log_parse_error(r
);
4554 r
= deserialize_and_dump_unit_file_changes(m
);
4558 /* Try to reload if enabeld */
4560 r
= daemon_reload(bus
, args
);
4565 if (carries_install_info
== 0)
4566 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4567 "using systemctl.\n"
4568 "Possible reasons for having this kind of units are:\n"
4569 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4570 " .wants/ or .requires/ directory.\n"
4571 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4572 " a requirement dependency on it.\n"
4573 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4574 " D-Bus, udev, scripted systemctl call, ...).\n");
4577 unit_file_changes_free(changes
, n_changes
);
4582 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
4584 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4585 _cleanup_strv_free_
char **mangled_names
= NULL
;
4590 r
= mangle_names(args
+1, &mangled_names
);
4594 r
= enable_sysv_units(args
[0], mangled_names
);
4600 if (!bus
|| avoid_bus()) {
4602 STRV_FOREACH(name
, mangled_names
) {
4603 UnitFileState state
;
4605 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
4607 log_error("Failed to get unit file state for %s: %s", *name
, strerror(-state
));
4611 if (state
== UNIT_FILE_ENABLED
||
4612 state
== UNIT_FILE_ENABLED_RUNTIME
||
4613 state
== UNIT_FILE_STATIC
)
4617 puts(unit_file_state_to_string(state
));
4621 STRV_FOREACH(name
, mangled_names
) {
4622 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4625 r
= sd_bus_call_method(
4627 "org.freedesktop.systemd1",
4628 "/org/freedesktop/systemd1",
4629 "org.freedesktop.systemd1.Manager",
4635 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
4639 r
= sd_bus_message_read(reply
, "s", &s
);
4641 return bus_log_parse_error(r
);
4643 if (streq(s
, "enabled") ||
4644 streq(s
, "enabled-runtime") ||
4656 static int systemctl_help(void) {
4658 pager_open_if_enabled();
4660 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4661 "Query or send control commands to the systemd manager.\n\n"
4662 " -h --help Show this help\n"
4663 " --version Show package version\n"
4664 " --system Connect to system manager\n"
4665 " --user Connect to user service manager\n"
4666 " -H --host=[USER@]HOST\n"
4667 " Operate on remote host\n"
4668 " -M --machine=CONTAINER\n"
4669 " Operate on local container\n"
4670 " -t --type=TYPE List only units of a particular type\n"
4671 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4672 " -p --property=NAME Show only properties by this name\n"
4673 " -a --all Show all loaded units/properties, including dead/empty\n"
4674 " ones. To list all units installed on the system, use\n"
4675 " the 'list-unit-files' command instead.\n"
4676 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4677 " -l --full Don't ellipsize unit names on output\n"
4678 " --fail When queueing a new job, fail if conflicting jobs are\n"
4680 " --irreversible When queueing a new job, make sure it cannot be implicitly\n"
4682 " --ignore-dependencies\n"
4683 " When queueing a new job, ignore all its dependencies\n"
4684 " --show-types When showing sockets, explicitly show their type\n"
4685 " -i --ignore-inhibitors\n"
4686 " When shutting down or sleeping, ignore inhibitors\n"
4687 " --kill-who=WHO Who to send signal to\n"
4688 " -s --signal=SIGNAL Which signal to send\n"
4689 " -q --quiet Suppress output\n"
4690 " --no-block Do not wait until operation finished\n"
4691 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4692 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4694 " --no-legend Do not print a legend (column headers and hints)\n"
4695 " --no-pager Do not pipe output into a pager\n"
4696 " --no-ask-password\n"
4697 " Do not ask for system passwords\n"
4698 " --global Enable/disable unit files globally\n"
4699 " --runtime Enable unit files only temporarily until next reboot\n"
4700 " -f --force When enabling unit files, override existing symlinks\n"
4701 " When shutting down, execute action immediately\n"
4702 " --root=PATH Enable unit files in the specified root directory\n"
4703 " -n --lines=INTEGER Number of journal entries to show\n"
4704 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4705 " verbose, export, json, json-pretty, json-sse, cat)\n\n"
4707 " list-units List loaded units\n"
4708 " list-sockets List loaded sockets ordered by address\n"
4709 " list-timers List loaded timers ordered by next elapse\n"
4710 " start [NAME...] Start (activate) one or more units\n"
4711 " stop [NAME...] Stop (deactivate) one or more units\n"
4712 " reload [NAME...] Reload one or more units\n"
4713 " restart [NAME...] Start or restart one or more units\n"
4714 " try-restart [NAME...] Restart one or more units if active\n"
4715 " reload-or-restart [NAME...] Reload one or more units if possible,\n"
4716 " otherwise start or restart\n"
4717 " reload-or-try-restart [NAME...] Reload one or more units if possible,\n"
4718 " otherwise restart if active\n"
4719 " isolate [NAME] Start one unit and stop all others\n"
4720 " kill [NAME...] Send signal to processes of a unit\n"
4721 " is-active [NAME...] Check whether units are active\n"
4722 " is-failed [NAME...] Check whether units are failed\n"
4723 " status [NAME...|PID...] Show runtime status of one or more units\n"
4724 " show [NAME...|JOB...] Show properties of one or more\n"
4725 " units/jobs or the manager\n"
4726 " set-property [NAME] [ASSIGNMENT...]\n"
4727 " Sets one or more properties of a unit\n"
4728 " help [NAME...|PID...] Show manual for one or more units\n"
4729 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4731 " list-dependencies [NAME] Recursively show units which are required\n"
4732 " or wanted by this unit or by which this\n"
4733 " unit is required or wanted\n\n"
4734 "Unit File Commands:\n"
4735 " list-unit-files List installed unit files\n"
4736 " enable [NAME...] Enable one or more unit files\n"
4737 " disable [NAME...] Disable one or more unit files\n"
4738 " reenable [NAME...] Reenable one or more unit files\n"
4739 " preset [NAME...] Enable/disable one or more unit files\n"
4740 " based on preset configuration\n"
4741 " is-enabled [NAME...] Check whether unit files are enabled\n\n"
4742 " mask [NAME...] Mask one or more units\n"
4743 " unmask [NAME...] Unmask one or more units\n"
4744 " link [PATH...] Link one or more units files into\n"
4745 " the search path\n"
4746 " get-default Get the name of the default target\n"
4747 " set-default NAME Set the default target\n\n"
4749 " list-jobs List jobs\n"
4750 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4751 "Snapshot Commands:\n"
4752 " snapshot [NAME] Create a snapshot\n"
4753 " delete [NAME...] Remove one or more snapshots\n\n"
4754 "Environment Commands:\n"
4755 " show-environment Dump environment\n"
4756 " set-environment [NAME=VALUE...] Set one or more environment variables\n"
4757 " unset-environment [NAME...] Unset one or more environment variables\n\n"
4758 "Manager Lifecycle Commands:\n"
4759 " daemon-reload Reload systemd manager configuration\n"
4760 " daemon-reexec Reexecute systemd manager\n\n"
4761 "System Commands:\n"
4762 " default Enter system default mode\n"
4763 " rescue Enter system rescue mode\n"
4764 " emergency Enter system emergency mode\n"
4765 " halt Shut down and halt the system\n"
4766 " poweroff Shut down and power-off the system\n"
4767 " reboot [ARG] Shut down and reboot the system\n"
4768 " kexec Shut down and reboot the system with kexec\n"
4769 " exit Request user instance exit\n"
4770 " switch-root [ROOT] [INIT] Change to a different root file system\n"
4771 " suspend Suspend the system\n"
4772 " hibernate Hibernate the system\n"
4773 " hybrid-sleep Hibernate and suspend the system\n",
4774 program_invocation_short_name
);
4779 static int halt_help(void) {
4781 printf("%s [OPTIONS...]%s\n\n"
4782 "%s the system.\n\n"
4783 " --help Show this help\n"
4784 " --halt Halt the machine\n"
4785 " -p --poweroff Switch off the machine\n"
4786 " --reboot Reboot the machine\n"
4787 " -f --force Force immediate halt/power-off/reboot\n"
4788 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4789 " -d --no-wtmp Don't write wtmp record\n"
4790 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4791 program_invocation_short_name
,
4792 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
4793 arg_action
== ACTION_REBOOT
? "Reboot" :
4794 arg_action
== ACTION_POWEROFF
? "Power off" :
4800 static int shutdown_help(void) {
4802 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4803 "Shut down the system.\n\n"
4804 " --help Show this help\n"
4805 " -H --halt Halt the machine\n"
4806 " -P --poweroff Power-off the machine\n"
4807 " -r --reboot Reboot the machine\n"
4808 " -h Equivalent to --poweroff, overridden by --halt\n"
4809 " -k Don't halt/power-off/reboot, just send warnings\n"
4810 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4811 " -c Cancel a pending shutdown\n",
4812 program_invocation_short_name
);
4817 static int telinit_help(void) {
4819 printf("%s [OPTIONS...] {COMMAND}\n\n"
4820 "Send control commands to the init daemon.\n\n"
4821 " --help Show this help\n"
4822 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
4824 " 0 Power-off the machine\n"
4825 " 6 Reboot the machine\n"
4826 " 2, 3, 4, 5 Start runlevelX.target unit\n"
4827 " 1, s, S Enter rescue mode\n"
4828 " q, Q Reload init daemon configuration\n"
4829 " u, U Reexecute init daemon\n",
4830 program_invocation_short_name
);
4835 static int runlevel_help(void) {
4837 printf("%s [OPTIONS...]\n\n"
4838 "Prints the previous and current runlevel of the init system.\n\n"
4839 " --help Show this help\n",
4840 program_invocation_short_name
);
4845 static int help_types(void) {
4849 puts("Available unit types:");
4850 for(i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
4851 t
= unit_type_to_string(i
);
4859 static int systemctl_parse_argv(int argc
, char *argv
[]) {
4868 ARG_IGNORE_DEPENDENCIES
,
4880 ARG_NO_ASK_PASSWORD
,
4888 static const struct option options
[] = {
4889 { "help", no_argument
, NULL
, 'h' },
4890 { "version", no_argument
, NULL
, ARG_VERSION
},
4891 { "type", required_argument
, NULL
, 't' },
4892 { "property", required_argument
, NULL
, 'p' },
4893 { "all", no_argument
, NULL
, 'a' },
4894 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
4895 { "after", no_argument
, NULL
, ARG_AFTER
},
4896 { "before", no_argument
, NULL
, ARG_BEFORE
},
4897 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
4898 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
4899 { "full", no_argument
, NULL
, 'l' },
4900 { "fail", no_argument
, NULL
, ARG_FAIL
},
4901 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
},
4902 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
},
4903 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
4904 { "user", no_argument
, NULL
, ARG_USER
},
4905 { "system", no_argument
, NULL
, ARG_SYSTEM
},
4906 { "global", no_argument
, NULL
, ARG_GLOBAL
},
4907 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
4908 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
4909 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
4910 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
4911 { "quiet", no_argument
, NULL
, 'q' },
4912 { "root", required_argument
, NULL
, ARG_ROOT
},
4913 { "force", no_argument
, NULL
, ARG_FORCE
},
4914 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
4915 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
4916 { "signal", required_argument
, NULL
, 's' },
4917 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
4918 { "host", required_argument
, NULL
, 'H' },
4919 { "machine", required_argument
, NULL
, 'M' },
4920 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
4921 { "lines", required_argument
, NULL
, 'n' },
4922 { "output", required_argument
, NULL
, 'o' },
4923 { "plain", no_argument
, NULL
, ARG_PLAIN
},
4924 { "state", required_argument
, NULL
, ARG_STATE
},
4933 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:i", options
, NULL
)) >= 0) {
4938 return systemctl_help();
4941 puts(PACKAGE_STRING
);
4942 puts(SYSTEMD_FEATURES
);
4949 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
4950 _cleanup_free_
char *type
;
4952 type
= strndup(word
, size
);
4956 if (streq(type
, "help")) {
4961 if (unit_type_from_string(type
) >= 0) {
4962 if (strv_push(&arg_types
, type
))
4968 /* It's much nicer to use --state= for
4969 * load states, but let's support this
4970 * in --types= too for compatibility
4971 * with old versions */
4972 if (unit_load_state_from_string(optarg
) >= 0) {
4973 if (strv_push(&arg_states
, type
) < 0)
4979 log_error("Unknown unit type or load state '%s'.", type
);
4980 log_info("Use -t help to see a list of allowed values.");
4988 /* Make sure that if the empty property list
4989 was specified, we won't show any properties. */
4990 if (isempty(optarg
) && !arg_properties
) {
4991 arg_properties
= new0(char*, 1);
4992 if (!arg_properties
)
4998 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
5001 prop
= strndup(word
, size
);
5005 if (strv_push(&arg_properties
, prop
) < 0) {
5012 /* If the user asked for a particular
5013 * property, show it to him, even if it is
5025 arg_dependency
= DEPENDENCY_REVERSE
;
5029 arg_dependency
= DEPENDENCY_AFTER
;
5033 arg_dependency
= DEPENDENCY_BEFORE
;
5036 case ARG_SHOW_TYPES
:
5037 arg_show_types
= true;
5041 arg_job_mode
= "fail";
5044 case ARG_IRREVERSIBLE
:
5045 arg_job_mode
= "replace-irreversibly";
5048 case ARG_IGNORE_DEPENDENCIES
:
5049 arg_job_mode
= "ignore-dependencies";
5053 arg_scope
= UNIT_FILE_USER
;
5057 arg_scope
= UNIT_FILE_SYSTEM
;
5061 arg_scope
= UNIT_FILE_GLOBAL
;
5065 arg_no_block
= true;
5069 arg_no_legend
= true;
5073 arg_no_pager
= true;
5089 if (strv_extend(&arg_states
, "failed") < 0)
5107 arg_no_reload
= true;
5111 arg_kill_who
= optarg
;
5115 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
5116 log_error("Failed to parse signal string %s.", optarg
);
5121 case ARG_NO_ASK_PASSWORD
:
5122 arg_ask_password
= false;
5126 arg_transport
= BUS_TRANSPORT_REMOTE
;
5131 arg_transport
= BUS_TRANSPORT_CONTAINER
;
5140 if (safe_atou(optarg
, &arg_lines
) < 0) {
5141 log_error("Failed to parse lines '%s'", optarg
);
5147 arg_output
= output_mode_from_string(optarg
);
5148 if (arg_output
< 0) {
5149 log_error("Unknown output '%s'.", optarg
);
5155 arg_ignore_inhibitors
= true;
5166 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
5169 s
= strndup(word
, size
);
5173 if (strv_push(&arg_states
, s
) < 0) {
5185 assert_not_reached("Unhandled option");
5189 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
5190 log_error("Cannot access user instance remotely.");
5197 static int halt_parse_argv(int argc
, char *argv
[]) {
5206 static const struct option options
[] = {
5207 { "help", no_argument
, NULL
, ARG_HELP
},
5208 { "halt", no_argument
, NULL
, ARG_HALT
},
5209 { "poweroff", no_argument
, NULL
, 'p' },
5210 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
5211 { "force", no_argument
, NULL
, 'f' },
5212 { "wtmp-only", no_argument
, NULL
, 'w' },
5213 { "no-wtmp", no_argument
, NULL
, 'd' },
5214 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5223 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
5224 if (runlevel
== '0' || runlevel
== '6')
5227 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0) {
5234 arg_action
= ACTION_HALT
;
5238 if (arg_action
!= ACTION_REBOOT
)
5239 arg_action
= ACTION_POWEROFF
;
5243 arg_action
= ACTION_REBOOT
;
5265 /* Compatibility nops */
5272 assert_not_reached("Unhandled option");
5276 if (arg_action
== ACTION_REBOOT
&& argc
== optind
+ 1) {
5277 r
= write_string_file(REBOOT_PARAM_FILE
, argv
[optind
]);
5279 log_error("Failed to write reboot param to "
5280 REBOOT_PARAM_FILE
": %s", strerror(-r
));
5283 } else if (optind
< argc
) {
5284 log_error("Too many arguments.");
5291 static int parse_time_spec(const char *t
, usec_t
*_u
) {
5295 if (streq(t
, "now"))
5297 else if (!strchr(t
, ':')) {
5300 if (safe_atou64(t
, &u
) < 0)
5303 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
5312 hour
= strtol(t
, &e
, 10);
5313 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
5316 minute
= strtol(e
+1, &e
, 10);
5317 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
5320 n
= now(CLOCK_REALTIME
);
5321 s
= (time_t) (n
/ USEC_PER_SEC
);
5323 assert_se(localtime_r(&s
, &tm
));
5325 tm
.tm_hour
= (int) hour
;
5326 tm
.tm_min
= (int) minute
;
5329 assert_se(s
= mktime(&tm
));
5331 *_u
= (usec_t
) s
* USEC_PER_SEC
;
5334 *_u
+= USEC_PER_DAY
;
5340 static int shutdown_parse_argv(int argc
, char *argv
[]) {
5347 static const struct option options
[] = {
5348 { "help", no_argument
, NULL
, ARG_HELP
},
5349 { "halt", no_argument
, NULL
, 'H' },
5350 { "poweroff", no_argument
, NULL
, 'P' },
5351 { "reboot", no_argument
, NULL
, 'r' },
5352 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
5353 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5362 while ((c
= getopt_long(argc
, argv
, "HPrhkt:afFc", options
, NULL
)) >= 0) {
5366 return shutdown_help();
5369 arg_action
= ACTION_HALT
;
5373 arg_action
= ACTION_POWEROFF
;
5378 arg_action
= ACTION_KEXEC
;
5380 arg_action
= ACTION_REBOOT
;
5384 arg_action
= ACTION_KEXEC
;
5388 if (arg_action
!= ACTION_HALT
)
5389 arg_action
= ACTION_POWEROFF
;
5402 /* Compatibility nops */
5406 arg_action
= ACTION_CANCEL_SHUTDOWN
;
5413 assert_not_reached("Unhandled option");
5417 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
5418 r
= parse_time_spec(argv
[optind
], &arg_when
);
5420 log_error("Failed to parse time specification: %s", argv
[optind
]);
5424 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
5426 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
5427 /* No time argument for shutdown cancel */
5428 arg_wall
= argv
+ optind
;
5429 else if (argc
> optind
+ 1)
5430 /* We skip the time argument */
5431 arg_wall
= argv
+ optind
+ 1;
5438 static int telinit_parse_argv(int argc
, char *argv
[]) {
5445 static const struct option options
[] = {
5446 { "help", no_argument
, NULL
, ARG_HELP
},
5447 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5451 static const struct {
5455 { '0', ACTION_POWEROFF
},
5456 { '6', ACTION_REBOOT
},
5457 { '1', ACTION_RESCUE
},
5458 { '2', ACTION_RUNLEVEL2
},
5459 { '3', ACTION_RUNLEVEL3
},
5460 { '4', ACTION_RUNLEVEL4
},
5461 { '5', ACTION_RUNLEVEL5
},
5462 { 's', ACTION_RESCUE
},
5463 { 'S', ACTION_RESCUE
},
5464 { 'q', ACTION_RELOAD
},
5465 { 'Q', ACTION_RELOAD
},
5466 { 'u', ACTION_REEXEC
},
5467 { 'U', ACTION_REEXEC
}
5476 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5480 return telinit_help();
5490 assert_not_reached("Unhandled option");
5494 if (optind
>= argc
) {
5499 if (optind
+ 1 < argc
) {
5500 log_error("Too many arguments.");
5504 if (strlen(argv
[optind
]) != 1) {
5505 log_error("Expected single character argument.");
5509 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
5510 if (table
[i
].from
== argv
[optind
][0])
5513 if (i
>= ELEMENTSOF(table
)) {
5514 log_error("Unknown command '%s'.", argv
[optind
]);
5518 arg_action
= table
[i
].to
;
5525 static int runlevel_parse_argv(int argc
, char *argv
[]) {
5531 static const struct option options
[] = {
5532 { "help", no_argument
, NULL
, ARG_HELP
},
5541 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5545 return runlevel_help();
5552 assert_not_reached("Unhandled option");
5556 if (optind
< argc
) {
5557 log_error("Too many arguments.");
5564 static int parse_argv(int argc
, char *argv
[]) {
5568 if (program_invocation_short_name
) {
5570 if (strstr(program_invocation_short_name
, "halt")) {
5571 arg_action
= ACTION_HALT
;
5572 return halt_parse_argv(argc
, argv
);
5573 } else if (strstr(program_invocation_short_name
, "poweroff")) {
5574 arg_action
= ACTION_POWEROFF
;
5575 return halt_parse_argv(argc
, argv
);
5576 } else if (strstr(program_invocation_short_name
, "reboot")) {
5578 arg_action
= ACTION_KEXEC
;
5580 arg_action
= ACTION_REBOOT
;
5581 return halt_parse_argv(argc
, argv
);
5582 } else if (strstr(program_invocation_short_name
, "shutdown")) {
5583 arg_action
= ACTION_POWEROFF
;
5584 return shutdown_parse_argv(argc
, argv
);
5585 } else if (strstr(program_invocation_short_name
, "init")) {
5587 if (sd_booted() > 0) {
5588 arg_action
= _ACTION_INVALID
;
5589 return telinit_parse_argv(argc
, argv
);
5591 /* Hmm, so some other init system is
5592 * running, we need to forward this
5593 * request to it. For now we simply
5594 * guess that it is Upstart. */
5596 execv(TELINIT
, argv
);
5598 log_error("Couldn't find an alternative telinit implementation to spawn.");
5602 } else if (strstr(program_invocation_short_name
, "runlevel")) {
5603 arg_action
= ACTION_RUNLEVEL
;
5604 return runlevel_parse_argv(argc
, argv
);
5608 arg_action
= ACTION_SYSTEMCTL
;
5609 return systemctl_parse_argv(argc
, argv
);
5612 _pure_
static int action_to_runlevel(void) {
5614 static const char table
[_ACTION_MAX
] = {
5615 [ACTION_HALT
] = '0',
5616 [ACTION_POWEROFF
] = '0',
5617 [ACTION_REBOOT
] = '6',
5618 [ACTION_RUNLEVEL2
] = '2',
5619 [ACTION_RUNLEVEL3
] = '3',
5620 [ACTION_RUNLEVEL4
] = '4',
5621 [ACTION_RUNLEVEL5
] = '5',
5622 [ACTION_RESCUE
] = '1'
5625 assert(arg_action
< _ACTION_MAX
);
5627 return table
[arg_action
];
5630 static int talk_initctl(void) {
5632 struct init_request request
= {
5633 .magic
= INIT_MAGIC
,
5635 .cmd
= INIT_CMD_RUNLVL
5638 _cleanup_close_
int fd
= -1;
5642 rl
= action_to_runlevel();
5646 request
.runlevel
= rl
;
5648 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
5650 if (errno
== ENOENT
)
5653 log_error("Failed to open "INIT_FIFO
": %m");
5658 r
= loop_write(fd
, &request
, sizeof(request
), false) != sizeof(request
);
5660 log_error("Failed to write to "INIT_FIFO
": %m");
5661 return errno
> 0 ? -errno
: -EIO
;
5667 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
5669 static const struct {
5677 int (* const dispatch
)(sd_bus
*bus
, char **args
);
5679 { "list-units", LESS
, 1, list_units
},
5680 { "list-unit-files", EQUAL
, 1, list_unit_files
},
5681 { "list-sockets", LESS
, 1, list_sockets
},
5682 { "list-timers", LESS
, 1, list_timers
},
5683 { "list-jobs", EQUAL
, 1, list_jobs
},
5684 { "clear-jobs", EQUAL
, 1, daemon_reload
},
5685 { "cancel", MORE
, 2, cancel_job
},
5686 { "start", MORE
, 2, start_unit
},
5687 { "stop", MORE
, 2, start_unit
},
5688 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5689 { "reload", MORE
, 2, start_unit
},
5690 { "restart", MORE
, 2, start_unit
},
5691 { "try-restart", MORE
, 2, start_unit
},
5692 { "reload-or-restart", MORE
, 2, start_unit
},
5693 { "reload-or-try-restart", MORE
, 2, start_unit
},
5694 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
5695 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5696 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
5697 { "isolate", EQUAL
, 2, start_unit
},
5698 { "kill", MORE
, 2, kill_unit
},
5699 { "is-active", MORE
, 2, check_unit_active
},
5700 { "check", MORE
, 2, check_unit_active
},
5701 { "is-failed", MORE
, 2, check_unit_failed
},
5702 { "show", MORE
, 1, show
},
5703 { "status", MORE
, 1, show
},
5704 { "help", MORE
, 2, show
},
5705 { "snapshot", LESS
, 2, snapshot
},
5706 { "delete", MORE
, 2, delete_snapshot
},
5707 { "daemon-reload", EQUAL
, 1, daemon_reload
},
5708 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
5709 { "show-environment", EQUAL
, 1, show_environment
},
5710 { "set-environment", MORE
, 2, set_environment
},
5711 { "unset-environment", MORE
, 2, set_environment
},
5712 { "halt", EQUAL
, 1, start_special
},
5713 { "poweroff", EQUAL
, 1, start_special
},
5714 { "reboot", EQUAL
, 1, start_special
},
5715 { "kexec", EQUAL
, 1, start_special
},
5716 { "suspend", EQUAL
, 1, start_special
},
5717 { "hibernate", EQUAL
, 1, start_special
},
5718 { "hybrid-sleep", EQUAL
, 1, start_special
},
5719 { "default", EQUAL
, 1, start_special
},
5720 { "rescue", EQUAL
, 1, start_special
},
5721 { "emergency", EQUAL
, 1, start_special
},
5722 { "exit", EQUAL
, 1, start_special
},
5723 { "reset-failed", MORE
, 1, reset_failed
},
5724 { "enable", MORE
, 2, enable_unit
},
5725 { "disable", MORE
, 2, enable_unit
},
5726 { "is-enabled", MORE
, 2, unit_is_enabled
},
5727 { "reenable", MORE
, 2, enable_unit
},
5728 { "preset", MORE
, 2, enable_unit
},
5729 { "mask", MORE
, 2, enable_unit
},
5730 { "unmask", MORE
, 2, enable_unit
},
5731 { "link", MORE
, 2, enable_unit
},
5732 { "switch-root", MORE
, 2, switch_root
},
5733 { "list-dependencies", LESS
, 2, list_dependencies
},
5734 { "set-default", EQUAL
, 2, set_default
},
5735 { "get-default", EQUAL
, 1, get_default
},
5736 { "set-property", MORE
, 3, set_property
},
5745 left
= argc
- optind
;
5748 /* Special rule: no arguments means "list-units" */
5751 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
5752 log_error("This command expects one or more "
5753 "unit names. Did you mean --help?");
5757 for (i
= 0; i
< ELEMENTSOF(verbs
); i
++)
5758 if (streq(argv
[optind
], verbs
[i
].verb
))
5761 if (i
>= ELEMENTSOF(verbs
)) {
5762 log_error("Unknown operation '%s'.", argv
[optind
]);
5767 switch (verbs
[i
].argc_cmp
) {
5770 if (left
!= verbs
[i
].argc
) {
5771 log_error("Invalid number of arguments.");
5778 if (left
< verbs
[i
].argc
) {
5779 log_error("Too few arguments.");
5786 if (left
> verbs
[i
].argc
) {
5787 log_error("Too many arguments.");
5794 assert_not_reached("Unknown comparison operator.");
5797 /* Require a bus connection for all operations but
5799 if (!streq(verbs
[i
].verb
, "enable") &&
5800 !streq(verbs
[i
].verb
, "disable") &&
5801 !streq(verbs
[i
].verb
, "is-enabled") &&
5802 !streq(verbs
[i
].verb
, "list-unit-files") &&
5803 !streq(verbs
[i
].verb
, "reenable") &&
5804 !streq(verbs
[i
].verb
, "preset") &&
5805 !streq(verbs
[i
].verb
, "mask") &&
5806 !streq(verbs
[i
].verb
, "unmask") &&
5807 !streq(verbs
[i
].verb
, "link") &&
5808 !streq(verbs
[i
].verb
, "set-default") &&
5809 !streq(verbs
[i
].verb
, "get-default")) {
5811 if (running_in_chroot() > 0) {
5812 log_info("Running in chroot, ignoring request.");
5816 if (((!streq(verbs
[i
].verb
, "reboot") &&
5817 !streq(verbs
[i
].verb
, "halt") &&
5818 !streq(verbs
[i
].verb
, "poweroff")) || arg_force
<= 0) && !bus
) {
5819 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error
));
5825 if (!bus
&& !avoid_bus()) {
5826 log_error("Failed to get D-Bus connection: %s", strerror (-bus_error
));
5831 return verbs
[i
].dispatch(bus
, argv
+ optind
);
5834 static int send_shutdownd(usec_t t
, char mode
, bool dry_run
, bool warn
, const char *message
) {
5836 struct sd_shutdown_command c
= {
5843 union sockaddr_union sockaddr
= {
5844 .un
.sun_family
= AF_UNIX
,
5845 .un
.sun_path
= "/run/systemd/shutdownd",
5848 struct iovec iovec
[2] = {{
5849 .iov_base
= (char*) &c
,
5850 .iov_len
= offsetof(struct sd_shutdown_command
, wall_message
),
5853 struct msghdr msghdr
= {
5854 .msg_name
= &sockaddr
,
5855 .msg_namelen
= offsetof(struct sockaddr_un
, sun_path
)
5856 + sizeof("/run/systemd/shutdownd") - 1,
5861 _cleanup_close_
int fd
;
5863 fd
= socket(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0);
5867 if (!isempty(message
)) {
5868 iovec
[1].iov_base
= (char*) message
;
5869 iovec
[1].iov_len
= strlen(message
);
5870 msghdr
.msg_iovlen
++;
5873 if (sendmsg(fd
, &msghdr
, MSG_NOSIGNAL
) < 0)
5879 static int reload_with_fallback(sd_bus
*bus
) {
5882 /* First, try systemd via D-Bus. */
5883 if (daemon_reload(bus
, NULL
) >= 0)
5887 /* Nothing else worked, so let's try signals */
5888 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
5890 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0) {
5891 log_error("kill() failed: %m");
5898 static int start_with_fallback(sd_bus
*bus
) {
5901 /* First, try systemd via D-Bus. */
5902 if (start_unit(bus
, NULL
) >= 0)
5906 /* Nothing else worked, so let's try
5908 if (talk_initctl() > 0)
5911 log_error("Failed to talk to init daemon.");
5915 warn_wall(arg_action
);
5919 static int halt_now(enum action a
) {
5921 /* Make sure C-A-D is handled by the kernel from this
5923 reboot(RB_ENABLE_CAD
);
5928 log_info("Halting.");
5929 reboot(RB_HALT_SYSTEM
);
5932 case ACTION_POWEROFF
:
5933 log_info("Powering off.");
5934 reboot(RB_POWER_OFF
);
5937 case ACTION_REBOOT
: {
5938 _cleanup_free_
char *param
= NULL
;
5940 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
5941 log_info("Rebooting with argument '%s'.", param
);
5942 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
5943 LINUX_REBOOT_CMD_RESTART2
, param
);
5946 log_info("Rebooting.");
5947 reboot(RB_AUTOBOOT
);
5952 assert_not_reached("Unknown action.");
5956 static int halt_main(sd_bus
*bus
) {
5959 r
= check_inhibitors(bus
, arg_action
);
5963 if (geteuid() != 0) {
5964 /* Try logind if we are a normal user and no special
5965 * mode applies. Maybe PolicyKit allows us to shutdown
5968 if (arg_when
<= 0 &&
5971 (arg_action
== ACTION_POWEROFF
||
5972 arg_action
== ACTION_REBOOT
)) {
5973 r
= reboot_with_logind(bus
, arg_action
);
5978 log_error("Must be root.");
5983 _cleanup_free_
char *m
;
5985 m
= strv_join(arg_wall
, " ");
5989 r
= send_shutdownd(arg_when
,
5990 arg_action
== ACTION_HALT
? 'H' :
5991 arg_action
== ACTION_POWEROFF
? 'P' :
5992 arg_action
== ACTION_KEXEC
? 'K' :
5999 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r
));
6001 char date
[FORMAT_TIMESTAMP_MAX
];
6003 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6004 format_timestamp(date
, sizeof(date
), arg_when
));
6009 if (!arg_dry
&& !arg_force
)
6010 return start_with_fallback(bus
);
6013 if (sd_booted() > 0)
6014 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6016 r
= utmp_put_shutdown();
6018 log_warning("Failed to write utmp record: %s", strerror(-r
));
6025 r
= halt_now(arg_action
);
6026 log_error("Failed to reboot: %s", strerror(-r
));
6031 static int runlevel_main(void) {
6032 int r
, runlevel
, previous
;
6034 r
= utmp_get_runlevel(&runlevel
, &previous
);
6041 previous
<= 0 ? 'N' : previous
,
6042 runlevel
<= 0 ? 'N' : runlevel
);
6047 int main(int argc
, char*argv
[]) {
6048 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
6051 setlocale(LC_ALL
, "");
6052 log_parse_environment();
6055 /* Explicitly not on_tty() to avoid setting cached value.
6056 * This becomes relevant for piping output which might be
6058 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
6060 r
= parse_argv(argc
, argv
);
6064 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6065 * let's shortcut this */
6066 if (arg_action
== ACTION_RUNLEVEL
) {
6067 r
= runlevel_main();
6071 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
6072 log_info("Running in chroot, ignoring request.");
6078 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
6080 /* systemctl_main() will print an error message for the bus
6081 * connection, but only if it needs to */
6083 switch (arg_action
) {
6085 case ACTION_SYSTEMCTL
:
6086 r
= systemctl_main(bus
, argc
, argv
, r
);
6090 case ACTION_POWEROFF
:
6096 case ACTION_RUNLEVEL2
:
6097 case ACTION_RUNLEVEL3
:
6098 case ACTION_RUNLEVEL4
:
6099 case ACTION_RUNLEVEL5
:
6101 case ACTION_EMERGENCY
:
6102 case ACTION_DEFAULT
:
6103 r
= start_with_fallback(bus
);
6108 r
= reload_with_fallback(bus
);
6111 case ACTION_CANCEL_SHUTDOWN
: {
6112 _cleanup_free_
char *m
= NULL
;
6115 m
= strv_join(arg_wall
, " ");
6122 r
= send_shutdownd(arg_when
, SD_SHUTDOWN_NONE
, false, !arg_no_wall
, m
);
6124 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r
));
6128 case ACTION_RUNLEVEL
:
6129 case _ACTION_INVALID
:
6131 assert_not_reached("Unknown action");
6136 ask_password_agent_close();
6137 polkit_agent_close();
6139 strv_free(arg_types
);
6140 strv_free(arg_states
);
6141 strv_free(arg_properties
);
6143 return r
< 0 ? EXIT_FAILURE
: r
;