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>
42 #include "sd-daemon.h"
43 #include "sd-shutdown.h"
50 #include "utmp-wtmp.h"
53 #include "path-util.h"
55 #include "cgroup-show.h"
56 #include "cgroup-util.h"
58 #include "path-lookup.h"
59 #include "conf-parser.h"
60 #include "exit-status.h"
61 #include "bus-errors.h"
63 #include "unit-name.h"
65 #include "spawn-ask-password-agent.h"
66 #include "spawn-polkit-agent.h"
68 #include "logs-show.h"
69 #include "socket-util.h"
72 #include "bus-message.h"
73 #include "bus-error.h"
74 #include "bus-errors.h"
76 static char **arg_types
= NULL
;
77 static char **arg_states
= NULL
;
78 static char **arg_properties
= NULL
;
79 static bool arg_all
= false;
80 static bool original_stdout_is_tty
;
81 static enum dependency
{
87 } arg_dependency
= DEPENDENCY_FORWARD
;
88 static const char *arg_job_mode
= "replace";
89 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
90 static bool arg_no_block
= false;
91 static bool arg_no_legend
= false;
92 static bool arg_no_pager
= false;
93 static bool arg_no_wtmp
= false;
94 static bool arg_no_wall
= false;
95 static bool arg_no_reload
= false;
96 static bool arg_show_types
= false;
97 static bool arg_ignore_inhibitors
= false;
98 static bool arg_dry
= false;
99 static bool arg_quiet
= false;
100 static bool arg_full
= false;
101 static int arg_force
= 0;
102 static bool arg_ask_password
= true;
103 static bool arg_runtime
= false;
104 static char **arg_wall
= NULL
;
105 static const char *arg_kill_who
= NULL
;
106 static int arg_signal
= SIGTERM
;
107 static const char *arg_root
= NULL
;
108 static usec_t arg_when
= 0;
130 ACTION_CANCEL_SHUTDOWN
,
132 } arg_action
= ACTION_SYSTEMCTL
;
133 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
134 static char *arg_host
= NULL
;
135 static unsigned arg_lines
= 10;
136 static OutputMode arg_output
= OUTPUT_SHORT
;
137 static bool arg_plain
= false;
139 static int daemon_reload(sd_bus
*bus
, char **args
);
140 static int halt_now(enum action a
);
142 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
144 static char** strv_skip_first(char **strv
) {
145 if (strv_length(strv
) > 0)
150 static void pager_open_if_enabled(void) {
158 static void ask_password_agent_open_if_enabled(void) {
160 /* Open the password agent as a child process if necessary */
162 if (!arg_ask_password
)
165 if (arg_scope
!= UNIT_FILE_SYSTEM
)
168 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
171 ask_password_agent_open();
175 static void polkit_agent_open_if_enabled(void) {
177 /* Open the polkit agent as a child process if necessary */
179 if (!arg_ask_password
)
182 if (arg_scope
!= UNIT_FILE_SYSTEM
)
185 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
192 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
195 if (!sd_bus_error_is_set(error
))
198 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
199 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
200 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
201 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
202 return EXIT_NOPERMISSION
;
204 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
205 return EXIT_NOTINSTALLED
;
207 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
208 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
209 return EXIT_NOTIMPLEMENTED
;
211 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
212 return EXIT_NOTCONFIGURED
;
220 static void warn_wall(enum action a
) {
221 static const char *table
[_ACTION_MAX
] = {
222 [ACTION_HALT
] = "The system is going down for system halt NOW!",
223 [ACTION_REBOOT
] = "The system is going down for reboot NOW!",
224 [ACTION_POWEROFF
] = "The system is going down for power-off NOW!",
225 [ACTION_KEXEC
] = "The system is going down for kexec reboot NOW!",
226 [ACTION_RESCUE
] = "The system is going down to rescue mode NOW!",
227 [ACTION_EMERGENCY
] = "The system is going down to emergency mode NOW!",
228 [ACTION_CANCEL_SHUTDOWN
] = "The system shutdown has been cancelled NOW!"
235 _cleanup_free_
char *p
;
237 p
= strv_join(arg_wall
, " ");
252 utmp_wall(table
[a
], NULL
);
255 static bool avoid_bus(void) {
257 if (running_in_chroot() > 0)
260 if (sd_booted() <= 0)
263 if (!isempty(arg_root
))
266 if (arg_scope
== UNIT_FILE_GLOBAL
)
272 static int compare_unit_info(const void *a
, const void *b
) {
273 const UnitInfo
*u
= a
, *v
= b
;
276 d1
= strrchr(u
->id
, '.');
277 d2
= strrchr(v
->id
, '.');
282 r
= strcasecmp(d1
, d2
);
287 return strcasecmp(u
->id
, v
->id
);
290 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
293 if (!strv_isempty(arg_states
))
295 strv_contains(arg_states
, u
->load_state
) ||
296 strv_contains(arg_states
, u
->sub_state
) ||
297 strv_contains(arg_states
, u
->active_state
);
299 if (!strv_isempty(patterns
)) {
302 STRV_FOREACH(pattern
, patterns
)
303 if (fnmatch(*pattern
, u
->id
, FNM_NOESCAPE
) == 0)
308 return (!arg_types
|| ((dot
= strrchr(u
->id
, '.')) &&
309 strv_find(arg_types
, dot
+1))) &&
310 (arg_all
|| !(streq(u
->active_state
, "inactive")
311 || u
->following
[0]) || u
->job_id
> 0);
314 static void output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
315 unsigned id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
317 unsigned n_shown
= 0;
320 max_id_len
= sizeof("UNIT")-1;
321 load_len
= sizeof("LOAD")-1;
322 active_len
= sizeof("ACTIVE")-1;
323 sub_len
= sizeof("SUB")-1;
324 job_len
= sizeof("JOB")-1;
327 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
328 max_id_len
= MAX(max_id_len
, strlen(u
->id
));
329 load_len
= MAX(load_len
, strlen(u
->load_state
));
330 active_len
= MAX(active_len
, strlen(u
->active_state
));
331 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
333 if (u
->job_id
!= 0) {
334 job_len
= MAX(job_len
, strlen(u
->job_type
));
339 if (!arg_full
&& original_stdout_is_tty
) {
342 id_len
= MIN(max_id_len
, 25u);
343 basic_len
= 5 + id_len
+ 5 + active_len
+ sub_len
;
346 basic_len
+= job_len
+ 1;
348 if (basic_len
< (unsigned) columns()) {
349 unsigned extra_len
, incr
;
350 extra_len
= columns() - basic_len
;
352 /* Either UNIT already got 25, or is fully satisfied.
353 * Grant up to 25 to DESC now. */
354 incr
= MIN(extra_len
, 25u);
358 /* split the remaining space between UNIT and DESC,
359 * but do not give UNIT more than it needs. */
361 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
363 desc_len
+= extra_len
- incr
;
369 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
370 _cleanup_free_
char *e
= NULL
;
371 const char *on_loaded
, *off_loaded
, *on
= "";
372 const char *on_active
, *off_active
, *off
= "";
374 if (!n_shown
&& !arg_no_legend
) {
375 printf("%-*s %-*s %-*s %-*s ",
378 active_len
, "ACTIVE",
382 printf("%-*s ", job_len
, "JOB");
384 if (!arg_full
&& arg_no_pager
)
385 printf("%.*s\n", desc_len
, "DESCRIPTION");
387 printf("%s\n", "DESCRIPTION");
392 if (streq(u
->load_state
, "error") ||
393 streq(u
->load_state
, "not-found")) {
394 on_loaded
= on
= ansi_highlight_red();
395 off_loaded
= off
= ansi_highlight_off();
397 on_loaded
= off_loaded
= "";
399 if (streq(u
->active_state
, "failed")) {
400 on_active
= on
= ansi_highlight_red();
401 off_active
= off
= ansi_highlight_off();
403 on_active
= off_active
= "";
405 e
= arg_full
? NULL
: ellipsize(u
->id
, id_len
, 33);
407 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
408 on
, id_len
, e
? e
: u
->id
, off
,
409 on_loaded
, load_len
, u
->load_state
, off_loaded
,
410 on_active
, active_len
, u
->active_state
,
411 sub_len
, u
->sub_state
, off_active
,
412 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
415 printf("%.*s\n", desc_len
, u
->description
);
417 printf("%s\n", u
->description
);
420 if (!arg_no_legend
) {
421 const char *on
, *off
;
424 puts("\nLOAD = Reflects whether the unit definition was properly loaded.\n"
425 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
426 "SUB = The low-level unit activation state, values depend on unit type.");
427 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
428 on
= ansi_highlight();
429 off
= ansi_highlight_off();
431 on
= ansi_highlight_red();
432 off
= ansi_highlight_off();
436 printf("%s%u loaded units listed.%s\n"
437 "To show all installed unit files use 'systemctl list-unit-files'.\n",
440 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
441 "To show all installed unit files use 'systemctl list-unit-files'.\n",
446 static int get_unit_list(
448 sd_bus_message
**_reply
,
449 UnitInfo
**_unit_infos
,
452 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
453 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
454 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
463 r
= sd_bus_call_method(
465 "org.freedesktop.systemd1",
466 "/org/freedesktop/systemd1",
467 "org.freedesktop.systemd1.Manager",
473 log_error("Failed to list units: %s", bus_error_message(&error
, r
));
477 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
479 return bus_log_parse_error(r
);
481 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
482 if (!output_show_unit(&u
, patterns
))
485 if (!GREEDY_REALLOC(unit_infos
, size
, c
+1))
491 return bus_log_parse_error(r
);
493 r
= sd_bus_message_exit_container(reply
);
495 return bus_log_parse_error(r
);
500 *_unit_infos
= unit_infos
;
506 static int list_units(sd_bus
*bus
, char **args
) {
507 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
508 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
511 pager_open_if_enabled();
513 r
= get_unit_list(bus
, &reply
, &unit_infos
, strv_skip_first(args
));
517 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
518 output_units_list(unit_infos
, r
);
523 static int get_triggered_units(
528 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
531 r
= sd_bus_get_property_strv(
533 "org.freedesktop.systemd1",
535 "org.freedesktop.systemd1.Unit",
541 log_error("Failed to determine triggers: %s", bus_error_message(&error
, r
));
546 static int get_listening(
548 const char* unit_path
,
551 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
552 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
553 const char *type
, *path
;
556 r
= sd_bus_get_property(
558 "org.freedesktop.systemd1",
560 "org.freedesktop.systemd1.Socket",
566 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
570 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
572 return bus_log_parse_error(r
);
574 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
576 r
= strv_extend(listening
, type
);
580 r
= strv_extend(listening
, path
);
587 return bus_log_parse_error(r
);
589 r
= sd_bus_message_exit_container(reply
);
591 return bus_log_parse_error(r
);
602 /* Note: triggered is a list here, although it almost certainly
603 * will always be one unit. Nevertheless, dbus API allows for multiple
604 * values, so let's follow that.*/
607 /* The strv above is shared. free is set only in the first one. */
611 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
617 o
= strcmp(a
->path
, b
->path
);
619 o
= strcmp(a
->type
, b
->type
);
624 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
625 struct socket_info
*s
;
626 unsigned pathlen
= sizeof("LISTEN") - 1,
627 typelen
= (sizeof("TYPE") - 1) * arg_show_types
,
628 socklen
= sizeof("UNIT") - 1,
629 servlen
= sizeof("ACTIVATES") - 1;
630 const char *on
, *off
;
632 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
636 socklen
= MAX(socklen
, strlen(s
->id
));
638 typelen
= MAX(typelen
, strlen(s
->type
));
639 pathlen
= MAX(pathlen
, strlen(s
->path
));
641 STRV_FOREACH(a
, s
->triggered
)
642 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
643 servlen
= MAX(servlen
, tmp
);
648 printf("%-*s %-*.*s%-*s %s\n",
650 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
654 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
658 printf("%-*s %-*s %-*s",
659 pathlen
, s
->path
, typelen
, s
->type
, socklen
, s
->id
);
662 pathlen
, s
->path
, socklen
, s
->id
);
663 STRV_FOREACH(a
, s
->triggered
)
665 a
== s
->triggered
? "" : ",", *a
);
669 on
= ansi_highlight();
670 off
= ansi_highlight_off();
674 on
= ansi_highlight_red();
675 off
= ansi_highlight_off();
678 if (!arg_no_legend
) {
679 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
681 printf("Pass --all to see loaded but inactive sockets, too.\n");
687 static int list_sockets(sd_bus
*bus
, char **args
) {
688 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
689 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
690 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
692 struct socket_info
*s
;
697 pager_open_if_enabled();
699 n
= get_unit_list(bus
, &reply
, &unit_infos
, strv_skip_first(args
));
703 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
704 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
707 if (!endswith(u
->id
, ".socket"))
710 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
714 c
= get_listening(bus
, u
->unit_path
, &listening
);
720 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
725 for (i
= 0; i
< c
; i
++)
726 socket_infos
[cs
+ i
] = (struct socket_info
) {
728 .type
= listening
[i
*2],
729 .path
= listening
[i
*2 + 1],
730 .triggered
= triggered
,
731 .own_triggered
= i
==0,
734 /* from this point on we will cleanup those socket_infos */
737 listening
= triggered
= NULL
; /* avoid cleanup */
740 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
741 (__compar_fn_t
) socket_info_compare
);
743 output_sockets_list(socket_infos
, cs
);
746 assert(cs
== 0 || socket_infos
);
747 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
750 if (s
->own_triggered
)
751 strv_free(s
->triggered
);
757 static int get_next_elapse(
760 dual_timestamp
*next
) {
762 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
770 r
= sd_bus_get_property_trivial(
772 "org.freedesktop.systemd1",
774 "org.freedesktop.systemd1.Timer",
775 "NextElapseUSecMonotonic",
780 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
784 r
= sd_bus_get_property_trivial(
786 "org.freedesktop.systemd1",
788 "org.freedesktop.systemd1.Timer",
789 "NextElapseUSecRealtime",
794 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
808 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
812 if (a
->next_elapse
< b
->next_elapse
)
814 if (a
->next_elapse
> b
->next_elapse
)
817 return strcmp(a
->id
, b
->id
);
820 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
821 struct timer_info
*t
;
823 nextlen
= sizeof("NEXT") - 1,
824 leftlen
= sizeof("LEFT") - 1,
825 unitlen
= sizeof("UNIT") - 1,
826 activatelen
= sizeof("ACTIVATES") - 1;
828 const char *on
, *off
;
830 assert(timer_infos
|| n
== 0);
832 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
836 if (t
->next_elapse
> 0) {
837 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
839 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
840 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
842 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
843 leftlen
= MAX(leftlen
, strlen(trel
));
846 unitlen
= MAX(unitlen
, strlen(t
->id
));
848 STRV_FOREACH(a
, t
->triggered
)
849 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
850 activatelen
= MAX(activatelen
, ul
);
855 printf("%-*s %-*s %-*s %s\n",
861 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
862 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
865 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
866 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
868 printf("%-*s %-*s %-*s",
869 nextlen
, tstamp
, leftlen
, trel
, unitlen
, t
->id
);
871 STRV_FOREACH(a
, t
->triggered
)
873 a
== t
->triggered
? "" : ",", *a
);
877 on
= ansi_highlight();
878 off
= ansi_highlight_off();
882 on
= ansi_highlight_red();
883 off
= ansi_highlight_off();
886 if (!arg_no_legend
) {
887 printf("%s%u timers listed.%s\n", on
, n
, off
);
889 printf("Pass --all to see loaded but inactive timers, too.\n");
895 static int list_timers(sd_bus
*bus
, char **args
) {
897 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
898 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
899 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
900 struct timer_info
*t
;
907 pager_open_if_enabled();
909 n
= get_unit_list(bus
, &reply
, &unit_infos
, strv_skip_first(args
));
913 dual_timestamp_get(&nw
);
915 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
916 _cleanup_strv_free_
char **triggered
= NULL
;
920 if (!endswith(u
->id
, ".timer"))
923 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
927 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
931 if (next
.monotonic
!= (usec_t
) -1 && next
.monotonic
> 0) {
934 if (next
.monotonic
> nw
.monotonic
)
935 converted
= nw
.realtime
+ (next
.monotonic
- nw
.monotonic
);
937 converted
= nw
.realtime
- (nw
.monotonic
- next
.monotonic
);
939 if (next
.realtime
!= (usec_t
) -1 && next
.realtime
> 0)
940 m
= MIN(converted
, next
.realtime
);
946 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
951 timer_infos
[c
++] = (struct timer_info
) {
954 .triggered
= triggered
,
957 triggered
= NULL
; /* avoid cleanup */
960 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
961 (__compar_fn_t
) timer_info_compare
);
963 output_timers_list(timer_infos
, c
);
966 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
967 strv_free(t
->triggered
);
972 static int compare_unit_file_list(const void *a
, const void *b
) {
974 const UnitFileList
*u
= a
, *v
= b
;
976 d1
= strrchr(u
->path
, '.');
977 d2
= strrchr(v
->path
, '.');
982 r
= strcasecmp(d1
, d2
);
987 return strcasecmp(basename(u
->path
), basename(v
->path
));
990 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
993 if (!strv_isempty(patterns
)) {
996 STRV_FOREACH(pattern
, patterns
)
997 if (fnmatch(*pattern
, basename(u
->path
), FNM_NOESCAPE
) == 0)
1002 return !arg_types
|| ((dot
= strrchr(u
->path
, '.')) && strv_find(arg_types
, dot
+1));
1005 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1006 unsigned max_id_len
, id_cols
, state_cols
, n_shown
= 0;
1007 const UnitFileList
*u
;
1009 max_id_len
= sizeof("UNIT FILE")-1;
1010 state_cols
= sizeof("STATE")-1;
1012 for (u
= units
; u
< units
+ c
; u
++) {
1013 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1014 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1018 unsigned basic_cols
;
1020 id_cols
= MIN(max_id_len
, 25u);
1021 basic_cols
= 1 + id_cols
+ state_cols
;
1022 if (basic_cols
< (unsigned) columns())
1023 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1025 id_cols
= max_id_len
;
1028 printf("%-*s %-*s\n",
1029 id_cols
, "UNIT FILE",
1030 state_cols
, "STATE");
1032 for (u
= units
; u
< units
+ c
; u
++) {
1033 _cleanup_free_
char *e
= NULL
;
1034 const char *on
, *off
;
1039 if (u
->state
== UNIT_FILE_MASKED
||
1040 u
->state
== UNIT_FILE_MASKED_RUNTIME
||
1041 u
->state
== UNIT_FILE_DISABLED
||
1042 u
->state
== UNIT_FILE_INVALID
) {
1043 on
= ansi_highlight_red();
1044 off
= ansi_highlight_off();
1045 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1046 on
= ansi_highlight_green();
1047 off
= ansi_highlight_off();
1051 id
= basename(u
->path
);
1053 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1055 printf("%-*s %s%-*s%s\n",
1056 id_cols
, e
? e
: id
,
1057 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1061 printf("\n%u unit files listed.\n", n_shown
);
1064 static int list_unit_files(sd_bus
*bus
, char **args
) {
1065 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1066 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1067 _cleanup_free_ UnitFileList
*units
= NULL
;
1075 pager_open_if_enabled();
1083 h
= hashmap_new(string_hash_func
, string_compare_func
);
1087 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1089 unit_file_list_free(h
);
1090 log_error("Failed to get unit file list: %s", strerror(-r
));
1094 n_units
= hashmap_size(h
);
1095 units
= new(UnitFileList
, n_units
);
1097 unit_file_list_free(h
);
1101 HASHMAP_FOREACH(u
, h
, i
) {
1102 if (!output_show_unit_file(u
, strv_skip_first(args
)))
1109 assert(c
<= n_units
);
1112 r
= sd_bus_call_method(
1114 "org.freedesktop.systemd1",
1115 "/org/freedesktop/systemd1",
1116 "org.freedesktop.systemd1.Manager",
1122 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1126 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1128 return bus_log_parse_error(r
);
1130 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1132 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1135 units
[c
] = (struct UnitFileList
) {
1137 unit_file_state_from_string(state
)
1140 if (output_show_unit_file(&units
[c
], strv_skip_first(args
)))
1145 return bus_log_parse_error(r
);
1147 r
= sd_bus_message_exit_container(reply
);
1149 return bus_log_parse_error(r
);
1153 qsort(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1154 output_unit_file_list(units
, c
);
1158 for (unit
= units
; unit
< units
+ c
; unit
++)
1164 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1165 _cleanup_free_
char *n
= NULL
;
1166 size_t max_len
= MAX(columns(),20u);
1172 for (i
= level
- 1; i
>= 0; i
--) {
1174 if (len
> max_len
- 3 && !arg_full
) {
1175 printf("%s...\n",max_len
% 2 ? "" : " ");
1178 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERT
: DRAW_TREE_SPACE
));
1182 if (len
> max_len
- 3 && !arg_full
) {
1183 printf("%s...\n",max_len
% 2 ? "" : " ");
1187 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1191 printf("%s\n", name
);
1195 n
= ellipsize(name
, max_len
-len
, 100);
1203 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1205 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1206 [DEPENDENCY_FORWARD
] = "Requires\0"
1207 "RequiresOverridable\0"
1209 "RequisiteOverridable\0"
1211 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1212 "RequiredByOverridable\0"
1215 [DEPENDENCY_AFTER
] = "After\0",
1216 [DEPENDENCY_BEFORE
] = "Before\0",
1219 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1220 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1221 _cleanup_strv_free_
char **ret
= NULL
;
1222 _cleanup_free_
char *path
= NULL
;
1228 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1230 path
= unit_dbus_path_from_name(name
);
1234 r
= sd_bus_call_method(
1236 "org.freedesktop.systemd1",
1238 "org.freedesktop.DBus.Properties",
1242 "s", "org.freedesktop.systemd1.Unit");
1244 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1248 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1250 return bus_log_parse_error(r
);
1252 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1255 r
= sd_bus_message_read(reply
, "s", &prop
);
1257 return bus_log_parse_error(r
);
1259 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1260 r
= sd_bus_message_skip(reply
, "v");
1262 return bus_log_parse_error(r
);
1265 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1267 return bus_log_parse_error(r
);
1269 r
= bus_message_read_strv_extend(reply
, &ret
);
1271 return bus_log_parse_error(r
);
1273 r
= sd_bus_message_exit_container(reply
);
1275 return bus_log_parse_error(r
);
1278 r
= sd_bus_message_exit_container(reply
);
1280 return bus_log_parse_error(r
);
1284 return bus_log_parse_error(r
);
1286 r
= sd_bus_message_exit_container(reply
);
1288 return bus_log_parse_error(r
);
1296 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1297 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1299 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1301 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1304 return strcasecmp(*a
, *b
);
1307 static int list_dependencies_one(
1312 unsigned int branches
) {
1314 _cleanup_strv_free_
char **deps
= NULL
, **u
;
1322 u
= strv_append(*units
, name
);
1326 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1330 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1332 STRV_FOREACH(c
, deps
) {
1335 if (strv_contains(u
, *c
)) {
1337 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1344 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1346 printf("%s%s%s", ansi_highlight_green(), draw_special_char(DRAW_BLACK_CIRCLE
), ansi_highlight_off());
1348 printf("%s%s%s", ansi_highlight_red(), draw_special_char(DRAW_BLACK_CIRCLE
), ansi_highlight_off());
1350 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1354 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1355 r
= list_dependencies_one(bus
, *c
, level
+ 1, &u
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1370 static int list_dependencies(sd_bus
*bus
, char **args
) {
1371 _cleanup_strv_free_
char **units
= NULL
;
1372 _cleanup_free_
char *unit
= NULL
;
1378 unit
= unit_name_mangle(args
[1], false);
1383 u
= SPECIAL_DEFAULT_TARGET
;
1385 pager_open_if_enabled();
1389 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1392 static int get_default(sd_bus
*bus
, char **args
) {
1393 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1394 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1395 _cleanup_free_
char *_path
= NULL
;
1399 if (!bus
|| avoid_bus()) {
1400 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1402 log_error("Failed to get default target: %s", strerror(-r
));
1408 r
= sd_bus_call_method(
1410 "org.freedesktop.systemd1",
1411 "/org/freedesktop/systemd1",
1412 "org.freedesktop.systemd1.Manager",
1418 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1422 r
= sd_bus_message_read(reply
, "s", &path
);
1424 return bus_log_parse_error(r
);
1428 printf("%s\n", path
);
1433 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1436 assert(changes
|| n_changes
== 0);
1438 for (i
= 0; i
< n_changes
; i
++) {
1439 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1440 log_info("ln -s '%s' '%s'", changes
[i
].source
, changes
[i
].path
);
1442 log_info("rm '%s'", changes
[i
].path
);
1446 static int deserialize_and_dump_unit_file_changes(sd_bus_message
*m
) {
1447 const char *type
, *path
, *source
;
1450 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sss)");
1452 return bus_log_parse_error(r
);
1454 while ((r
= sd_bus_message_read(m
, "(sss)", &type
, &path
, &source
)) > 0) {
1456 if (streq(type
, "symlink"))
1457 log_info("ln -s '%s' '%s'", source
, path
);
1459 log_info("rm '%s'", path
);
1463 return bus_log_parse_error(r
);
1465 r
= sd_bus_message_exit_container(m
);
1467 return bus_log_parse_error(r
);
1472 static int set_default(sd_bus
*bus
, char **args
) {
1473 _cleanup_free_
char *unit
= NULL
;
1474 UnitFileChange
*changes
= NULL
;
1475 unsigned n_changes
= 0;
1478 unit
= unit_name_mangle_with_suffix(args
[1], false, ".target");
1482 if (!bus
|| avoid_bus()) {
1483 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, arg_force
, &changes
, &n_changes
);
1485 log_error("Failed to set default target: %s", strerror(-r
));
1490 dump_unit_file_changes(changes
, n_changes
);
1494 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1495 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1497 r
= sd_bus_call_method(
1499 "org.freedesktop.systemd1",
1500 "/org/freedesktop/systemd1",
1501 "org.freedesktop.systemd1.Manager",
1505 "sb", unit
, arg_force
);
1507 log_error("Failed to set default target: %s", bus_error_message(&error
, -r
));
1511 r
= deserialize_and_dump_unit_file_changes(reply
);
1515 /* Try to reload if enabeld */
1517 r
= daemon_reload(bus
, args
);
1522 unit_file_changes_free(changes
, n_changes
);
1529 const char *name
, *type
, *state
;
1532 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
1533 unsigned id_len
, unit_len
, type_len
, state_len
;
1534 const struct job_info
*j
;
1535 const char *on
, *off
;
1536 bool shorten
= false;
1538 assert(n
== 0 || jobs
);
1541 on
= ansi_highlight_green();
1542 off
= ansi_highlight_off();
1544 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
1548 pager_open_if_enabled();
1550 id_len
= sizeof("JOB")-1;
1551 unit_len
= sizeof("UNIT")-1;
1552 type_len
= sizeof("TYPE")-1;
1553 state_len
= sizeof("STATE")-1;
1555 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1556 uint32_t id
= j
->id
;
1557 assert(j
->name
&& j
->type
&& j
->state
);
1559 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
1560 unit_len
= MAX(unit_len
, strlen(j
->name
));
1561 type_len
= MAX(type_len
, strlen(j
->type
));
1562 state_len
= MAX(state_len
, strlen(j
->state
));
1565 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
1566 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
1571 printf("%*s %-*s %-*s %-*s\n",
1575 state_len
, "STATE");
1577 for (j
= jobs
; j
< jobs
+ n
; j
++) {
1578 _cleanup_free_
char *e
= NULL
;
1580 if (streq(j
->state
, "running")) {
1581 on
= ansi_highlight();
1582 off
= ansi_highlight_off();
1586 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
1587 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
1589 on
, unit_len
, e
? e
: j
->name
, off
,
1591 on
, state_len
, j
->state
, off
);
1594 if (!arg_no_legend
) {
1595 on
= ansi_highlight();
1596 off
= ansi_highlight_off();
1598 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
1602 static bool output_show_job(struct job_info
*job
, char **patterns
) {
1603 if (!strv_isempty(patterns
)) {
1606 STRV_FOREACH(pattern
, patterns
)
1607 if (fnmatch(*pattern
, job
->name
, FNM_NOESCAPE
) == 0)
1615 static int list_jobs(sd_bus
*bus
, char **args
) {
1616 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1617 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1618 const char *name
, *type
, *state
, *job_path
, *unit_path
;
1619 _cleanup_free_
struct job_info
*jobs
= NULL
;
1624 bool skipped
= false;
1626 r
= sd_bus_call_method(
1628 "org.freedesktop.systemd1",
1629 "/org/freedesktop/systemd1",
1630 "org.freedesktop.systemd1.Manager",
1636 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
1640 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
1642 return bus_log_parse_error(r
);
1644 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
1645 struct job_info job
= { id
, name
, type
, state
};
1647 if (!output_show_job(&job
, strv_skip_first(args
))) {
1652 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
1658 return bus_log_parse_error(r
);
1660 r
= sd_bus_message_exit_container(reply
);
1662 return bus_log_parse_error(r
);
1664 output_jobs_list(jobs
, c
, skipped
);
1668 static int cancel_job(sd_bus
*bus
, char **args
) {
1669 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1674 if (strv_length(args
) <= 1)
1675 return daemon_reload(bus
, args
);
1677 STRV_FOREACH(name
, args
+1) {
1681 r
= safe_atou32(*name
, &id
);
1683 log_error("Failed to parse job id \"%s\": %s", *name
, strerror(-r
));
1687 r
= sd_bus_call_method(
1689 "org.freedesktop.systemd1",
1690 "/org/freedesktop/systemd1",
1691 "org.freedesktop.systemd1.Manager",
1697 log_error("Failed to cancel job %u: %s", (unsigned) id
, bus_error_message(&error
, r
));
1705 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
1706 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1710 /* We ignore all errors here, since this is used to show a
1713 /* We don't use unit_dbus_path_from_name() directly since we
1714 * don't want to load the unit if it isn't loaded. */
1716 r
= sd_bus_call_method(
1718 "org.freedesktop.systemd1",
1719 "/org/freedesktop/systemd1",
1720 "org.freedesktop.systemd1.Manager",
1728 r
= sd_bus_message_read(reply
, "o", &path
);
1732 r
= sd_bus_get_property_trivial(
1734 "org.freedesktop.systemd1",
1736 "org.freedesktop.systemd1.Unit",
1746 typedef struct WaitData
{
1753 static int wait_filter(sd_bus
*bus
, sd_bus_message
*m
, void *data
, sd_bus_error
*error
) {
1760 log_debug("Got D-Bus request: %s.%s() on %s",
1761 sd_bus_message_get_interface(m
),
1762 sd_bus_message_get_member(m
),
1763 sd_bus_message_get_path(m
));
1765 if (sd_bus_message_is_signal(m
, "org.freedesktop.DBus.Local", "Disconnected")) {
1766 log_error("Warning! D-Bus connection terminated.");
1768 } else if (sd_bus_message_is_signal(m
, "org.freedesktop.systemd1.Manager", "JobRemoved")) {
1770 const char *path
, *result
, *unit
;
1774 r
= sd_bus_message_read(m
, "uoss", &id
, &path
, &unit
, &result
);
1776 ret
= set_remove(d
->set
, (char*) path
);
1782 if (!isempty(result
))
1783 d
->result
= strdup(result
);
1786 d
->name
= strdup(unit
);
1791 r
= sd_bus_message_read(m
, "uos", &id
, &path
, &result
);
1793 ret
= set_remove(d
->set
, (char*) path
);
1800 d
->result
= strdup(result
);
1806 bus_log_parse_error(r
);
1812 static int enable_wait_for_jobs(sd_bus
*bus
) {
1817 r
= sd_bus_add_match(
1820 "sender='org.freedesktop.systemd1',"
1821 "interface='org.freedesktop.systemd1.Manager',"
1822 "member='JobRemoved',"
1823 "path='/org/freedesktop/systemd1'",
1826 log_error("Failed to add match");
1830 /* This is slightly dirty, since we don't undo the match registrations. */
1834 static int bus_process_wait(sd_bus
*bus
) {
1838 r
= sd_bus_process(bus
, NULL
);
1843 r
= sd_bus_wait(bus
, (uint64_t) -1);
1849 static int check_wait_response(WaitData
*d
) {
1855 if (streq(d
->result
, "timeout"))
1856 log_error("Job for %s timed out.", strna(d
->name
));
1857 else if (streq(d
->result
, "canceled"))
1858 log_error("Job for %s canceled.", strna(d
->name
));
1859 else if (streq(d
->result
, "dependency"))
1860 log_error("A dependency job for %s failed. See 'journalctl -xn' for details.", strna(d
->name
));
1861 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1862 log_error("Job for %s failed. See 'systemctl status %s' and 'journalctl -xn' for details.", strna(d
->name
), strna(d
->name
));
1865 if (streq(d
->result
, "timeout"))
1867 else if (streq(d
->result
, "canceled"))
1869 else if (streq(d
->result
, "dependency"))
1871 else if (!streq(d
->result
, "done") && !streq(d
->result
, "skipped"))
1877 static int wait_for_jobs(sd_bus
*bus
, Set
*s
) {
1878 WaitData d
= { .set
= s
};
1884 q
= sd_bus_add_filter(bus
, wait_filter
, &d
);
1888 while (!set_isempty(s
)) {
1889 q
= bus_process_wait(bus
);
1891 log_error("Failed to wait for response: %s", strerror(-r
));
1896 q
= check_wait_response(&d
);
1897 /* Return the first error as it is most likely to be
1899 if (q
< 0 && r
== 0)
1901 log_debug("Got result %s/%s for job %s",
1902 strna(d
.result
), strerror(-q
), strna(d
.name
));
1912 q
= sd_bus_remove_filter(bus
, wait_filter
, &d
);
1913 if (q
< 0 && r
== 0)
1919 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
1920 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1921 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
1927 n
= unit_name_mangle(name
, false);
1931 /* We don't use unit_dbus_path_from_name() directly since we
1932 * don't want to load the unit if it isn't loaded. */
1934 r
= sd_bus_call_method(
1936 "org.freedesktop.systemd1",
1937 "/org/freedesktop/systemd1",
1938 "org.freedesktop.systemd1.Manager",
1949 r
= sd_bus_message_read(reply
, "o", &path
);
1951 return bus_log_parse_error(r
);
1953 r
= sd_bus_get_property_string(
1955 "org.freedesktop.systemd1",
1957 "org.freedesktop.systemd1.Unit",
1970 return nulstr_contains(good_states
, state
);
1973 static int check_triggering_units(
1977 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1978 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
1979 _cleanup_strv_free_
char **triggered_by
= NULL
;
1980 bool print_warning_label
= true;
1984 n
= unit_name_mangle(name
, false);
1988 path
= unit_dbus_path_from_name(n
);
1992 r
= sd_bus_get_property_string(
1994 "org.freedesktop.systemd1",
1996 "org.freedesktop.systemd1.Unit",
2001 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2005 if (streq(state
, "masked"))
2008 r
= sd_bus_get_property_strv(
2010 "org.freedesktop.systemd1",
2012 "org.freedesktop.systemd1.Unit",
2017 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2021 STRV_FOREACH(i
, triggered_by
) {
2022 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2024 log_error("Failed to check unit: %s", strerror(-r
));
2031 if (print_warning_label
) {
2032 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2033 print_warning_label
= false;
2036 log_warning(" %s", *i
);
2042 static int start_unit_one(
2047 sd_bus_error
*error
,
2050 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2059 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2060 r
= sd_bus_call_method(
2062 "org.freedesktop.systemd1",
2063 "/org/freedesktop/systemd1",
2064 "org.freedesktop.systemd1.Manager",
2070 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2071 /* There's always a fallback possible for
2072 * legacy actions. */
2073 return -EADDRNOTAVAIL
;
2075 log_error("Failed to %s %s: %s", method
, name
, bus_error_message(error
, r
));
2079 r
= sd_bus_message_read(reply
, "o", &path
);
2081 return bus_log_parse_error(r
);
2083 if (need_daemon_reload(bus
, name
) > 0)
2084 log_warning("Warning: Unit file of %s changed on disk, 'systemctl%s daemon-reload' recommended.",
2085 name
, arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2094 log_debug("Adding %s to the set", p
);
2095 r
= set_consume(s
, p
);
2103 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2105 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2106 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2110 STRV_FOREACH(name
, names
) {
2114 t
= unit_name_mangle_with_suffix(*name
, true, suffix
);
2116 t
= unit_name_mangle(*name
, true);
2120 if (string_is_glob(t
))
2121 r
= strv_push(&globs
, t
);
2123 r
= strv_push(&mangled
, t
);
2130 /* Query the manager only if any of the names are a glob, since
2131 * this is fairly expensive */
2132 if (!strv_isempty(globs
)) {
2133 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2135 r
= get_unit_list(bus
, &reply
, &unit_infos
, globs
);
2139 for (i
= 0; i
< r
; i
++)
2140 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2145 mangled
= NULL
; /* do not free */
2149 static const struct {
2153 } action_table
[_ACTION_MAX
] = {
2154 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2155 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2156 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2157 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2158 [ACTION_RUNLEVEL2
] = { SPECIAL_RUNLEVEL2_TARGET
, NULL
, "isolate" },
2159 [ACTION_RUNLEVEL3
] = { SPECIAL_RUNLEVEL3_TARGET
, NULL
, "isolate" },
2160 [ACTION_RUNLEVEL4
] = { SPECIAL_RUNLEVEL4_TARGET
, NULL
, "isolate" },
2161 [ACTION_RUNLEVEL5
] = { SPECIAL_RUNLEVEL5_TARGET
, NULL
, "isolate" },
2162 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2163 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2164 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2165 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2166 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2167 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2168 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2171 static enum action
verb_to_action(const char *verb
) {
2174 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2175 if (streq_ptr(action_table
[i
].verb
, verb
))
2178 return _ACTION_INVALID
;
2181 static int start_unit(sd_bus
*bus
, char **args
) {
2182 _cleanup_set_free_free_ Set
*s
= NULL
;
2183 _cleanup_strv_free_
char **names
= NULL
;
2184 const char *method
, *mode
, *one_name
;
2190 ask_password_agent_open_if_enabled();
2192 if (arg_action
== ACTION_SYSTEMCTL
) {
2195 streq(args
[0], "stop") ||
2196 streq(args
[0], "condstop") ? "StopUnit" :
2197 streq(args
[0], "reload") ? "ReloadUnit" :
2198 streq(args
[0], "restart") ? "RestartUnit" :
2200 streq(args
[0], "try-restart") ||
2201 streq(args
[0], "condrestart") ? "TryRestartUnit" :
2203 streq(args
[0], "reload-or-restart") ? "ReloadOrRestartUnit" :
2205 streq(args
[0], "reload-or-try-restart") ||
2206 streq(args
[0], "condreload") ||
2207 streq(args
[0], "force-reload") ? "ReloadOrTryRestartUnit" :
2209 action
= verb_to_action(args
[0]);
2211 mode
= streq(args
[0], "isolate") ? "isolate" :
2212 action_table
[action
].mode
?: arg_job_mode
;
2214 one_name
= action_table
[action
].target
;
2216 assert(arg_action
< ELEMENTSOF(action_table
));
2217 assert(action_table
[arg_action
].target
);
2219 method
= "StartUnit";
2221 mode
= action_table
[arg_action
].mode
;
2222 one_name
= action_table
[arg_action
].target
;
2226 names
= strv_new(one_name
, NULL
);
2228 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
2230 log_error("Failed to expand names: %s", strerror(-r
));
2233 if (!arg_no_block
) {
2234 r
= enable_wait_for_jobs(bus
);
2236 log_error("Could not watch jobs: %s", strerror(-r
));
2240 s
= set_new(string_hash_func
, string_compare_func
);
2245 STRV_FOREACH(name
, names
) {
2246 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2249 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, s
);
2250 if (r
>= 0 && q
< 0)
2251 r
= translate_bus_error_to_exit_status(q
, &error
);
2254 if (!arg_no_block
) {
2257 q
= wait_for_jobs(bus
, s
);
2261 /* When stopping units, warn if they can still be triggered by
2262 * another active unit (socket, path, timer) */
2263 if (!arg_quiet
&& streq(method
, "StopUnit"))
2264 STRV_FOREACH(name
, names
)
2265 check_triggering_units(bus
, *name
);
2271 /* Ask systemd-logind, which might grant access to unprivileged users
2272 * through PolicyKit */
2273 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
2275 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2282 polkit_agent_open_if_enabled();
2290 case ACTION_POWEROFF
:
2291 method
= "PowerOff";
2294 case ACTION_SUSPEND
:
2298 case ACTION_HIBERNATE
:
2299 method
= "Hibernate";
2302 case ACTION_HYBRID_SLEEP
:
2303 method
= "HybridSleep";
2310 r
= sd_bus_call_method(
2312 "org.freedesktop.login1",
2313 "/org/freedesktop/login1",
2314 "org.freedesktop.login1.Manager",
2320 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
2328 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
2330 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2331 _cleanup_strv_free_
char **sessions
= NULL
;
2332 const char *what
, *who
, *why
, *mode
;
2341 if (arg_ignore_inhibitors
|| arg_force
> 0)
2353 r
= sd_bus_call_method(
2355 "org.freedesktop.login1",
2356 "/org/freedesktop/login1",
2357 "org.freedesktop.login1.Manager",
2363 /* If logind is not around, then there are no inhibitors... */
2366 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2368 return bus_log_parse_error(r
);
2370 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2371 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2372 _cleanup_strv_free_
char **sv
= NULL
;
2374 if (!streq(mode
, "block"))
2377 sv
= strv_split(what
, ":");
2381 if (!strv_contains(sv
,
2383 a
== ACTION_POWEROFF
||
2384 a
== ACTION_REBOOT
||
2385 a
== ACTION_KEXEC
? "shutdown" : "sleep"))
2388 get_process_comm(pid
, &comm
);
2389 user
= uid_to_name(uid
);
2391 log_warning("Operation inhibited by \"%s\" (PID %lu \"%s\", user %s), reason is \"%s\".",
2392 who
, (unsigned long) pid
, strna(comm
), strna(user
), why
);
2397 return bus_log_parse_error(r
);
2399 r
= sd_bus_message_exit_container(reply
);
2401 return bus_log_parse_error(r
);
2403 /* Check for current sessions */
2404 sd_get_sessions(&sessions
);
2405 STRV_FOREACH(s
, sessions
) {
2406 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2408 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2411 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2414 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2417 sd_session_get_tty(*s
, &tty
);
2418 sd_session_get_seat(*s
, &seat
);
2419 sd_session_get_service(*s
, &service
);
2420 user
= uid_to_name(uid
);
2422 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2429 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2430 action_table
[a
].verb
);
2438 static int start_special(sd_bus
*bus
, char **args
) {
2444 a
= verb_to_action(args
[0]);
2446 r
= check_inhibitors(bus
, a
);
2450 if (arg_force
>= 2 && geteuid() != 0) {
2451 log_error("Must be root.");
2455 if (arg_force
>= 2 &&
2456 (a
== ACTION_HALT
||
2457 a
== ACTION_POWEROFF
||
2458 a
== ACTION_REBOOT
))
2461 if (arg_force
>= 1 &&
2462 (a
== ACTION_HALT
||
2463 a
== ACTION_POWEROFF
||
2464 a
== ACTION_REBOOT
||
2465 a
== ACTION_KEXEC
||
2467 return daemon_reload(bus
, args
);
2469 /* first try logind, to allow authentication with polkit */
2470 if (geteuid() != 0 &&
2471 (a
== ACTION_POWEROFF
||
2472 a
== ACTION_REBOOT
||
2473 a
== ACTION_SUSPEND
||
2474 a
== ACTION_HIBERNATE
||
2475 a
== ACTION_HYBRID_SLEEP
)) {
2476 r
= reboot_with_logind(bus
, a
);
2481 r
= start_unit(bus
, args
);
2482 if (r
== EXIT_SUCCESS
)
2488 static int check_unit_generic(sd_bus
*bus
, int code
, const char *good_states
, char **args
) {
2489 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2490 _cleanup_strv_free_
char **names
= NULL
;
2497 r
= expand_names(bus
, args
, NULL
, &names
);
2499 log_error("Failed to expand names: %s", strerror(-r
));
2501 STRV_FOREACH(name
, names
) {
2504 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
2514 static int check_unit_active(sd_bus
*bus
, char **args
) {
2515 /* According to LSB: 3, "program is not running" */
2516 return check_unit_generic(bus
, 3, "active\0reloading\0", args
+ 1);
2519 static int check_unit_failed(sd_bus
*bus
, char **args
) {
2520 return check_unit_generic(bus
, 1, "failed\0", args
+ 1);
2523 static int kill_unit(sd_bus
*bus
, char **args
) {
2524 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2525 _cleanup_strv_free_
char **names
= NULL
;
2533 arg_kill_who
= "all";
2535 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
2537 log_error("Failed to expand names: %s", strerror(-r
));
2539 STRV_FOREACH(name
, names
) {
2540 q
= sd_bus_call_method(
2542 "org.freedesktop.systemd1",
2543 "/org/freedesktop/systemd1",
2544 "org.freedesktop.systemd1.Manager",
2548 "ssi", *names
, arg_kill_who
, arg_signal
);
2550 log_error("Failed to kill unit %s: %s",
2551 *names
, bus_error_message(&error
, r
));
2560 typedef struct ExecStatusInfo
{
2568 usec_t start_timestamp
;
2569 usec_t exit_timestamp
;
2574 LIST_FIELDS(struct ExecStatusInfo
, exec
);
2577 static void exec_status_info_free(ExecStatusInfo
*i
) {
2586 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
2587 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
2590 int32_t code
, status
;
2596 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
2598 return bus_log_parse_error(r
);
2602 r
= sd_bus_message_read(m
, "s", &path
);
2604 return bus_log_parse_error(r
);
2606 i
->path
= strdup(path
);
2610 r
= sd_bus_message_read_strv(m
, &i
->argv
);
2612 return bus_log_parse_error(r
);
2614 r
= sd_bus_message_read(m
,
2617 &start_timestamp
, &start_timestamp_monotonic
,
2618 &exit_timestamp
, &exit_timestamp_monotonic
,
2622 return bus_log_parse_error(r
);
2625 i
->start_timestamp
= (usec_t
) start_timestamp
;
2626 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
2627 i
->pid
= (pid_t
) pid
;
2631 r
= sd_bus_message_exit_container(m
);
2633 return bus_log_parse_error(r
);
2638 typedef struct UnitStatusInfo
{
2640 const char *load_state
;
2641 const char *active_state
;
2642 const char *sub_state
;
2643 const char *unit_file_state
;
2645 const char *description
;
2646 const char *following
;
2648 char **documentation
;
2650 const char *fragment_path
;
2651 const char *source_path
;
2652 const char *control_group
;
2654 char **dropin_paths
;
2656 const char *load_error
;
2659 usec_t inactive_exit_timestamp
;
2660 usec_t inactive_exit_timestamp_monotonic
;
2661 usec_t active_enter_timestamp
;
2662 usec_t active_exit_timestamp
;
2663 usec_t inactive_enter_timestamp
;
2665 bool need_daemon_reload
;
2670 const char *status_text
;
2671 const char *pid_file
;
2674 usec_t start_timestamp
;
2675 usec_t exit_timestamp
;
2677 int exit_code
, exit_status
;
2679 usec_t condition_timestamp
;
2680 bool condition_result
;
2681 bool failed_condition_trigger
;
2682 bool failed_condition_negate
;
2683 const char *failed_condition
;
2684 const char *failed_condition_param
;
2687 unsigned n_accepted
;
2688 unsigned n_connections
;
2691 /* Pairs of type, path */
2695 const char *sysfs_path
;
2697 /* Mount, Automount */
2703 LIST_HEAD(ExecStatusInfo
, exec
);
2706 static void print_status_info(
2711 const char *on
, *off
, *ss
;
2713 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
2714 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
2717 arg_all
* OUTPUT_SHOW_ALL
|
2718 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
2719 on_tty() * OUTPUT_COLOR
|
2720 !arg_quiet
* OUTPUT_WARN_CUTOFF
|
2721 arg_full
* OUTPUT_FULL_WIDTH
;
2726 /* This shows pretty information about a unit. See
2727 * print_property() for a low-level property printer */
2729 printf("%s", strna(i
->id
));
2731 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
2732 printf(" - %s", i
->description
);
2737 printf(" Follow: unit currently follows state of %s\n", i
->following
);
2739 if (streq_ptr(i
->load_state
, "error")) {
2740 on
= ansi_highlight_red();
2741 off
= ansi_highlight_off();
2745 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
2748 printf(" Loaded: %s%s%s (Reason: %s)\n",
2749 on
, strna(i
->load_state
), off
, i
->load_error
);
2750 else if (path
&& i
->unit_file_state
)
2751 printf(" Loaded: %s%s%s (%s; %s)\n",
2752 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
2754 printf(" Loaded: %s%s%s (%s)\n",
2755 on
, strna(i
->load_state
), off
, path
);
2757 printf(" Loaded: %s%s%s\n",
2758 on
, strna(i
->load_state
), off
);
2760 if (!strv_isempty(i
->dropin_paths
)) {
2761 _cleanup_free_
char *dir
= NULL
;
2765 STRV_FOREACH(dropin
, i
->dropin_paths
) {
2766 if (! dir
|| last
) {
2767 printf(dir
? " " : " Drop-In: ");
2772 if (path_get_parent(*dropin
, &dir
) < 0) {
2777 printf("%s\n %s", dir
,
2778 draw_special_char(DRAW_TREE_RIGHT
));
2781 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
2783 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
2787 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
2789 if (streq_ptr(i
->active_state
, "failed")) {
2790 on
= ansi_highlight_red();
2791 off
= ansi_highlight_off();
2792 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
2793 on
= ansi_highlight_green();
2794 off
= ansi_highlight_off();
2799 printf(" Active: %s%s (%s)%s",
2800 on
, strna(i
->active_state
), ss
, off
);
2802 printf(" Active: %s%s%s",
2803 on
, strna(i
->active_state
), off
);
2805 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
2806 printf(" (Result: %s)", i
->result
);
2808 timestamp
= (streq_ptr(i
->active_state
, "active") ||
2809 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
2810 (streq_ptr(i
->active_state
, "inactive") ||
2811 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
2812 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
2813 i
->active_exit_timestamp
;
2815 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
2816 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
2819 printf(" since %s; %s\n", s2
, s1
);
2821 printf(" since %s\n", s2
);
2825 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
2826 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
2827 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
2829 printf(" start condition failed at %s%s%s\n",
2830 s2
, s1
? "; " : "", s1
? s1
: "");
2831 if (i
->failed_condition_trigger
)
2832 printf(" none of the trigger conditions were met\n");
2833 else if (i
->failed_condition
)
2834 printf(" %s=%s%s was not met\n",
2835 i
->failed_condition
,
2836 i
->failed_condition_negate
? "!" : "",
2837 i
->failed_condition_param
);
2841 printf(" Device: %s\n", i
->sysfs_path
);
2843 printf(" Where: %s\n", i
->where
);
2845 printf(" What: %s\n", i
->what
);
2847 STRV_FOREACH(t
, i
->documentation
)
2848 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
2850 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
2851 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
2854 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
2856 LIST_FOREACH(exec
, p
, i
->exec
) {
2857 _cleanup_free_
char *argv
= NULL
;
2860 /* Only show exited processes here */
2864 argv
= strv_join(p
->argv
, " ");
2865 printf(" Process: %u %s=%s ", p
->pid
, p
->name
, strna(argv
));
2867 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
2869 on
= ansi_highlight_red();
2870 off
= ansi_highlight_off();
2874 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
2876 if (p
->code
== CLD_EXITED
) {
2879 printf("status=%i", p
->status
);
2881 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
2886 printf("signal=%s", signal_to_string(p
->status
));
2888 printf(")%s\n", off
);
2890 if (i
->main_pid
== p
->pid
&&
2891 i
->start_timestamp
== p
->start_timestamp
&&
2892 i
->exit_timestamp
== p
->start_timestamp
)
2893 /* Let's not show this twice */
2896 if (p
->pid
== i
->control_pid
)
2900 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
2901 if (i
->main_pid
> 0) {
2902 printf(" Main PID: %u", (unsigned) i
->main_pid
);
2905 _cleanup_free_
char *comm
= NULL
;
2906 get_process_comm(i
->main_pid
, &comm
);
2908 printf(" (%s)", comm
);
2909 } else if (i
->exit_code
> 0) {
2910 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
2912 if (i
->exit_code
== CLD_EXITED
) {
2915 printf("status=%i", i
->exit_status
);
2917 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
2922 printf("signal=%s", signal_to_string(i
->exit_status
));
2926 if (i
->control_pid
> 0)
2930 if (i
->control_pid
> 0) {
2931 _cleanup_free_
char *c
= NULL
;
2933 printf(" %8s: %u", i
->main_pid
? "" : " Control", (unsigned) i
->control_pid
);
2935 get_process_comm(i
->control_pid
, &c
);
2944 printf(" Status: \"%s\"\n", i
->status_text
);
2946 if (i
->control_group
&&
2947 (i
->main_pid
> 0 || i
->control_pid
> 0 || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, false) == 0)) {
2950 printf(" CGroup: %s\n", i
->control_group
);
2952 if (arg_transport
== BUS_TRANSPORT_LOCAL
|| arg_transport
== BUS_TRANSPORT_CONTAINER
) {
2955 char prefix
[] = " ";
2958 if (c
> sizeof(prefix
) - 1)
2959 c
-= sizeof(prefix
) - 1;
2963 if (i
->main_pid
> 0)
2964 extra
[k
++] = i
->main_pid
;
2966 if (i
->control_pid
> 0)
2967 extra
[k
++] = i
->control_pid
;
2969 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
,
2970 c
, false, extra
, k
, flags
);
2974 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
) {
2976 show_journal_by_unit(stdout
,
2980 i
->inactive_exit_timestamp_monotonic
,
2984 arg_scope
== UNIT_FILE_SYSTEM
,
2988 if (i
->need_daemon_reload
)
2989 printf("\n%sWarning:%s Unit file changed on disk, 'systemctl %sdaemon-reload' recommended.\n",
2990 ansi_highlight_red(),
2991 ansi_highlight_off(),
2992 arg_scope
== UNIT_FILE_SYSTEM
? "" : "--user ");
2995 static void show_unit_help(UnitStatusInfo
*i
) {
3000 if (!i
->documentation
) {
3001 log_info("Documentation for %s not known.", i
->id
);
3005 STRV_FOREACH(p
, i
->documentation
) {
3007 if (startswith(*p
, "man:")) {
3008 const char *args
[4] = { "man", NULL
, NULL
, NULL
};
3009 _cleanup_free_
char *page
= NULL
, *section
= NULL
;
3016 if ((*p
)[k
-1] == ')')
3017 e
= strrchr(*p
, '(');
3020 page
= strndup((*p
) + 4, e
- *p
- 4);
3021 section
= strndup(e
+ 1, *p
+ k
- e
- 2);
3022 if (!page
|| !section
) {
3034 log_error("Failed to fork: %m");
3040 execvp(args
[0], (char**) args
);
3041 log_error("Failed to execute man: %m");
3042 _exit(EXIT_FAILURE
);
3045 wait_for_terminate(pid
, NULL
);
3047 log_info("Can't show: %s", *p
);
3051 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3058 switch (contents
[0]) {
3060 case SD_BUS_TYPE_STRING
: {
3063 r
= sd_bus_message_read(m
, "s", &s
);
3065 return bus_log_parse_error(r
);
3068 if (streq(name
, "Id"))
3070 else if (streq(name
, "LoadState"))
3072 else if (streq(name
, "ActiveState"))
3073 i
->active_state
= s
;
3074 else if (streq(name
, "SubState"))
3076 else if (streq(name
, "Description"))
3078 else if (streq(name
, "FragmentPath"))
3079 i
->fragment_path
= s
;
3080 else if (streq(name
, "SourcePath"))
3083 else if (streq(name
, "DefaultControlGroup")) {
3085 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3087 i
->control_group
= e
;
3090 else if (streq(name
, "ControlGroup"))
3091 i
->control_group
= s
;
3092 else if (streq(name
, "StatusText"))
3094 else if (streq(name
, "PIDFile"))
3096 else if (streq(name
, "SysFSPath"))
3098 else if (streq(name
, "Where"))
3100 else if (streq(name
, "What"))
3102 else if (streq(name
, "Following"))
3104 else if (streq(name
, "UnitFileState"))
3105 i
->unit_file_state
= s
;
3106 else if (streq(name
, "Result"))
3113 case SD_BUS_TYPE_BOOLEAN
: {
3116 r
= sd_bus_message_read(m
, "b", &b
);
3118 return bus_log_parse_error(r
);
3120 if (streq(name
, "Accept"))
3122 else if (streq(name
, "NeedDaemonReload"))
3123 i
->need_daemon_reload
= b
;
3124 else if (streq(name
, "ConditionResult"))
3125 i
->condition_result
= b
;
3130 case SD_BUS_TYPE_UINT32
: {
3133 r
= sd_bus_message_read(m
, "u", &u
);
3135 return bus_log_parse_error(r
);
3137 if (streq(name
, "MainPID")) {
3139 i
->main_pid
= (pid_t
) u
;
3142 } else if (streq(name
, "ControlPID"))
3143 i
->control_pid
= (pid_t
) u
;
3144 else if (streq(name
, "ExecMainPID")) {
3146 i
->main_pid
= (pid_t
) u
;
3147 } else if (streq(name
, "NAccepted"))
3149 else if (streq(name
, "NConnections"))
3150 i
->n_connections
= u
;
3155 case SD_BUS_TYPE_INT32
: {
3158 r
= sd_bus_message_read(m
, "i", &j
);
3160 return bus_log_parse_error(r
);
3162 if (streq(name
, "ExecMainCode"))
3163 i
->exit_code
= (int) j
;
3164 else if (streq(name
, "ExecMainStatus"))
3165 i
->exit_status
= (int) j
;
3170 case SD_BUS_TYPE_UINT64
: {
3173 r
= sd_bus_message_read(m
, "t", &u
);
3175 return bus_log_parse_error(r
);
3177 if (streq(name
, "ExecMainStartTimestamp"))
3178 i
->start_timestamp
= (usec_t
) u
;
3179 else if (streq(name
, "ExecMainExitTimestamp"))
3180 i
->exit_timestamp
= (usec_t
) u
;
3181 else if (streq(name
, "ActiveEnterTimestamp"))
3182 i
->active_enter_timestamp
= (usec_t
) u
;
3183 else if (streq(name
, "InactiveEnterTimestamp"))
3184 i
->inactive_enter_timestamp
= (usec_t
) u
;
3185 else if (streq(name
, "InactiveExitTimestamp"))
3186 i
->inactive_exit_timestamp
= (usec_t
) u
;
3187 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3188 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3189 else if (streq(name
, "ActiveExitTimestamp"))
3190 i
->active_exit_timestamp
= (usec_t
) u
;
3191 else if (streq(name
, "ConditionTimestamp"))
3192 i
->condition_timestamp
= (usec_t
) u
;
3197 case SD_BUS_TYPE_ARRAY
:
3199 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3200 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3202 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3204 return bus_log_parse_error(r
);
3206 info
= new0(ExecStatusInfo
, 1);
3210 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3212 info
->name
= strdup(name
);
3216 LIST_PREPEND(exec
, i
->exec
, info
);
3218 info
= new0(ExecStatusInfo
, 1);
3224 return bus_log_parse_error(r
);
3226 r
= sd_bus_message_exit_container(m
);
3228 return bus_log_parse_error(r
);
3232 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3233 const char *type
, *path
;
3235 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3237 return bus_log_parse_error(r
);
3239 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3241 r
= strv_extend(&i
->listen
, type
);
3245 r
= strv_extend(&i
->listen
, path
);
3250 return bus_log_parse_error(r
);
3252 r
= sd_bus_message_exit_container(m
);
3254 return bus_log_parse_error(r
);
3258 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3260 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3262 return bus_log_parse_error(r
);
3264 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3266 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3268 return bus_log_parse_error(r
);
3270 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3271 const char *cond
, *param
;
3272 int trigger
, negate
;
3275 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3277 return bus_log_parse_error(r
);
3279 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3280 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3281 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3282 i
->failed_condition
= cond
;
3283 i
->failed_condition_trigger
= trigger
;
3284 i
->failed_condition_negate
= negate
;
3285 i
->failed_condition_param
= param
;
3289 return bus_log_parse_error(r
);
3291 r
= sd_bus_message_exit_container(m
);
3293 return bus_log_parse_error(r
);
3300 case SD_BUS_TYPE_STRUCT_BEGIN
:
3302 if (streq(name
, "LoadError")) {
3303 const char *n
, *message
;
3305 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3307 return bus_log_parse_error(r
);
3309 if (!isempty(message
))
3310 i
->load_error
= message
;
3323 r
= sd_bus_message_skip(m
, contents
);
3325 return bus_log_parse_error(r
);
3330 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
3336 /* This is a low-level property printer, see
3337 * print_status_info() for the nicer output */
3339 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
3340 /* skip what we didn't read */
3341 r
= sd_bus_message_skip(m
, contents
);
3345 switch (contents
[0]) {
3347 case SD_BUS_TYPE_STRUCT_BEGIN
:
3349 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
3352 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
3354 return bus_log_parse_error(r
);
3357 printf("%s=%u\n", name
, (unsigned) u
);
3359 printf("%s=\n", name
);
3363 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
3366 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
3368 return bus_log_parse_error(r
);
3370 if (arg_all
|| !isempty(s
))
3371 printf("%s=%s\n", name
, s
);
3375 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
3376 const char *a
= NULL
, *b
= NULL
;
3378 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
3380 return bus_log_parse_error(r
);
3382 if (arg_all
|| !isempty(a
) || !isempty(b
))
3383 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
3390 case SD_BUS_TYPE_ARRAY
:
3392 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
3396 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
3398 return bus_log_parse_error(r
);
3400 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
3401 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
3404 return bus_log_parse_error(r
);
3406 r
= sd_bus_message_exit_container(m
);
3408 return bus_log_parse_error(r
);
3412 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
3413 const char *type
, *path
;
3415 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3417 return bus_log_parse_error(r
);
3419 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3420 printf("%s=%s\n", type
, path
);
3422 return bus_log_parse_error(r
);
3424 r
= sd_bus_message_exit_container(m
);
3426 return bus_log_parse_error(r
);
3430 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3431 const char *type
, *path
;
3433 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3435 return bus_log_parse_error(r
);
3437 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
3438 printf("Listen%s=%s\n", type
, path
);
3440 return bus_log_parse_error(r
);
3442 r
= sd_bus_message_exit_container(m
);
3444 return bus_log_parse_error(r
);
3448 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
3450 uint64_t value
, next_elapse
;
3452 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
3454 return bus_log_parse_error(r
);
3456 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
3457 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
3459 printf("%s={ value=%s ; next_elapse=%s }\n",
3461 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
3462 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
3465 return bus_log_parse_error(r
);
3467 r
= sd_bus_message_exit_container(m
);
3469 return bus_log_parse_error(r
);
3473 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3474 ExecStatusInfo info
= {};
3476 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3478 return bus_log_parse_error(r
);
3480 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
3481 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
3482 _cleanup_free_
char *tt
;
3484 tt
= strv_join(info
.argv
, " ");
3486 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid=%u ; code=%s ; status=%i%s%s }\n",
3490 yes_no(info
.ignore
),
3491 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
3492 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
3493 (unsigned) info
. pid
,
3494 sigchld_code_to_string(info
.code
),
3496 info
.code
== CLD_EXITED
? "" : "/",
3497 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
3500 strv_free(info
.argv
);
3504 r
= sd_bus_message_exit_container(m
);
3506 return bus_log_parse_error(r
);
3510 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
3511 const char *path
, *rwm
;
3513 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3515 return bus_log_parse_error(r
);
3517 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
3518 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
3520 return bus_log_parse_error(r
);
3522 r
= sd_bus_message_exit_container(m
);
3524 return bus_log_parse_error(r
);
3528 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
3532 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3534 return bus_log_parse_error(r
);
3536 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
3537 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
3539 return bus_log_parse_error(r
);
3541 r
= sd_bus_message_exit_container(m
);
3543 return bus_log_parse_error(r
);
3547 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
3551 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
3553 return bus_log_parse_error(r
);
3555 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
3556 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
3558 return bus_log_parse_error(r
);
3560 r
= sd_bus_message_exit_container(m
);
3562 return bus_log_parse_error(r
);
3570 r
= bus_print_property(name
, m
, arg_all
);
3572 return bus_log_parse_error(r
);
3575 r
= sd_bus_message_skip(m
, contents
);
3577 return bus_log_parse_error(r
);
3580 printf("%s=[unprintable]\n", name
);
3586 static int show_one(
3590 bool show_properties
,
3594 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3595 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3596 UnitStatusInfo info
= {};
3603 log_debug("Showing one %s", path
);
3605 r
= sd_bus_call_method(
3607 "org.freedesktop.systemd1",
3609 "org.freedesktop.DBus.Properties",
3615 log_error("Failed to get properties: %s", bus_error_message(&error
, r
));
3619 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
3621 return bus_log_parse_error(r
);
3628 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
3629 const char *name
, *contents
;
3631 r
= sd_bus_message_read(reply
, "s", &name
);
3633 return bus_log_parse_error(r
);
3635 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
3637 return bus_log_parse_error(r
);
3639 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
3641 return bus_log_parse_error(r
);
3643 if (show_properties
)
3644 r
= print_property(name
, reply
, contents
);
3646 r
= status_property(name
, reply
, &info
, contents
);
3650 r
= sd_bus_message_exit_container(reply
);
3652 return bus_log_parse_error(r
);
3654 r
= sd_bus_message_exit_container(reply
);
3656 return bus_log_parse_error(r
);
3659 return bus_log_parse_error(r
);
3661 r
= sd_bus_message_exit_container(reply
);
3663 return bus_log_parse_error(r
);
3667 if (!show_properties
) {
3668 if (streq(verb
, "help"))
3669 show_unit_help(&info
);
3671 print_status_info(&info
, ellipsized
);
3674 strv_free(info
.documentation
);
3675 strv_free(info
.dropin_paths
);
3676 strv_free(info
.listen
);
3678 if (!streq_ptr(info
.active_state
, "active") &&
3679 !streq_ptr(info
.active_state
, "reloading") &&
3680 streq(verb
, "status")) {
3681 /* According to LSB: "program not running" */
3682 /* 0: program is running or service is OK
3683 * 1: program is dead and /var/run pid file exists
3684 * 2: program is dead and /var/lock lock file exists
3685 * 3: program is not running
3686 * 4: program or service status is unknown
3688 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
3694 while ((p
= info
.exec
)) {
3695 LIST_REMOVE(exec
, info
.exec
, p
);
3696 exec_status_info_free(p
);
3702 static int get_unit_dbus_path_by_pid(
3707 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3708 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3712 r
= sd_bus_call_method(
3714 "org.freedesktop.systemd1",
3715 "/org/freedesktop/systemd1",
3716 "org.freedesktop.systemd1.Manager",
3722 log_error("Failed to get unit for PID %lu: %s", (unsigned long) pid
, bus_error_message(&error
, r
));
3726 r
= sd_bus_message_read(reply
, "o", &u
);
3728 return bus_log_parse_error(r
);
3738 static int show_all(
3741 bool show_properties
,
3745 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
3746 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
3751 r
= get_unit_list(bus
, &reply
, &unit_infos
, NULL
);
3755 pager_open_if_enabled();
3759 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
3761 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
3762 _cleanup_free_
char *p
= NULL
;
3764 p
= unit_dbus_path_from_name(u
->id
);
3768 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
3776 static int cat(sd_bus
*bus
, char **args
) {
3777 _cleanup_free_
char *unit
= NULL
;
3778 _cleanup_strv_free_
char **names
= NULL
;
3786 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
3788 log_error("Failed to expand names: %s", strerror(-r
));
3790 pager_open_if_enabled();
3792 STRV_FOREACH(name
, names
) {
3793 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3794 _cleanup_strv_free_
char **dropin_paths
= NULL
;
3795 _cleanup_free_
char *fragment_path
= NULL
;
3798 unit
= unit_dbus_path_from_name(*name
);
3802 if (need_daemon_reload(bus
, *name
) > 0)
3803 log_warning("Unit file of %s changed on disk. Run 'systemctl%s daemon-reload'.",
3804 *name
, arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
3806 r
= sd_bus_get_property_string(
3808 "org.freedesktop.systemd1",
3810 "org.freedesktop.systemd1.Unit",
3815 log_warning("Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
3819 r
= sd_bus_get_property_strv(
3821 "org.freedesktop.systemd1",
3823 "org.freedesktop.systemd1.Unit",
3828 log_warning("Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
3837 if (!isempty(fragment_path
)) {
3838 printf("%s# %s%s\n",
3839 ansi_highlight_blue(),
3841 ansi_highlight_off());
3844 r
= sendfile_full(STDOUT_FILENO
, fragment_path
);
3846 log_warning("Failed to cat %s: %s", fragment_path
, strerror(-r
));
3851 STRV_FOREACH(path
, dropin_paths
) {
3852 printf("%s%s# %s%s\n",
3853 isempty(fragment_path
) && path
== dropin_paths
? "" : "\n",
3854 ansi_highlight_blue(),
3856 ansi_highlight_off());
3859 r
= sendfile_full(STDOUT_FILENO
, *path
);
3861 log_warning("Failed to cat %s: %s", *path
, strerror(-r
));
3867 return r
< 0 ? r
: 0;
3870 static int show(sd_bus
*bus
, char **args
) {
3871 bool show_properties
, show_status
, new_line
= false;
3872 bool ellipsized
= false;
3878 show_properties
= streq(args
[0], "show");
3879 show_status
= streq(args
[0], "status");
3881 if (show_properties
)
3882 pager_open_if_enabled();
3884 /* If no argument is specified inspect the manager itself */
3886 if (show_properties
&& strv_length(args
) <= 1)
3887 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
3889 if (show_status
&& strv_length(args
) <= 1)
3890 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
3892 _cleanup_free_
char **patterns
= NULL
;
3895 STRV_FOREACH(name
, args
+ 1) {
3896 _cleanup_free_
char *unit
= NULL
;
3899 if (safe_atou32(*name
, &id
) < 0) {
3900 if (strv_push(&patterns
, *name
) < 0)
3904 } else if (show_properties
) {
3905 /* Interpret as job id */
3906 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
3910 /* Interpret as PID */
3911 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
3918 show_one(args
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
3921 if (!strv_isempty(patterns
)) {
3922 _cleanup_strv_free_
char **names
= NULL
;
3924 r
= expand_names(bus
, patterns
, NULL
, &names
);
3926 log_error("Failed to expand names: %s", strerror(-r
));
3928 STRV_FOREACH(name
, names
) {
3929 _cleanup_free_
char *unit
;
3931 unit
= unit_dbus_path_from_name(*name
);
3935 show_one(args
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
3940 if (ellipsized
&& !arg_quiet
)
3941 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
3946 static int append_assignment(sd_bus_message
*m
, const char *assignment
) {
3954 eq
= strchr(assignment
, '=');
3956 log_error("Not an assignment: %s", assignment
);
3960 field
= strndupa(assignment
, eq
- assignment
);
3963 r
= sd_bus_message_append_basic(m
, SD_BUS_TYPE_STRING
, field
);
3965 return bus_log_create_error(r
);
3967 if (streq(field
, "CPUAccounting") ||
3968 streq(field
, "MemoryAccounting") ||
3969 streq(field
, "BlockIOAccounting")) {
3971 r
= parse_boolean(eq
);
3973 log_error("Failed to parse boolean assignment %s.", assignment
);
3977 r
= sd_bus_message_append(m
, "v", "b", r
);
3979 } else if (streq(field
, "MemoryLimit")) {
3982 r
= parse_bytes(eq
, &bytes
);
3984 log_error("Failed to parse bytes specification %s", assignment
);
3988 r
= sd_bus_message_append(m
, "v", "t", (uint64_t) bytes
);
3990 } else if (streq(field
, "CPUShares") || streq(field
, "BlockIOWeight")) {
3993 r
= safe_atou64(eq
, &u
);
3995 log_error("Failed to parse %s value %s.", field
, eq
);
3999 r
= sd_bus_message_append(m
, "v", "t", u
);
4001 } else if (streq(field
, "DevicePolicy"))
4002 r
= sd_bus_message_append(m
, "v", "s", eq
);
4004 else if (streq(field
, "DeviceAllow")) {
4007 r
= sd_bus_message_append(m
, "v", "a(ss)", 0);
4009 const char *path
, *rwm
;
4012 e
= strchr(eq
, ' ');
4014 path
= strndupa(eq
, e
- eq
);
4021 if (!path_startswith(path
, "/dev")) {
4022 log_error("%s is not a device file in /dev.", path
);
4026 r
= sd_bus_message_append(m
, "v", "a(ss)", 1, path
, rwm
);
4029 } else if (streq(field
, "BlockIOReadBandwidth") || streq(field
, "BlockIOWriteBandwidth")) {
4032 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
4034 const char *path
, *bandwidth
;
4038 e
= strchr(eq
, ' ');
4040 path
= strndupa(eq
, e
- eq
);
4043 log_error("Failed to parse %s value %s.", field
, eq
);
4047 if (!path_startswith(path
, "/dev")) {
4048 log_error("%s is not a device file in /dev.", path
);
4052 r
= parse_bytes(bandwidth
, &bytes
);
4054 log_error("Failed to parse byte value %s.", bandwidth
);
4058 r
= sd_bus_message_append(m
, "v", "a(st)", 1, path
, (uint64_t) bytes
);
4061 } else if (streq(field
, "BlockIODeviceWeight")) {
4064 r
= sd_bus_message_append(m
, "v", "a(st)", 0);
4066 const char *path
, *weight
;
4070 e
= strchr(eq
, ' ');
4072 path
= strndupa(eq
, e
- eq
);
4075 log_error("Failed to parse %s value %s.", field
, eq
);
4079 if (!path_startswith(path
, "/dev")) {
4080 log_error("%s is not a device file in /dev.", path
);
4084 r
= safe_atou64(weight
, &u
);
4086 log_error("Failed to parse %s value %s.", field
, weight
);
4089 r
= sd_bus_message_append(m
, "v", "a(st)", path
, u
);
4093 log_error("Unknown assignment %s.", assignment
);
4098 return bus_log_create_error(r
);
4103 static int set_property(sd_bus
*bus
, char **args
) {
4104 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4105 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4106 _cleanup_free_
char *n
= NULL
;
4110 r
= sd_bus_message_new_method_call(
4112 "org.freedesktop.systemd1",
4113 "/org/freedesktop/systemd1",
4114 "org.freedesktop.systemd1.Manager",
4115 "SetUnitProperties",
4118 return bus_log_create_error(r
);
4120 n
= unit_name_mangle(args
[1], false);
4124 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4126 return bus_log_create_error(r
);
4128 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4130 return bus_log_create_error(r
);
4132 STRV_FOREACH(i
, args
+ 2) {
4133 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4135 return bus_log_create_error(r
);
4137 r
= append_assignment(m
, *i
);
4141 r
= sd_bus_message_close_container(m
);
4143 return bus_log_create_error(r
);
4146 r
= sd_bus_message_close_container(m
);
4148 return bus_log_create_error(r
);
4150 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4152 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4159 static int snapshot(sd_bus
*bus
, char **args
) {
4160 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4161 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4162 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4166 if (strv_length(args
) > 1)
4167 n
= unit_name_mangle_with_suffix(args
[1], false, ".snapshot");
4173 r
= sd_bus_call_method(
4175 "org.freedesktop.systemd1",
4176 "/org/freedesktop/systemd1",
4177 "org.freedesktop.systemd1.Manager",
4183 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
4187 r
= sd_bus_message_read(reply
, "o", &path
);
4189 return bus_log_parse_error(r
);
4191 r
= sd_bus_get_property_string(
4193 "org.freedesktop.systemd1",
4195 "org.freedesktop.systemd1.Unit",
4200 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4210 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4211 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4212 _cleanup_strv_free_
char **names
= NULL
;
4218 r
= expand_names(bus
, args
+ 1, ".snapshot", &names
);
4220 log_error("Failed to expand names: %s", strerror(-r
));
4222 STRV_FOREACH(name
, names
) {
4223 q
= sd_bus_call_method(
4225 "org.freedesktop.systemd1",
4226 "/org/freedesktop/systemd1",
4227 "org.freedesktop.systemd1.Manager",
4233 log_error("Failed to remove snapshot %s: %s",
4234 *name
, bus_error_message(&error
, r
));
4243 static int daemon_reload(sd_bus
*bus
, char **args
) {
4244 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4248 if (arg_action
== ACTION_RELOAD
)
4250 else if (arg_action
== ACTION_REEXEC
)
4251 method
= "Reexecute";
4253 assert(arg_action
== ACTION_SYSTEMCTL
);
4256 streq(args
[0], "clear-jobs") ||
4257 streq(args
[0], "cancel") ? "ClearJobs" :
4258 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4259 streq(args
[0], "reset-failed") ? "ResetFailed" :
4260 streq(args
[0], "halt") ? "Halt" :
4261 streq(args
[0], "poweroff") ? "PowerOff" :
4262 streq(args
[0], "reboot") ? "Reboot" :
4263 streq(args
[0], "kexec") ? "KExec" :
4264 streq(args
[0], "exit") ? "Exit" :
4265 /* "daemon-reload" */ "Reload";
4268 r
= sd_bus_call_method(
4270 "org.freedesktop.systemd1",
4271 "/org/freedesktop/systemd1",
4272 "org.freedesktop.systemd1.Manager",
4278 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4279 /* There's always a fallback possible for
4280 * legacy actions. */
4282 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4283 /* On reexecution, we expect a disconnect, not a
4287 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4289 return r
< 0 ? r
: 0;
4292 static int reset_failed(sd_bus
*bus
, char **args
) {
4293 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4294 _cleanup_strv_free_
char **names
= NULL
;
4298 if (strv_length(args
) <= 1)
4299 return daemon_reload(bus
, args
);
4301 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4303 log_error("Failed to expand names: %s", strerror(-r
));
4305 STRV_FOREACH(name
, names
) {
4306 q
= sd_bus_call_method(
4308 "org.freedesktop.systemd1",
4309 "/org/freedesktop/systemd1",
4310 "org.freedesktop.systemd1.Manager",
4316 log_error("Failed to reset failed state of unit %s: %s",
4317 *name
, bus_error_message(&error
, r
));
4326 static int show_environment(sd_bus
*bus
, char **args
) {
4327 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4328 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4332 pager_open_if_enabled();
4334 r
= sd_bus_get_property(
4336 "org.freedesktop.systemd1",
4337 "/org/freedesktop/systemd1",
4338 "org.freedesktop.systemd1.Manager",
4344 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
4348 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
4350 return bus_log_parse_error(r
);
4352 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
4355 return bus_log_parse_error(r
);
4357 r
= sd_bus_message_exit_container(reply
);
4359 return bus_log_parse_error(r
);
4364 static int switch_root(sd_bus
*bus
, char **args
) {
4365 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4366 _cleanup_free_
char *init
= NULL
;
4371 l
= strv_length(args
);
4372 if (l
< 2 || l
> 3) {
4373 log_error("Wrong number of arguments.");
4380 init
= strdup(args
[2]);
4382 parse_env_file("/proc/cmdline", WHITESPACE
,
4393 log_debug("switching root - root: %s; init: %s", root
, init
);
4395 r
= sd_bus_call_method(
4397 "org.freedesktop.systemd1",
4398 "/org/freedesktop/systemd1",
4399 "org.freedesktop.systemd1.Manager",
4405 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
4412 static int set_environment(sd_bus
*bus
, char **args
) {
4413 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4414 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4421 method
= streq(args
[0], "set-environment")
4423 : "UnsetEnvironment";
4425 r
= sd_bus_message_new_method_call(
4427 "org.freedesktop.systemd1",
4428 "/org/freedesktop/systemd1",
4429 "org.freedesktop.systemd1.Manager",
4433 return bus_log_create_error(r
);
4435 r
= sd_bus_message_append_strv(m
, args
+ 1);
4437 return bus_log_create_error(r
);
4439 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4441 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
4448 static int enable_sysv_units(const char *verb
, char **args
) {
4451 #if defined(HAVE_SYSV_COMPAT) && defined(HAVE_CHKCONFIG)
4452 unsigned f
= 1, t
= 1;
4453 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
4455 if (arg_scope
!= UNIT_FILE_SYSTEM
)
4458 if (!streq(verb
, "enable") &&
4459 !streq(verb
, "disable") &&
4460 !streq(verb
, "is-enabled"))
4463 /* Processes all SysV units, and reshuffles the array so that
4464 * afterwards only the native units remain */
4466 r
= lookup_paths_init(&paths
, SYSTEMD_SYSTEM
, false, NULL
, NULL
, NULL
);
4471 for (f
= 0; args
[f
]; f
++) {
4473 _cleanup_free_
char *p
= NULL
, *q
= NULL
;
4474 bool found_native
= false, found_sysv
;
4476 const char *argv
[6] = { "/sbin/chkconfig", NULL
, NULL
, NULL
, NULL
};
4484 if (!endswith(name
, ".service"))
4487 if (path_is_absolute(name
))
4490 STRV_FOREACH(k
, paths
.unit_path
) {
4491 if (!isempty(arg_root
))
4492 asprintf(&p
, "%s/%s/%s", arg_root
, *k
, name
);
4494 asprintf(&p
, "%s/%s", *k
, name
);
4501 found_native
= access(p
, F_OK
) >= 0;
4512 if (!isempty(arg_root
))
4513 asprintf(&p
, "%s/" SYSTEM_SYSVINIT_PATH
"/%s", arg_root
, name
);
4515 asprintf(&p
, SYSTEM_SYSVINIT_PATH
"/%s", name
);
4521 p
[strlen(p
) - sizeof(".service") + 1] = 0;
4522 found_sysv
= access(p
, F_OK
) >= 0;
4527 /* Mark this entry, so that we don't try enabling it as native unit */
4528 args
[f
] = (char*) "";
4530 log_info("%s is not a native service, redirecting to /sbin/chkconfig.", name
);
4532 if (!isempty(arg_root
))
4533 argv
[c
++] = q
= strappend("--root=", arg_root
);
4535 argv
[c
++] = basename(p
);
4537 streq(verb
, "enable") ? "on" :
4538 streq(verb
, "disable") ? "off" : "--level=5";
4541 l
= strv_join((char**)argv
, " ");
4547 log_info("Executing %s", l
);
4552 log_error("Failed to fork: %m");
4555 } else if (pid
== 0) {
4558 execv(argv
[0], (char**) argv
);
4559 _exit(EXIT_FAILURE
);
4562 j
= wait_for_terminate(pid
, &status
);
4564 log_error("Failed to wait for child: %s", strerror(-r
));
4569 if (status
.si_code
== CLD_EXITED
) {
4570 if (streq(verb
, "is-enabled")) {
4571 if (status
.si_status
== 0) {
4580 } else if (status
.si_status
!= 0) {
4591 /* Drop all SysV units */
4592 for (f
= 0, t
= 0; args
[f
]; f
++) {
4594 if (isempty(args
[f
]))
4597 args
[t
++] = args
[f
];
4606 static int mangle_names(char **original_names
, char ***mangled_names
) {
4607 char **i
, **l
, **name
;
4609 l
= new(char*, strv_length(original_names
) + 1);
4614 STRV_FOREACH(name
, original_names
) {
4616 /* When enabling units qualified path names are OK,
4617 * too, hence allow them explicitly. */
4622 *i
= unit_name_mangle(*name
, false);
4638 static int enable_unit(sd_bus
*bus
, char **args
) {
4639 _cleanup_strv_free_
char **names
= NULL
;
4640 const char *verb
= args
[0];
4641 UnitFileChange
*changes
= NULL
;
4642 unsigned n_changes
= 0;
4643 int carries_install_info
= -1;
4649 r
= mangle_names(args
+1, &names
);
4653 r
= enable_sysv_units(verb
, names
);
4657 if (!bus
|| avoid_bus()) {
4658 if (streq(verb
, "enable")) {
4659 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
4660 carries_install_info
= r
;
4661 } else if (streq(verb
, "disable"))
4662 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
4663 else if (streq(verb
, "reenable")) {
4664 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
4665 carries_install_info
= r
;
4666 } else if (streq(verb
, "link"))
4667 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
4668 else if (streq(verb
, "preset")) {
4669 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
4670 carries_install_info
= r
;
4671 } else if (streq(verb
, "mask"))
4672 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
4673 else if (streq(verb
, "unmask"))
4674 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
4676 assert_not_reached("Unknown verb");
4679 log_error("Operation failed: %s", strerror(-r
));
4684 dump_unit_file_changes(changes
, n_changes
);
4688 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
4689 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4690 int expect_carries_install_info
= false;
4691 bool send_force
= true;
4694 if (streq(verb
, "enable")) {
4695 method
= "EnableUnitFiles";
4696 expect_carries_install_info
= true;
4697 } else if (streq(verb
, "disable")) {
4698 method
= "DisableUnitFiles";
4700 } else if (streq(verb
, "reenable")) {
4701 method
= "ReenableUnitFiles";
4702 expect_carries_install_info
= true;
4703 } else if (streq(verb
, "link"))
4704 method
= "LinkUnitFiles";
4705 else if (streq(verb
, "preset")) {
4706 method
= "PresetUnitFiles";
4707 expect_carries_install_info
= true;
4708 } else if (streq(verb
, "mask"))
4709 method
= "MaskUnitFiles";
4710 else if (streq(verb
, "unmask")) {
4711 method
= "UnmaskUnitFiles";
4714 assert_not_reached("Unknown verb");
4716 r
= sd_bus_message_new_method_call(
4718 "org.freedesktop.systemd1",
4719 "/org/freedesktop/systemd1",
4720 "org.freedesktop.systemd1.Manager",
4724 return bus_log_create_error(r
);
4726 r
= sd_bus_message_append_strv(m
, names
);
4728 return bus_log_create_error(r
);
4730 r
= sd_bus_message_append(m
, "b", arg_runtime
);
4732 return bus_log_create_error(r
);
4735 r
= sd_bus_message_append(m
, "b", arg_force
);
4737 return bus_log_create_error(r
);
4740 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
4742 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4746 if (expect_carries_install_info
) {
4747 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
4749 return bus_log_parse_error(r
);
4752 r
= deserialize_and_dump_unit_file_changes(reply
);
4756 /* Try to reload if enabeld */
4758 r
= daemon_reload(bus
, args
);
4763 if (carries_install_info
== 0)
4764 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
4765 "using systemctl.\n"
4766 "Possible reasons for having this kind of units are:\n"
4767 "1) A unit may be statically enabled by being symlinked from another unit's\n"
4768 " .wants/ or .requires/ directory.\n"
4769 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
4770 " a requirement dependency on it.\n"
4771 "3) A unit may be started when needed via activation (socket, path, timer,\n"
4772 " D-Bus, udev, scripted systemctl call, ...).\n");
4775 unit_file_changes_free(changes
, n_changes
);
4780 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
4782 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4783 _cleanup_strv_free_
char **names
= NULL
;
4788 r
= mangle_names(args
+1, &names
);
4792 r
= enable_sysv_units(args
[0], names
);
4798 if (!bus
|| avoid_bus()) {
4800 STRV_FOREACH(name
, names
) {
4801 UnitFileState state
;
4803 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
4805 log_error("Failed to get unit file state for %s: %s", *name
, strerror(-state
));
4809 if (state
== UNIT_FILE_ENABLED
||
4810 state
== UNIT_FILE_ENABLED_RUNTIME
||
4811 state
== UNIT_FILE_STATIC
)
4815 puts(unit_file_state_to_string(state
));
4819 STRV_FOREACH(name
, names
) {
4820 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4823 r
= sd_bus_call_method(
4825 "org.freedesktop.systemd1",
4826 "/org/freedesktop/systemd1",
4827 "org.freedesktop.systemd1.Manager",
4833 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
4837 r
= sd_bus_message_read(reply
, "s", &s
);
4839 return bus_log_parse_error(r
);
4841 if (streq(s
, "enabled") ||
4842 streq(s
, "enabled-runtime") ||
4854 static int systemctl_help(void) {
4856 pager_open_if_enabled();
4858 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
4859 "Query or send control commands to the systemd manager.\n\n"
4860 " -h --help Show this help\n"
4861 " --version Show package version\n"
4862 " --system Connect to system manager\n"
4863 " --user Connect to user service manager\n"
4864 " -H --host=[USER@]HOST\n"
4865 " Operate on remote host\n"
4866 " -M --machine=CONTAINER\n"
4867 " Operate on local container\n"
4868 " -t --type=TYPE List only units of a particular type\n"
4869 " --state=STATE List only units with particular LOAD or SUB or ACTIVE state\n"
4870 " -p --property=NAME Show only properties by this name\n"
4871 " -a --all Show all loaded units/properties, including dead/empty\n"
4872 " ones. To list all units installed on the system, use\n"
4873 " the 'list-unit-files' command instead.\n"
4874 " -l --full Don't ellipsize unit names on output\n"
4875 " --reverse Show reverse dependencies with 'list-dependencies'\n"
4876 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
4877 " queueing a new job\n"
4878 " --show-types When showing sockets, explicitly show their type\n"
4879 " -i --ignore-inhibitors\n"
4880 " When shutting down or sleeping, ignore inhibitors\n"
4881 " --kill-who=WHO Who to send signal to\n"
4882 " -s --signal=SIGNAL Which signal to send\n"
4883 " -q --quiet Suppress output\n"
4884 " --no-block Do not wait until operation finished\n"
4885 " --no-wall Don't send wall message before halt/power-off/reboot\n"
4886 " --no-reload When enabling/disabling unit files, don't reload daemon\n"
4888 " --no-legend Do not print a legend (column headers and hints)\n"
4889 " --no-pager Do not pipe output into a pager\n"
4890 " --no-ask-password\n"
4891 " Do not ask for system passwords\n"
4892 " --global Enable/disable unit files globally\n"
4893 " --runtime Enable unit files only temporarily until next reboot\n"
4894 " -f --force When enabling unit files, override existing symlinks\n"
4895 " When shutting down, execute action immediately\n"
4896 " --root=PATH Enable unit files in the specified root directory\n"
4897 " -n --lines=INTEGER Number of journal entries to show\n"
4898 " -o --output=STRING Change journal output mode (short, short-monotonic,\n"
4899 " verbose, export, json, json-pretty, json-sse, cat)\n"
4900 " --plain Print unit dependencies as a list instead of a tree\n\n"
4902 " list-units [PATTERN...] List loaded units\n"
4903 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
4904 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
4905 " start NAME... Start (activate) one or more units\n"
4906 " stop NAME... Stop (deactivate) one or more units\n"
4907 " reload NAME... Reload one or more units\n"
4908 " restart NAME... Start or restart one or more units\n"
4909 " try-restart NAME... Restart one or more units if active\n"
4910 " reload-or-restart NAME... Reload one or more units if possible,\n"
4911 " otherwise start or restart\n"
4912 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
4913 " otherwise restart if active\n"
4914 " isolate NAME Start one unit and stop all others\n"
4915 " kill NAME... Send signal to processes of a unit\n"
4916 " is-active NAME... Check whether units are active\n"
4917 " is-failed NAME... Check whether units are failed\n"
4918 " status [NAME...|PID...] Show runtime status of one or more units\n"
4919 " show [NAME...|JOB...] Show properties of one or more\n"
4920 " units/jobs or the manager\n"
4921 " cat NAME... Show files and drop-ins of one or more units\n"
4922 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
4923 " help NAME...|PID... Show manual for one or more units\n"
4924 " reset-failed [NAME...] Reset failed state for all, one, or more\n"
4926 " list-dependencies [NAME] Recursively show units which are required\n"
4927 " or wanted by this unit or by which this\n"
4928 " unit is required or wanted\n\n"
4929 "Unit File Commands:\n"
4930 " list-unit-files [PATTERN...] List installed unit files\n"
4931 " enable NAME... Enable one or more unit files\n"
4932 " disable NAME... Disable one or more unit files\n"
4933 " reenable NAME... Reenable one or more unit files\n"
4934 " preset NAME... Enable/disable one or more unit files\n"
4935 " based on preset configuration\n"
4936 " is-enabled NAME... Check whether unit files are enabled\n\n"
4937 " mask NAME... Mask one or more units\n"
4938 " unmask NAME... Unmask one or more units\n"
4939 " link PATH... Link one or more units files into\n"
4940 " the search path\n"
4941 " get-default Get the name of the default target\n"
4942 " set-default NAME Set the default target\n\n"
4944 " list-jobs [PATTERN...] List jobs\n"
4945 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
4946 "Snapshot Commands:\n"
4947 " snapshot [NAME] Create a snapshot\n"
4948 " delete NAME... Remove one or more snapshots\n\n"
4949 "Environment Commands:\n"
4950 " show-environment Dump environment\n"
4951 " set-environment NAME=VALUE... Set one or more environment variables\n"
4952 " unset-environment NAME... Unset one or more environment variables\n\n"
4953 "Manager Lifecycle Commands:\n"
4954 " daemon-reload Reload systemd manager configuration\n"
4955 " daemon-reexec Reexecute systemd manager\n\n"
4956 "System Commands:\n"
4957 " default Enter system default mode\n"
4958 " rescue Enter system rescue mode\n"
4959 " emergency Enter system emergency mode\n"
4960 " halt Shut down and halt the system\n"
4961 " poweroff Shut down and power-off the system\n"
4962 " reboot [ARG] Shut down and reboot the system\n"
4963 " kexec Shut down and reboot the system with kexec\n"
4964 " exit Request user instance exit\n"
4965 " switch-root ROOT [INIT] Change to a different root file system\n"
4966 " suspend Suspend the system\n"
4967 " hibernate Hibernate the system\n"
4968 " hybrid-sleep Hibernate and suspend the system\n",
4969 program_invocation_short_name
);
4974 static int halt_help(void) {
4976 printf("%s [OPTIONS...]%s\n\n"
4977 "%s the system.\n\n"
4978 " --help Show this help\n"
4979 " --halt Halt the machine\n"
4980 " -p --poweroff Switch off the machine\n"
4981 " --reboot Reboot the machine\n"
4982 " -f --force Force immediate halt/power-off/reboot\n"
4983 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
4984 " -d --no-wtmp Don't write wtmp record\n"
4985 " --no-wall Don't send wall message before halt/power-off/reboot\n",
4986 program_invocation_short_name
,
4987 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
4988 arg_action
== ACTION_REBOOT
? "Reboot" :
4989 arg_action
== ACTION_POWEROFF
? "Power off" :
4995 static int shutdown_help(void) {
4997 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
4998 "Shut down the system.\n\n"
4999 " --help Show this help\n"
5000 " -H --halt Halt the machine\n"
5001 " -P --poweroff Power-off the machine\n"
5002 " -r --reboot Reboot the machine\n"
5003 " -h Equivalent to --poweroff, overridden by --halt\n"
5004 " -k Don't halt/power-off/reboot, just send warnings\n"
5005 " --no-wall Don't send wall message before halt/power-off/reboot\n"
5006 " -c Cancel a pending shutdown\n",
5007 program_invocation_short_name
);
5012 static int telinit_help(void) {
5014 printf("%s [OPTIONS...] {COMMAND}\n\n"
5015 "Send control commands to the init daemon.\n\n"
5016 " --help Show this help\n"
5017 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
5019 " 0 Power-off the machine\n"
5020 " 6 Reboot the machine\n"
5021 " 2, 3, 4, 5 Start runlevelX.target unit\n"
5022 " 1, s, S Enter rescue mode\n"
5023 " q, Q Reload init daemon configuration\n"
5024 " u, U Reexecute init daemon\n",
5025 program_invocation_short_name
);
5030 static int runlevel_help(void) {
5032 printf("%s [OPTIONS...]\n\n"
5033 "Prints the previous and current runlevel of the init system.\n\n"
5034 " --help Show this help\n",
5035 program_invocation_short_name
);
5040 static int help_types(void) {
5044 puts("Available unit types:");
5045 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
5046 t
= unit_type_to_string(i
);
5054 static int systemctl_parse_argv(int argc
, char *argv
[]) {
5063 ARG_IGNORE_DEPENDENCIES
,
5075 ARG_NO_ASK_PASSWORD
,
5084 static const struct option options
[] = {
5085 { "help", no_argument
, NULL
, 'h' },
5086 { "version", no_argument
, NULL
, ARG_VERSION
},
5087 { "type", required_argument
, NULL
, 't' },
5088 { "property", required_argument
, NULL
, 'p' },
5089 { "all", no_argument
, NULL
, 'a' },
5090 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
5091 { "after", no_argument
, NULL
, ARG_AFTER
},
5092 { "before", no_argument
, NULL
, ARG_BEFORE
},
5093 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
5094 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
5095 { "full", no_argument
, NULL
, 'l' },
5096 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
5097 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
5098 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
5099 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
5100 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
5101 { "user", no_argument
, NULL
, ARG_USER
},
5102 { "system", no_argument
, NULL
, ARG_SYSTEM
},
5103 { "global", no_argument
, NULL
, ARG_GLOBAL
},
5104 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
5105 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
5106 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
5107 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5108 { "quiet", no_argument
, NULL
, 'q' },
5109 { "root", required_argument
, NULL
, ARG_ROOT
},
5110 { "force", no_argument
, NULL
, ARG_FORCE
},
5111 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
5112 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
5113 { "signal", required_argument
, NULL
, 's' },
5114 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
5115 { "host", required_argument
, NULL
, 'H' },
5116 { "machine", required_argument
, NULL
, 'M' },
5117 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
5118 { "lines", required_argument
, NULL
, 'n' },
5119 { "output", required_argument
, NULL
, 'o' },
5120 { "plain", no_argument
, NULL
, ARG_PLAIN
},
5121 { "state", required_argument
, NULL
, ARG_STATE
},
5130 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:i", options
, NULL
)) >= 0) {
5135 return systemctl_help();
5138 puts(PACKAGE_STRING
);
5139 puts(SYSTEMD_FEATURES
);
5146 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
5147 _cleanup_free_
char *type
;
5149 type
= strndup(word
, size
);
5153 if (streq(type
, "help")) {
5158 if (unit_type_from_string(type
) >= 0) {
5159 if (strv_push(&arg_types
, type
))
5165 /* It's much nicer to use --state= for
5166 * load states, but let's support this
5167 * in --types= too for compatibility
5168 * with old versions */
5169 if (unit_load_state_from_string(optarg
) >= 0) {
5170 if (strv_push(&arg_states
, type
) < 0)
5176 log_error("Unknown unit type or load state '%s'.", type
);
5177 log_info("Use -t help to see a list of allowed values.");
5185 /* Make sure that if the empty property list
5186 was specified, we won't show any properties. */
5187 if (isempty(optarg
) && !arg_properties
) {
5188 arg_properties
= new0(char*, 1);
5189 if (!arg_properties
)
5195 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
5198 prop
= strndup(word
, size
);
5202 if (strv_push(&arg_properties
, prop
) < 0) {
5209 /* If the user asked for a particular
5210 * property, show it to him, even if it is
5222 arg_dependency
= DEPENDENCY_REVERSE
;
5226 arg_dependency
= DEPENDENCY_AFTER
;
5230 arg_dependency
= DEPENDENCY_BEFORE
;
5233 case ARG_SHOW_TYPES
:
5234 arg_show_types
= true;
5238 arg_job_mode
= optarg
;
5242 arg_job_mode
= "fail";
5245 case ARG_IRREVERSIBLE
:
5246 arg_job_mode
= "replace-irreversibly";
5249 case ARG_IGNORE_DEPENDENCIES
:
5250 arg_job_mode
= "ignore-dependencies";
5254 arg_scope
= UNIT_FILE_USER
;
5258 arg_scope
= UNIT_FILE_SYSTEM
;
5262 arg_scope
= UNIT_FILE_GLOBAL
;
5266 arg_no_block
= true;
5270 arg_no_legend
= true;
5274 arg_no_pager
= true;
5290 if (strv_extend(&arg_states
, "failed") < 0)
5308 arg_no_reload
= true;
5312 arg_kill_who
= optarg
;
5316 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
5317 log_error("Failed to parse signal string %s.", optarg
);
5322 case ARG_NO_ASK_PASSWORD
:
5323 arg_ask_password
= false;
5327 arg_transport
= BUS_TRANSPORT_REMOTE
;
5332 arg_transport
= BUS_TRANSPORT_CONTAINER
;
5341 if (safe_atou(optarg
, &arg_lines
) < 0) {
5342 log_error("Failed to parse lines '%s'", optarg
);
5348 arg_output
= output_mode_from_string(optarg
);
5349 if (arg_output
< 0) {
5350 log_error("Unknown output '%s'.", optarg
);
5356 arg_ignore_inhibitors
= true;
5367 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
5370 s
= strndup(word
, size
);
5374 if (strv_push(&arg_states
, s
) < 0) {
5386 assert_not_reached("Unhandled option");
5390 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
5391 log_error("Cannot access user instance remotely.");
5398 static int halt_parse_argv(int argc
, char *argv
[]) {
5407 static const struct option options
[] = {
5408 { "help", no_argument
, NULL
, ARG_HELP
},
5409 { "halt", no_argument
, NULL
, ARG_HALT
},
5410 { "poweroff", no_argument
, NULL
, 'p' },
5411 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
5412 { "force", no_argument
, NULL
, 'f' },
5413 { "wtmp-only", no_argument
, NULL
, 'w' },
5414 { "no-wtmp", no_argument
, NULL
, 'd' },
5415 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5424 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
5425 if (runlevel
== '0' || runlevel
== '6')
5428 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0) {
5435 arg_action
= ACTION_HALT
;
5439 if (arg_action
!= ACTION_REBOOT
)
5440 arg_action
= ACTION_POWEROFF
;
5444 arg_action
= ACTION_REBOOT
;
5466 /* Compatibility nops */
5473 assert_not_reached("Unhandled option");
5477 if (arg_action
== ACTION_REBOOT
&& argc
== optind
+ 1) {
5478 r
= write_string_file(REBOOT_PARAM_FILE
, argv
[optind
]);
5480 log_error("Failed to write reboot param to "
5481 REBOOT_PARAM_FILE
": %s", strerror(-r
));
5484 } else if (optind
< argc
) {
5485 log_error("Too many arguments.");
5492 static int parse_time_spec(const char *t
, usec_t
*_u
) {
5496 if (streq(t
, "now"))
5498 else if (!strchr(t
, ':')) {
5501 if (safe_atou64(t
, &u
) < 0)
5504 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
5513 hour
= strtol(t
, &e
, 10);
5514 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
5517 minute
= strtol(e
+1, &e
, 10);
5518 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
5521 n
= now(CLOCK_REALTIME
);
5522 s
= (time_t) (n
/ USEC_PER_SEC
);
5524 assert_se(localtime_r(&s
, &tm
));
5526 tm
.tm_hour
= (int) hour
;
5527 tm
.tm_min
= (int) minute
;
5530 assert_se(s
= mktime(&tm
));
5532 *_u
= (usec_t
) s
* USEC_PER_SEC
;
5535 *_u
+= USEC_PER_DAY
;
5541 static int shutdown_parse_argv(int argc
, char *argv
[]) {
5548 static const struct option options
[] = {
5549 { "help", no_argument
, NULL
, ARG_HELP
},
5550 { "halt", no_argument
, NULL
, 'H' },
5551 { "poweroff", no_argument
, NULL
, 'P' },
5552 { "reboot", no_argument
, NULL
, 'r' },
5553 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
5554 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5563 while ((c
= getopt_long(argc
, argv
, "HPrhkt:afFc", options
, NULL
)) >= 0) {
5567 return shutdown_help();
5570 arg_action
= ACTION_HALT
;
5574 arg_action
= ACTION_POWEROFF
;
5579 arg_action
= ACTION_KEXEC
;
5581 arg_action
= ACTION_REBOOT
;
5585 arg_action
= ACTION_KEXEC
;
5589 if (arg_action
!= ACTION_HALT
)
5590 arg_action
= ACTION_POWEROFF
;
5603 /* Compatibility nops */
5607 arg_action
= ACTION_CANCEL_SHUTDOWN
;
5614 assert_not_reached("Unhandled option");
5618 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
5619 r
= parse_time_spec(argv
[optind
], &arg_when
);
5621 log_error("Failed to parse time specification: %s", argv
[optind
]);
5625 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
5627 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
5628 /* No time argument for shutdown cancel */
5629 arg_wall
= argv
+ optind
;
5630 else if (argc
> optind
+ 1)
5631 /* We skip the time argument */
5632 arg_wall
= argv
+ optind
+ 1;
5639 static int telinit_parse_argv(int argc
, char *argv
[]) {
5646 static const struct option options
[] = {
5647 { "help", no_argument
, NULL
, ARG_HELP
},
5648 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
5652 static const struct {
5656 { '0', ACTION_POWEROFF
},
5657 { '6', ACTION_REBOOT
},
5658 { '1', ACTION_RESCUE
},
5659 { '2', ACTION_RUNLEVEL2
},
5660 { '3', ACTION_RUNLEVEL3
},
5661 { '4', ACTION_RUNLEVEL4
},
5662 { '5', ACTION_RUNLEVEL5
},
5663 { 's', ACTION_RESCUE
},
5664 { 'S', ACTION_RESCUE
},
5665 { 'q', ACTION_RELOAD
},
5666 { 'Q', ACTION_RELOAD
},
5667 { 'u', ACTION_REEXEC
},
5668 { 'U', ACTION_REEXEC
}
5677 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5681 return telinit_help();
5691 assert_not_reached("Unhandled option");
5695 if (optind
>= argc
) {
5700 if (optind
+ 1 < argc
) {
5701 log_error("Too many arguments.");
5705 if (strlen(argv
[optind
]) != 1) {
5706 log_error("Expected single character argument.");
5710 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
5711 if (table
[i
].from
== argv
[optind
][0])
5714 if (i
>= ELEMENTSOF(table
)) {
5715 log_error("Unknown command '%s'.", argv
[optind
]);
5719 arg_action
= table
[i
].to
;
5726 static int runlevel_parse_argv(int argc
, char *argv
[]) {
5732 static const struct option options
[] = {
5733 { "help", no_argument
, NULL
, ARG_HELP
},
5742 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0) {
5746 return runlevel_help();
5753 assert_not_reached("Unhandled option");
5757 if (optind
< argc
) {
5758 log_error("Too many arguments.");
5765 static int parse_argv(int argc
, char *argv
[]) {
5769 if (program_invocation_short_name
) {
5771 if (strstr(program_invocation_short_name
, "halt")) {
5772 arg_action
= ACTION_HALT
;
5773 return halt_parse_argv(argc
, argv
);
5774 } else if (strstr(program_invocation_short_name
, "poweroff")) {
5775 arg_action
= ACTION_POWEROFF
;
5776 return halt_parse_argv(argc
, argv
);
5777 } else if (strstr(program_invocation_short_name
, "reboot")) {
5779 arg_action
= ACTION_KEXEC
;
5781 arg_action
= ACTION_REBOOT
;
5782 return halt_parse_argv(argc
, argv
);
5783 } else if (strstr(program_invocation_short_name
, "shutdown")) {
5784 arg_action
= ACTION_POWEROFF
;
5785 return shutdown_parse_argv(argc
, argv
);
5786 } else if (strstr(program_invocation_short_name
, "init")) {
5788 if (sd_booted() > 0) {
5789 arg_action
= _ACTION_INVALID
;
5790 return telinit_parse_argv(argc
, argv
);
5792 /* Hmm, so some other init system is
5793 * running, we need to forward this
5794 * request to it. For now we simply
5795 * guess that it is Upstart. */
5797 execv(TELINIT
, argv
);
5799 log_error("Couldn't find an alternative telinit implementation to spawn.");
5803 } else if (strstr(program_invocation_short_name
, "runlevel")) {
5804 arg_action
= ACTION_RUNLEVEL
;
5805 return runlevel_parse_argv(argc
, argv
);
5809 arg_action
= ACTION_SYSTEMCTL
;
5810 return systemctl_parse_argv(argc
, argv
);
5813 _pure_
static int action_to_runlevel(void) {
5815 static const char table
[_ACTION_MAX
] = {
5816 [ACTION_HALT
] = '0',
5817 [ACTION_POWEROFF
] = '0',
5818 [ACTION_REBOOT
] = '6',
5819 [ACTION_RUNLEVEL2
] = '2',
5820 [ACTION_RUNLEVEL3
] = '3',
5821 [ACTION_RUNLEVEL4
] = '4',
5822 [ACTION_RUNLEVEL5
] = '5',
5823 [ACTION_RESCUE
] = '1'
5826 assert(arg_action
< _ACTION_MAX
);
5828 return table
[arg_action
];
5831 static int talk_initctl(void) {
5833 struct init_request request
= {
5834 .magic
= INIT_MAGIC
,
5836 .cmd
= INIT_CMD_RUNLVL
5839 _cleanup_close_
int fd
= -1;
5843 rl
= action_to_runlevel();
5847 request
.runlevel
= rl
;
5849 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
5851 if (errno
== ENOENT
)
5854 log_error("Failed to open "INIT_FIFO
": %m");
5859 r
= loop_write(fd
, &request
, sizeof(request
), false) != sizeof(request
);
5861 log_error("Failed to write to "INIT_FIFO
": %m");
5862 return errno
> 0 ? -errno
: -EIO
;
5868 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
5870 static const struct {
5878 int (* const dispatch
)(sd_bus
*bus
, char **args
);
5884 { "list-units", MORE
, 0, list_units
},
5885 { "list-unit-files", MORE
, 1, list_unit_files
, NOBUS
},
5886 { "list-sockets", MORE
, 1, list_sockets
},
5887 { "list-timers", MORE
, 1, list_timers
},
5888 { "list-jobs", MORE
, 1, list_jobs
},
5889 { "clear-jobs", EQUAL
, 1, daemon_reload
},
5890 { "cancel", MORE
, 2, cancel_job
},
5891 { "start", MORE
, 2, start_unit
},
5892 { "stop", MORE
, 2, start_unit
},
5893 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5894 { "reload", MORE
, 2, start_unit
},
5895 { "restart", MORE
, 2, start_unit
},
5896 { "try-restart", MORE
, 2, start_unit
},
5897 { "reload-or-restart", MORE
, 2, start_unit
},
5898 { "reload-or-try-restart", MORE
, 2, start_unit
},
5899 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
5900 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
5901 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
5902 { "isolate", EQUAL
, 2, start_unit
},
5903 { "kill", MORE
, 2, kill_unit
},
5904 { "is-active", MORE
, 2, check_unit_active
},
5905 { "check", MORE
, 2, check_unit_active
},
5906 { "is-failed", MORE
, 2, check_unit_failed
},
5907 { "show", MORE
, 1, show
},
5908 { "cat", MORE
, 2, cat
},
5909 { "status", MORE
, 1, show
},
5910 { "help", MORE
, 2, show
},
5911 { "snapshot", LESS
, 2, snapshot
},
5912 { "delete", MORE
, 2, delete_snapshot
},
5913 { "daemon-reload", EQUAL
, 1, daemon_reload
},
5914 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
5915 { "show-environment", EQUAL
, 1, show_environment
},
5916 { "set-environment", MORE
, 2, set_environment
},
5917 { "unset-environment", MORE
, 2, set_environment
},
5918 { "halt", EQUAL
, 1, start_special
, FORCE
},
5919 { "poweroff", EQUAL
, 1, start_special
, FORCE
},
5920 { "reboot", EQUAL
, 1, start_special
, FORCE
},
5921 { "kexec", EQUAL
, 1, start_special
},
5922 { "suspend", EQUAL
, 1, start_special
},
5923 { "hibernate", EQUAL
, 1, start_special
},
5924 { "hybrid-sleep", EQUAL
, 1, start_special
},
5925 { "default", EQUAL
, 1, start_special
},
5926 { "rescue", EQUAL
, 1, start_special
},
5927 { "emergency", EQUAL
, 1, start_special
},
5928 { "exit", EQUAL
, 1, start_special
},
5929 { "reset-failed", MORE
, 1, reset_failed
},
5930 { "enable", MORE
, 2, enable_unit
, NOBUS
},
5931 { "disable", MORE
, 2, enable_unit
, NOBUS
},
5932 { "is-enabled", MORE
, 2, unit_is_enabled
, NOBUS
},
5933 { "reenable", MORE
, 2, enable_unit
, NOBUS
},
5934 { "preset", MORE
, 2, enable_unit
, NOBUS
},
5935 { "mask", MORE
, 2, enable_unit
, NOBUS
},
5936 { "unmask", MORE
, 2, enable_unit
, NOBUS
},
5937 { "link", MORE
, 2, enable_unit
, NOBUS
},
5938 { "switch-root", MORE
, 2, switch_root
},
5939 { "list-dependencies", LESS
, 2, list_dependencies
},
5940 { "set-default", EQUAL
, 2, set_default
, NOBUS
},
5941 { "get-default", EQUAL
, 1, get_default
, NOBUS
},
5942 { "set-property", MORE
, 3, set_property
},
5951 left
= argc
- optind
;
5953 /* Special rule: no arguments (left == 0) means "list-units" */
5955 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
5956 log_error("This command expects one or more "
5957 "unit names. Did you mean --help?");
5961 for (; verb
->verb
; verb
++)
5962 if (streq(argv
[optind
], verb
->verb
))
5965 log_error("Unknown operation '%s'.", argv
[optind
]);
5970 switch (verb
->argc_cmp
) {
5973 if (left
!= verb
->argc
) {
5974 log_error("Invalid number of arguments.");
5981 if (left
< verb
->argc
) {
5982 log_error("Too few arguments.");
5989 if (left
> verb
->argc
) {
5990 log_error("Too many arguments.");
5997 assert_not_reached("Unknown comparison operator.");
6000 /* Require a bus connection for all operations but
6002 if (verb
->bus
== NOBUS
) {
6003 if (!bus
&& !avoid_bus()) {
6004 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error
));
6009 if (running_in_chroot() > 0) {
6010 log_info("Running in chroot, ignoring request.");
6014 if ((verb
->bus
!= FORCE
|| arg_force
<= 0) && !bus
) {
6015 log_error("Failed to get D-Bus connection: %s", strerror(-bus_error
));
6020 return verb
->dispatch(bus
, argv
+ optind
);
6023 static int send_shutdownd(usec_t t
, char mode
, bool dry_run
, bool warn
, const char *message
) {
6025 struct sd_shutdown_command c
= {
6032 union sockaddr_union sockaddr
= {
6033 .un
.sun_family
= AF_UNIX
,
6034 .un
.sun_path
= "/run/systemd/shutdownd",
6037 struct iovec iovec
[2] = {{
6038 .iov_base
= (char*) &c
,
6039 .iov_len
= offsetof(struct sd_shutdown_command
, wall_message
),
6042 struct msghdr msghdr
= {
6043 .msg_name
= &sockaddr
,
6044 .msg_namelen
= offsetof(struct sockaddr_un
, sun_path
)
6045 + sizeof("/run/systemd/shutdownd") - 1,
6050 _cleanup_close_
int fd
;
6052 fd
= socket(AF_UNIX
, SOCK_DGRAM
|SOCK_CLOEXEC
, 0);
6056 if (!isempty(message
)) {
6057 iovec
[1].iov_base
= (char*) message
;
6058 iovec
[1].iov_len
= strlen(message
);
6059 msghdr
.msg_iovlen
++;
6062 if (sendmsg(fd
, &msghdr
, MSG_NOSIGNAL
) < 0)
6068 static int reload_with_fallback(sd_bus
*bus
) {
6071 /* First, try systemd via D-Bus. */
6072 if (daemon_reload(bus
, NULL
) >= 0)
6076 /* Nothing else worked, so let's try signals */
6077 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
6079 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0) {
6080 log_error("kill() failed: %m");
6087 static int start_with_fallback(sd_bus
*bus
) {
6090 /* First, try systemd via D-Bus. */
6091 if (start_unit(bus
, NULL
) >= 0)
6095 /* Nothing else worked, so let's try
6097 if (talk_initctl() > 0)
6100 log_error("Failed to talk to init daemon.");
6104 warn_wall(arg_action
);
6108 static int halt_now(enum action a
) {
6110 /* Make sure C-A-D is handled by the kernel from this
6112 reboot(RB_ENABLE_CAD
);
6117 log_info("Halting.");
6118 reboot(RB_HALT_SYSTEM
);
6121 case ACTION_POWEROFF
:
6122 log_info("Powering off.");
6123 reboot(RB_POWER_OFF
);
6126 case ACTION_REBOOT
: {
6127 _cleanup_free_
char *param
= NULL
;
6129 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
6130 log_info("Rebooting with argument '%s'.", param
);
6131 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
6132 LINUX_REBOOT_CMD_RESTART2
, param
);
6135 log_info("Rebooting.");
6136 reboot(RB_AUTOBOOT
);
6141 assert_not_reached("Unknown action.");
6145 static int halt_main(sd_bus
*bus
) {
6148 r
= check_inhibitors(bus
, arg_action
);
6152 if (geteuid() != 0) {
6153 /* Try logind if we are a normal user and no special
6154 * mode applies. Maybe PolicyKit allows us to shutdown
6157 if (arg_when
<= 0 &&
6160 (arg_action
== ACTION_POWEROFF
||
6161 arg_action
== ACTION_REBOOT
)) {
6162 r
= reboot_with_logind(bus
, arg_action
);
6167 log_error("Must be root.");
6172 _cleanup_free_
char *m
;
6174 m
= strv_join(arg_wall
, " ");
6178 r
= send_shutdownd(arg_when
,
6179 arg_action
== ACTION_HALT
? 'H' :
6180 arg_action
== ACTION_POWEROFF
? 'P' :
6181 arg_action
== ACTION_KEXEC
? 'K' :
6188 log_warning("Failed to talk to shutdownd, proceeding with immediate shutdown: %s", strerror(-r
));
6190 char date
[FORMAT_TIMESTAMP_MAX
];
6192 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
6193 format_timestamp(date
, sizeof(date
), arg_when
));
6198 if (!arg_dry
&& !arg_force
)
6199 return start_with_fallback(bus
);
6202 if (sd_booted() > 0)
6203 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
6205 r
= utmp_put_shutdown();
6207 log_warning("Failed to write utmp record: %s", strerror(-r
));
6214 r
= halt_now(arg_action
);
6215 log_error("Failed to reboot: %s", strerror(-r
));
6220 static int runlevel_main(void) {
6221 int r
, runlevel
, previous
;
6223 r
= utmp_get_runlevel(&runlevel
, &previous
);
6230 previous
<= 0 ? 'N' : previous
,
6231 runlevel
<= 0 ? 'N' : runlevel
);
6236 int main(int argc
, char*argv
[]) {
6237 _cleanup_bus_unref_ sd_bus
*bus
= NULL
;
6240 setlocale(LC_ALL
, "");
6241 log_parse_environment();
6244 /* Explicitly not on_tty() to avoid setting cached value.
6245 * This becomes relevant for piping output which might be
6247 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
6249 r
= parse_argv(argc
, argv
);
6253 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
6254 * let's shortcut this */
6255 if (arg_action
== ACTION_RUNLEVEL
) {
6256 r
= runlevel_main();
6260 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
6261 log_info("Running in chroot, ignoring request.");
6267 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
6269 /* systemctl_main() will print an error message for the bus
6270 * connection, but only if it needs to */
6272 switch (arg_action
) {
6274 case ACTION_SYSTEMCTL
:
6275 r
= systemctl_main(bus
, argc
, argv
, r
);
6279 case ACTION_POWEROFF
:
6285 case ACTION_RUNLEVEL2
:
6286 case ACTION_RUNLEVEL3
:
6287 case ACTION_RUNLEVEL4
:
6288 case ACTION_RUNLEVEL5
:
6290 case ACTION_EMERGENCY
:
6291 case ACTION_DEFAULT
:
6292 r
= start_with_fallback(bus
);
6297 r
= reload_with_fallback(bus
);
6300 case ACTION_CANCEL_SHUTDOWN
: {
6301 _cleanup_free_
char *m
= NULL
;
6304 m
= strv_join(arg_wall
, " ");
6311 r
= send_shutdownd(arg_when
, SD_SHUTDOWN_NONE
, false, !arg_no_wall
, m
);
6313 log_warning("Failed to talk to shutdownd, shutdown hasn't been cancelled: %s", strerror(-r
));
6317 case ACTION_RUNLEVEL
:
6318 case _ACTION_INVALID
:
6320 assert_not_reached("Unknown action");
6325 ask_password_agent_close();
6326 polkit_agent_close();
6328 strv_free(arg_types
);
6329 strv_free(arg_states
);
6330 strv_free(arg_properties
);
6332 return r
< 0 ? EXIT_FAILURE
: r
;