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/>.
26 #include <linux/reboot.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
37 #include "sd-daemon.h"
40 #include "bus-common-errors.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
50 #include "exit-status.h"
52 #include "formats-util.h"
53 #include "hostname-util.h"
58 #include "logs-show.h"
62 #include "path-lookup.h"
63 #include "path-util.h"
64 #include "process-util.h"
66 #include "signal-util.h"
67 #include "socket-util.h"
68 #include "spawn-ask-password-agent.h"
69 #include "spawn-polkit-agent.h"
72 #include "terminal-util.h"
73 #include "unit-name.h"
75 #include "utmp-wtmp.h"
77 static char **arg_types
= NULL
;
78 static char **arg_states
= NULL
;
79 static char **arg_properties
= NULL
;
80 static bool arg_all
= false;
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 bool arg_recursive
= false;
102 static int arg_force
= 0;
103 static bool arg_ask_password
= false;
104 static bool arg_runtime
= false;
105 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
106 static char **arg_wall
= NULL
;
107 static const char *arg_kill_who
= NULL
;
108 static int arg_signal
= SIGTERM
;
109 static const char *arg_root
= NULL
;
110 static usec_t arg_when
= 0;
132 ACTION_CANCEL_SHUTDOWN
,
134 } arg_action
= ACTION_SYSTEMCTL
;
135 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
136 static char *arg_host
= NULL
;
137 static unsigned arg_lines
= 10;
138 static OutputMode arg_output
= OUTPUT_SHORT
;
139 static bool arg_plain
= false;
140 static bool arg_firmware_setup
= false;
141 static bool arg_now
= false;
143 static bool original_stdout_is_tty
;
145 static int daemon_reload(sd_bus
*bus
, char **args
);
146 static int halt_now(enum action a
);
147 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
149 static void pager_open_if_enabled(void) {
157 static void ask_password_agent_open_if_enabled(void) {
159 /* Open the password agent as a child process if necessary */
161 if (!arg_ask_password
)
164 if (arg_scope
!= UNIT_FILE_SYSTEM
)
167 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
170 ask_password_agent_open();
173 static void polkit_agent_open_if_enabled(void) {
175 /* Open the polkit agent as a child process if necessary */
177 if (!arg_ask_password
)
180 if (arg_scope
!= UNIT_FILE_SYSTEM
)
183 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
189 static OutputFlags
get_output_flags(void) {
191 arg_all
* OUTPUT_SHOW_ALL
|
192 arg_full
* OUTPUT_FULL_WIDTH
|
193 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
194 on_tty() * OUTPUT_COLOR
|
195 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
198 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
201 if (!sd_bus_error_is_set(error
))
204 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
205 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
206 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
207 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
208 return EXIT_NOPERMISSION
;
210 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
211 return EXIT_NOTINSTALLED
;
213 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
214 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
215 return EXIT_NOTIMPLEMENTED
;
217 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
218 return EXIT_NOTCONFIGURED
;
226 static void warn_wall(enum action a
) {
227 static const char *table
[_ACTION_MAX
] = {
228 [ACTION_HALT
] = "The system is going down for system halt NOW!",
229 [ACTION_REBOOT
] = "The system is going down for reboot NOW!",
230 [ACTION_POWEROFF
] = "The system is going down for power-off NOW!",
231 [ACTION_KEXEC
] = "The system is going down for kexec reboot NOW!",
232 [ACTION_RESCUE
] = "The system is going down to rescue mode NOW!",
233 [ACTION_EMERGENCY
] = "The system is going down to emergency mode NOW!",
234 [ACTION_CANCEL_SHUTDOWN
] = "The system shutdown has been cancelled NOW!"
241 _cleanup_free_
char *p
;
243 p
= strv_join(arg_wall
, " ");
250 utmp_wall(p
, NULL
, NULL
, NULL
, NULL
);
258 utmp_wall(table
[a
], NULL
, NULL
, NULL
, NULL
);
261 static bool avoid_bus(void) {
263 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
264 * let's shortcut this */
265 if (arg_action
== ACTION_RUNLEVEL
)
268 if (running_in_chroot() > 0)
271 if (sd_booted() <= 0)
274 if (!isempty(arg_root
))
277 if (arg_scope
== UNIT_FILE_GLOBAL
)
283 static int compare_unit_info(const void *a
, const void *b
) {
284 const UnitInfo
*u
= a
, *v
= b
;
288 /* First, order by machine */
289 if (!u
->machine
&& v
->machine
)
291 if (u
->machine
&& !v
->machine
)
293 if (u
->machine
&& v
->machine
) {
294 r
= strcasecmp(u
->machine
, v
->machine
);
299 /* Second, order by unit type */
300 d1
= strrchr(u
->id
, '.');
301 d2
= strrchr(v
->id
, '.');
303 r
= strcasecmp(d1
, d2
);
308 /* Third, order by name */
309 return strcasecmp(u
->id
, v
->id
);
312 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
313 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
319 dot
= strrchr(u
->id
, '.');
323 if (!strv_find(arg_types
, dot
+1))
333 if (streq(u
->active_state
, "inactive") || u
->following
[0])
339 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
340 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
342 unsigned n_shown
= 0;
345 max_id_len
= strlen("UNIT");
346 load_len
= strlen("LOAD");
347 active_len
= strlen("ACTIVE");
348 sub_len
= strlen("SUB");
349 job_len
= strlen("JOB");
352 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
353 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
354 load_len
= MAX(load_len
, strlen(u
->load_state
));
355 active_len
= MAX(active_len
, strlen(u
->active_state
));
356 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
358 if (u
->job_id
!= 0) {
359 job_len
= MAX(job_len
, strlen(u
->job_type
));
363 if (!arg_no_legend
&&
364 (streq(u
->active_state
, "failed") ||
365 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
369 if (!arg_full
&& original_stdout_is_tty
) {
372 id_len
= MIN(max_id_len
, 25u);
373 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
376 basic_len
+= job_len
+ 1;
378 if (basic_len
< (unsigned) columns()) {
379 unsigned extra_len
, incr
;
380 extra_len
= columns() - basic_len
;
382 /* Either UNIT already got 25, or is fully satisfied.
383 * Grant up to 25 to DESC now. */
384 incr
= MIN(extra_len
, 25u);
388 /* split the remaining space between UNIT and DESC,
389 * but do not give UNIT more than it needs. */
391 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
393 desc_len
+= extra_len
- incr
;
399 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
400 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
401 const char *on_loaded
= "", *off_loaded
= "";
402 const char *on_active
= "", *off_active
= "";
403 const char *on_circle
= "", *off_circle
= "";
407 if (!n_shown
&& !arg_no_legend
) {
412 printf("%-*s %-*s %-*s %-*s ",
415 active_len
, "ACTIVE",
419 printf("%-*s ", job_len
, "JOB");
421 if (!arg_full
&& arg_no_pager
)
422 printf("%.*s\n", desc_len
, "DESCRIPTION");
424 printf("%s\n", "DESCRIPTION");
429 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
430 on_loaded
= ansi_highlight_red();
431 on_circle
= ansi_highlight_yellow();
432 off_loaded
= off_circle
= ansi_normal();
434 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
435 on_circle
= on_active
= ansi_highlight_red();
436 off_circle
= off_active
= ansi_normal();
441 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
450 e
= ellipsize(id
, id_len
, 33);
458 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
460 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
461 on_active
, id_len
, id
, off_active
,
462 on_loaded
, load_len
, u
->load_state
, off_loaded
,
463 on_active
, active_len
, u
->active_state
,
464 sub_len
, u
->sub_state
, off_active
,
465 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
468 printf("%.*s\n", desc_len
, u
->description
);
470 printf("%s\n", u
->description
);
473 if (!arg_no_legend
) {
474 const char *on
, *off
;
478 "LOAD = Reflects whether the unit definition was properly loaded.\n"
479 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
480 "SUB = The low-level unit activation state, values depend on unit type.");
481 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
482 on
= ansi_highlight();
485 on
= ansi_highlight_red();
490 printf("%s%u loaded units listed.%s\n"
491 "To show all installed unit files use 'systemctl list-unit-files'.\n",
494 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
495 "To show all installed unit files use 'systemctl list-unit-files'.\n",
502 static int get_unit_list(
506 UnitInfo
**unit_infos
,
508 sd_bus_message
**_reply
) {
510 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
511 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
512 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
521 r
= sd_bus_message_new_method_call(
524 "org.freedesktop.systemd1",
525 "/org/freedesktop/systemd1",
526 "org.freedesktop.systemd1.Manager",
527 "ListUnitsFiltered");
530 return bus_log_create_error(r
);
532 r
= sd_bus_message_append_strv(m
, arg_states
);
534 return bus_log_create_error(r
);
536 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
538 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
540 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
542 return bus_log_parse_error(r
);
544 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
547 if (!output_show_unit(&u
, patterns
))
550 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
553 (*unit_infos
)[c
++] = u
;
556 return bus_log_parse_error(r
);
558 r
= sd_bus_message_exit_container(reply
);
560 return bus_log_parse_error(r
);
568 static void message_set_freep(Set
**set
) {
571 while ((m
= set_steal_first(*set
)))
572 sd_bus_message_unref(m
);
577 static int get_unit_list_recursive(
580 UnitInfo
**_unit_infos
,
584 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
585 _cleanup_(message_set_freep
) Set
*replies
;
586 sd_bus_message
*reply
;
594 replies
= set_new(NULL
);
598 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
602 r
= set_put(replies
, reply
);
604 sd_bus_message_unref(reply
);
609 _cleanup_strv_free_
char **machines
= NULL
;
612 r
= sd_get_machine_names(&machines
);
614 return log_error_errno(r
, "Failed to get machine names: %m");
616 STRV_FOREACH(i
, machines
) {
617 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
620 r
= sd_bus_open_system_machine(&container
, *i
);
622 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
626 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
632 r
= set_put(replies
, reply
);
634 sd_bus_message_unref(reply
);
639 *_machines
= machines
;
644 *_unit_infos
= unit_infos
;
653 static int list_units(sd_bus
*bus
, char **args
) {
654 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
655 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
656 _cleanup_strv_free_
char **machines
= NULL
;
659 pager_open_if_enabled();
661 r
= get_unit_list_recursive(bus
, strv_skip(args
, 1), &unit_infos
, &replies
, &machines
);
665 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
666 return output_units_list(unit_infos
, r
);
669 static int get_triggered_units(
674 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
677 r
= sd_bus_get_property_strv(
679 "org.freedesktop.systemd1",
681 "org.freedesktop.systemd1.Unit",
687 log_error("Failed to determine triggers: %s", bus_error_message(&error
, r
));
692 static int get_listening(
694 const char* unit_path
,
697 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
698 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
699 const char *type
, *path
;
702 r
= sd_bus_get_property(
704 "org.freedesktop.systemd1",
706 "org.freedesktop.systemd1.Socket",
712 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
716 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
718 return bus_log_parse_error(r
);
720 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
722 r
= strv_extend(listening
, type
);
726 r
= strv_extend(listening
, path
);
733 return bus_log_parse_error(r
);
735 r
= sd_bus_message_exit_container(reply
);
737 return bus_log_parse_error(r
);
749 /* Note: triggered is a list here, although it almost certainly
750 * will always be one unit. Nevertheless, dbus API allows for multiple
751 * values, so let's follow that. */
754 /* The strv above is shared. free is set only in the first one. */
758 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
764 if (!a
->machine
&& b
->machine
)
766 if (a
->machine
&& !b
->machine
)
768 if (a
->machine
&& b
->machine
) {
769 o
= strcasecmp(a
->machine
, b
->machine
);
774 o
= strcmp(a
->path
, b
->path
);
776 o
= strcmp(a
->type
, b
->type
);
781 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
782 struct socket_info
*s
;
783 unsigned pathlen
= strlen("LISTEN"),
784 typelen
= strlen("TYPE") * arg_show_types
,
785 socklen
= strlen("UNIT"),
786 servlen
= strlen("ACTIVATES");
787 const char *on
, *off
;
789 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
793 socklen
= MAX(socklen
, strlen(s
->id
));
795 typelen
= MAX(typelen
, strlen(s
->type
));
796 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
798 STRV_FOREACH(a
, s
->triggered
)
799 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
800 servlen
= MAX(servlen
, tmp
);
805 printf("%-*s %-*.*s%-*s %s\n",
807 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
811 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
812 _cleanup_free_
char *j
= NULL
;
817 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
825 printf("%-*s %-*s %-*s",
826 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
829 pathlen
, path
, socklen
, s
->id
);
830 STRV_FOREACH(a
, s
->triggered
)
832 a
== s
->triggered
? "" : ",", *a
);
836 on
= ansi_highlight();
841 on
= ansi_highlight_red();
845 if (!arg_no_legend
) {
846 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
848 printf("Pass --all to see loaded but inactive sockets, too.\n");
854 static int list_sockets(sd_bus
*bus
, char **args
) {
855 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
856 _cleanup_strv_free_
char **machines
= NULL
;
857 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
858 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
860 struct socket_info
*s
;
865 pager_open_if_enabled();
867 n
= get_unit_list_recursive(bus
, strv_skip(args
, 1), &unit_infos
, &replies
, &machines
);
871 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
872 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
875 if (!endswith(u
->id
, ".socket"))
878 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
882 c
= get_listening(bus
, u
->unit_path
, &listening
);
888 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
893 for (i
= 0; i
< c
; i
++)
894 socket_infos
[cs
+ i
] = (struct socket_info
) {
895 .machine
= u
->machine
,
897 .type
= listening
[i
*2],
898 .path
= listening
[i
*2 + 1],
899 .triggered
= triggered
,
900 .own_triggered
= i
==0,
903 /* from this point on we will cleanup those socket_infos */
906 listening
= triggered
= NULL
; /* avoid cleanup */
909 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
910 (__compar_fn_t
) socket_info_compare
);
912 output_sockets_list(socket_infos
, cs
);
915 assert(cs
== 0 || socket_infos
);
916 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
919 if (s
->own_triggered
)
920 strv_free(s
->triggered
);
926 static int get_next_elapse(
929 dual_timestamp
*next
) {
931 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
939 r
= sd_bus_get_property_trivial(
941 "org.freedesktop.systemd1",
943 "org.freedesktop.systemd1.Timer",
944 "NextElapseUSecMonotonic",
949 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
953 r
= sd_bus_get_property_trivial(
955 "org.freedesktop.systemd1",
957 "org.freedesktop.systemd1.Timer",
958 "NextElapseUSecRealtime",
963 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
971 static int get_last_trigger(
976 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
983 r
= sd_bus_get_property_trivial(
985 "org.freedesktop.systemd1",
987 "org.freedesktop.systemd1.Timer",
993 log_error("Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1001 const char* machine
;
1004 usec_t last_trigger
;
1008 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1014 if (!a
->machine
&& b
->machine
)
1016 if (a
->machine
&& !b
->machine
)
1018 if (a
->machine
&& b
->machine
) {
1019 o
= strcasecmp(a
->machine
, b
->machine
);
1024 if (a
->next_elapse
< b
->next_elapse
)
1026 if (a
->next_elapse
> b
->next_elapse
)
1029 return strcmp(a
->id
, b
->id
);
1032 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1033 struct timer_info
*t
;
1035 nextlen
= strlen("NEXT"),
1036 leftlen
= strlen("LEFT"),
1037 lastlen
= strlen("LAST"),
1038 passedlen
= strlen("PASSED"),
1039 unitlen
= strlen("UNIT"),
1040 activatelen
= strlen("ACTIVATES");
1042 const char *on
, *off
;
1044 assert(timer_infos
|| n
== 0);
1046 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1050 if (t
->next_elapse
> 0) {
1051 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1053 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1054 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1056 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1057 leftlen
= MAX(leftlen
, strlen(trel
));
1060 if (t
->last_trigger
> 0) {
1061 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1063 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1064 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1066 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1067 passedlen
= MAX(passedlen
, strlen(trel
));
1070 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1072 STRV_FOREACH(a
, t
->triggered
)
1073 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1075 activatelen
= MAX(activatelen
, ul
);
1080 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1084 passedlen
, "PASSED",
1088 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1089 _cleanup_free_
char *j
= NULL
;
1091 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1092 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1095 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1096 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1098 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1099 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1102 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1109 printf("%-*s %-*s %-*s %-*s %-*s",
1110 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1112 STRV_FOREACH(a
, t
->triggered
)
1114 a
== t
->triggered
? "" : ",", *a
);
1118 on
= ansi_highlight();
1119 off
= ansi_normal();
1123 on
= ansi_highlight_red();
1124 off
= ansi_normal();
1127 if (!arg_no_legend
) {
1128 printf("%s%u timers listed.%s\n", on
, n
, off
);
1130 printf("Pass --all to see loaded but inactive timers, too.\n");
1136 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1142 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1145 if (next
->monotonic
> nw
->monotonic
)
1146 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1148 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1150 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1151 next_elapse
= MIN(converted
, next
->realtime
);
1153 next_elapse
= converted
;
1156 next_elapse
= next
->realtime
;
1161 static int list_timers(sd_bus
*bus
, char **args
) {
1162 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1163 _cleanup_strv_free_
char **machines
= NULL
;
1164 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1165 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1166 struct timer_info
*t
;
1173 pager_open_if_enabled();
1175 n
= get_unit_list_recursive(bus
, strv_skip(args
, 1), &unit_infos
, &replies
, &machines
);
1179 dual_timestamp_get(&nw
);
1181 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1182 _cleanup_strv_free_
char **triggered
= NULL
;
1183 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1186 if (!endswith(u
->id
, ".timer"))
1189 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1193 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1197 get_last_trigger(bus
, u
->unit_path
, &last
);
1199 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1204 m
= calc_next_elapse(&nw
, &next
);
1206 timer_infos
[c
++] = (struct timer_info
) {
1207 .machine
= u
->machine
,
1210 .last_trigger
= last
,
1211 .triggered
= triggered
,
1214 triggered
= NULL
; /* avoid cleanup */
1217 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1218 (__compar_fn_t
) timer_info_compare
);
1220 output_timers_list(timer_infos
, c
);
1223 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1224 strv_free(t
->triggered
);
1229 static int compare_unit_file_list(const void *a
, const void *b
) {
1230 const char *d1
, *d2
;
1231 const UnitFileList
*u
= a
, *v
= b
;
1233 d1
= strrchr(u
->path
, '.');
1234 d2
= strrchr(v
->path
, '.');
1239 r
= strcasecmp(d1
, d2
);
1244 return strcasecmp(basename(u
->path
), basename(v
->path
));
1247 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1248 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1251 if (!strv_isempty(arg_types
)) {
1254 dot
= strrchr(u
->path
, '.');
1258 if (!strv_find(arg_types
, dot
+1))
1262 if (!strv_isempty(arg_states
) &&
1263 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1269 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1270 unsigned max_id_len
, id_cols
, state_cols
;
1271 const UnitFileList
*u
;
1273 max_id_len
= strlen("UNIT FILE");
1274 state_cols
= strlen("STATE");
1276 for (u
= units
; u
< units
+ c
; u
++) {
1277 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1278 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1282 unsigned basic_cols
;
1284 id_cols
= MIN(max_id_len
, 25u);
1285 basic_cols
= 1 + id_cols
+ state_cols
;
1286 if (basic_cols
< (unsigned) columns())
1287 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1289 id_cols
= max_id_len
;
1292 printf("%-*s %-*s\n",
1293 id_cols
, "UNIT FILE",
1294 state_cols
, "STATE");
1296 for (u
= units
; u
< units
+ c
; u
++) {
1297 _cleanup_free_
char *e
= NULL
;
1298 const char *on
, *off
;
1301 if (IN_SET(u
->state
,
1303 UNIT_FILE_MASKED_RUNTIME
,
1305 UNIT_FILE_INVALID
)) {
1306 on
= ansi_highlight_red();
1307 off
= ansi_normal();
1308 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1309 on
= ansi_highlight_green();
1310 off
= ansi_normal();
1314 id
= basename(u
->path
);
1316 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1318 printf("%-*s %s%-*s%s\n",
1319 id_cols
, e
? e
: id
,
1320 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1324 printf("\n%u unit files listed.\n", c
);
1327 static int list_unit_files(sd_bus
*bus
, char **args
) {
1328 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1329 _cleanup_free_ UnitFileList
*units
= NULL
;
1337 pager_open_if_enabled();
1345 h
= hashmap_new(&string_hash_ops
);
1349 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1351 unit_file_list_free(h
);
1352 log_error_errno(r
, "Failed to get unit file list: %m");
1356 n_units
= hashmap_size(h
);
1358 units
= new(UnitFileList
, n_units
);
1359 if (!units
&& n_units
> 0) {
1360 unit_file_list_free(h
);
1364 HASHMAP_FOREACH(u
, h
, i
) {
1365 if (!output_show_unit_file(u
, strv_skip(args
, 1)))
1372 assert(c
<= n_units
);
1375 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1377 r
= sd_bus_call_method(
1379 "org.freedesktop.systemd1",
1380 "/org/freedesktop/systemd1",
1381 "org.freedesktop.systemd1.Manager",
1387 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1391 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1393 return bus_log_parse_error(r
);
1395 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1397 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1400 units
[c
] = (struct UnitFileList
) {
1402 unit_file_state_from_string(state
)
1405 if (output_show_unit_file(&units
[c
], strv_skip(args
, 1)))
1410 return bus_log_parse_error(r
);
1412 r
= sd_bus_message_exit_container(reply
);
1414 return bus_log_parse_error(r
);
1417 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1418 output_unit_file_list(units
, c
);
1421 for (unit
= units
; unit
< units
+ c
; unit
++)
1428 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1429 _cleanup_free_
char *n
= NULL
;
1430 size_t max_len
= MAX(columns(),20u);
1436 for (i
= level
- 1; i
>= 0; i
--) {
1438 if (len
> max_len
- 3 && !arg_full
) {
1439 printf("%s...\n",max_len
% 2 ? "" : " ");
1442 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1446 if (len
> max_len
- 3 && !arg_full
) {
1447 printf("%s...\n",max_len
% 2 ? "" : " ");
1451 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1455 printf("%s\n", name
);
1459 n
= ellipsize(name
, max_len
-len
, 100);
1467 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1469 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1470 [DEPENDENCY_FORWARD
] = "Requires\0"
1471 "RequiresOverridable\0"
1473 "RequisiteOverridable\0"
1477 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1478 "RequiredByOverridable\0"
1480 "RequisiteOfOverridable\0"
1484 [DEPENDENCY_AFTER
] = "After\0",
1485 [DEPENDENCY_BEFORE
] = "Before\0",
1488 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1489 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1490 _cleanup_strv_free_
char **ret
= NULL
;
1491 _cleanup_free_
char *path
= NULL
;
1497 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1499 path
= unit_dbus_path_from_name(name
);
1503 r
= sd_bus_call_method(
1505 "org.freedesktop.systemd1",
1507 "org.freedesktop.DBus.Properties",
1511 "s", "org.freedesktop.systemd1.Unit");
1513 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1517 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1519 return bus_log_parse_error(r
);
1521 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1524 r
= sd_bus_message_read(reply
, "s", &prop
);
1526 return bus_log_parse_error(r
);
1528 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1529 r
= sd_bus_message_skip(reply
, "v");
1531 return bus_log_parse_error(r
);
1534 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1536 return bus_log_parse_error(r
);
1538 r
= bus_message_read_strv_extend(reply
, &ret
);
1540 return bus_log_parse_error(r
);
1542 r
= sd_bus_message_exit_container(reply
);
1544 return bus_log_parse_error(r
);
1547 r
= sd_bus_message_exit_container(reply
);
1549 return bus_log_parse_error(r
);
1553 return bus_log_parse_error(r
);
1555 r
= sd_bus_message_exit_container(reply
);
1557 return bus_log_parse_error(r
);
1565 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1566 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1568 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1570 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1573 return strcasecmp(*a
, *b
);
1576 static int list_dependencies_one(
1581 unsigned int branches
) {
1583 _cleanup_strv_free_
char **deps
= NULL
;
1591 r
= strv_extend(units
, name
);
1595 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1599 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1601 STRV_FOREACH(c
, deps
) {
1602 if (strv_contains(*units
, *c
)) {
1604 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1617 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1618 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1619 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1622 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1626 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1627 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1634 strv_remove(*units
, name
);
1639 static int list_dependencies(sd_bus
*bus
, char **args
) {
1640 _cleanup_strv_free_
char **units
= NULL
;
1641 _cleanup_free_
char *unit
= NULL
;
1648 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &unit
);
1650 return log_error_errno(r
, "Failed to mangle unit name: %m");
1654 u
= SPECIAL_DEFAULT_TARGET
;
1656 pager_open_if_enabled();
1660 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1663 struct machine_info
{
1667 char *control_group
;
1668 uint32_t n_failed_units
;
1673 static const struct bus_properties_map machine_info_property_map
[] = {
1674 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1675 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1676 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1677 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1678 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1682 static void machine_info_clear(struct machine_info
*info
) {
1686 free(info
->control_group
);
1691 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1697 for (i
= 0; i
< n
; i
++)
1698 machine_info_clear(&machine_infos
[i
]);
1700 free(machine_infos
);
1703 static int compare_machine_info(const void *a
, const void *b
) {
1704 const struct machine_info
*u
= a
, *v
= b
;
1706 if (u
->is_host
!= v
->is_host
)
1707 return u
->is_host
> v
->is_host
? -1 : 1;
1709 return strcasecmp(u
->name
, v
->name
);
1712 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1713 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1719 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1726 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1733 static bool output_show_machine(const char *name
, char **patterns
) {
1734 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1737 static int get_machine_list(
1739 struct machine_info
**_machine_infos
,
1742 struct machine_info
*machine_infos
= NULL
;
1743 _cleanup_strv_free_
char **m
= NULL
;
1744 _cleanup_free_
char *hn
= NULL
;
1749 hn
= gethostname_malloc();
1753 if (output_show_machine(hn
, patterns
)) {
1754 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1757 machine_infos
[c
].is_host
= true;
1758 machine_infos
[c
].name
= hn
;
1761 get_machine_properties(bus
, &machine_infos
[c
]);
1765 r
= sd_get_machine_names(&m
);
1767 return log_error_errno(r
, "Failed to get machine list: %m");
1769 STRV_FOREACH(i
, m
) {
1770 _cleanup_free_
char *class = NULL
;
1772 if (!output_show_machine(*i
, patterns
))
1775 sd_machine_get_class(*i
, &class);
1776 if (!streq_ptr(class, "container"))
1779 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1780 free_machines_list(machine_infos
, c
);
1784 machine_infos
[c
].is_host
= false;
1785 machine_infos
[c
].name
= strdup(*i
);
1786 if (!machine_infos
[c
].name
) {
1787 free_machines_list(machine_infos
, c
);
1791 get_machine_properties(NULL
, &machine_infos
[c
]);
1795 *_machine_infos
= machine_infos
;
1799 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1800 struct machine_info
*m
;
1803 namelen
= sizeof("NAME") - 1,
1804 statelen
= sizeof("STATE") - 1,
1805 failedlen
= sizeof("FAILED") - 1,
1806 jobslen
= sizeof("JOBS") - 1;
1808 assert(machine_infos
|| n
== 0);
1810 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1811 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1812 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1813 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1814 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1816 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1820 if (!arg_no_legend
) {
1824 printf("%-*s %-*s %-*s %-*s\n",
1827 failedlen
, "FAILED",
1831 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1832 const char *on_state
= "", *off_state
= "";
1833 const char *on_failed
= "", *off_failed
= "";
1834 bool circle
= false;
1836 if (streq_ptr(m
->state
, "degraded")) {
1837 on_state
= ansi_highlight_red();
1838 off_state
= ansi_normal();
1840 } else if (!streq_ptr(m
->state
, "running")) {
1841 on_state
= ansi_highlight_yellow();
1842 off_state
= ansi_normal();
1846 if (m
->n_failed_units
> 0) {
1847 on_failed
= ansi_highlight_red();
1848 off_failed
= ansi_normal();
1850 on_failed
= off_failed
= "";
1853 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1856 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1857 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1858 on_state
, statelen
, strna(m
->state
), off_state
,
1859 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1860 jobslen
, m
->n_jobs
);
1862 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1863 namelen
, strna(m
->name
),
1864 on_state
, statelen
, strna(m
->state
), off_state
,
1865 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1866 jobslen
, m
->n_jobs
);
1870 printf("\n%u machines listed.\n", n
);
1873 static int list_machines(sd_bus
*bus
, char **args
) {
1874 struct machine_info
*machine_infos
= NULL
;
1879 if (geteuid() != 0) {
1880 log_error("Must be root.");
1884 pager_open_if_enabled();
1886 r
= get_machine_list(bus
, &machine_infos
, strv_skip(args
, 1));
1890 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1891 output_machines_list(machine_infos
, r
);
1892 free_machines_list(machine_infos
, r
);
1897 static int get_default(sd_bus
*bus
, char **args
) {
1898 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1899 _cleanup_free_
char *_path
= NULL
;
1903 if (!bus
|| avoid_bus()) {
1904 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1906 return log_error_errno(r
, "Failed to get default target: %m");
1910 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1912 r
= sd_bus_call_method(
1914 "org.freedesktop.systemd1",
1915 "/org/freedesktop/systemd1",
1916 "org.freedesktop.systemd1.Manager",
1922 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1926 r
= sd_bus_message_read(reply
, "s", &path
);
1928 return bus_log_parse_error(r
);
1932 printf("%s\n", path
);
1937 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1940 assert(changes
|| n_changes
== 0);
1942 for (i
= 0; i
< n_changes
; i
++) {
1943 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1944 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1946 log_info("Removed symlink %s.", changes
[i
].path
);
1950 static int set_default(sd_bus
*bus
, char **args
) {
1951 _cleanup_free_
char *unit
= NULL
;
1952 UnitFileChange
*changes
= NULL
;
1953 unsigned n_changes
= 0;
1956 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1958 return log_error_errno(r
, "Failed to mangle unit name: %m");
1960 if (!bus
|| avoid_bus()) {
1961 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1963 return log_error_errno(r
, "Failed to set default target: %m");
1966 dump_unit_file_changes(changes
, n_changes
);
1970 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1971 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1973 polkit_agent_open_if_enabled();
1975 r
= sd_bus_call_method(
1977 "org.freedesktop.systemd1",
1978 "/org/freedesktop/systemd1",
1979 "org.freedesktop.systemd1.Manager",
1985 log_error("Failed to set default target: %s", bus_error_message(&error
, -r
));
1989 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
1993 /* Try to reload if enabled */
1995 r
= daemon_reload(bus
, args
);
2000 unit_file_changes_free(changes
, n_changes
);
2007 const char *name
, *type
, *state
;
2010 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2011 unsigned id_len
, unit_len
, type_len
, state_len
;
2012 const struct job_info
*j
;
2013 const char *on
, *off
;
2014 bool shorten
= false;
2016 assert(n
== 0 || jobs
);
2019 if (!arg_no_legend
) {
2020 on
= ansi_highlight_green();
2021 off
= ansi_normal();
2023 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2028 pager_open_if_enabled();
2030 id_len
= strlen("JOB");
2031 unit_len
= strlen("UNIT");
2032 type_len
= strlen("TYPE");
2033 state_len
= strlen("STATE");
2035 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2036 uint32_t id
= j
->id
;
2037 assert(j
->name
&& j
->type
&& j
->state
);
2039 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2040 unit_len
= MAX(unit_len
, strlen(j
->name
));
2041 type_len
= MAX(type_len
, strlen(j
->type
));
2042 state_len
= MAX(state_len
, strlen(j
->state
));
2045 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2046 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2051 printf("%*s %-*s %-*s %-*s\n",
2055 state_len
, "STATE");
2057 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2058 _cleanup_free_
char *e
= NULL
;
2060 if (streq(j
->state
, "running")) {
2061 on
= ansi_highlight();
2062 off
= ansi_normal();
2066 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2067 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2069 on
, unit_len
, e
? e
: j
->name
, off
,
2071 on
, state_len
, j
->state
, off
);
2074 if (!arg_no_legend
) {
2075 on
= ansi_highlight();
2076 off
= ansi_normal();
2078 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2082 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2083 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2086 static int list_jobs(sd_bus
*bus
, char **args
) {
2087 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2088 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2089 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2090 _cleanup_free_
struct job_info
*jobs
= NULL
;
2095 bool skipped
= false;
2097 r
= sd_bus_call_method(
2099 "org.freedesktop.systemd1",
2100 "/org/freedesktop/systemd1",
2101 "org.freedesktop.systemd1.Manager",
2107 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
2111 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2113 return bus_log_parse_error(r
);
2115 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2116 struct job_info job
= { id
, name
, type
, state
};
2118 if (!output_show_job(&job
, strv_skip(args
, 1))) {
2123 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2129 return bus_log_parse_error(r
);
2131 r
= sd_bus_message_exit_container(reply
);
2133 return bus_log_parse_error(r
);
2135 output_jobs_list(jobs
, c
, skipped
);
2139 static int cancel_job(sd_bus
*bus
, char **args
) {
2145 if (strv_length(args
) <= 1)
2146 return daemon_reload(bus
, args
);
2148 polkit_agent_open_if_enabled();
2150 STRV_FOREACH(name
, args
+1) {
2151 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2155 q
= safe_atou32(*name
, &id
);
2157 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2159 q
= sd_bus_call_method(
2161 "org.freedesktop.systemd1",
2162 "/org/freedesktop/systemd1",
2163 "org.freedesktop.systemd1.Manager",
2169 log_error("Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2178 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2179 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2183 /* We ignore all errors here, since this is used to show a
2186 /* We don't use unit_dbus_path_from_name() directly since we
2187 * don't want to load the unit if it isn't loaded. */
2189 r
= sd_bus_call_method(
2191 "org.freedesktop.systemd1",
2192 "/org/freedesktop/systemd1",
2193 "org.freedesktop.systemd1.Manager",
2201 r
= sd_bus_message_read(reply
, "o", &path
);
2205 r
= sd_bus_get_property_trivial(
2207 "org.freedesktop.systemd1",
2209 "org.freedesktop.systemd1.Unit",
2219 static void warn_unit_file_changed(const char *name
) {
2220 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2221 ansi_highlight_red(),
2224 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2227 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2234 STRV_FOREACH(p
, lp
->unit_path
) {
2235 _cleanup_free_
char *path
;
2237 path
= path_join(arg_root
, *p
, unit_name
);
2241 if (access(path
, F_OK
) == 0) {
2251 static int unit_find_paths(
2253 const char *unit_name
,
2254 bool avoid_bus_cache
,
2256 char **fragment_path
,
2257 char ***dropin_paths
) {
2259 _cleanup_free_
char *path
= NULL
;
2260 _cleanup_strv_free_
char **dropins
= NULL
;
2264 * Finds where the unit is defined on disk. Returns 0 if the unit
2265 * is not found. Returns 1 if it is found, and sets
2266 * - the path to the unit in *path, if it exists on disk,
2267 * - and a strv of existing drop-ins in *dropins,
2268 * if the arg is not NULL and any dropins were found.
2272 assert(fragment_path
);
2275 if (!avoid_bus_cache
&& !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2276 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2277 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2278 _cleanup_free_
char *unit
= NULL
;
2279 char *unit_load_error_name
, *unit_load_error_message
;
2281 unit
= unit_dbus_path_from_name(unit_name
);
2285 if (need_daemon_reload(bus
, unit_name
) > 0)
2286 warn_unit_file_changed(unit_name
);
2288 r
= sd_bus_get_property(
2290 "org.freedesktop.systemd1",
2292 "org.freedesktop.systemd1.Unit",
2298 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2300 r
= sd_bus_message_read(
2303 &unit_load_error_name
,
2304 &unit_load_error_message
);
2306 return bus_log_parse_error(r
);
2308 if (!isempty(unit_load_error_name
)) {
2309 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2313 r
= sd_bus_get_property_string(
2315 "org.freedesktop.systemd1",
2317 "org.freedesktop.systemd1.Unit",
2322 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2325 r
= sd_bus_get_property_strv(
2327 "org.freedesktop.systemd1",
2329 "org.freedesktop.systemd1.Unit",
2334 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2337 _cleanup_set_free_ Set
*names
;
2339 names
= set_new(NULL
);
2343 r
= set_put(names
, unit_name
);
2345 return log_error_errno(r
, "Failed to add unit name: %m");
2347 r
= unit_file_find_path(lp
, unit_name
, &path
);
2352 _cleanup_free_
char *template = NULL
;
2354 r
= unit_name_template(unit_name
, &template);
2355 if (r
< 0 && r
!= -EINVAL
)
2356 return log_error_errno(r
, "Failed to determine template name: %m");
2358 r
= unit_file_find_path(lp
, template, &path
);
2365 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2373 if (!isempty(path
)) {
2374 *fragment_path
= path
;
2379 if (dropin_paths
&& !strv_isempty(dropins
)) {
2380 *dropin_paths
= dropins
;
2386 log_error("No files found for %s.", unit_name
);
2391 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2392 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2393 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2399 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2401 return log_error_errno(r
, "Failed to mangle unit name: %m");
2403 /* We don't use unit_dbus_path_from_name() directly since we
2404 * don't want to load the unit if it isn't loaded. */
2406 r
= sd_bus_call_method(
2408 "org.freedesktop.systemd1",
2409 "/org/freedesktop/systemd1",
2410 "org.freedesktop.systemd1.Manager",
2421 r
= sd_bus_message_read(reply
, "o", &path
);
2423 return bus_log_parse_error(r
);
2425 r
= sd_bus_get_property_string(
2427 "org.freedesktop.systemd1",
2429 "org.freedesktop.systemd1.Unit",
2442 return nulstr_contains(good_states
, state
);
2445 static int check_triggering_units(
2449 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2450 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2451 _cleanup_strv_free_
char **triggered_by
= NULL
;
2452 bool print_warning_label
= true;
2456 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2458 return log_error_errno(r
, "Failed to mangle unit name: %m");
2460 path
= unit_dbus_path_from_name(n
);
2464 r
= sd_bus_get_property_string(
2466 "org.freedesktop.systemd1",
2468 "org.freedesktop.systemd1.Unit",
2473 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2477 if (streq(state
, "masked"))
2480 r
= sd_bus_get_property_strv(
2482 "org.freedesktop.systemd1",
2484 "org.freedesktop.systemd1.Unit",
2489 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2493 STRV_FOREACH(i
, triggered_by
) {
2494 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2496 return log_error_errno(r
, "Failed to check unit: %m");
2501 if (print_warning_label
) {
2502 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2503 print_warning_label
= false;
2506 log_warning(" %s", *i
);
2512 static const struct {
2515 } unit_actions
[] = {
2516 { "start", "StartUnit" },
2517 { "stop", "StopUnit" },
2518 { "condstop", "StopUnit" },
2519 { "reload", "ReloadUnit" },
2520 { "restart", "RestartUnit" },
2521 { "try-restart", "TryRestartUnit" },
2522 { "condrestart", "TryRestartUnit" },
2523 { "reload-or-restart", "ReloadOrRestartUnit" },
2524 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2525 { "condreload", "ReloadOrTryRestartUnit" },
2526 { "force-reload", "ReloadOrTryRestartUnit" }
2529 static const char *verb_to_method(const char *verb
) {
2532 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2533 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2534 return unit_actions
[i
].method
;
2539 static const char *method_to_verb(const char *method
) {
2542 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2543 if (streq_ptr(unit_actions
[i
].method
, method
))
2544 return unit_actions
[i
].verb
;
2549 static int start_unit_one(
2554 sd_bus_error
*error
,
2555 BusWaitForJobs
*w
) {
2557 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2566 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2568 r
= sd_bus_call_method(
2570 "org.freedesktop.systemd1",
2571 "/org/freedesktop/systemd1",
2572 "org.freedesktop.systemd1.Manager",
2580 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2581 /* There's always a fallback possible for
2582 * legacy actions. */
2583 return -EADDRNOTAVAIL
;
2585 verb
= method_to_verb(method
);
2587 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2591 r
= sd_bus_message_read(reply
, "o", &path
);
2593 return bus_log_parse_error(r
);
2595 if (need_daemon_reload(bus
, name
) > 0)
2596 warn_unit_file_changed(name
);
2599 log_debug("Adding %s to the set", path
);
2600 r
= bus_wait_for_jobs_add(w
, path
);
2608 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2610 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2614 STRV_FOREACH(name
, names
) {
2618 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2620 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2622 return log_error_errno(r
, "Failed to mangle name: %m");
2624 if (string_is_glob(t
))
2625 r
= strv_consume(&globs
, t
);
2627 r
= strv_consume(&mangled
, t
);
2632 /* Query the manager only if any of the names are a glob, since
2633 * this is fairly expensive */
2634 if (!strv_isempty(globs
)) {
2635 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2636 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2639 return log_error_errno(EOPNOTSUPP
, "Unit name globbing without bus is not implemented.");
2641 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2645 for (i
= 0; i
< r
; i
++)
2646 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2651 mangled
= NULL
; /* do not free */
2656 static const struct {
2660 } action_table
[_ACTION_MAX
] = {
2661 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2662 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2663 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2664 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2665 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2666 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2667 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2668 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2669 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2670 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2671 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2672 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2673 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2674 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2675 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2678 static enum action
verb_to_action(const char *verb
) {
2681 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2682 if (streq_ptr(action_table
[i
].verb
, verb
))
2685 return _ACTION_INVALID
;
2688 static int start_unit(sd_bus
*bus
, char **args
) {
2689 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2690 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2691 _cleanup_strv_free_
char **names
= NULL
;
2697 ask_password_agent_open_if_enabled();
2698 polkit_agent_open_if_enabled();
2700 if (arg_action
== ACTION_SYSTEMCTL
) {
2702 method
= verb_to_method(args
[0]);
2703 action
= verb_to_action(args
[0]);
2705 if (streq(args
[0], "isolate")) {
2709 mode
= action_table
[action
].mode
?: arg_job_mode
;
2711 one_name
= action_table
[action
].target
;
2713 assert(arg_action
< ELEMENTSOF(action_table
));
2714 assert(action_table
[arg_action
].target
);
2716 method
= "StartUnit";
2718 mode
= action_table
[arg_action
].mode
;
2719 one_name
= action_table
[arg_action
].target
;
2723 names
= strv_new(one_name
, NULL
);
2725 r
= expand_names(bus
, args
+ 1, suffix
, &names
);
2727 log_error_errno(r
, "Failed to expand names: %m");
2730 if (!arg_no_block
) {
2731 r
= bus_wait_for_jobs_new(bus
, &w
);
2733 return log_error_errno(r
, "Could not watch jobs: %m");
2736 STRV_FOREACH(name
, names
) {
2737 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2740 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2741 if (r
>= 0 && q
< 0)
2742 r
= translate_bus_error_to_exit_status(q
, &error
);
2745 if (!arg_no_block
) {
2748 q
= bus_wait_for_jobs(w
, arg_quiet
);
2752 /* When stopping units, warn if they can still be triggered by
2753 * another active unit (socket, path, timer) */
2754 if (!arg_quiet
&& streq(method
, "StopUnit"))
2755 STRV_FOREACH(name
, names
)
2756 check_triggering_units(bus
, *name
);
2762 static int logind_set_wall_message(sd_bus
*bus
) {
2764 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2765 _cleanup_free_
char *m
= NULL
;
2770 m
= strv_join(arg_wall
, " ");
2774 r
= sd_bus_call_method(
2776 "org.freedesktop.login1",
2777 "/org/freedesktop/login1",
2778 "org.freedesktop.login1.Manager",
2787 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2793 /* Ask systemd-logind, which might grant access to unprivileged users
2794 * through PolicyKit */
2795 static int logind_reboot(sd_bus
*bus
, enum action a
) {
2797 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2798 const char *method
, *description
;
2804 polkit_agent_open_if_enabled();
2806 (void) logind_set_wall_message(bus
);
2812 description
= "reboot system";
2815 case ACTION_POWEROFF
:
2816 method
= "PowerOff";
2817 description
= "power off system";
2820 case ACTION_SUSPEND
:
2822 description
= "suspend system";
2825 case ACTION_HIBERNATE
:
2826 method
= "Hibernate";
2827 description
= "hibernate system";
2830 case ACTION_HYBRID_SLEEP
:
2831 method
= "HybridSleep";
2832 description
= "put system into hybrid sleep";
2839 r
= sd_bus_call_method(
2841 "org.freedesktop.login1",
2842 "/org/freedesktop/login1",
2843 "org.freedesktop.login1.Manager",
2847 "b", arg_ask_password
);
2849 log_error("Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2857 static int logind_check_inhibitors(sd_bus
*bus
, enum action a
) {
2859 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2860 _cleanup_strv_free_
char **sessions
= NULL
;
2861 const char *what
, *who
, *why
, *mode
;
2870 if (arg_ignore_inhibitors
|| arg_force
> 0)
2882 r
= sd_bus_call_method(
2884 "org.freedesktop.login1",
2885 "/org/freedesktop/login1",
2886 "org.freedesktop.login1.Manager",
2892 /* If logind is not around, then there are no inhibitors... */
2895 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2897 return bus_log_parse_error(r
);
2899 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2900 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2901 _cleanup_strv_free_
char **sv
= NULL
;
2903 if (!streq(mode
, "block"))
2906 sv
= strv_split(what
, ":");
2910 if ((pid_t
) pid
< 0)
2911 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2913 if (!strv_contains(sv
,
2918 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2921 get_process_comm(pid
, &comm
);
2922 user
= uid_to_name(uid
);
2924 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2925 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2930 return bus_log_parse_error(r
);
2932 r
= sd_bus_message_exit_container(reply
);
2934 return bus_log_parse_error(r
);
2936 /* Check for current sessions */
2937 sd_get_sessions(&sessions
);
2938 STRV_FOREACH(s
, sessions
) {
2939 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2941 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2944 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2947 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2950 sd_session_get_tty(*s
, &tty
);
2951 sd_session_get_seat(*s
, &seat
);
2952 sd_session_get_service(*s
, &service
);
2953 user
= uid_to_name(uid
);
2955 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2962 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2963 action_table
[a
].verb
);
2971 static int prepare_firmware_setup(sd_bus
*bus
) {
2973 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2977 if (!arg_firmware_setup
)
2980 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
2982 r
= efi_set_reboot_to_firmware(true);
2984 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
2990 r
= sd_bus_call_method(
2992 "org.freedesktop.login1",
2993 "/org/freedesktop/login1",
2994 "org.freedesktop.login1.Manager",
2995 "SetRebootToFirmwareSetup",
3000 log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3006 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3011 static int start_special(sd_bus
*bus
, char **args
) {
3012 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3018 a
= verb_to_action(args
[0]);
3020 r
= logind_check_inhibitors(bus
, a
);
3024 if (arg_force
>= 2 && geteuid() != 0) {
3025 log_error("Must be root.");
3029 r
= prepare_firmware_setup(bus
);
3033 if (a
== ACTION_REBOOT
&& args
[1]) {
3034 r
= update_reboot_param_file(args
[1]);
3037 } else if (a
== ACTION_EXIT
&& strv_length(args
) > 1) {
3038 /* If the exit code is not given on the command line, don't
3039 * reset it to zero: just keep it as it might have been set
3043 r
= safe_atou8(args
[1], &code
);
3045 log_error("Invalid exit code.");
3049 r
= sd_bus_call_method(
3051 "org.freedesktop.systemd1",
3052 "/org/freedesktop/systemd1",
3053 "org.freedesktop.systemd1.Manager",
3059 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
3064 if (arg_force
>= 2 &&
3071 if (arg_force
>= 1 &&
3078 return daemon_reload(bus
, args
);
3080 /* first try logind, to allow authentication with polkit */
3081 if (geteuid() != 0 &&
3087 ACTION_HYBRID_SLEEP
)) {
3088 r
= logind_reboot(bus
, a
);
3091 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3092 /* requested operation is not supported or already in progress */
3094 /* on all other errors, try low-level operation */
3097 r
= start_unit(bus
, args
);
3098 if (r
== EXIT_SUCCESS
)
3104 static int check_unit_generic(sd_bus
*bus
, int code
, const char *good_states
, char **args
) {
3105 _cleanup_strv_free_
char **names
= NULL
;
3112 r
= expand_names(bus
, args
, NULL
, &names
);
3114 return log_error_errno(r
, "Failed to expand names: %m");
3116 STRV_FOREACH(name
, names
) {
3119 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3129 static int check_unit_active(sd_bus
*bus
, char **args
) {
3130 /* According to LSB: 3, "program is not running" */
3131 return check_unit_generic(bus
, 3, "active\0reloading\0", args
+ 1);
3134 static int check_unit_failed(sd_bus
*bus
, char **args
) {
3135 return check_unit_generic(bus
, 1, "failed\0", args
+ 1);
3138 static int kill_unit(sd_bus
*bus
, char **args
) {
3139 _cleanup_strv_free_
char **names
= NULL
;
3140 char *kill_who
= NULL
, **name
;
3146 polkit_agent_open_if_enabled();
3149 arg_kill_who
= "all";
3151 /* --fail was specified */
3152 if (streq(arg_job_mode
, "fail"))
3153 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3155 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
3157 log_error_errno(r
, "Failed to expand names: %m");
3159 STRV_FOREACH(name
, names
) {
3160 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3162 q
= sd_bus_call_method(
3164 "org.freedesktop.systemd1",
3165 "/org/freedesktop/systemd1",
3166 "org.freedesktop.systemd1.Manager",
3170 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3172 log_error("Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3181 typedef struct ExecStatusInfo
{
3189 usec_t start_timestamp
;
3190 usec_t exit_timestamp
;
3195 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3198 static void exec_status_info_free(ExecStatusInfo
*i
) {
3207 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3208 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3211 int32_t code
, status
;
3217 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3219 return bus_log_parse_error(r
);
3223 r
= sd_bus_message_read(m
, "s", &path
);
3225 return bus_log_parse_error(r
);
3227 i
->path
= strdup(path
);
3231 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3233 return bus_log_parse_error(r
);
3235 r
= sd_bus_message_read(m
,
3238 &start_timestamp
, &start_timestamp_monotonic
,
3239 &exit_timestamp
, &exit_timestamp_monotonic
,
3243 return bus_log_parse_error(r
);
3246 i
->start_timestamp
= (usec_t
) start_timestamp
;
3247 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3248 i
->pid
= (pid_t
) pid
;
3252 r
= sd_bus_message_exit_container(m
);
3254 return bus_log_parse_error(r
);
3259 typedef struct UnitStatusInfo
{
3261 const char *load_state
;
3262 const char *active_state
;
3263 const char *sub_state
;
3264 const char *unit_file_state
;
3265 const char *unit_file_preset
;
3267 const char *description
;
3268 const char *following
;
3270 char **documentation
;
3272 const char *fragment_path
;
3273 const char *source_path
;
3274 const char *control_group
;
3276 char **dropin_paths
;
3278 const char *load_error
;
3281 usec_t inactive_exit_timestamp
;
3282 usec_t inactive_exit_timestamp_monotonic
;
3283 usec_t active_enter_timestamp
;
3284 usec_t active_exit_timestamp
;
3285 usec_t inactive_enter_timestamp
;
3287 bool need_daemon_reload
;
3292 const char *status_text
;
3293 const char *pid_file
;
3297 usec_t start_timestamp
;
3298 usec_t exit_timestamp
;
3300 int exit_code
, exit_status
;
3302 usec_t condition_timestamp
;
3303 bool condition_result
;
3304 bool failed_condition_trigger
;
3305 bool failed_condition_negate
;
3306 const char *failed_condition
;
3307 const char *failed_condition_parameter
;
3309 usec_t assert_timestamp
;
3311 bool failed_assert_trigger
;
3312 bool failed_assert_negate
;
3313 const char *failed_assert
;
3314 const char *failed_assert_parameter
;
3317 unsigned n_accepted
;
3318 unsigned n_connections
;
3321 /* Pairs of type, path */
3325 const char *sysfs_path
;
3327 /* Mount, Automount */
3334 uint64_t memory_current
;
3335 uint64_t memory_limit
;
3336 uint64_t cpu_usage_nsec
;
3337 uint64_t tasks_current
;
3340 LIST_HEAD(ExecStatusInfo
, exec
);
3343 static void print_status_info(
3348 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3350 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3351 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3357 /* This shows pretty information about a unit. See
3358 * print_property() for a low-level property printer */
3360 if (streq_ptr(i
->active_state
, "failed")) {
3361 active_on
= ansi_highlight_red();
3362 active_off
= ansi_normal();
3363 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3364 active_on
= ansi_highlight_green();
3365 active_off
= ansi_normal();
3367 active_on
= active_off
= "";
3369 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3371 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3372 printf(" - %s", i
->description
);
3377 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3379 if (streq_ptr(i
->load_state
, "error")) {
3380 on
= ansi_highlight_red();
3381 off
= ansi_normal();
3385 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3388 printf(" Loaded: %s%s%s (Reason: %s)\n",
3389 on
, strna(i
->load_state
), off
, i
->load_error
);
3390 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3391 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3392 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3393 else if (path
&& !isempty(i
->unit_file_state
))
3394 printf(" Loaded: %s%s%s (%s; %s)\n",
3395 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3397 printf(" Loaded: %s%s%s (%s)\n",
3398 on
, strna(i
->load_state
), off
, path
);
3400 printf(" Loaded: %s%s%s\n",
3401 on
, strna(i
->load_state
), off
);
3403 if (!strv_isempty(i
->dropin_paths
)) {
3404 _cleanup_free_
char *dir
= NULL
;
3408 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3409 if (! dir
|| last
) {
3410 printf(dir
? " " : " Drop-In: ");
3414 if (path_get_parent(*dropin
, &dir
) < 0) {
3419 printf("%s\n %s", dir
,
3420 draw_special_char(DRAW_TREE_RIGHT
));
3423 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3425 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3429 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3431 printf(" Active: %s%s (%s)%s",
3432 active_on
, strna(i
->active_state
), ss
, active_off
);
3434 printf(" Active: %s%s%s",
3435 active_on
, strna(i
->active_state
), active_off
);
3437 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3438 printf(" (Result: %s)", i
->result
);
3440 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3441 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3442 (streq_ptr(i
->active_state
, "inactive") ||
3443 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3444 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3445 i
->active_exit_timestamp
;
3447 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3448 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3451 printf(" since %s; %s\n", s2
, s1
);
3453 printf(" since %s\n", s2
);
3457 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3458 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3459 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3461 printf("Condition: start %scondition failed%s at %s%s%s\n",
3462 ansi_highlight_yellow(), ansi_normal(),
3463 s2
, s1
? "; " : "", s1
? s1
: "");
3464 if (i
->failed_condition_trigger
)
3465 printf(" none of the trigger conditions were met\n");
3466 else if (i
->failed_condition
)
3467 printf(" %s=%s%s was not met\n",
3468 i
->failed_condition
,
3469 i
->failed_condition_negate
? "!" : "",
3470 i
->failed_condition_parameter
);
3473 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3474 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3475 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3477 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3478 ansi_highlight_red(), ansi_normal(),
3479 s2
, s1
? "; " : "", s1
? s1
: "");
3480 if (i
->failed_assert_trigger
)
3481 printf(" none of the trigger assertions were met\n");
3482 else if (i
->failed_assert
)
3483 printf(" %s=%s%s was not met\n",
3485 i
->failed_assert_negate
? "!" : "",
3486 i
->failed_assert_parameter
);
3490 printf(" Device: %s\n", i
->sysfs_path
);
3492 printf(" Where: %s\n", i
->where
);
3494 printf(" What: %s\n", i
->what
);
3496 STRV_FOREACH(t
, i
->documentation
)
3497 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3499 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3500 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3503 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3505 LIST_FOREACH(exec
, p
, i
->exec
) {
3506 _cleanup_free_
char *argv
= NULL
;
3509 /* Only show exited processes here */
3513 argv
= strv_join(p
->argv
, " ");
3514 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3516 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3518 on
= ansi_highlight_red();
3519 off
= ansi_normal();
3523 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3525 if (p
->code
== CLD_EXITED
) {
3528 printf("status=%i", p
->status
);
3530 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3535 printf("signal=%s", signal_to_string(p
->status
));
3537 printf(")%s\n", off
);
3539 if (i
->main_pid
== p
->pid
&&
3540 i
->start_timestamp
== p
->start_timestamp
&&
3541 i
->exit_timestamp
== p
->start_timestamp
)
3542 /* Let's not show this twice */
3545 if (p
->pid
== i
->control_pid
)
3549 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3550 if (i
->main_pid
> 0) {
3551 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3554 _cleanup_free_
char *comm
= NULL
;
3555 get_process_comm(i
->main_pid
, &comm
);
3557 printf(" (%s)", comm
);
3558 } else if (i
->exit_code
> 0) {
3559 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3561 if (i
->exit_code
== CLD_EXITED
) {
3564 printf("status=%i", i
->exit_status
);
3566 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3571 printf("signal=%s", signal_to_string(i
->exit_status
));
3575 if (i
->control_pid
> 0)
3579 if (i
->control_pid
> 0) {
3580 _cleanup_free_
char *c
= NULL
;
3582 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3584 get_process_comm(i
->control_pid
, &c
);
3593 printf(" Status: \"%s\"\n", i
->status_text
);
3594 if (i
->status_errno
> 0)
3595 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3597 if (i
->tasks_current
!= (uint64_t) -1) {
3598 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3600 if (i
->tasks_max
!= (uint64_t) -1)
3601 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3606 if (i
->memory_current
!= (uint64_t) -1) {
3607 char buf
[FORMAT_BYTES_MAX
];
3609 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3611 if (i
->memory_limit
!= (uint64_t) -1)
3612 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3617 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3618 char buf
[FORMAT_TIMESPAN_MAX
];
3619 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3622 if (i
->control_group
&&
3623 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3624 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3627 printf(" CGroup: %s\n", i
->control_group
);
3629 if (IN_SET(arg_transport
,
3630 BUS_TRANSPORT_LOCAL
,
3631 BUS_TRANSPORT_MACHINE
)) {
3634 static const char prefix
[] = " ";
3637 if (c
> sizeof(prefix
) - 1)
3638 c
-= sizeof(prefix
) - 1;
3642 if (i
->main_pid
> 0)
3643 extra
[k
++] = i
->main_pid
;
3645 if (i
->control_pid
> 0)
3646 extra
[k
++] = i
->control_pid
;
3648 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3652 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3653 show_journal_by_unit(
3658 i
->inactive_exit_timestamp_monotonic
,
3661 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3662 SD_JOURNAL_LOCAL_ONLY
,
3663 arg_scope
== UNIT_FILE_SYSTEM
,
3666 if (i
->need_daemon_reload
)
3667 warn_unit_file_changed(i
->id
);
3670 static void show_unit_help(UnitStatusInfo
*i
) {
3675 if (!i
->documentation
) {
3676 log_info("Documentation for %s not known.", i
->id
);
3680 STRV_FOREACH(p
, i
->documentation
)
3681 if (startswith(*p
, "man:"))
3682 show_man_page(*p
+ 4, false);
3684 log_info("Can't show: %s", *p
);
3687 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3694 switch (contents
[0]) {
3696 case SD_BUS_TYPE_STRING
: {
3699 r
= sd_bus_message_read(m
, "s", &s
);
3701 return bus_log_parse_error(r
);
3704 if (streq(name
, "Id"))
3706 else if (streq(name
, "LoadState"))
3708 else if (streq(name
, "ActiveState"))
3709 i
->active_state
= s
;
3710 else if (streq(name
, "SubState"))
3712 else if (streq(name
, "Description"))
3714 else if (streq(name
, "FragmentPath"))
3715 i
->fragment_path
= s
;
3716 else if (streq(name
, "SourcePath"))
3719 else if (streq(name
, "DefaultControlGroup")) {
3721 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3723 i
->control_group
= e
;
3726 else if (streq(name
, "ControlGroup"))
3727 i
->control_group
= s
;
3728 else if (streq(name
, "StatusText"))
3730 else if (streq(name
, "PIDFile"))
3732 else if (streq(name
, "SysFSPath"))
3734 else if (streq(name
, "Where"))
3736 else if (streq(name
, "What"))
3738 else if (streq(name
, "Following"))
3740 else if (streq(name
, "UnitFileState"))
3741 i
->unit_file_state
= s
;
3742 else if (streq(name
, "UnitFilePreset"))
3743 i
->unit_file_preset
= s
;
3744 else if (streq(name
, "Result"))
3751 case SD_BUS_TYPE_BOOLEAN
: {
3754 r
= sd_bus_message_read(m
, "b", &b
);
3756 return bus_log_parse_error(r
);
3758 if (streq(name
, "Accept"))
3760 else if (streq(name
, "NeedDaemonReload"))
3761 i
->need_daemon_reload
= b
;
3762 else if (streq(name
, "ConditionResult"))
3763 i
->condition_result
= b
;
3764 else if (streq(name
, "AssertResult"))
3765 i
->assert_result
= b
;
3770 case SD_BUS_TYPE_UINT32
: {
3773 r
= sd_bus_message_read(m
, "u", &u
);
3775 return bus_log_parse_error(r
);
3777 if (streq(name
, "MainPID")) {
3779 i
->main_pid
= (pid_t
) u
;
3782 } else if (streq(name
, "ControlPID"))
3783 i
->control_pid
= (pid_t
) u
;
3784 else if (streq(name
, "ExecMainPID")) {
3786 i
->main_pid
= (pid_t
) u
;
3787 } else if (streq(name
, "NAccepted"))
3789 else if (streq(name
, "NConnections"))
3790 i
->n_connections
= u
;
3795 case SD_BUS_TYPE_INT32
: {
3798 r
= sd_bus_message_read(m
, "i", &j
);
3800 return bus_log_parse_error(r
);
3802 if (streq(name
, "ExecMainCode"))
3803 i
->exit_code
= (int) j
;
3804 else if (streq(name
, "ExecMainStatus"))
3805 i
->exit_status
= (int) j
;
3806 else if (streq(name
, "StatusErrno"))
3807 i
->status_errno
= (int) j
;
3812 case SD_BUS_TYPE_UINT64
: {
3815 r
= sd_bus_message_read(m
, "t", &u
);
3817 return bus_log_parse_error(r
);
3819 if (streq(name
, "ExecMainStartTimestamp"))
3820 i
->start_timestamp
= (usec_t
) u
;
3821 else if (streq(name
, "ExecMainExitTimestamp"))
3822 i
->exit_timestamp
= (usec_t
) u
;
3823 else if (streq(name
, "ActiveEnterTimestamp"))
3824 i
->active_enter_timestamp
= (usec_t
) u
;
3825 else if (streq(name
, "InactiveEnterTimestamp"))
3826 i
->inactive_enter_timestamp
= (usec_t
) u
;
3827 else if (streq(name
, "InactiveExitTimestamp"))
3828 i
->inactive_exit_timestamp
= (usec_t
) u
;
3829 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3830 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3831 else if (streq(name
, "ActiveExitTimestamp"))
3832 i
->active_exit_timestamp
= (usec_t
) u
;
3833 else if (streq(name
, "ConditionTimestamp"))
3834 i
->condition_timestamp
= (usec_t
) u
;
3835 else if (streq(name
, "AssertTimestamp"))
3836 i
->assert_timestamp
= (usec_t
) u
;
3837 else if (streq(name
, "MemoryCurrent"))
3838 i
->memory_current
= u
;
3839 else if (streq(name
, "MemoryLimit"))
3840 i
->memory_limit
= u
;
3841 else if (streq(name
, "TasksCurrent"))
3842 i
->tasks_current
= u
;
3843 else if (streq(name
, "TasksMax"))
3845 else if (streq(name
, "CPUUsageNSec"))
3846 i
->cpu_usage_nsec
= u
;
3851 case SD_BUS_TYPE_ARRAY
:
3853 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3854 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3856 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3858 return bus_log_parse_error(r
);
3860 info
= new0(ExecStatusInfo
, 1);
3864 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3866 info
->name
= strdup(name
);
3870 LIST_PREPEND(exec
, i
->exec
, info
);
3872 info
= new0(ExecStatusInfo
, 1);
3878 return bus_log_parse_error(r
);
3880 r
= sd_bus_message_exit_container(m
);
3882 return bus_log_parse_error(r
);
3886 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3887 const char *type
, *path
;
3889 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3891 return bus_log_parse_error(r
);
3893 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3895 r
= strv_extend(&i
->listen
, type
);
3899 r
= strv_extend(&i
->listen
, path
);
3904 return bus_log_parse_error(r
);
3906 r
= sd_bus_message_exit_container(m
);
3908 return bus_log_parse_error(r
);
3912 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3914 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3916 return bus_log_parse_error(r
);
3918 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3920 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3922 return bus_log_parse_error(r
);
3924 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3925 const char *cond
, *param
;
3926 int trigger
, negate
;
3929 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3931 return bus_log_parse_error(r
);
3933 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3934 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3935 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3936 i
->failed_condition
= cond
;
3937 i
->failed_condition_trigger
= trigger
;
3938 i
->failed_condition_negate
= negate
;
3939 i
->failed_condition_parameter
= param
;
3943 return bus_log_parse_error(r
);
3945 r
= sd_bus_message_exit_container(m
);
3947 return bus_log_parse_error(r
);
3949 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
3950 const char *cond
, *param
;
3951 int trigger
, negate
;
3954 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3956 return bus_log_parse_error(r
);
3958 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3959 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3960 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
3961 i
->failed_assert
= cond
;
3962 i
->failed_assert_trigger
= trigger
;
3963 i
->failed_assert_negate
= negate
;
3964 i
->failed_assert_parameter
= param
;
3968 return bus_log_parse_error(r
);
3970 r
= sd_bus_message_exit_container(m
);
3972 return bus_log_parse_error(r
);
3979 case SD_BUS_TYPE_STRUCT_BEGIN
:
3981 if (streq(name
, "LoadError")) {
3982 const char *n
, *message
;
3984 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3986 return bus_log_parse_error(r
);
3988 if (!isempty(message
))
3989 i
->load_error
= message
;
4002 r
= sd_bus_message_skip(m
, contents
);
4004 return bus_log_parse_error(r
);
4009 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4015 /* This is a low-level property printer, see
4016 * print_status_info() for the nicer output */
4018 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4019 /* skip what we didn't read */
4020 r
= sd_bus_message_skip(m
, contents
);
4024 switch (contents
[0]) {
4026 case SD_BUS_TYPE_STRUCT_BEGIN
:
4028 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4031 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4033 return bus_log_parse_error(r
);
4036 printf("%s=%"PRIu32
"\n", name
, u
);
4038 printf("%s=\n", name
);
4042 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4045 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4047 return bus_log_parse_error(r
);
4049 if (arg_all
|| !isempty(s
))
4050 printf("%s=%s\n", name
, s
);
4054 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4055 const char *a
= NULL
, *b
= NULL
;
4057 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4059 return bus_log_parse_error(r
);
4061 if (arg_all
|| !isempty(a
) || !isempty(b
))
4062 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4065 } else if (streq_ptr(name
, "SystemCallFilter")) {
4066 _cleanup_strv_free_
char **l
= NULL
;
4069 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4071 return bus_log_parse_error(r
);
4073 r
= sd_bus_message_read(m
, "b", &whitelist
);
4075 return bus_log_parse_error(r
);
4077 r
= sd_bus_message_read_strv(m
, &l
);
4079 return bus_log_parse_error(r
);
4081 r
= sd_bus_message_exit_container(m
);
4083 return bus_log_parse_error(r
);
4085 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4089 fputs(name
, stdout
);
4095 STRV_FOREACH(i
, l
) {
4103 fputc('\n', stdout
);
4111 case SD_BUS_TYPE_ARRAY
:
4113 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4117 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4119 return bus_log_parse_error(r
);
4121 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4122 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4125 return bus_log_parse_error(r
);
4127 r
= sd_bus_message_exit_container(m
);
4129 return bus_log_parse_error(r
);
4133 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4134 const char *type
, *path
;
4136 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4138 return bus_log_parse_error(r
);
4140 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4141 printf("%s=%s\n", type
, path
);
4143 return bus_log_parse_error(r
);
4145 r
= sd_bus_message_exit_container(m
);
4147 return bus_log_parse_error(r
);
4151 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4152 const char *type
, *path
;
4154 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4156 return bus_log_parse_error(r
);
4158 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4159 printf("Listen%s=%s\n", type
, path
);
4161 return bus_log_parse_error(r
);
4163 r
= sd_bus_message_exit_container(m
);
4165 return bus_log_parse_error(r
);
4169 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4171 uint64_t value
, next_elapse
;
4173 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4175 return bus_log_parse_error(r
);
4177 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4178 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4180 printf("%s={ value=%s ; next_elapse=%s }\n",
4182 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4183 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4186 return bus_log_parse_error(r
);
4188 r
= sd_bus_message_exit_container(m
);
4190 return bus_log_parse_error(r
);
4194 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4195 ExecStatusInfo info
= {};
4197 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4199 return bus_log_parse_error(r
);
4201 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4202 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4203 _cleanup_free_
char *tt
;
4205 tt
= strv_join(info
.argv
, " ");
4207 printf("%s={ path=%s ; argv[]=%s ; ignore_errors=%s ; start_time=[%s] ; stop_time=[%s] ; pid="PID_FMT
" ; code=%s ; status=%i%s%s }\n",
4211 yes_no(info
.ignore
),
4212 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4213 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4215 sigchld_code_to_string(info
.code
),
4217 info
.code
== CLD_EXITED
? "" : "/",
4218 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4221 strv_free(info
.argv
);
4225 r
= sd_bus_message_exit_container(m
);
4227 return bus_log_parse_error(r
);
4231 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4232 const char *path
, *rwm
;
4234 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4236 return bus_log_parse_error(r
);
4238 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4239 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4241 return bus_log_parse_error(r
);
4243 r
= sd_bus_message_exit_container(m
);
4245 return bus_log_parse_error(r
);
4249 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4253 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4255 return bus_log_parse_error(r
);
4257 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4258 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4260 return bus_log_parse_error(r
);
4262 r
= sd_bus_message_exit_container(m
);
4264 return bus_log_parse_error(r
);
4268 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4272 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4274 return bus_log_parse_error(r
);
4276 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4277 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4279 return bus_log_parse_error(r
);
4281 r
= sd_bus_message_exit_container(m
);
4283 return bus_log_parse_error(r
);
4291 r
= bus_print_property(name
, m
, arg_all
);
4293 return bus_log_parse_error(r
);
4296 r
= sd_bus_message_skip(m
, contents
);
4298 return bus_log_parse_error(r
);
4301 printf("%s=[unprintable]\n", name
);
4307 static int show_one(
4311 bool show_properties
,
4315 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4316 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4317 UnitStatusInfo info
= {
4318 .memory_current
= (uint64_t) -1,
4319 .memory_limit
= (uint64_t) -1,
4320 .cpu_usage_nsec
= (uint64_t) -1,
4321 .tasks_current
= (uint64_t) -1,
4322 .tasks_max
= (uint64_t) -1,
4330 log_debug("Showing one %s", path
);
4332 r
= sd_bus_call_method(
4334 "org.freedesktop.systemd1",
4336 "org.freedesktop.DBus.Properties",
4342 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4344 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4346 return bus_log_parse_error(r
);
4353 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4354 const char *name
, *contents
;
4356 r
= sd_bus_message_read(reply
, "s", &name
);
4358 return bus_log_parse_error(r
);
4360 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4362 return bus_log_parse_error(r
);
4364 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4366 return bus_log_parse_error(r
);
4368 if (show_properties
)
4369 r
= print_property(name
, reply
, contents
);
4371 r
= status_property(name
, reply
, &info
, contents
);
4375 r
= sd_bus_message_exit_container(reply
);
4377 return bus_log_parse_error(r
);
4379 r
= sd_bus_message_exit_container(reply
);
4381 return bus_log_parse_error(r
);
4384 return bus_log_parse_error(r
);
4386 r
= sd_bus_message_exit_container(reply
);
4388 return bus_log_parse_error(r
);
4392 if (!show_properties
) {
4393 if (streq(verb
, "help"))
4394 show_unit_help(&info
);
4396 print_status_info(&info
, ellipsized
);
4399 strv_free(info
.documentation
);
4400 strv_free(info
.dropin_paths
);
4401 strv_free(info
.listen
);
4403 if (!streq_ptr(info
.active_state
, "active") &&
4404 !streq_ptr(info
.active_state
, "reloading") &&
4405 streq(verb
, "status")) {
4406 /* According to LSB: "program not running" */
4407 /* 0: program is running or service is OK
4408 * 1: program is dead and /run PID file exists
4409 * 2: program is dead and /run/lock lock file exists
4410 * 3: program is not running
4411 * 4: program or service status is unknown
4413 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4419 while ((p
= info
.exec
)) {
4420 LIST_REMOVE(exec
, info
.exec
, p
);
4421 exec_status_info_free(p
);
4427 static int get_unit_dbus_path_by_pid(
4432 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4433 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4437 r
= sd_bus_call_method(
4439 "org.freedesktop.systemd1",
4440 "/org/freedesktop/systemd1",
4441 "org.freedesktop.systemd1.Manager",
4447 log_error("Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4451 r
= sd_bus_message_read(reply
, "o", &u
);
4453 return bus_log_parse_error(r
);
4463 static int show_all(
4466 bool show_properties
,
4470 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4471 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4476 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4480 pager_open_if_enabled();
4484 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4486 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4487 _cleanup_free_
char *p
= NULL
;
4489 p
= unit_dbus_path_from_name(u
->id
);
4493 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4496 else if (r
> 0 && ret
== 0)
4503 static int show_system_status(sd_bus
*bus
) {
4504 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4505 _cleanup_free_
char *hn
= NULL
;
4506 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4507 const char *on
, *off
;
4510 hn
= gethostname_malloc();
4514 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4516 return log_error_errno(r
, "Failed to read server status: %m");
4518 if (streq_ptr(mi
.state
, "degraded")) {
4519 on
= ansi_highlight_red();
4520 off
= ansi_normal();
4521 } else if (!streq_ptr(mi
.state
, "running")) {
4522 on
= ansi_highlight_yellow();
4523 off
= ansi_normal();
4527 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4529 printf(" State: %s%s%s\n",
4530 on
, strna(mi
.state
), off
);
4532 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4533 printf(" Failed: %u units\n", mi
.n_failed_units
);
4535 printf(" Since: %s; %s\n",
4536 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4537 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4539 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4540 if (IN_SET(arg_transport
,
4541 BUS_TRANSPORT_LOCAL
,
4542 BUS_TRANSPORT_MACHINE
)) {
4543 static const char prefix
[] = " ";
4547 if (c
> sizeof(prefix
) - 1)
4548 c
-= sizeof(prefix
) - 1;
4552 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4558 static int show(sd_bus
*bus
, char **args
) {
4559 bool show_properties
, show_status
, new_line
= false;
4560 bool ellipsized
= false;
4566 show_properties
= streq(args
[0], "show");
4567 show_status
= streq(args
[0], "status");
4569 if (show_properties
)
4570 pager_open_if_enabled();
4573 /* Increase max number of open files to 16K if we can, we
4574 * might needs this when browsing journal files, which might
4575 * be split up into many files. */
4576 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4578 /* If no argument is specified inspect the manager itself */
4580 if (show_properties
&& strv_length(args
) <= 1)
4581 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4583 if (show_status
&& strv_length(args
) <= 1) {
4585 pager_open_if_enabled();
4586 show_system_status(bus
);
4590 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
4592 _cleanup_free_
char **patterns
= NULL
;
4595 STRV_FOREACH(name
, args
+ 1) {
4596 _cleanup_free_
char *unit
= NULL
;
4599 if (safe_atou32(*name
, &id
) < 0) {
4600 if (strv_push(&patterns
, *name
) < 0)
4604 } else if (show_properties
) {
4605 /* Interpret as job id */
4606 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4610 /* Interpret as PID */
4611 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4618 r
= show_one(args
[0], bus
, unit
, show_properties
,
4619 &new_line
, &ellipsized
);
4622 else if (r
> 0 && ret
== 0)
4626 if (!strv_isempty(patterns
)) {
4627 _cleanup_strv_free_
char **names
= NULL
;
4629 r
= expand_names(bus
, patterns
, NULL
, &names
);
4631 log_error_errno(r
, "Failed to expand names: %m");
4633 STRV_FOREACH(name
, names
) {
4634 _cleanup_free_
char *unit
;
4636 unit
= unit_dbus_path_from_name(*name
);
4640 r
= show_one(args
[0], bus
, unit
, show_properties
,
4641 &new_line
, &ellipsized
);
4644 else if (r
> 0 && ret
== 0)
4650 if (ellipsized
&& !arg_quiet
)
4651 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4656 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4660 assert(user_runtime
);
4663 if (arg_scope
== UNIT_FILE_USER
) {
4664 r
= user_config_home(user_home
);
4666 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4668 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4670 r
= user_runtime_dir(user_runtime
);
4672 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4674 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4677 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4679 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4684 static int cat_file(const char *filename
, bool newline
) {
4685 _cleanup_close_
int fd
;
4687 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4691 printf("%s%s# %s%s\n",
4692 newline
? "\n" : "",
4693 ansi_highlight_blue(),
4698 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4701 static int cat(sd_bus
*bus
, char **args
) {
4702 _cleanup_free_
char *user_home
= NULL
;
4703 _cleanup_free_
char *user_runtime
= NULL
;
4704 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4705 _cleanup_strv_free_
char **names
= NULL
;
4707 bool first
= true, avoid_bus_cache
;
4712 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4713 log_error("Cannot remotely cat units");
4717 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4721 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4723 return log_error_errno(r
, "Failed to expand names: %m");
4725 avoid_bus_cache
= !bus
|| avoid_bus();
4727 pager_open_if_enabled();
4729 STRV_FOREACH(name
, names
) {
4730 _cleanup_free_
char *fragment_path
= NULL
;
4731 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4734 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &fragment_path
, &dropin_paths
);
4745 if (fragment_path
) {
4746 r
= cat_file(fragment_path
, false);
4748 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4751 STRV_FOREACH(path
, dropin_paths
) {
4752 r
= cat_file(*path
, path
== dropin_paths
);
4754 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4761 static int set_property(sd_bus
*bus
, char **args
) {
4762 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4763 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4764 _cleanup_free_
char *n
= NULL
;
4768 polkit_agent_open_if_enabled();
4770 r
= sd_bus_message_new_method_call(
4773 "org.freedesktop.systemd1",
4774 "/org/freedesktop/systemd1",
4775 "org.freedesktop.systemd1.Manager",
4776 "SetUnitProperties");
4778 return bus_log_create_error(r
);
4780 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &n
);
4782 return log_error_errno(r
, "Failed to mangle unit name: %m");
4784 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4786 return bus_log_create_error(r
);
4788 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4790 return bus_log_create_error(r
);
4792 STRV_FOREACH(i
, args
+ 2) {
4793 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4795 return bus_log_create_error(r
);
4797 r
= bus_append_unit_property_assignment(m
, *i
);
4801 r
= sd_bus_message_close_container(m
);
4803 return bus_log_create_error(r
);
4806 r
= sd_bus_message_close_container(m
);
4808 return bus_log_create_error(r
);
4810 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4812 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4819 static int snapshot(sd_bus
*bus
, char **args
) {
4820 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4821 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4822 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4826 polkit_agent_open_if_enabled();
4828 if (strv_length(args
) > 1) {
4829 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4831 return log_error_errno(r
, "Failed to generate unit name: %m");
4838 r
= sd_bus_call_method(
4840 "org.freedesktop.systemd1",
4841 "/org/freedesktop/systemd1",
4842 "org.freedesktop.systemd1.Manager",
4848 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
4852 r
= sd_bus_message_read(reply
, "o", &path
);
4854 return bus_log_parse_error(r
);
4856 r
= sd_bus_get_property_string(
4858 "org.freedesktop.systemd1",
4860 "org.freedesktop.systemd1.Unit",
4865 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4875 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4876 _cleanup_strv_free_
char **names
= NULL
;
4882 polkit_agent_open_if_enabled();
4884 r
= expand_names(bus
, args
+ 1, ".snapshot", &names
);
4886 log_error_errno(r
, "Failed to expand names: %m");
4888 STRV_FOREACH(name
, names
) {
4889 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4892 q
= sd_bus_call_method(
4894 "org.freedesktop.systemd1",
4895 "/org/freedesktop/systemd1",
4896 "org.freedesktop.systemd1.Manager",
4902 log_error("Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4911 static int daemon_reload(sd_bus
*bus
, char **args
) {
4912 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4916 polkit_agent_open_if_enabled();
4918 if (arg_action
== ACTION_RELOAD
)
4920 else if (arg_action
== ACTION_REEXEC
)
4921 method
= "Reexecute";
4923 assert(arg_action
== ACTION_SYSTEMCTL
);
4926 streq(args
[0], "clear-jobs") ||
4927 streq(args
[0], "cancel") ? "ClearJobs" :
4928 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4929 streq(args
[0], "reset-failed") ? "ResetFailed" :
4930 streq(args
[0], "halt") ? "Halt" :
4931 streq(args
[0], "poweroff") ? "PowerOff" :
4932 streq(args
[0], "reboot") ? "Reboot" :
4933 streq(args
[0], "kexec") ? "KExec" :
4934 streq(args
[0], "exit") ? "Exit" :
4935 /* "daemon-reload" */ "Reload";
4938 r
= sd_bus_call_method(
4940 "org.freedesktop.systemd1",
4941 "/org/freedesktop/systemd1",
4942 "org.freedesktop.systemd1.Manager",
4947 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4948 /* There's always a fallback possible for
4949 * legacy actions. */
4951 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4952 /* On reexecution, we expect a disconnect, not a
4956 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4958 return r
< 0 ? r
: 0;
4961 static int reset_failed(sd_bus
*bus
, char **args
) {
4962 _cleanup_strv_free_
char **names
= NULL
;
4966 if (strv_length(args
) <= 1)
4967 return daemon_reload(bus
, args
);
4969 polkit_agent_open_if_enabled();
4971 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4973 log_error_errno(r
, "Failed to expand names: %m");
4975 STRV_FOREACH(name
, names
) {
4976 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4978 q
= sd_bus_call_method(
4980 "org.freedesktop.systemd1",
4981 "/org/freedesktop/systemd1",
4982 "org.freedesktop.systemd1.Manager",
4988 log_error("Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4997 static int show_environment(sd_bus
*bus
, char **args
) {
4998 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4999 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5003 pager_open_if_enabled();
5005 r
= sd_bus_get_property(
5007 "org.freedesktop.systemd1",
5008 "/org/freedesktop/systemd1",
5009 "org.freedesktop.systemd1.Manager",
5015 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
5019 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5021 return bus_log_parse_error(r
);
5023 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5026 return bus_log_parse_error(r
);
5028 r
= sd_bus_message_exit_container(reply
);
5030 return bus_log_parse_error(r
);
5035 static int switch_root(sd_bus
*bus
, char **args
) {
5036 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5037 _cleanup_free_
char *cmdline_init
= NULL
;
5038 const char *root
, *init
;
5042 l
= strv_length(args
);
5043 if (l
< 2 || l
> 3) {
5044 log_error("Wrong number of arguments.");
5053 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5054 "init", &cmdline_init
,
5057 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5059 init
= cmdline_init
;
5066 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5068 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5069 root_init_path
= strjoina(root
, "/", init
);
5071 /* If the passed init is actually the same as the
5072 * systemd binary, then let's suppress it. */
5073 if (files_same(root_init_path
, root_systemd_path
) > 0)
5077 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5079 r
= sd_bus_call_method(
5081 "org.freedesktop.systemd1",
5082 "/org/freedesktop/systemd1",
5083 "org.freedesktop.systemd1.Manager",
5089 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
5096 static int set_environment(sd_bus
*bus
, char **args
) {
5097 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5098 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5105 polkit_agent_open_if_enabled();
5107 method
= streq(args
[0], "set-environment")
5109 : "UnsetEnvironment";
5111 r
= sd_bus_message_new_method_call(
5114 "org.freedesktop.systemd1",
5115 "/org/freedesktop/systemd1",
5116 "org.freedesktop.systemd1.Manager",
5119 return bus_log_create_error(r
);
5121 r
= sd_bus_message_append_strv(m
, args
+ 1);
5123 return bus_log_create_error(r
);
5125 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5127 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
5134 static int import_environment(sd_bus
*bus
, char **args
) {
5135 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5136 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5142 polkit_agent_open_if_enabled();
5144 r
= sd_bus_message_new_method_call(
5147 "org.freedesktop.systemd1",
5148 "/org/freedesktop/systemd1",
5149 "org.freedesktop.systemd1.Manager",
5152 return bus_log_create_error(r
);
5154 if (strv_isempty(args
+ 1))
5155 r
= sd_bus_message_append_strv(m
, environ
);
5159 r
= sd_bus_message_open_container(m
, 'a', "s");
5161 return bus_log_create_error(r
);
5163 STRV_FOREACH(a
, args
+ 1) {
5165 if (!env_name_is_valid(*a
)) {
5166 log_error("Not a valid environment variable name: %s", *a
);
5170 STRV_FOREACH(b
, environ
) {
5173 eq
= startswith(*b
, *a
);
5174 if (eq
&& *eq
== '=') {
5176 r
= sd_bus_message_append(m
, "s", *b
);
5178 return bus_log_create_error(r
);
5185 r
= sd_bus_message_close_container(m
);
5188 return bus_log_create_error(r
);
5190 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5192 log_error("Failed to import environment: %s", bus_error_message(&error
, r
));
5199 static int enable_sysv_units(const char *verb
, char **args
) {
5202 #if defined(HAVE_SYSV_COMPAT)
5204 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5206 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5209 if (!STR_IN_SET(verb
,
5215 /* Processes all SysV units, and reshuffles the array so that
5216 * afterwards only the native units remain */
5218 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5225 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5226 bool found_native
= false, found_sysv
;
5228 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5236 if (!endswith(name
, ".service"))
5239 if (path_is_absolute(name
))
5242 STRV_FOREACH(k
, paths
.unit_path
) {
5243 _cleanup_free_
char *path
= NULL
;
5245 path
= path_join(arg_root
, *k
, name
);
5249 found_native
= access(path
, F_OK
) >= 0;
5254 /* If we have both a native unit and a SysV script,
5255 * enable/disable them both (below); for is-enabled, prefer the
5257 if (found_native
&& streq(verb
, "is-enabled"))
5260 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5264 p
[strlen(p
) - strlen(".service")] = 0;
5265 found_sysv
= access(p
, F_OK
) >= 0;
5270 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5272 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5274 if (!isempty(arg_root
))
5275 argv
[c
++] = q
= strappend("--root=", arg_root
);
5278 argv
[c
++] = basename(p
);
5281 l
= strv_join((char**)argv
, " ");
5285 log_info("Executing %s", l
);
5289 return log_error_errno(errno
, "Failed to fork: %m");
5290 else if (pid
== 0) {
5293 (void) reset_all_signal_handlers();
5294 (void) reset_signal_mask();
5296 execv(argv
[0], (char**) argv
);
5297 log_error("Failed to execute %s: %m", argv
[0]);
5298 _exit(EXIT_FAILURE
);
5301 j
= wait_for_terminate(pid
, &status
);
5303 log_error_errno(r
, "Failed to wait for child: %m");
5307 if (status
.si_code
== CLD_EXITED
) {
5308 if (streq(verb
, "is-enabled")) {
5309 if (status
.si_status
== 0) {
5318 } else if (status
.si_status
!= 0)
5326 /* Remove this entry, so that we don't try enabling it as native unit */
5329 assert(args
[f
] == name
);
5330 strv_remove(args
, name
);
5337 static int mangle_names(char **original_names
, char ***mangled_names
) {
5338 char **i
, **l
, **name
;
5341 l
= i
= new(char*, strv_length(original_names
) + 1);
5345 STRV_FOREACH(name
, original_names
) {
5347 /* When enabling units qualified path names are OK,
5348 * too, hence allow them explicitly. */
5350 if (is_path(*name
)) {
5357 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5360 return log_error_errno(r
, "Failed to mangle unit name: %m");
5373 static int enable_unit(sd_bus
*bus
, char **args
) {
5374 _cleanup_strv_free_
char **names
= NULL
;
5375 const char *verb
= args
[0];
5376 UnitFileChange
*changes
= NULL
;
5377 unsigned n_changes
= 0;
5378 int carries_install_info
= -1;
5384 r
= mangle_names(args
+1, &names
);
5388 r
= enable_sysv_units(verb
, names
);
5392 /* If the operation was fully executed by the SysV compat,
5393 * let's finish early */
5394 if (strv_isempty(names
))
5397 if (!bus
|| avoid_bus()) {
5398 if (streq(verb
, "enable")) {
5399 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5400 carries_install_info
= r
;
5401 } else if (streq(verb
, "disable"))
5402 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5403 else if (streq(verb
, "reenable")) {
5404 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5405 carries_install_info
= r
;
5406 } else if (streq(verb
, "link"))
5407 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5408 else if (streq(verb
, "preset")) {
5409 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5410 carries_install_info
= r
;
5411 } else if (streq(verb
, "mask"))
5412 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5413 else if (streq(verb
, "unmask"))
5414 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5416 assert_not_reached("Unknown verb");
5419 log_error_errno(r
, "Operation failed: %m");
5424 dump_unit_file_changes(changes
, n_changes
);
5428 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5429 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5430 int expect_carries_install_info
= false;
5431 bool send_force
= true, send_preset_mode
= false;
5434 polkit_agent_open_if_enabled();
5436 if (streq(verb
, "enable")) {
5437 method
= "EnableUnitFiles";
5438 expect_carries_install_info
= true;
5439 } else if (streq(verb
, "disable")) {
5440 method
= "DisableUnitFiles";
5442 } else if (streq(verb
, "reenable")) {
5443 method
= "ReenableUnitFiles";
5444 expect_carries_install_info
= true;
5445 } else if (streq(verb
, "link"))
5446 method
= "LinkUnitFiles";
5447 else if (streq(verb
, "preset")) {
5449 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5450 method
= "PresetUnitFilesWithMode";
5451 send_preset_mode
= true;
5453 method
= "PresetUnitFiles";
5455 expect_carries_install_info
= true;
5456 } else if (streq(verb
, "mask"))
5457 method
= "MaskUnitFiles";
5458 else if (streq(verb
, "unmask")) {
5459 method
= "UnmaskUnitFiles";
5462 assert_not_reached("Unknown verb");
5464 r
= sd_bus_message_new_method_call(
5467 "org.freedesktop.systemd1",
5468 "/org/freedesktop/systemd1",
5469 "org.freedesktop.systemd1.Manager",
5472 return bus_log_create_error(r
);
5474 r
= sd_bus_message_append_strv(m
, names
);
5476 return bus_log_create_error(r
);
5478 if (send_preset_mode
) {
5479 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5481 return bus_log_create_error(r
);
5484 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5486 return bus_log_create_error(r
);
5489 r
= sd_bus_message_append(m
, "b", arg_force
);
5491 return bus_log_create_error(r
);
5494 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5496 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5500 if (expect_carries_install_info
) {
5501 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5503 return bus_log_parse_error(r
);
5506 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5510 /* Try to reload if enabled */
5512 r
= daemon_reload(bus
, args
);
5517 if (carries_install_info
== 0)
5518 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5519 "using systemctl.\n"
5520 "Possible reasons for having this kind of units are:\n"
5521 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5522 " .wants/ or .requires/ directory.\n"
5523 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5524 " a requirement dependency on it.\n"
5525 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5526 " D-Bus, udev, scripted systemctl call, ...).\n");
5528 if (arg_now
&& n_changes
> 0 && STR_IN_SET(args
[0], "enable", "disable", "mask")) {
5529 char *new_args
[n_changes
+ 2];
5532 new_args
[0] = streq(args
[0], "enable") ? (char *)"start" : (char *)"stop";
5533 for (i
= 0; i
< n_changes
; i
++)
5534 new_args
[i
+ 1] = basename(changes
[i
].path
);
5535 new_args
[i
+ 1] = NULL
;
5537 r
= start_unit(bus
, new_args
);
5541 unit_file_changes_free(changes
, n_changes
);
5546 static int add_dependency(sd_bus
*bus
, char **args
) {
5547 _cleanup_strv_free_
char **names
= NULL
;
5548 _cleanup_free_
char *target
= NULL
;
5549 const char *verb
= args
[0];
5556 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5558 return log_error_errno(r
, "Failed to mangle unit name: %m");
5560 r
= mangle_names(args
+2, &names
);
5564 if (streq(verb
, "add-wants"))
5566 else if (streq(verb
, "add-requires"))
5567 dep
= UNIT_REQUIRES
;
5569 assert_not_reached("Unknown verb");
5571 if (!bus
|| avoid_bus()) {
5572 UnitFileChange
*changes
= NULL
;
5573 unsigned n_changes
= 0;
5575 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5578 return log_error_errno(r
, "Can't add dependency: %m");
5581 dump_unit_file_changes(changes
, n_changes
);
5583 unit_file_changes_free(changes
, n_changes
);
5586 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5587 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5589 polkit_agent_open_if_enabled();
5591 r
= sd_bus_message_new_method_call(
5594 "org.freedesktop.systemd1",
5595 "/org/freedesktop/systemd1",
5596 "org.freedesktop.systemd1.Manager",
5597 "AddDependencyUnitFiles");
5599 return bus_log_create_error(r
);
5601 r
= sd_bus_message_append_strv(m
, names
);
5603 return bus_log_create_error(r
);
5605 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5607 return bus_log_create_error(r
);
5609 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5611 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5615 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5620 r
= daemon_reload(bus
, args
);
5628 static int preset_all(sd_bus
*bus
, char **args
) {
5629 UnitFileChange
*changes
= NULL
;
5630 unsigned n_changes
= 0;
5633 if (!bus
|| avoid_bus()) {
5635 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5637 log_error_errno(r
, "Operation failed: %m");
5642 dump_unit_file_changes(changes
, n_changes
);
5647 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5648 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5650 polkit_agent_open_if_enabled();
5652 r
= sd_bus_call_method(
5654 "org.freedesktop.systemd1",
5655 "/org/freedesktop/systemd1",
5656 "org.freedesktop.systemd1.Manager",
5657 "PresetAllUnitFiles",
5661 unit_file_preset_mode_to_string(arg_preset_mode
),
5665 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5669 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5674 r
= daemon_reload(bus
, args
);
5680 unit_file_changes_free(changes
, n_changes
);
5685 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
5687 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5688 _cleanup_strv_free_
char **names
= NULL
;
5693 r
= mangle_names(args
+1, &names
);
5697 r
= enable_sysv_units(args
[0], names
);
5703 if (!bus
|| avoid_bus()) {
5705 STRV_FOREACH(name
, names
) {
5706 UnitFileState state
;
5708 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5710 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5714 UNIT_FILE_ENABLED_RUNTIME
,
5716 UNIT_FILE_INDIRECT
))
5720 puts(unit_file_state_to_string(state
));
5724 STRV_FOREACH(name
, names
) {
5725 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5728 r
= sd_bus_call_method(
5730 "org.freedesktop.systemd1",
5731 "/org/freedesktop/systemd1",
5732 "org.freedesktop.systemd1.Manager",
5738 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5742 r
= sd_bus_message_read(reply
, "s", &s
);
5744 return bus_log_parse_error(r
);
5746 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5757 static int is_system_running(sd_bus
*bus
, char **args
) {
5758 _cleanup_free_
char *state
= NULL
;
5761 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5764 return EXIT_FAILURE
;
5767 r
= sd_bus_get_property_string(
5769 "org.freedesktop.systemd1",
5770 "/org/freedesktop/systemd1",
5771 "org.freedesktop.systemd1.Manager",
5784 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5787 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5792 assert(original_path
);
5795 r
= tempfn_random(new_path
, NULL
, &t
);
5797 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5799 r
= mkdir_parents(new_path
, 0755);
5801 log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5806 r
= copy_file(original_path
, t
, 0, 0644, 0);
5810 log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5815 log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5825 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5826 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5828 switch (arg_scope
) {
5829 case UNIT_FILE_SYSTEM
:
5830 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5832 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5834 case UNIT_FILE_GLOBAL
:
5835 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5837 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5839 case UNIT_FILE_USER
:
5841 assert(user_runtime
);
5843 path
= path_join(arg_root
, user_home
, name
);
5845 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5848 run
= path_join(arg_root
, user_runtime
, name
);
5852 assert_not_reached("Invalid scope");
5854 if (!path
|| (arg_runtime
&& !run
))
5858 if (access(path
, F_OK
) >= 0)
5859 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5861 if (path2
&& access(path2
, F_OK
) >= 0)
5862 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5874 static int unit_file_create_dropin(const char *unit_name
, const char *user_home
, const char *user_runtime
, char **ret_new_path
, char **ret_tmp_path
) {
5875 char *tmp_new_path
, *ending
;
5880 assert(ret_new_path
);
5881 assert(ret_tmp_path
);
5883 ending
= strjoina(unit_name
, ".d/override.conf");
5884 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5888 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5894 *ret_new_path
= tmp_new_path
;
5895 *ret_tmp_path
= tmp_tmp_path
;
5900 static int unit_file_create_copy(
5901 const char *unit_name
,
5902 const char *fragment_path
,
5903 const char *user_home
,
5904 const char *user_runtime
,
5905 char **ret_new_path
,
5906 char **ret_tmp_path
) {
5912 assert(fragment_path
);
5914 assert(ret_new_path
);
5915 assert(ret_tmp_path
);
5917 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5921 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5924 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5929 if (response
!= 'y') {
5930 log_warning("%s ignored", unit_name
);
5936 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5938 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5943 *ret_new_path
= tmp_new_path
;
5944 *ret_tmp_path
= tmp_tmp_path
;
5949 static int run_editor(char **paths
) {
5957 log_error_errno(errno
, "Failed to fork: %m");
5963 char *editor
, **editor_args
= NULL
;
5964 char **tmp_path
, **original_path
, *p
;
5965 unsigned n_editor_args
= 0, i
= 1;
5968 (void) reset_all_signal_handlers();
5969 (void) reset_signal_mask();
5971 argc
= strv_length(paths
)/2 + 1;
5973 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5974 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5975 * we try to execute well known editors
5977 editor
= getenv("SYSTEMD_EDITOR");
5979 editor
= getenv("EDITOR");
5981 editor
= getenv("VISUAL");
5983 if (!isempty(editor
)) {
5984 editor_args
= strv_split(editor
, WHITESPACE
);
5987 _exit(EXIT_FAILURE
);
5989 n_editor_args
= strv_length(editor_args
);
5990 argc
+= n_editor_args
- 1;
5992 args
= newa(const char*, argc
+ 1);
5994 if (n_editor_args
> 0) {
5995 args
[0] = editor_args
[0];
5996 for (; i
< n_editor_args
; i
++)
5997 args
[i
] = editor_args
[i
];
6000 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6001 args
[i
] = *tmp_path
;
6006 if (n_editor_args
> 0)
6007 execvp(args
[0], (char* const*) args
);
6009 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6011 execvp(p
, (char* const*) args
);
6012 /* We do not fail if the editor doesn't exist
6013 * because we want to try each one of them before
6016 if (errno
!= ENOENT
) {
6017 log_error("Failed to execute %s: %m", editor
);
6018 _exit(EXIT_FAILURE
);
6022 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6023 _exit(EXIT_FAILURE
);
6026 r
= wait_for_terminate_and_warn("editor", pid
, true);
6028 return log_error_errno(r
, "Failed to wait for child: %m");
6033 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6034 _cleanup_free_
char *user_home
= NULL
;
6035 _cleanup_free_
char *user_runtime
= NULL
;
6036 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6037 bool avoid_bus_cache
;
6044 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6048 avoid_bus_cache
= !bus
|| avoid_bus();
6050 STRV_FOREACH(name
, names
) {
6051 _cleanup_free_
char *path
= NULL
;
6052 char *new_path
, *tmp_path
;
6054 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &path
, NULL
);
6060 // FIXME: support units with path==NULL (no FragmentPath)
6061 log_error("No fragment exists for %s.", *name
);
6066 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6068 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6072 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6080 static int edit(sd_bus
*bus
, char **args
) {
6081 _cleanup_strv_free_
char **names
= NULL
;
6082 _cleanup_strv_free_
char **paths
= NULL
;
6083 char **original
, **tmp
;
6089 log_error("Cannot edit units if not on a tty");
6093 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6094 log_error("Cannot remotely edit units");
6098 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
6100 return log_error_errno(r
, "Failed to expand names: %m");
6102 r
= find_paths_to_edit(bus
, names
, &paths
);
6106 if (strv_isempty(paths
))
6109 r
= run_editor(paths
);
6113 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6114 /* If the temporary file is empty we ignore it.
6115 * It's useful if the user wants to cancel its modification
6117 if (null_or_empty_path(*tmp
)) {
6118 log_warning("Editing \"%s\" canceled: temporary file is empty", *original
);
6121 r
= rename(*tmp
, *original
);
6123 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6128 if (!arg_no_reload
&& bus
&& !avoid_bus())
6129 r
= daemon_reload(bus
, args
);
6132 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6133 unlink_noerrno(*tmp
);
6138 static void systemctl_help(void) {
6140 pager_open_if_enabled();
6142 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6143 "Query or send control commands to the systemd manager.\n\n"
6144 " -h --help Show this help\n"
6145 " --version Show package version\n"
6146 " --system Connect to system manager\n"
6147 " --user Connect to user service manager\n"
6148 " -H --host=[USER@]HOST\n"
6149 " Operate on remote host\n"
6150 " -M --machine=CONTAINER\n"
6151 " Operate on local container\n"
6152 " -t --type=TYPE List units of a particular type\n"
6153 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6154 " -p --property=NAME Show only properties by this name\n"
6155 " -a --all Show all loaded units/properties, including dead/empty\n"
6156 " ones. To list all units installed on the system, use\n"
6157 " the 'list-unit-files' command instead.\n"
6158 " -l --full Don't ellipsize unit names on output\n"
6159 " -r --recursive Show unit list of host and local containers\n"
6160 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6161 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6162 " queueing a new job\n"
6163 " --show-types When showing sockets, explicitly show their type\n"
6164 " -i --ignore-inhibitors\n"
6165 " When shutting down or sleeping, ignore inhibitors\n"
6166 " --kill-who=WHO Who to send signal to\n"
6167 " -s --signal=SIGNAL Which signal to send\n"
6168 " --now Start or stop unit in addition to enabling or disabling it\n"
6169 " -q --quiet Suppress output\n"
6170 " --no-block Do not wait until operation finished\n"
6171 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6172 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6173 " --no-legend Do not print a legend (column headers and hints)\n"
6174 " --no-pager Do not pipe output into a pager\n"
6175 " --no-ask-password\n"
6176 " Do not ask for system passwords\n"
6177 " --global Enable/disable unit files globally\n"
6178 " --runtime Enable unit files only temporarily until next reboot\n"
6179 " -f --force When enabling unit files, override existing symlinks\n"
6180 " When shutting down, execute action immediately\n"
6181 " --preset-mode= Apply only enable, only disable, or all presets\n"
6182 " --root=PATH Enable unit files in the specified root directory\n"
6183 " -n --lines=INTEGER Number of journal entries to show\n"
6184 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6185 " short-precise, short-monotonic, verbose,\n"
6186 " export, json, json-pretty, json-sse, cat)\n"
6187 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6188 " --plain Print unit dependencies as a list instead of a tree\n\n"
6190 " list-units [PATTERN...] List loaded units\n"
6191 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6192 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6193 " start NAME... Start (activate) one or more units\n"
6194 " stop NAME... Stop (deactivate) one or more units\n"
6195 " reload NAME... Reload one or more units\n"
6196 " restart NAME... Start or restart one or more units\n"
6197 " try-restart NAME... Restart one or more units if active\n"
6198 " reload-or-restart NAME... Reload one or more units if possible,\n"
6199 " otherwise start or restart\n"
6200 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6201 " otherwise restart if active\n"
6202 " isolate NAME Start one unit and stop all others\n"
6203 " kill NAME... Send signal to processes of a unit\n"
6204 " is-active PATTERN... Check whether units are active\n"
6205 " is-failed PATTERN... Check whether units are failed\n"
6206 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6207 " show [PATTERN...|JOB...] Show properties of one or more\n"
6208 " units/jobs or the manager\n"
6209 " cat PATTERN... Show files and drop-ins of one or more units\n"
6210 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6211 " help PATTERN...|PID... Show manual for one or more units\n"
6212 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6214 " list-dependencies [NAME] Recursively show units which are required\n"
6215 " or wanted by this unit or by which this\n"
6216 " unit is required or wanted\n\n"
6217 "Unit File Commands:\n"
6218 " list-unit-files [PATTERN...] List installed unit files\n"
6219 " enable NAME... Enable one or more unit files\n"
6220 " disable NAME... Disable one or more unit files\n"
6221 " reenable NAME... Reenable one or more unit files\n"
6222 " preset NAME... Enable/disable one or more unit files\n"
6223 " based on preset configuration\n"
6224 " preset-all Enable/disable all unit files based on\n"
6225 " preset configuration\n"
6226 " is-enabled NAME... Check whether unit files are enabled\n"
6227 " mask NAME... Mask one or more units\n"
6228 " unmask NAME... Unmask one or more units\n"
6229 " link PATH... Link one or more units files into\n"
6230 " the search path\n"
6231 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6232 " on specified one or more units\n"
6233 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6234 " on specified one or more units\n"
6235 " edit NAME... Edit one or more unit files\n"
6236 " get-default Get the name of the default target\n"
6237 " set-default NAME Set the default target\n\n"
6238 "Machine Commands:\n"
6239 " list-machines [PATTERN...] List local containers and host\n\n"
6241 " list-jobs [PATTERN...] List jobs\n"
6242 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6243 "Snapshot Commands:\n"
6244 " snapshot [NAME] Create a snapshot\n"
6245 " delete NAME... Remove one or more snapshots\n\n"
6246 "Environment Commands:\n"
6247 " show-environment Dump environment\n"
6248 " set-environment NAME=VALUE... Set one or more environment variables\n"
6249 " unset-environment NAME... Unset one or more environment variables\n"
6250 " import-environment [NAME...] Import all or some environment variables\n\n"
6251 "Manager Lifecycle Commands:\n"
6252 " daemon-reload Reload systemd manager configuration\n"
6253 " daemon-reexec Reexecute systemd manager\n\n"
6254 "System Commands:\n"
6255 " is-system-running Check whether system is fully running\n"
6256 " default Enter system default mode\n"
6257 " rescue Enter system rescue mode\n"
6258 " emergency Enter system emergency mode\n"
6259 " halt Shut down and halt the system\n"
6260 " poweroff Shut down and power-off the system\n"
6261 " reboot [ARG] Shut down and reboot the system\n"
6262 " kexec Shut down and reboot the system with kexec\n"
6263 " exit [EXIT_CODE] Request user instance or container exit\n"
6264 " switch-root ROOT [INIT] Change to a different root file system\n"
6265 " suspend Suspend the system\n"
6266 " hibernate Hibernate the system\n"
6267 " hybrid-sleep Hibernate and suspend the system\n",
6268 program_invocation_short_name
);
6271 static void halt_help(void) {
6272 printf("%s [OPTIONS...]%s\n\n"
6273 "%s the system.\n\n"
6274 " --help Show this help\n"
6275 " --halt Halt the machine\n"
6276 " -p --poweroff Switch off the machine\n"
6277 " --reboot Reboot the machine\n"
6278 " -f --force Force immediate halt/power-off/reboot\n"
6279 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6280 " -d --no-wtmp Don't write wtmp record\n"
6281 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6282 program_invocation_short_name
,
6283 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6284 arg_action
== ACTION_REBOOT
? "Reboot" :
6285 arg_action
== ACTION_POWEROFF
? "Power off" :
6289 static void shutdown_help(void) {
6290 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6291 "Shut down the system.\n\n"
6292 " --help Show this help\n"
6293 " -H --halt Halt the machine\n"
6294 " -P --poweroff Power-off the machine\n"
6295 " -r --reboot Reboot the machine\n"
6296 " -h Equivalent to --poweroff, overridden by --halt\n"
6297 " -k Don't halt/power-off/reboot, just send warnings\n"
6298 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6299 " -c Cancel a pending shutdown\n",
6300 program_invocation_short_name
);
6303 static void telinit_help(void) {
6304 printf("%s [OPTIONS...] {COMMAND}\n\n"
6305 "Send control commands to the init daemon.\n\n"
6306 " --help Show this help\n"
6307 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6309 " 0 Power-off the machine\n"
6310 " 6 Reboot the machine\n"
6311 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6312 " 1, s, S Enter rescue mode\n"
6313 " q, Q Reload init daemon configuration\n"
6314 " u, U Reexecute init daemon\n",
6315 program_invocation_short_name
);
6318 static void runlevel_help(void) {
6319 printf("%s [OPTIONS...]\n\n"
6320 "Prints the previous and current runlevel of the init system.\n\n"
6321 " --help Show this help\n",
6322 program_invocation_short_name
);
6325 static void help_types(void) {
6330 puts("Available unit types:");
6331 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
6332 t
= unit_type_to_string(i
);
6338 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6347 ARG_IGNORE_DEPENDENCIES
,
6359 ARG_NO_ASK_PASSWORD
,
6372 static const struct option options
[] = {
6373 { "help", no_argument
, NULL
, 'h' },
6374 { "version", no_argument
, NULL
, ARG_VERSION
},
6375 { "type", required_argument
, NULL
, 't' },
6376 { "property", required_argument
, NULL
, 'p' },
6377 { "all", no_argument
, NULL
, 'a' },
6378 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6379 { "after", no_argument
, NULL
, ARG_AFTER
},
6380 { "before", no_argument
, NULL
, ARG_BEFORE
},
6381 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6382 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6383 { "full", no_argument
, NULL
, 'l' },
6384 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6385 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6386 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6387 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6388 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6389 { "user", no_argument
, NULL
, ARG_USER
},
6390 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6391 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6392 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6393 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6394 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6395 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6396 { "quiet", no_argument
, NULL
, 'q' },
6397 { "root", required_argument
, NULL
, ARG_ROOT
},
6398 { "force", no_argument
, NULL
, ARG_FORCE
},
6399 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6400 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6401 { "signal", required_argument
, NULL
, 's' },
6402 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6403 { "host", required_argument
, NULL
, 'H' },
6404 { "machine", required_argument
, NULL
, 'M' },
6405 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6406 { "lines", required_argument
, NULL
, 'n' },
6407 { "output", required_argument
, NULL
, 'o' },
6408 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6409 { "state", required_argument
, NULL
, ARG_STATE
},
6410 { "recursive", no_argument
, NULL
, 'r' },
6411 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6412 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6413 { "now", no_argument
, NULL
, ARG_NOW
},
6414 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6423 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6424 arg_ask_password
= true;
6426 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6438 const char *word
, *state
;
6441 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6442 _cleanup_free_
char *type
;
6444 type
= strndup(word
, size
);
6448 if (streq(type
, "help")) {
6453 if (unit_type_from_string(type
) >= 0) {
6454 if (strv_push(&arg_types
, type
))
6460 /* It's much nicer to use --state= for
6461 * load states, but let's support this
6462 * in --types= too for compatibility
6463 * with old versions */
6464 if (unit_load_state_from_string(optarg
) >= 0) {
6465 if (strv_push(&arg_states
, type
) < 0)
6471 log_error("Unknown unit type or load state '%s'.", type
);
6472 log_info("Use -t help to see a list of allowed values.");
6480 /* Make sure that if the empty property list
6481 was specified, we won't show any properties. */
6482 if (isempty(optarg
) && !arg_properties
) {
6483 arg_properties
= new0(char*, 1);
6484 if (!arg_properties
)
6487 const char *word
, *state
;
6490 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6493 prop
= strndup(word
, size
);
6497 if (strv_consume(&arg_properties
, prop
) < 0)
6502 /* If the user asked for a particular
6503 * property, show it to him, even if it is
6515 arg_dependency
= DEPENDENCY_REVERSE
;
6519 arg_dependency
= DEPENDENCY_AFTER
;
6523 arg_dependency
= DEPENDENCY_BEFORE
;
6526 case ARG_SHOW_TYPES
:
6527 arg_show_types
= true;
6531 arg_job_mode
= optarg
;
6535 arg_job_mode
= "fail";
6538 case ARG_IRREVERSIBLE
:
6539 arg_job_mode
= "replace-irreversibly";
6542 case ARG_IGNORE_DEPENDENCIES
:
6543 arg_job_mode
= "ignore-dependencies";
6547 arg_scope
= UNIT_FILE_USER
;
6551 arg_scope
= UNIT_FILE_SYSTEM
;
6555 arg_scope
= UNIT_FILE_GLOBAL
;
6559 arg_no_block
= true;
6563 arg_no_legend
= true;
6567 arg_no_pager
= true;
6583 if (strv_extend(&arg_states
, "failed") < 0)
6601 arg_no_reload
= true;
6605 arg_kill_who
= optarg
;
6609 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
6610 log_error("Failed to parse signal string %s.", optarg
);
6615 case ARG_NO_ASK_PASSWORD
:
6616 arg_ask_password
= false;
6620 arg_transport
= BUS_TRANSPORT_REMOTE
;
6625 arg_transport
= BUS_TRANSPORT_MACHINE
;
6634 if (safe_atou(optarg
, &arg_lines
) < 0) {
6635 log_error("Failed to parse lines '%s'", optarg
);
6641 arg_output
= output_mode_from_string(optarg
);
6642 if (arg_output
< 0) {
6643 log_error("Unknown output '%s'.", optarg
);
6649 arg_ignore_inhibitors
= true;
6656 case ARG_FIRMWARE_SETUP
:
6657 arg_firmware_setup
= true;
6661 const char *word
, *state
;
6664 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6667 s
= strndup(word
, size
);
6671 if (strv_consume(&arg_states
, s
) < 0)
6678 if (geteuid() != 0) {
6679 log_error("--recursive requires root privileges.");
6683 arg_recursive
= true;
6686 case ARG_PRESET_MODE
:
6688 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6689 if (arg_preset_mode
< 0) {
6690 log_error("Failed to parse preset mode: %s.", optarg
);
6701 if (strv_extend(&arg_wall
, optarg
) < 0)
6709 assert_not_reached("Unhandled option");
6712 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6713 log_error("Cannot access user instance remotely.");
6720 static int halt_parse_argv(int argc
, char *argv
[]) {
6729 static const struct option options
[] = {
6730 { "help", no_argument
, NULL
, ARG_HELP
},
6731 { "halt", no_argument
, NULL
, ARG_HALT
},
6732 { "poweroff", no_argument
, NULL
, 'p' },
6733 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6734 { "force", no_argument
, NULL
, 'f' },
6735 { "wtmp-only", no_argument
, NULL
, 'w' },
6736 { "no-wtmp", no_argument
, NULL
, 'd' },
6737 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6746 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6747 if (runlevel
== '0' || runlevel
== '6')
6750 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6758 arg_action
= ACTION_HALT
;
6762 if (arg_action
!= ACTION_REBOOT
)
6763 arg_action
= ACTION_POWEROFF
;
6767 arg_action
= ACTION_REBOOT
;
6789 /* Compatibility nops */
6796 assert_not_reached("Unhandled option");
6799 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6800 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6803 } else if (optind
< argc
) {
6804 log_error("Too many arguments.");
6811 static int parse_time_spec(const char *t
, usec_t
*_u
) {
6815 if (streq(t
, "now"))
6817 else if (!strchr(t
, ':')) {
6820 if (safe_atou64(t
, &u
) < 0)
6823 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6832 hour
= strtol(t
, &e
, 10);
6833 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6836 minute
= strtol(e
+1, &e
, 10);
6837 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6840 n
= now(CLOCK_REALTIME
);
6841 s
= (time_t) (n
/ USEC_PER_SEC
);
6843 assert_se(localtime_r(&s
, &tm
));
6845 tm
.tm_hour
= (int) hour
;
6846 tm
.tm_min
= (int) minute
;
6849 assert_se(s
= mktime(&tm
));
6851 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6854 *_u
+= USEC_PER_DAY
;
6860 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6867 static const struct option options
[] = {
6868 { "help", no_argument
, NULL
, ARG_HELP
},
6869 { "halt", no_argument
, NULL
, 'H' },
6870 { "poweroff", no_argument
, NULL
, 'P' },
6871 { "reboot", no_argument
, NULL
, 'r' },
6872 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6873 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6882 while ((c
= getopt_long(argc
, argv
, "HPrhkKt:afFc", options
, NULL
)) >= 0)
6890 arg_action
= ACTION_HALT
;
6894 arg_action
= ACTION_POWEROFF
;
6899 arg_action
= ACTION_KEXEC
;
6901 arg_action
= ACTION_REBOOT
;
6905 arg_action
= ACTION_KEXEC
;
6909 if (arg_action
!= ACTION_HALT
)
6910 arg_action
= ACTION_POWEROFF
;
6925 /* Compatibility nops */
6929 arg_action
= ACTION_CANCEL_SHUTDOWN
;
6936 assert_not_reached("Unhandled option");
6939 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
6940 r
= parse_time_spec(argv
[optind
], &arg_when
);
6942 log_error("Failed to parse time specification: %s", argv
[optind
]);
6946 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
6948 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
6949 /* No time argument for shutdown cancel */
6950 arg_wall
= argv
+ optind
;
6951 else if (argc
> optind
+ 1)
6952 /* We skip the time argument */
6953 arg_wall
= argv
+ optind
+ 1;
6960 static int telinit_parse_argv(int argc
, char *argv
[]) {
6967 static const struct option options
[] = {
6968 { "help", no_argument
, NULL
, ARG_HELP
},
6969 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6973 static const struct {
6977 { '0', ACTION_POWEROFF
},
6978 { '6', ACTION_REBOOT
},
6979 { '1', ACTION_RESCUE
},
6980 { '2', ACTION_RUNLEVEL2
},
6981 { '3', ACTION_RUNLEVEL3
},
6982 { '4', ACTION_RUNLEVEL4
},
6983 { '5', ACTION_RUNLEVEL5
},
6984 { 's', ACTION_RESCUE
},
6985 { 'S', ACTION_RESCUE
},
6986 { 'q', ACTION_RELOAD
},
6987 { 'Q', ACTION_RELOAD
},
6988 { 'u', ACTION_REEXEC
},
6989 { 'U', ACTION_REEXEC
}
6998 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7013 assert_not_reached("Unhandled option");
7016 if (optind
>= argc
) {
7017 log_error("%s: required argument missing.",
7018 program_invocation_short_name
);
7022 if (optind
+ 1 < argc
) {
7023 log_error("Too many arguments.");
7027 if (strlen(argv
[optind
]) != 1) {
7028 log_error("Expected single character argument.");
7032 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7033 if (table
[i
].from
== argv
[optind
][0])
7036 if (i
>= ELEMENTSOF(table
)) {
7037 log_error("Unknown command '%s'.", argv
[optind
]);
7041 arg_action
= table
[i
].to
;
7048 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7054 static const struct option options
[] = {
7055 { "help", no_argument
, NULL
, ARG_HELP
},
7064 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7075 assert_not_reached("Unhandled option");
7078 if (optind
< argc
) {
7079 log_error("Too many arguments.");
7086 static int parse_argv(int argc
, char *argv
[]) {
7090 if (program_invocation_short_name
) {
7092 if (strstr(program_invocation_short_name
, "halt")) {
7093 arg_action
= ACTION_HALT
;
7094 return halt_parse_argv(argc
, argv
);
7095 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7096 arg_action
= ACTION_POWEROFF
;
7097 return halt_parse_argv(argc
, argv
);
7098 } else if (strstr(program_invocation_short_name
, "reboot")) {
7100 arg_action
= ACTION_KEXEC
;
7102 arg_action
= ACTION_REBOOT
;
7103 return halt_parse_argv(argc
, argv
);
7104 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7105 arg_action
= ACTION_POWEROFF
;
7106 return shutdown_parse_argv(argc
, argv
);
7107 } else if (strstr(program_invocation_short_name
, "init")) {
7109 if (sd_booted() > 0) {
7110 arg_action
= _ACTION_INVALID
;
7111 return telinit_parse_argv(argc
, argv
);
7113 /* Hmm, so some other init system is
7114 * running, we need to forward this
7115 * request to it. For now we simply
7116 * guess that it is Upstart. */
7118 execv(TELINIT
, argv
);
7120 log_error("Couldn't find an alternative telinit implementation to spawn.");
7124 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7125 arg_action
= ACTION_RUNLEVEL
;
7126 return runlevel_parse_argv(argc
, argv
);
7130 arg_action
= ACTION_SYSTEMCTL
;
7131 return systemctl_parse_argv(argc
, argv
);
7134 _pure_
static int action_to_runlevel(void) {
7136 static const char table
[_ACTION_MAX
] = {
7137 [ACTION_HALT
] = '0',
7138 [ACTION_POWEROFF
] = '0',
7139 [ACTION_REBOOT
] = '6',
7140 [ACTION_RUNLEVEL2
] = '2',
7141 [ACTION_RUNLEVEL3
] = '3',
7142 [ACTION_RUNLEVEL4
] = '4',
7143 [ACTION_RUNLEVEL5
] = '5',
7144 [ACTION_RESCUE
] = '1'
7147 assert(arg_action
< _ACTION_MAX
);
7149 return table
[arg_action
];
7152 static int talk_initctl(void) {
7154 struct init_request request
= {
7155 .magic
= INIT_MAGIC
,
7157 .cmd
= INIT_CMD_RUNLVL
7160 _cleanup_close_
int fd
= -1;
7164 rl
= action_to_runlevel();
7168 request
.runlevel
= rl
;
7170 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7172 if (errno
== ENOENT
)
7175 log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7179 r
= loop_write(fd
, &request
, sizeof(request
), false);
7181 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7186 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
7188 static const struct {
7196 int (* const dispatch
)(sd_bus
*bus
, char **args
);
7202 { "list-units", MORE
, 0, list_units
},
7203 { "list-unit-files", MORE
, 1, list_unit_files
, NOBUS
},
7204 { "list-sockets", MORE
, 1, list_sockets
},
7205 { "list-timers", MORE
, 1, list_timers
},
7206 { "list-jobs", MORE
, 1, list_jobs
},
7207 { "list-machines", MORE
, 1, list_machines
},
7208 { "clear-jobs", EQUAL
, 1, daemon_reload
},
7209 { "cancel", MORE
, 2, cancel_job
},
7210 { "start", MORE
, 2, start_unit
},
7211 { "stop", MORE
, 2, start_unit
},
7212 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7213 { "reload", MORE
, 2, start_unit
},
7214 { "restart", MORE
, 2, start_unit
},
7215 { "try-restart", MORE
, 2, start_unit
},
7216 { "reload-or-restart", MORE
, 2, start_unit
},
7217 { "reload-or-try-restart", MORE
, 2, start_unit
},
7218 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
7219 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7220 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
7221 { "isolate", EQUAL
, 2, start_unit
},
7222 { "kill", MORE
, 2, kill_unit
},
7223 { "is-active", MORE
, 2, check_unit_active
},
7224 { "check", MORE
, 2, check_unit_active
},
7225 { "is-failed", MORE
, 2, check_unit_failed
},
7226 { "show", MORE
, 1, show
},
7227 { "cat", MORE
, 2, cat
, NOBUS
},
7228 { "status", MORE
, 1, show
},
7229 { "help", MORE
, 2, show
},
7230 { "snapshot", LESS
, 2, snapshot
},
7231 { "delete", MORE
, 2, delete_snapshot
},
7232 { "daemon-reload", EQUAL
, 1, daemon_reload
},
7233 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
7234 { "show-environment", EQUAL
, 1, show_environment
},
7235 { "set-environment", MORE
, 2, set_environment
},
7236 { "unset-environment", MORE
, 2, set_environment
},
7237 { "import-environment", MORE
, 1, import_environment
},
7238 { "halt", EQUAL
, 1, start_special
, FORCE
},
7239 { "poweroff", EQUAL
, 1, start_special
, FORCE
},
7240 { "reboot", MORE
, 1, start_special
, FORCE
},
7241 { "kexec", EQUAL
, 1, start_special
},
7242 { "suspend", EQUAL
, 1, start_special
},
7243 { "hibernate", EQUAL
, 1, start_special
},
7244 { "hybrid-sleep", EQUAL
, 1, start_special
},
7245 { "default", EQUAL
, 1, start_special
},
7246 { "rescue", EQUAL
, 1, start_special
},
7247 { "emergency", EQUAL
, 1, start_special
},
7248 { "exit", LESS
, 2, start_special
},
7249 { "reset-failed", MORE
, 1, reset_failed
},
7250 { "enable", MORE
, 2, enable_unit
, NOBUS
},
7251 { "disable", MORE
, 2, enable_unit
, NOBUS
},
7252 { "is-enabled", MORE
, 2, unit_is_enabled
, NOBUS
},
7253 { "reenable", MORE
, 2, enable_unit
, NOBUS
},
7254 { "preset", MORE
, 2, enable_unit
, NOBUS
},
7255 { "preset-all", EQUAL
, 1, preset_all
, NOBUS
},
7256 { "mask", MORE
, 2, enable_unit
, NOBUS
},
7257 { "unmask", MORE
, 2, enable_unit
, NOBUS
},
7258 { "link", MORE
, 2, enable_unit
, NOBUS
},
7259 { "switch-root", MORE
, 2, switch_root
},
7260 { "list-dependencies", LESS
, 2, list_dependencies
},
7261 { "set-default", EQUAL
, 2, set_default
, NOBUS
},
7262 { "get-default", EQUAL
, 1, get_default
, NOBUS
},
7263 { "set-property", MORE
, 3, set_property
},
7264 { "is-system-running", EQUAL
, 1, is_system_running
},
7265 { "add-wants", MORE
, 3, add_dependency
, NOBUS
},
7266 { "add-requires", MORE
, 3, add_dependency
, NOBUS
},
7267 { "edit", MORE
, 2, edit
, NOBUS
},
7276 left
= argc
- optind
;
7278 /* Special rule: no arguments (left == 0) means "list-units" */
7280 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
7281 log_error("This command expects one or more "
7282 "unit names. Did you mean --help?");
7286 for (; verb
->verb
; verb
++)
7287 if (streq(argv
[optind
], verb
->verb
))
7290 log_error("Unknown operation '%s'.", argv
[optind
]);
7295 switch (verb
->argc_cmp
) {
7298 if (left
!= verb
->argc
) {
7299 log_error("Invalid number of arguments.");
7306 if (left
< verb
->argc
) {
7307 log_error("Too few arguments.");
7314 if (left
> verb
->argc
) {
7315 log_error("Too many arguments.");
7322 assert_not_reached("Unknown comparison operator.");
7325 /* Require a bus connection for all operations but
7327 if (verb
->bus
== NOBUS
) {
7328 if (!bus
&& !avoid_bus()) {
7329 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7334 if (running_in_chroot() > 0) {
7335 log_info("Running in chroot, ignoring request.");
7339 if ((verb
->bus
!= FORCE
|| arg_force
<= 0) && !bus
) {
7340 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7345 return verb
->dispatch(bus
, argv
+ optind
);
7348 static int reload_with_fallback(sd_bus
*bus
) {
7351 /* First, try systemd via D-Bus. */
7352 if (daemon_reload(bus
, NULL
) >= 0)
7356 /* Nothing else worked, so let's try signals */
7357 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7359 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7360 return log_error_errno(errno
, "kill() failed: %m");
7365 static int start_with_fallback(sd_bus
*bus
) {
7368 /* First, try systemd via D-Bus. */
7369 if (start_unit(bus
, NULL
) >= 0)
7373 /* Nothing else worked, so let's try
7375 if (talk_initctl() > 0)
7378 log_error("Failed to talk to init daemon.");
7382 warn_wall(arg_action
);
7386 static int halt_now(enum action a
) {
7388 /* The kernel will automaticall flush ATA disks and suchlike
7389 * on reboot(), but the file systems need to be synce'd
7390 * explicitly in advance. */
7393 /* Make sure C-A-D is handled by the kernel from this point
7395 reboot(RB_ENABLE_CAD
);
7400 log_info("Halting.");
7401 reboot(RB_HALT_SYSTEM
);
7404 case ACTION_POWEROFF
:
7405 log_info("Powering off.");
7406 reboot(RB_POWER_OFF
);
7410 case ACTION_REBOOT
: {
7411 _cleanup_free_
char *param
= NULL
;
7413 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7414 log_info("Rebooting with argument '%s'.", param
);
7415 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
7416 LINUX_REBOOT_CMD_RESTART2
, param
);
7419 log_info("Rebooting.");
7420 reboot(RB_AUTOBOOT
);
7425 assert_not_reached("Unknown action.");
7429 static int logind_schedule_shutdown(void) {
7432 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7433 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7434 char date
[FORMAT_TIMESTAMP_MAX
];
7438 assert(geteuid() == 0);
7441 log_error("Unable to perform operation without bus connection.");
7445 r
= sd_bus_open_system(&b
);
7447 return log_error_errno(r
, "Unable to open system bus: %m");
7449 (void) logind_set_wall_message(b
);
7451 switch (arg_action
) {
7455 case ACTION_POWEROFF
:
7456 action
= "poweroff";
7467 action
= strjoina("dry-", action
);
7469 r
= sd_bus_call_method(
7471 "org.freedesktop.login1",
7472 "/org/freedesktop/login1",
7473 "org.freedesktop.login1.Manager",
7481 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7483 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7486 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7491 static int halt_main(sd_bus
*bus
) {
7494 r
= logind_check_inhibitors(bus
, arg_action
);
7498 if (geteuid() != 0) {
7502 log_error("Must be root.");
7506 /* Try logind if we are a normal user and no special
7507 * mode applies. Maybe PolicyKit allows us to shutdown
7509 if (IN_SET(arg_action
,
7512 r
= logind_reboot(bus
, arg_action
);
7515 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7516 /* requested operation is not supported or already in progress */
7518 /* on all other errors, try low-level operation */
7523 r
= logind_schedule_shutdown();
7528 if (!arg_dry
&& !arg_force
)
7529 return start_with_fallback(bus
);
7531 assert(geteuid() == 0);
7534 if (sd_booted() > 0)
7535 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7537 r
= utmp_put_shutdown();
7539 log_warning_errno(r
, "Failed to write utmp record: %m");
7546 r
= halt_now(arg_action
);
7547 log_error_errno(r
, "Failed to reboot: %m");
7552 static int runlevel_main(void) {
7553 int r
, runlevel
, previous
;
7555 r
= utmp_get_runlevel(&runlevel
, &previous
);
7562 previous
<= 0 ? 'N' : previous
,
7563 runlevel
<= 0 ? 'N' : runlevel
);
7568 static int logind_cancel_shutdown(void) {
7570 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7571 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7575 log_error("Unable to perform operation without bus connection.");
7579 r
= sd_bus_open_system(&b
);
7581 return log_error_errno(r
, "Unable to open system bus: %m");
7583 (void) logind_set_wall_message(b
);
7585 r
= sd_bus_call_method(
7587 "org.freedesktop.login1",
7588 "/org/freedesktop/login1",
7589 "org.freedesktop.login1.Manager",
7590 "CancelScheduledShutdown",
7594 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7598 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7603 int main(int argc
, char*argv
[]) {
7604 _cleanup_bus_flush_close_unref_ sd_bus
*bus
= NULL
;
7607 setlocale(LC_ALL
, "");
7608 log_parse_environment();
7611 /* Explicitly not on_tty() to avoid setting cached value.
7612 * This becomes relevant for piping output which might be
7614 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7616 r
= parse_argv(argc
, argv
);
7620 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7621 log_info("Running in chroot, ignoring request.");
7627 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
7630 sd_bus_set_allow_interactive_authorization(bus
, arg_ask_password
);
7632 /* systemctl_main() will print an error message for the bus
7633 * connection, but only if it needs to */
7635 switch (arg_action
) {
7637 case ACTION_SYSTEMCTL
:
7638 r
= systemctl_main(bus
, argc
, argv
, r
);
7642 case ACTION_POWEROFF
:
7648 case ACTION_RUNLEVEL2
:
7649 case ACTION_RUNLEVEL3
:
7650 case ACTION_RUNLEVEL4
:
7651 case ACTION_RUNLEVEL5
:
7653 case ACTION_EMERGENCY
:
7654 case ACTION_DEFAULT
:
7655 r
= start_with_fallback(bus
);
7660 r
= reload_with_fallback(bus
);
7663 case ACTION_CANCEL_SHUTDOWN
:
7664 r
= logind_cancel_shutdown();
7667 case ACTION_RUNLEVEL
:
7668 r
= runlevel_main();
7671 case _ACTION_INVALID
:
7673 assert_not_reached("Unknown action");
7678 ask_password_agent_close();
7679 polkit_agent_close();
7681 strv_free(arg_types
);
7682 strv_free(arg_states
);
7683 strv_free(arg_properties
);
7685 sd_bus_default_flush_close();
7687 return r
< 0 ? EXIT_FAILURE
: r
;