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 char** strv_skip_first(char **strv
) {
150 if (strv_length(strv
) > 0)
155 static void pager_open_if_enabled(void) {
163 static void ask_password_agent_open_if_enabled(void) {
165 /* Open the password agent as a child process if necessary */
167 if (!arg_ask_password
)
170 if (arg_scope
!= UNIT_FILE_SYSTEM
)
173 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
176 ask_password_agent_open();
179 static void polkit_agent_open_if_enabled(void) {
181 /* Open the polkit agent as a child process if necessary */
183 if (!arg_ask_password
)
186 if (arg_scope
!= UNIT_FILE_SYSTEM
)
189 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
195 static OutputFlags
get_output_flags(void) {
197 arg_all
* OUTPUT_SHOW_ALL
|
198 arg_full
* OUTPUT_FULL_WIDTH
|
199 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
200 on_tty() * OUTPUT_COLOR
|
201 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
204 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
207 if (!sd_bus_error_is_set(error
))
210 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
211 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
212 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
213 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
214 return EXIT_NOPERMISSION
;
216 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
217 return EXIT_NOTINSTALLED
;
219 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
220 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
221 return EXIT_NOTIMPLEMENTED
;
223 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
224 return EXIT_NOTCONFIGURED
;
232 static void warn_wall(enum action a
) {
233 static const char *table
[_ACTION_MAX
] = {
234 [ACTION_HALT
] = "The system is going down for system halt NOW!",
235 [ACTION_REBOOT
] = "The system is going down for reboot NOW!",
236 [ACTION_POWEROFF
] = "The system is going down for power-off NOW!",
237 [ACTION_KEXEC
] = "The system is going down for kexec reboot NOW!",
238 [ACTION_RESCUE
] = "The system is going down to rescue mode NOW!",
239 [ACTION_EMERGENCY
] = "The system is going down to emergency mode NOW!",
240 [ACTION_CANCEL_SHUTDOWN
] = "The system shutdown has been cancelled NOW!"
247 _cleanup_free_
char *p
;
249 p
= strv_join(arg_wall
, " ");
256 utmp_wall(p
, NULL
, NULL
, NULL
, NULL
);
264 utmp_wall(table
[a
], NULL
, NULL
, NULL
, NULL
);
267 static bool avoid_bus(void) {
269 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
270 * let's shortcut this */
271 if (arg_action
== ACTION_RUNLEVEL
)
274 if (running_in_chroot() > 0)
277 if (sd_booted() <= 0)
280 if (!isempty(arg_root
))
283 if (arg_scope
== UNIT_FILE_GLOBAL
)
289 static int compare_unit_info(const void *a
, const void *b
) {
290 const UnitInfo
*u
= a
, *v
= b
;
294 /* First, order by machine */
295 if (!u
->machine
&& v
->machine
)
297 if (u
->machine
&& !v
->machine
)
299 if (u
->machine
&& v
->machine
) {
300 r
= strcasecmp(u
->machine
, v
->machine
);
305 /* Second, order by unit type */
306 d1
= strrchr(u
->id
, '.');
307 d2
= strrchr(v
->id
, '.');
309 r
= strcasecmp(d1
, d2
);
314 /* Third, order by name */
315 return strcasecmp(u
->id
, v
->id
);
318 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
319 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
325 dot
= strrchr(u
->id
, '.');
329 if (!strv_find(arg_types
, dot
+1))
339 if (streq(u
->active_state
, "inactive") || u
->following
[0])
345 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
346 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
348 unsigned n_shown
= 0;
351 max_id_len
= strlen("UNIT");
352 load_len
= strlen("LOAD");
353 active_len
= strlen("ACTIVE");
354 sub_len
= strlen("SUB");
355 job_len
= strlen("JOB");
358 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
359 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
360 load_len
= MAX(load_len
, strlen(u
->load_state
));
361 active_len
= MAX(active_len
, strlen(u
->active_state
));
362 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
364 if (u
->job_id
!= 0) {
365 job_len
= MAX(job_len
, strlen(u
->job_type
));
369 if (!arg_no_legend
&&
370 (streq(u
->active_state
, "failed") ||
371 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
375 if (!arg_full
&& original_stdout_is_tty
) {
378 id_len
= MIN(max_id_len
, 25u);
379 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
382 basic_len
+= job_len
+ 1;
384 if (basic_len
< (unsigned) columns()) {
385 unsigned extra_len
, incr
;
386 extra_len
= columns() - basic_len
;
388 /* Either UNIT already got 25, or is fully satisfied.
389 * Grant up to 25 to DESC now. */
390 incr
= MIN(extra_len
, 25u);
394 /* split the remaining space between UNIT and DESC,
395 * but do not give UNIT more than it needs. */
397 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
399 desc_len
+= extra_len
- incr
;
405 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
406 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
407 const char *on_loaded
= "", *off_loaded
= "";
408 const char *on_active
= "", *off_active
= "";
409 const char *on_circle
= "", *off_circle
= "";
413 if (!n_shown
&& !arg_no_legend
) {
418 printf("%-*s %-*s %-*s %-*s ",
421 active_len
, "ACTIVE",
425 printf("%-*s ", job_len
, "JOB");
427 if (!arg_full
&& arg_no_pager
)
428 printf("%.*s\n", desc_len
, "DESCRIPTION");
430 printf("%s\n", "DESCRIPTION");
435 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
436 on_loaded
= ansi_highlight_red();
437 on_circle
= ansi_highlight_yellow();
438 off_loaded
= off_circle
= ansi_normal();
440 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
441 on_circle
= on_active
= ansi_highlight_red();
442 off_circle
= off_active
= ansi_normal();
447 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
456 e
= ellipsize(id
, id_len
, 33);
464 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
466 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
467 on_active
, id_len
, id
, off_active
,
468 on_loaded
, load_len
, u
->load_state
, off_loaded
,
469 on_active
, active_len
, u
->active_state
,
470 sub_len
, u
->sub_state
, off_active
,
471 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
474 printf("%.*s\n", desc_len
, u
->description
);
476 printf("%s\n", u
->description
);
479 if (!arg_no_legend
) {
480 const char *on
, *off
;
484 "LOAD = Reflects whether the unit definition was properly loaded.\n"
485 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
486 "SUB = The low-level unit activation state, values depend on unit type.");
487 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
488 on
= ansi_highlight();
491 on
= ansi_highlight_red();
496 printf("%s%u loaded units listed.%s\n"
497 "To show all installed unit files use 'systemctl list-unit-files'.\n",
500 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
501 "To show all installed unit files use 'systemctl list-unit-files'.\n",
508 static int get_unit_list(
512 UnitInfo
**unit_infos
,
514 sd_bus_message
**_reply
) {
516 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
517 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
518 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
527 r
= sd_bus_message_new_method_call(
530 "org.freedesktop.systemd1",
531 "/org/freedesktop/systemd1",
532 "org.freedesktop.systemd1.Manager",
533 "ListUnitsFiltered");
536 return bus_log_create_error(r
);
538 r
= sd_bus_message_append_strv(m
, arg_states
);
540 return bus_log_create_error(r
);
542 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
544 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
546 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
548 return bus_log_parse_error(r
);
550 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
553 if (!output_show_unit(&u
, patterns
))
556 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
559 (*unit_infos
)[c
++] = u
;
562 return bus_log_parse_error(r
);
564 r
= sd_bus_message_exit_container(reply
);
566 return bus_log_parse_error(r
);
574 static void message_set_freep(Set
**set
) {
577 while ((m
= set_steal_first(*set
)))
578 sd_bus_message_unref(m
);
583 static int get_unit_list_recursive(
586 UnitInfo
**_unit_infos
,
590 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
591 _cleanup_(message_set_freep
) Set
*replies
;
592 sd_bus_message
*reply
;
600 replies
= set_new(NULL
);
604 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
608 r
= set_put(replies
, reply
);
610 sd_bus_message_unref(reply
);
615 _cleanup_strv_free_
char **machines
= NULL
;
618 r
= sd_get_machine_names(&machines
);
620 return log_error_errno(r
, "Failed to get machine names: %m");
622 STRV_FOREACH(i
, machines
) {
623 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
626 r
= sd_bus_open_system_machine(&container
, *i
);
628 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
632 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
638 r
= set_put(replies
, reply
);
640 sd_bus_message_unref(reply
);
645 *_machines
= machines
;
650 *_unit_infos
= unit_infos
;
659 static int list_units(sd_bus
*bus
, char **args
) {
660 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
661 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
662 _cleanup_strv_free_
char **machines
= NULL
;
665 pager_open_if_enabled();
667 r
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
671 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
672 return output_units_list(unit_infos
, r
);
675 static int get_triggered_units(
680 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
683 r
= sd_bus_get_property_strv(
685 "org.freedesktop.systemd1",
687 "org.freedesktop.systemd1.Unit",
693 log_error("Failed to determine triggers: %s", bus_error_message(&error
, r
));
698 static int get_listening(
700 const char* unit_path
,
703 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
704 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
705 const char *type
, *path
;
708 r
= sd_bus_get_property(
710 "org.freedesktop.systemd1",
712 "org.freedesktop.systemd1.Socket",
718 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
722 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
724 return bus_log_parse_error(r
);
726 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
728 r
= strv_extend(listening
, type
);
732 r
= strv_extend(listening
, path
);
739 return bus_log_parse_error(r
);
741 r
= sd_bus_message_exit_container(reply
);
743 return bus_log_parse_error(r
);
755 /* Note: triggered is a list here, although it almost certainly
756 * will always be one unit. Nevertheless, dbus API allows for multiple
757 * values, so let's follow that. */
760 /* The strv above is shared. free is set only in the first one. */
764 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
770 if (!a
->machine
&& b
->machine
)
772 if (a
->machine
&& !b
->machine
)
774 if (a
->machine
&& b
->machine
) {
775 o
= strcasecmp(a
->machine
, b
->machine
);
780 o
= strcmp(a
->path
, b
->path
);
782 o
= strcmp(a
->type
, b
->type
);
787 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
788 struct socket_info
*s
;
789 unsigned pathlen
= strlen("LISTEN"),
790 typelen
= strlen("TYPE") * arg_show_types
,
791 socklen
= strlen("UNIT"),
792 servlen
= strlen("ACTIVATES");
793 const char *on
, *off
;
795 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
799 socklen
= MAX(socklen
, strlen(s
->id
));
801 typelen
= MAX(typelen
, strlen(s
->type
));
802 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
804 STRV_FOREACH(a
, s
->triggered
)
805 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
806 servlen
= MAX(servlen
, tmp
);
811 printf("%-*s %-*.*s%-*s %s\n",
813 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
817 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
818 _cleanup_free_
char *j
= NULL
;
823 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
831 printf("%-*s %-*s %-*s",
832 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
835 pathlen
, path
, socklen
, s
->id
);
836 STRV_FOREACH(a
, s
->triggered
)
838 a
== s
->triggered
? "" : ",", *a
);
842 on
= ansi_highlight();
847 on
= ansi_highlight_red();
851 if (!arg_no_legend
) {
852 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
854 printf("Pass --all to see loaded but inactive sockets, too.\n");
860 static int list_sockets(sd_bus
*bus
, char **args
) {
861 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
862 _cleanup_strv_free_
char **machines
= NULL
;
863 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
864 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
866 struct socket_info
*s
;
871 pager_open_if_enabled();
873 n
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
877 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
878 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
881 if (!endswith(u
->id
, ".socket"))
884 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
888 c
= get_listening(bus
, u
->unit_path
, &listening
);
894 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
899 for (i
= 0; i
< c
; i
++)
900 socket_infos
[cs
+ i
] = (struct socket_info
) {
901 .machine
= u
->machine
,
903 .type
= listening
[i
*2],
904 .path
= listening
[i
*2 + 1],
905 .triggered
= triggered
,
906 .own_triggered
= i
==0,
909 /* from this point on we will cleanup those socket_infos */
912 listening
= triggered
= NULL
; /* avoid cleanup */
915 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
916 (__compar_fn_t
) socket_info_compare
);
918 output_sockets_list(socket_infos
, cs
);
921 assert(cs
== 0 || socket_infos
);
922 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
925 if (s
->own_triggered
)
926 strv_free(s
->triggered
);
932 static int get_next_elapse(
935 dual_timestamp
*next
) {
937 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
945 r
= sd_bus_get_property_trivial(
947 "org.freedesktop.systemd1",
949 "org.freedesktop.systemd1.Timer",
950 "NextElapseUSecMonotonic",
955 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
959 r
= sd_bus_get_property_trivial(
961 "org.freedesktop.systemd1",
963 "org.freedesktop.systemd1.Timer",
964 "NextElapseUSecRealtime",
969 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
977 static int get_last_trigger(
982 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
989 r
= sd_bus_get_property_trivial(
991 "org.freedesktop.systemd1",
993 "org.freedesktop.systemd1.Timer",
999 log_error("Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1007 const char* machine
;
1010 usec_t last_trigger
;
1014 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1020 if (!a
->machine
&& b
->machine
)
1022 if (a
->machine
&& !b
->machine
)
1024 if (a
->machine
&& b
->machine
) {
1025 o
= strcasecmp(a
->machine
, b
->machine
);
1030 if (a
->next_elapse
< b
->next_elapse
)
1032 if (a
->next_elapse
> b
->next_elapse
)
1035 return strcmp(a
->id
, b
->id
);
1038 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1039 struct timer_info
*t
;
1041 nextlen
= strlen("NEXT"),
1042 leftlen
= strlen("LEFT"),
1043 lastlen
= strlen("LAST"),
1044 passedlen
= strlen("PASSED"),
1045 unitlen
= strlen("UNIT"),
1046 activatelen
= strlen("ACTIVATES");
1048 const char *on
, *off
;
1050 assert(timer_infos
|| n
== 0);
1052 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1056 if (t
->next_elapse
> 0) {
1057 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1059 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1060 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1062 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1063 leftlen
= MAX(leftlen
, strlen(trel
));
1066 if (t
->last_trigger
> 0) {
1067 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1069 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1070 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1072 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1073 passedlen
= MAX(passedlen
, strlen(trel
));
1076 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1078 STRV_FOREACH(a
, t
->triggered
)
1079 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1081 activatelen
= MAX(activatelen
, ul
);
1086 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1090 passedlen
, "PASSED",
1094 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1095 _cleanup_free_
char *j
= NULL
;
1097 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1098 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1101 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1102 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1104 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1105 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1108 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1115 printf("%-*s %-*s %-*s %-*s %-*s",
1116 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1118 STRV_FOREACH(a
, t
->triggered
)
1120 a
== t
->triggered
? "" : ",", *a
);
1124 on
= ansi_highlight();
1125 off
= ansi_normal();
1129 on
= ansi_highlight_red();
1130 off
= ansi_normal();
1133 if (!arg_no_legend
) {
1134 printf("%s%u timers listed.%s\n", on
, n
, off
);
1136 printf("Pass --all to see loaded but inactive timers, too.\n");
1142 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1148 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1151 if (next
->monotonic
> nw
->monotonic
)
1152 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1154 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1156 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1157 next_elapse
= MIN(converted
, next
->realtime
);
1159 next_elapse
= converted
;
1162 next_elapse
= next
->realtime
;
1167 static int list_timers(sd_bus
*bus
, char **args
) {
1168 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1169 _cleanup_strv_free_
char **machines
= NULL
;
1170 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1171 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1172 struct timer_info
*t
;
1179 pager_open_if_enabled();
1181 n
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
1185 dual_timestamp_get(&nw
);
1187 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1188 _cleanup_strv_free_
char **triggered
= NULL
;
1189 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1192 if (!endswith(u
->id
, ".timer"))
1195 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1199 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1203 get_last_trigger(bus
, u
->unit_path
, &last
);
1205 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1210 m
= calc_next_elapse(&nw
, &next
);
1212 timer_infos
[c
++] = (struct timer_info
) {
1213 .machine
= u
->machine
,
1216 .last_trigger
= last
,
1217 .triggered
= triggered
,
1220 triggered
= NULL
; /* avoid cleanup */
1223 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1224 (__compar_fn_t
) timer_info_compare
);
1226 output_timers_list(timer_infos
, c
);
1229 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1230 strv_free(t
->triggered
);
1235 static int compare_unit_file_list(const void *a
, const void *b
) {
1236 const char *d1
, *d2
;
1237 const UnitFileList
*u
= a
, *v
= b
;
1239 d1
= strrchr(u
->path
, '.');
1240 d2
= strrchr(v
->path
, '.');
1245 r
= strcasecmp(d1
, d2
);
1250 return strcasecmp(basename(u
->path
), basename(v
->path
));
1253 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1254 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1257 if (!strv_isempty(arg_types
)) {
1260 dot
= strrchr(u
->path
, '.');
1264 if (!strv_find(arg_types
, dot
+1))
1268 if (!strv_isempty(arg_states
) &&
1269 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1275 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1276 unsigned max_id_len
, id_cols
, state_cols
;
1277 const UnitFileList
*u
;
1279 max_id_len
= strlen("UNIT FILE");
1280 state_cols
= strlen("STATE");
1282 for (u
= units
; u
< units
+ c
; u
++) {
1283 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1284 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1288 unsigned basic_cols
;
1290 id_cols
= MIN(max_id_len
, 25u);
1291 basic_cols
= 1 + id_cols
+ state_cols
;
1292 if (basic_cols
< (unsigned) columns())
1293 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1295 id_cols
= max_id_len
;
1298 printf("%-*s %-*s\n",
1299 id_cols
, "UNIT FILE",
1300 state_cols
, "STATE");
1302 for (u
= units
; u
< units
+ c
; u
++) {
1303 _cleanup_free_
char *e
= NULL
;
1304 const char *on
, *off
;
1307 if (IN_SET(u
->state
,
1309 UNIT_FILE_MASKED_RUNTIME
,
1311 UNIT_FILE_INVALID
)) {
1312 on
= ansi_highlight_red();
1313 off
= ansi_normal();
1314 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1315 on
= ansi_highlight_green();
1316 off
= ansi_normal();
1320 id
= basename(u
->path
);
1322 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1324 printf("%-*s %s%-*s%s\n",
1325 id_cols
, e
? e
: id
,
1326 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1330 printf("\n%u unit files listed.\n", c
);
1333 static int list_unit_files(sd_bus
*bus
, char **args
) {
1334 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1335 _cleanup_free_ UnitFileList
*units
= NULL
;
1343 pager_open_if_enabled();
1351 h
= hashmap_new(&string_hash_ops
);
1355 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1357 unit_file_list_free(h
);
1358 log_error_errno(r
, "Failed to get unit file list: %m");
1362 n_units
= hashmap_size(h
);
1364 units
= new(UnitFileList
, n_units
);
1365 if (!units
&& n_units
> 0) {
1366 unit_file_list_free(h
);
1370 HASHMAP_FOREACH(u
, h
, i
) {
1371 if (!output_show_unit_file(u
, strv_skip_first(args
)))
1378 assert(c
<= n_units
);
1381 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1383 r
= sd_bus_call_method(
1385 "org.freedesktop.systemd1",
1386 "/org/freedesktop/systemd1",
1387 "org.freedesktop.systemd1.Manager",
1393 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1397 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1399 return bus_log_parse_error(r
);
1401 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1403 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1406 units
[c
] = (struct UnitFileList
) {
1408 unit_file_state_from_string(state
)
1411 if (output_show_unit_file(&units
[c
], strv_skip_first(args
)))
1416 return bus_log_parse_error(r
);
1418 r
= sd_bus_message_exit_container(reply
);
1420 return bus_log_parse_error(r
);
1423 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1424 output_unit_file_list(units
, c
);
1427 for (unit
= units
; unit
< units
+ c
; unit
++)
1434 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1435 _cleanup_free_
char *n
= NULL
;
1436 size_t max_len
= MAX(columns(),20u);
1442 for (i
= level
- 1; i
>= 0; i
--) {
1444 if (len
> max_len
- 3 && !arg_full
) {
1445 printf("%s...\n",max_len
% 2 ? "" : " ");
1448 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1452 if (len
> max_len
- 3 && !arg_full
) {
1453 printf("%s...\n",max_len
% 2 ? "" : " ");
1457 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1461 printf("%s\n", name
);
1465 n
= ellipsize(name
, max_len
-len
, 100);
1473 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1475 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1476 [DEPENDENCY_FORWARD
] = "Requires\0"
1477 "RequiresOverridable\0"
1479 "RequisiteOverridable\0"
1483 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1484 "RequiredByOverridable\0"
1486 "RequisiteOfOverridable\0"
1490 [DEPENDENCY_AFTER
] = "After\0",
1491 [DEPENDENCY_BEFORE
] = "Before\0",
1494 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1495 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1496 _cleanup_strv_free_
char **ret
= NULL
;
1497 _cleanup_free_
char *path
= NULL
;
1503 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1505 path
= unit_dbus_path_from_name(name
);
1509 r
= sd_bus_call_method(
1511 "org.freedesktop.systemd1",
1513 "org.freedesktop.DBus.Properties",
1517 "s", "org.freedesktop.systemd1.Unit");
1519 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1523 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1525 return bus_log_parse_error(r
);
1527 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1530 r
= sd_bus_message_read(reply
, "s", &prop
);
1532 return bus_log_parse_error(r
);
1534 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1535 r
= sd_bus_message_skip(reply
, "v");
1537 return bus_log_parse_error(r
);
1540 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1542 return bus_log_parse_error(r
);
1544 r
= bus_message_read_strv_extend(reply
, &ret
);
1546 return bus_log_parse_error(r
);
1548 r
= sd_bus_message_exit_container(reply
);
1550 return bus_log_parse_error(r
);
1553 r
= sd_bus_message_exit_container(reply
);
1555 return bus_log_parse_error(r
);
1559 return bus_log_parse_error(r
);
1561 r
= sd_bus_message_exit_container(reply
);
1563 return bus_log_parse_error(r
);
1571 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1572 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1574 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1576 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1579 return strcasecmp(*a
, *b
);
1582 static int list_dependencies_one(
1587 unsigned int branches
) {
1589 _cleanup_strv_free_
char **deps
= NULL
;
1597 r
= strv_extend(units
, name
);
1601 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1605 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1607 STRV_FOREACH(c
, deps
) {
1608 if (strv_contains(*units
, *c
)) {
1610 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1623 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1624 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1625 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1628 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1632 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1633 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1640 strv_remove(*units
, name
);
1645 static int list_dependencies(sd_bus
*bus
, char **args
) {
1646 _cleanup_strv_free_
char **units
= NULL
;
1647 _cleanup_free_
char *unit
= NULL
;
1654 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &unit
);
1656 return log_error_errno(r
, "Failed to mangle unit name: %m");
1660 u
= SPECIAL_DEFAULT_TARGET
;
1662 pager_open_if_enabled();
1666 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1669 struct machine_info
{
1673 char *control_group
;
1674 uint32_t n_failed_units
;
1679 static const struct bus_properties_map machine_info_property_map
[] = {
1680 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1681 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1682 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1683 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1684 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1688 static void machine_info_clear(struct machine_info
*info
) {
1692 free(info
->control_group
);
1697 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1703 for (i
= 0; i
< n
; i
++)
1704 machine_info_clear(&machine_infos
[i
]);
1706 free(machine_infos
);
1709 static int compare_machine_info(const void *a
, const void *b
) {
1710 const struct machine_info
*u
= a
, *v
= b
;
1712 if (u
->is_host
!= v
->is_host
)
1713 return u
->is_host
> v
->is_host
? -1 : 1;
1715 return strcasecmp(u
->name
, v
->name
);
1718 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1719 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1725 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1732 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1739 static bool output_show_machine(const char *name
, char **patterns
) {
1740 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1743 static int get_machine_list(
1745 struct machine_info
**_machine_infos
,
1748 struct machine_info
*machine_infos
= NULL
;
1749 _cleanup_strv_free_
char **m
= NULL
;
1750 _cleanup_free_
char *hn
= NULL
;
1755 hn
= gethostname_malloc();
1759 if (output_show_machine(hn
, patterns
)) {
1760 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1763 machine_infos
[c
].is_host
= true;
1764 machine_infos
[c
].name
= hn
;
1767 get_machine_properties(bus
, &machine_infos
[c
]);
1771 r
= sd_get_machine_names(&m
);
1773 return log_error_errno(r
, "Failed to get machine list: %m");
1775 STRV_FOREACH(i
, m
) {
1776 _cleanup_free_
char *class = NULL
;
1778 if (!output_show_machine(*i
, patterns
))
1781 sd_machine_get_class(*i
, &class);
1782 if (!streq_ptr(class, "container"))
1785 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1786 free_machines_list(machine_infos
, c
);
1790 machine_infos
[c
].is_host
= false;
1791 machine_infos
[c
].name
= strdup(*i
);
1792 if (!machine_infos
[c
].name
) {
1793 free_machines_list(machine_infos
, c
);
1797 get_machine_properties(NULL
, &machine_infos
[c
]);
1801 *_machine_infos
= machine_infos
;
1805 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1806 struct machine_info
*m
;
1809 namelen
= sizeof("NAME") - 1,
1810 statelen
= sizeof("STATE") - 1,
1811 failedlen
= sizeof("FAILED") - 1,
1812 jobslen
= sizeof("JOBS") - 1;
1814 assert(machine_infos
|| n
== 0);
1816 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1817 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1818 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1819 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1820 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1822 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1826 if (!arg_no_legend
) {
1830 printf("%-*s %-*s %-*s %-*s\n",
1833 failedlen
, "FAILED",
1837 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1838 const char *on_state
= "", *off_state
= "";
1839 const char *on_failed
= "", *off_failed
= "";
1840 bool circle
= false;
1842 if (streq_ptr(m
->state
, "degraded")) {
1843 on_state
= ansi_highlight_red();
1844 off_state
= ansi_normal();
1846 } else if (!streq_ptr(m
->state
, "running")) {
1847 on_state
= ansi_highlight_yellow();
1848 off_state
= ansi_normal();
1852 if (m
->n_failed_units
> 0) {
1853 on_failed
= ansi_highlight_red();
1854 off_failed
= ansi_normal();
1856 on_failed
= off_failed
= "";
1859 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1862 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1863 (int) (namelen
- (sizeof(" (host)")-1)), 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
);
1868 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1869 namelen
, strna(m
->name
),
1870 on_state
, statelen
, strna(m
->state
), off_state
,
1871 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1872 jobslen
, m
->n_jobs
);
1876 printf("\n%u machines listed.\n", n
);
1879 static int list_machines(sd_bus
*bus
, char **args
) {
1880 struct machine_info
*machine_infos
= NULL
;
1885 if (geteuid() != 0) {
1886 log_error("Must be root.");
1890 pager_open_if_enabled();
1892 r
= get_machine_list(bus
, &machine_infos
, strv_skip_first(args
));
1896 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1897 output_machines_list(machine_infos
, r
);
1898 free_machines_list(machine_infos
, r
);
1903 static int get_default(sd_bus
*bus
, char **args
) {
1904 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1905 _cleanup_free_
char *_path
= NULL
;
1909 if (!bus
|| avoid_bus()) {
1910 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1912 return log_error_errno(r
, "Failed to get default target: %m");
1916 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1918 r
= sd_bus_call_method(
1920 "org.freedesktop.systemd1",
1921 "/org/freedesktop/systemd1",
1922 "org.freedesktop.systemd1.Manager",
1928 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1932 r
= sd_bus_message_read(reply
, "s", &path
);
1934 return bus_log_parse_error(r
);
1938 printf("%s\n", path
);
1943 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1946 assert(changes
|| n_changes
== 0);
1948 for (i
= 0; i
< n_changes
; i
++) {
1949 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1950 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1952 log_info("Removed symlink %s.", changes
[i
].path
);
1956 static int set_default(sd_bus
*bus
, char **args
) {
1957 _cleanup_free_
char *unit
= NULL
;
1958 UnitFileChange
*changes
= NULL
;
1959 unsigned n_changes
= 0;
1962 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1964 return log_error_errno(r
, "Failed to mangle unit name: %m");
1966 if (!bus
|| avoid_bus()) {
1967 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1969 return log_error_errno(r
, "Failed to set default target: %m");
1972 dump_unit_file_changes(changes
, n_changes
);
1976 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1977 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1979 polkit_agent_open_if_enabled();
1981 r
= sd_bus_call_method(
1983 "org.freedesktop.systemd1",
1984 "/org/freedesktop/systemd1",
1985 "org.freedesktop.systemd1.Manager",
1991 log_error("Failed to set default target: %s", bus_error_message(&error
, -r
));
1995 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
1999 /* Try to reload if enabled */
2001 r
= daemon_reload(bus
, args
);
2006 unit_file_changes_free(changes
, n_changes
);
2013 const char *name
, *type
, *state
;
2016 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2017 unsigned id_len
, unit_len
, type_len
, state_len
;
2018 const struct job_info
*j
;
2019 const char *on
, *off
;
2020 bool shorten
= false;
2022 assert(n
== 0 || jobs
);
2025 if (!arg_no_legend
) {
2026 on
= ansi_highlight_green();
2027 off
= ansi_normal();
2029 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2034 pager_open_if_enabled();
2036 id_len
= strlen("JOB");
2037 unit_len
= strlen("UNIT");
2038 type_len
= strlen("TYPE");
2039 state_len
= strlen("STATE");
2041 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2042 uint32_t id
= j
->id
;
2043 assert(j
->name
&& j
->type
&& j
->state
);
2045 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2046 unit_len
= MAX(unit_len
, strlen(j
->name
));
2047 type_len
= MAX(type_len
, strlen(j
->type
));
2048 state_len
= MAX(state_len
, strlen(j
->state
));
2051 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2052 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2057 printf("%*s %-*s %-*s %-*s\n",
2061 state_len
, "STATE");
2063 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2064 _cleanup_free_
char *e
= NULL
;
2066 if (streq(j
->state
, "running")) {
2067 on
= ansi_highlight();
2068 off
= ansi_normal();
2072 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2073 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2075 on
, unit_len
, e
? e
: j
->name
, off
,
2077 on
, state_len
, j
->state
, off
);
2080 if (!arg_no_legend
) {
2081 on
= ansi_highlight();
2082 off
= ansi_normal();
2084 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2088 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2089 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2092 static int list_jobs(sd_bus
*bus
, char **args
) {
2093 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2094 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2095 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2096 _cleanup_free_
struct job_info
*jobs
= NULL
;
2101 bool skipped
= false;
2103 r
= sd_bus_call_method(
2105 "org.freedesktop.systemd1",
2106 "/org/freedesktop/systemd1",
2107 "org.freedesktop.systemd1.Manager",
2113 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
2117 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2119 return bus_log_parse_error(r
);
2121 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2122 struct job_info job
= { id
, name
, type
, state
};
2124 if (!output_show_job(&job
, strv_skip_first(args
))) {
2129 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2135 return bus_log_parse_error(r
);
2137 r
= sd_bus_message_exit_container(reply
);
2139 return bus_log_parse_error(r
);
2141 output_jobs_list(jobs
, c
, skipped
);
2145 static int cancel_job(sd_bus
*bus
, char **args
) {
2151 if (strv_length(args
) <= 1)
2152 return daemon_reload(bus
, args
);
2154 polkit_agent_open_if_enabled();
2156 STRV_FOREACH(name
, args
+1) {
2157 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2161 q
= safe_atou32(*name
, &id
);
2163 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2165 q
= sd_bus_call_method(
2167 "org.freedesktop.systemd1",
2168 "/org/freedesktop/systemd1",
2169 "org.freedesktop.systemd1.Manager",
2175 log_error("Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2184 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2185 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2189 /* We ignore all errors here, since this is used to show a
2192 /* We don't use unit_dbus_path_from_name() directly since we
2193 * don't want to load the unit if it isn't loaded. */
2195 r
= sd_bus_call_method(
2197 "org.freedesktop.systemd1",
2198 "/org/freedesktop/systemd1",
2199 "org.freedesktop.systemd1.Manager",
2207 r
= sd_bus_message_read(reply
, "o", &path
);
2211 r
= sd_bus_get_property_trivial(
2213 "org.freedesktop.systemd1",
2215 "org.freedesktop.systemd1.Unit",
2225 static void warn_unit_file_changed(const char *name
) {
2226 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2227 ansi_highlight_red(),
2230 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2233 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2240 STRV_FOREACH(p
, lp
->unit_path
) {
2241 _cleanup_free_
char *path
;
2243 path
= path_join(arg_root
, *p
, unit_name
);
2247 if (access(path
, F_OK
) == 0) {
2257 static int unit_find_paths(
2259 const char *unit_name
,
2260 bool avoid_bus_cache
,
2262 char **fragment_path
,
2263 char ***dropin_paths
) {
2265 _cleanup_free_
char *path
= NULL
;
2266 _cleanup_strv_free_
char **dropins
= NULL
;
2270 * Finds where the unit is defined on disk. Returns 0 if the unit
2271 * is not found. Returns 1 if it is found, and sets
2272 * - the path to the unit in *path, if it exists on disk,
2273 * - and a strv of existing drop-ins in *dropins,
2274 * if the arg is not NULL and any dropins were found.
2278 assert(fragment_path
);
2281 if (!avoid_bus_cache
&& !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2282 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2283 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2284 _cleanup_free_
char *unit
= NULL
;
2285 char *unit_load_error_name
, *unit_load_error_message
;
2287 unit
= unit_dbus_path_from_name(unit_name
);
2291 if (need_daemon_reload(bus
, unit_name
) > 0)
2292 warn_unit_file_changed(unit_name
);
2294 r
= sd_bus_get_property(
2296 "org.freedesktop.systemd1",
2298 "org.freedesktop.systemd1.Unit",
2304 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2306 r
= sd_bus_message_read(
2309 &unit_load_error_name
,
2310 &unit_load_error_message
);
2312 return bus_log_parse_error(r
);
2314 if (!isempty(unit_load_error_name
)) {
2315 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2319 r
= sd_bus_get_property_string(
2321 "org.freedesktop.systemd1",
2323 "org.freedesktop.systemd1.Unit",
2328 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2331 r
= sd_bus_get_property_strv(
2333 "org.freedesktop.systemd1",
2335 "org.freedesktop.systemd1.Unit",
2340 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2343 _cleanup_set_free_ Set
*names
;
2345 names
= set_new(NULL
);
2349 r
= set_put(names
, unit_name
);
2351 return log_error_errno(r
, "Failed to add unit name: %m");
2353 r
= unit_file_find_path(lp
, unit_name
, &path
);
2358 _cleanup_free_
char *template = NULL
;
2360 r
= unit_name_template(unit_name
, &template);
2361 if (r
< 0 && r
!= -EINVAL
)
2362 return log_error_errno(r
, "Failed to determine template name: %m");
2364 r
= unit_file_find_path(lp
, template, &path
);
2371 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2379 if (!isempty(path
)) {
2380 *fragment_path
= path
;
2385 if (dropin_paths
&& !strv_isempty(dropins
)) {
2386 *dropin_paths
= dropins
;
2392 log_error("No files found for %s.", unit_name
);
2397 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2398 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2399 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2405 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2407 return log_error_errno(r
, "Failed to mangle unit name: %m");
2409 /* We don't use unit_dbus_path_from_name() directly since we
2410 * don't want to load the unit if it isn't loaded. */
2412 r
= sd_bus_call_method(
2414 "org.freedesktop.systemd1",
2415 "/org/freedesktop/systemd1",
2416 "org.freedesktop.systemd1.Manager",
2427 r
= sd_bus_message_read(reply
, "o", &path
);
2429 return bus_log_parse_error(r
);
2431 r
= sd_bus_get_property_string(
2433 "org.freedesktop.systemd1",
2435 "org.freedesktop.systemd1.Unit",
2448 return nulstr_contains(good_states
, state
);
2451 static int check_triggering_units(
2455 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2456 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2457 _cleanup_strv_free_
char **triggered_by
= NULL
;
2458 bool print_warning_label
= true;
2462 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2464 return log_error_errno(r
, "Failed to mangle unit name: %m");
2466 path
= unit_dbus_path_from_name(n
);
2470 r
= sd_bus_get_property_string(
2472 "org.freedesktop.systemd1",
2474 "org.freedesktop.systemd1.Unit",
2479 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2483 if (streq(state
, "masked"))
2486 r
= sd_bus_get_property_strv(
2488 "org.freedesktop.systemd1",
2490 "org.freedesktop.systemd1.Unit",
2495 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2499 STRV_FOREACH(i
, triggered_by
) {
2500 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2502 return log_error_errno(r
, "Failed to check unit: %m");
2507 if (print_warning_label
) {
2508 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2509 print_warning_label
= false;
2512 log_warning(" %s", *i
);
2518 static const struct {
2521 } unit_actions
[] = {
2522 { "start", "StartUnit" },
2523 { "stop", "StopUnit" },
2524 { "condstop", "StopUnit" },
2525 { "reload", "ReloadUnit" },
2526 { "restart", "RestartUnit" },
2527 { "try-restart", "TryRestartUnit" },
2528 { "condrestart", "TryRestartUnit" },
2529 { "reload-or-restart", "ReloadOrRestartUnit" },
2530 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2531 { "condreload", "ReloadOrTryRestartUnit" },
2532 { "force-reload", "ReloadOrTryRestartUnit" }
2535 static const char *verb_to_method(const char *verb
) {
2538 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2539 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2540 return unit_actions
[i
].method
;
2545 static const char *method_to_verb(const char *method
) {
2548 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2549 if (streq_ptr(unit_actions
[i
].method
, method
))
2550 return unit_actions
[i
].verb
;
2555 static int start_unit_one(
2560 sd_bus_error
*error
,
2561 BusWaitForJobs
*w
) {
2563 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2572 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2574 r
= sd_bus_call_method(
2576 "org.freedesktop.systemd1",
2577 "/org/freedesktop/systemd1",
2578 "org.freedesktop.systemd1.Manager",
2586 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2587 /* There's always a fallback possible for
2588 * legacy actions. */
2589 return -EADDRNOTAVAIL
;
2591 verb
= method_to_verb(method
);
2593 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2597 r
= sd_bus_message_read(reply
, "o", &path
);
2599 return bus_log_parse_error(r
);
2601 if (need_daemon_reload(bus
, name
) > 0)
2602 warn_unit_file_changed(name
);
2605 log_debug("Adding %s to the set", path
);
2606 r
= bus_wait_for_jobs_add(w
, path
);
2614 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2616 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2620 STRV_FOREACH(name
, names
) {
2624 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2626 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2628 return log_error_errno(r
, "Failed to mangle name: %m");
2630 if (string_is_glob(t
))
2631 r
= strv_consume(&globs
, t
);
2633 r
= strv_consume(&mangled
, t
);
2638 /* Query the manager only if any of the names are a glob, since
2639 * this is fairly expensive */
2640 if (!strv_isempty(globs
)) {
2641 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2642 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2645 return log_error_errno(EOPNOTSUPP
, "Unit name globbing without bus is not implemented.");
2647 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2651 for (i
= 0; i
< r
; i
++)
2652 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2657 mangled
= NULL
; /* do not free */
2662 static const struct {
2666 } action_table
[_ACTION_MAX
] = {
2667 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2668 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2669 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2670 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2671 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2672 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2673 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2674 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2675 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2676 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2677 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2678 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2679 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2680 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2681 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2684 static enum action
verb_to_action(const char *verb
) {
2687 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2688 if (streq_ptr(action_table
[i
].verb
, verb
))
2691 return _ACTION_INVALID
;
2694 static int start_unit(sd_bus
*bus
, char **args
) {
2695 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2696 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2697 _cleanup_strv_free_
char **names
= NULL
;
2703 ask_password_agent_open_if_enabled();
2704 polkit_agent_open_if_enabled();
2706 if (arg_action
== ACTION_SYSTEMCTL
) {
2708 method
= verb_to_method(args
[0]);
2709 action
= verb_to_action(args
[0]);
2711 if (streq(args
[0], "isolate")) {
2715 mode
= action_table
[action
].mode
?: arg_job_mode
;
2717 one_name
= action_table
[action
].target
;
2719 assert(arg_action
< ELEMENTSOF(action_table
));
2720 assert(action_table
[arg_action
].target
);
2722 method
= "StartUnit";
2724 mode
= action_table
[arg_action
].mode
;
2725 one_name
= action_table
[arg_action
].target
;
2729 names
= strv_new(one_name
, NULL
);
2731 r
= expand_names(bus
, args
+ 1, suffix
, &names
);
2733 log_error_errno(r
, "Failed to expand names: %m");
2736 if (!arg_no_block
) {
2737 r
= bus_wait_for_jobs_new(bus
, &w
);
2739 return log_error_errno(r
, "Could not watch jobs: %m");
2742 STRV_FOREACH(name
, names
) {
2743 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2746 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2747 if (r
>= 0 && q
< 0)
2748 r
= translate_bus_error_to_exit_status(q
, &error
);
2751 if (!arg_no_block
) {
2754 q
= bus_wait_for_jobs(w
, arg_quiet
);
2758 /* When stopping units, warn if they can still be triggered by
2759 * another active unit (socket, path, timer) */
2760 if (!arg_quiet
&& streq(method
, "StopUnit"))
2761 STRV_FOREACH(name
, names
)
2762 check_triggering_units(bus
, *name
);
2768 static int set_wall_message(sd_bus
*bus
) {
2770 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2771 _cleanup_free_
char *m
= NULL
;
2776 m
= strv_join(arg_wall
, " ");
2780 r
= sd_bus_call_method(
2782 "org.freedesktop.login1",
2783 "/org/freedesktop/login1",
2784 "org.freedesktop.login1.Manager",
2793 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2799 /* Ask systemd-logind, which might grant access to unprivileged users
2800 * through PolicyKit */
2801 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
2803 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2804 const char *method
, *description
;
2810 polkit_agent_open_if_enabled();
2812 (void) set_wall_message(bus
);
2818 description
= "reboot system";
2821 case ACTION_POWEROFF
:
2822 method
= "PowerOff";
2823 description
= "power off system";
2826 case ACTION_SUSPEND
:
2828 description
= "suspend system";
2831 case ACTION_HIBERNATE
:
2832 method
= "Hibernate";
2833 description
= "hibernate system";
2836 case ACTION_HYBRID_SLEEP
:
2837 method
= "HybridSleep";
2838 description
= "put system into hybrid sleep";
2845 r
= sd_bus_call_method(
2847 "org.freedesktop.login1",
2848 "/org/freedesktop/login1",
2849 "org.freedesktop.login1.Manager",
2853 "b", arg_ask_password
);
2855 log_error("Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2863 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
2865 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2866 _cleanup_strv_free_
char **sessions
= NULL
;
2867 const char *what
, *who
, *why
, *mode
;
2876 if (arg_ignore_inhibitors
|| arg_force
> 0)
2888 r
= sd_bus_call_method(
2890 "org.freedesktop.login1",
2891 "/org/freedesktop/login1",
2892 "org.freedesktop.login1.Manager",
2898 /* If logind is not around, then there are no inhibitors... */
2901 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2903 return bus_log_parse_error(r
);
2905 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2906 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2907 _cleanup_strv_free_
char **sv
= NULL
;
2909 if (!streq(mode
, "block"))
2912 sv
= strv_split(what
, ":");
2916 if ((pid_t
) pid
< 0)
2917 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2919 if (!strv_contains(sv
,
2924 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2927 get_process_comm(pid
, &comm
);
2928 user
= uid_to_name(uid
);
2930 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2931 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2936 return bus_log_parse_error(r
);
2938 r
= sd_bus_message_exit_container(reply
);
2940 return bus_log_parse_error(r
);
2942 /* Check for current sessions */
2943 sd_get_sessions(&sessions
);
2944 STRV_FOREACH(s
, sessions
) {
2945 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2947 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2950 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2953 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2956 sd_session_get_tty(*s
, &tty
);
2957 sd_session_get_seat(*s
, &seat
);
2958 sd_session_get_service(*s
, &service
);
2959 user
= uid_to_name(uid
);
2961 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2968 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2969 action_table
[a
].verb
);
2977 static int prepare_firmware_setup(sd_bus
*bus
) {
2979 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2983 if (!arg_firmware_setup
)
2986 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
2988 r
= efi_set_reboot_to_firmware(true);
2990 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
2996 r
= sd_bus_call_method(
2998 "org.freedesktop.login1",
2999 "/org/freedesktop/login1",
3000 "org.freedesktop.login1.Manager",
3001 "SetRebootToFirmwareSetup",
3006 log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3012 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3017 static int start_special(sd_bus
*bus
, char **args
) {
3018 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3024 a
= verb_to_action(args
[0]);
3026 r
= check_inhibitors(bus
, a
);
3030 if (arg_force
>= 2 && geteuid() != 0) {
3031 log_error("Must be root.");
3035 r
= prepare_firmware_setup(bus
);
3039 if (a
== ACTION_REBOOT
&& args
[1]) {
3040 r
= update_reboot_param_file(args
[1]);
3043 } else if (a
== ACTION_EXIT
&& strv_length(args
) > 1) {
3044 /* If the exit code is not given on the command line, don't
3045 * reset it to zero: just keep it as it might have been set
3049 r
= safe_atou8(args
[1], &code
);
3051 log_error("Invalid exit code.");
3055 r
= sd_bus_call_method(
3057 "org.freedesktop.systemd1",
3058 "/org/freedesktop/systemd1",
3059 "org.freedesktop.systemd1.Manager",
3065 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
3070 if (arg_force
>= 2 &&
3077 if (arg_force
>= 1 &&
3084 return daemon_reload(bus
, args
);
3086 /* first try logind, to allow authentication with polkit */
3087 if (geteuid() != 0 &&
3093 ACTION_HYBRID_SLEEP
)) {
3094 r
= reboot_with_logind(bus
, a
);
3097 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3098 /* requested operation is not supported or already in progress */
3100 /* on all other errors, try low-level operation */
3103 r
= start_unit(bus
, args
);
3104 if (r
== EXIT_SUCCESS
)
3110 static int check_unit_generic(sd_bus
*bus
, int code
, const char *good_states
, char **args
) {
3111 _cleanup_strv_free_
char **names
= NULL
;
3118 r
= expand_names(bus
, args
, NULL
, &names
);
3120 return log_error_errno(r
, "Failed to expand names: %m");
3122 STRV_FOREACH(name
, names
) {
3125 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3135 static int check_unit_active(sd_bus
*bus
, char **args
) {
3136 /* According to LSB: 3, "program is not running" */
3137 return check_unit_generic(bus
, 3, "active\0reloading\0", args
+ 1);
3140 static int check_unit_failed(sd_bus
*bus
, char **args
) {
3141 return check_unit_generic(bus
, 1, "failed\0", args
+ 1);
3144 static int kill_unit(sd_bus
*bus
, char **args
) {
3145 _cleanup_strv_free_
char **names
= NULL
;
3146 char *kill_who
= NULL
, **name
;
3152 polkit_agent_open_if_enabled();
3155 arg_kill_who
= "all";
3157 /* --fail was specified */
3158 if (streq(arg_job_mode
, "fail"))
3159 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3161 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
3163 log_error_errno(r
, "Failed to expand names: %m");
3165 STRV_FOREACH(name
, names
) {
3166 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3168 q
= sd_bus_call_method(
3170 "org.freedesktop.systemd1",
3171 "/org/freedesktop/systemd1",
3172 "org.freedesktop.systemd1.Manager",
3176 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3178 log_error("Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3187 typedef struct ExecStatusInfo
{
3195 usec_t start_timestamp
;
3196 usec_t exit_timestamp
;
3201 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3204 static void exec_status_info_free(ExecStatusInfo
*i
) {
3213 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3214 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3217 int32_t code
, status
;
3223 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3225 return bus_log_parse_error(r
);
3229 r
= sd_bus_message_read(m
, "s", &path
);
3231 return bus_log_parse_error(r
);
3233 i
->path
= strdup(path
);
3237 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3239 return bus_log_parse_error(r
);
3241 r
= sd_bus_message_read(m
,
3244 &start_timestamp
, &start_timestamp_monotonic
,
3245 &exit_timestamp
, &exit_timestamp_monotonic
,
3249 return bus_log_parse_error(r
);
3252 i
->start_timestamp
= (usec_t
) start_timestamp
;
3253 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3254 i
->pid
= (pid_t
) pid
;
3258 r
= sd_bus_message_exit_container(m
);
3260 return bus_log_parse_error(r
);
3265 typedef struct UnitStatusInfo
{
3267 const char *load_state
;
3268 const char *active_state
;
3269 const char *sub_state
;
3270 const char *unit_file_state
;
3271 const char *unit_file_preset
;
3273 const char *description
;
3274 const char *following
;
3276 char **documentation
;
3278 const char *fragment_path
;
3279 const char *source_path
;
3280 const char *control_group
;
3282 char **dropin_paths
;
3284 const char *load_error
;
3287 usec_t inactive_exit_timestamp
;
3288 usec_t inactive_exit_timestamp_monotonic
;
3289 usec_t active_enter_timestamp
;
3290 usec_t active_exit_timestamp
;
3291 usec_t inactive_enter_timestamp
;
3293 bool need_daemon_reload
;
3298 const char *status_text
;
3299 const char *pid_file
;
3303 usec_t start_timestamp
;
3304 usec_t exit_timestamp
;
3306 int exit_code
, exit_status
;
3308 usec_t condition_timestamp
;
3309 bool condition_result
;
3310 bool failed_condition_trigger
;
3311 bool failed_condition_negate
;
3312 const char *failed_condition
;
3313 const char *failed_condition_parameter
;
3315 usec_t assert_timestamp
;
3317 bool failed_assert_trigger
;
3318 bool failed_assert_negate
;
3319 const char *failed_assert
;
3320 const char *failed_assert_parameter
;
3323 unsigned n_accepted
;
3324 unsigned n_connections
;
3327 /* Pairs of type, path */
3331 const char *sysfs_path
;
3333 /* Mount, Automount */
3340 uint64_t memory_current
;
3341 uint64_t memory_limit
;
3342 uint64_t cpu_usage_nsec
;
3343 uint64_t tasks_current
;
3346 LIST_HEAD(ExecStatusInfo
, exec
);
3349 static void print_status_info(
3354 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3356 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3357 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3363 /* This shows pretty information about a unit. See
3364 * print_property() for a low-level property printer */
3366 if (streq_ptr(i
->active_state
, "failed")) {
3367 active_on
= ansi_highlight_red();
3368 active_off
= ansi_normal();
3369 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3370 active_on
= ansi_highlight_green();
3371 active_off
= ansi_normal();
3373 active_on
= active_off
= "";
3375 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3377 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3378 printf(" - %s", i
->description
);
3383 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3385 if (streq_ptr(i
->load_state
, "error")) {
3386 on
= ansi_highlight_red();
3387 off
= ansi_normal();
3391 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3394 printf(" Loaded: %s%s%s (Reason: %s)\n",
3395 on
, strna(i
->load_state
), off
, i
->load_error
);
3396 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3397 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3398 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3399 else if (path
&& !isempty(i
->unit_file_state
))
3400 printf(" Loaded: %s%s%s (%s; %s)\n",
3401 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3403 printf(" Loaded: %s%s%s (%s)\n",
3404 on
, strna(i
->load_state
), off
, path
);
3406 printf(" Loaded: %s%s%s\n",
3407 on
, strna(i
->load_state
), off
);
3409 if (!strv_isempty(i
->dropin_paths
)) {
3410 _cleanup_free_
char *dir
= NULL
;
3414 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3415 if (! dir
|| last
) {
3416 printf(dir
? " " : " Drop-In: ");
3420 if (path_get_parent(*dropin
, &dir
) < 0) {
3425 printf("%s\n %s", dir
,
3426 draw_special_char(DRAW_TREE_RIGHT
));
3429 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3431 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3435 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3437 printf(" Active: %s%s (%s)%s",
3438 active_on
, strna(i
->active_state
), ss
, active_off
);
3440 printf(" Active: %s%s%s",
3441 active_on
, strna(i
->active_state
), active_off
);
3443 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3444 printf(" (Result: %s)", i
->result
);
3446 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3447 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3448 (streq_ptr(i
->active_state
, "inactive") ||
3449 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3450 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3451 i
->active_exit_timestamp
;
3453 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3454 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3457 printf(" since %s; %s\n", s2
, s1
);
3459 printf(" since %s\n", s2
);
3463 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3464 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3465 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3467 printf("Condition: start %scondition failed%s at %s%s%s\n",
3468 ansi_highlight_yellow(), ansi_normal(),
3469 s2
, s1
? "; " : "", s1
? s1
: "");
3470 if (i
->failed_condition_trigger
)
3471 printf(" none of the trigger conditions were met\n");
3472 else if (i
->failed_condition
)
3473 printf(" %s=%s%s was not met\n",
3474 i
->failed_condition
,
3475 i
->failed_condition_negate
? "!" : "",
3476 i
->failed_condition_parameter
);
3479 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3480 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3481 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3483 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3484 ansi_highlight_red(), ansi_normal(),
3485 s2
, s1
? "; " : "", s1
? s1
: "");
3486 if (i
->failed_assert_trigger
)
3487 printf(" none of the trigger assertions were met\n");
3488 else if (i
->failed_assert
)
3489 printf(" %s=%s%s was not met\n",
3491 i
->failed_assert_negate
? "!" : "",
3492 i
->failed_assert_parameter
);
3496 printf(" Device: %s\n", i
->sysfs_path
);
3498 printf(" Where: %s\n", i
->where
);
3500 printf(" What: %s\n", i
->what
);
3502 STRV_FOREACH(t
, i
->documentation
)
3503 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3505 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3506 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3509 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3511 LIST_FOREACH(exec
, p
, i
->exec
) {
3512 _cleanup_free_
char *argv
= NULL
;
3515 /* Only show exited processes here */
3519 argv
= strv_join(p
->argv
, " ");
3520 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3522 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3524 on
= ansi_highlight_red();
3525 off
= ansi_normal();
3529 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3531 if (p
->code
== CLD_EXITED
) {
3534 printf("status=%i", p
->status
);
3536 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3541 printf("signal=%s", signal_to_string(p
->status
));
3543 printf(")%s\n", off
);
3545 if (i
->main_pid
== p
->pid
&&
3546 i
->start_timestamp
== p
->start_timestamp
&&
3547 i
->exit_timestamp
== p
->start_timestamp
)
3548 /* Let's not show this twice */
3551 if (p
->pid
== i
->control_pid
)
3555 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3556 if (i
->main_pid
> 0) {
3557 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3560 _cleanup_free_
char *comm
= NULL
;
3561 get_process_comm(i
->main_pid
, &comm
);
3563 printf(" (%s)", comm
);
3564 } else if (i
->exit_code
> 0) {
3565 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3567 if (i
->exit_code
== CLD_EXITED
) {
3570 printf("status=%i", i
->exit_status
);
3572 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3577 printf("signal=%s", signal_to_string(i
->exit_status
));
3581 if (i
->control_pid
> 0)
3585 if (i
->control_pid
> 0) {
3586 _cleanup_free_
char *c
= NULL
;
3588 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3590 get_process_comm(i
->control_pid
, &c
);
3599 printf(" Status: \"%s\"\n", i
->status_text
);
3600 if (i
->status_errno
> 0)
3601 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3603 if (i
->tasks_current
!= (uint64_t) -1) {
3604 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3606 if (i
->tasks_max
!= (uint64_t) -1)
3607 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3612 if (i
->memory_current
!= (uint64_t) -1) {
3613 char buf
[FORMAT_BYTES_MAX
];
3615 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3617 if (i
->memory_limit
!= (uint64_t) -1)
3618 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3623 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3624 char buf
[FORMAT_TIMESPAN_MAX
];
3625 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3628 if (i
->control_group
&&
3629 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3630 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3633 printf(" CGroup: %s\n", i
->control_group
);
3635 if (IN_SET(arg_transport
,
3636 BUS_TRANSPORT_LOCAL
,
3637 BUS_TRANSPORT_MACHINE
)) {
3640 static const char prefix
[] = " ";
3643 if (c
> sizeof(prefix
) - 1)
3644 c
-= sizeof(prefix
) - 1;
3648 if (i
->main_pid
> 0)
3649 extra
[k
++] = i
->main_pid
;
3651 if (i
->control_pid
> 0)
3652 extra
[k
++] = i
->control_pid
;
3654 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3658 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3659 show_journal_by_unit(
3664 i
->inactive_exit_timestamp_monotonic
,
3667 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3668 SD_JOURNAL_LOCAL_ONLY
,
3669 arg_scope
== UNIT_FILE_SYSTEM
,
3672 if (i
->need_daemon_reload
)
3673 warn_unit_file_changed(i
->id
);
3676 static void show_unit_help(UnitStatusInfo
*i
) {
3681 if (!i
->documentation
) {
3682 log_info("Documentation for %s not known.", i
->id
);
3686 STRV_FOREACH(p
, i
->documentation
)
3687 if (startswith(*p
, "man:"))
3688 show_man_page(*p
+ 4, false);
3690 log_info("Can't show: %s", *p
);
3693 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3700 switch (contents
[0]) {
3702 case SD_BUS_TYPE_STRING
: {
3705 r
= sd_bus_message_read(m
, "s", &s
);
3707 return bus_log_parse_error(r
);
3710 if (streq(name
, "Id"))
3712 else if (streq(name
, "LoadState"))
3714 else if (streq(name
, "ActiveState"))
3715 i
->active_state
= s
;
3716 else if (streq(name
, "SubState"))
3718 else if (streq(name
, "Description"))
3720 else if (streq(name
, "FragmentPath"))
3721 i
->fragment_path
= s
;
3722 else if (streq(name
, "SourcePath"))
3725 else if (streq(name
, "DefaultControlGroup")) {
3727 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3729 i
->control_group
= e
;
3732 else if (streq(name
, "ControlGroup"))
3733 i
->control_group
= s
;
3734 else if (streq(name
, "StatusText"))
3736 else if (streq(name
, "PIDFile"))
3738 else if (streq(name
, "SysFSPath"))
3740 else if (streq(name
, "Where"))
3742 else if (streq(name
, "What"))
3744 else if (streq(name
, "Following"))
3746 else if (streq(name
, "UnitFileState"))
3747 i
->unit_file_state
= s
;
3748 else if (streq(name
, "UnitFilePreset"))
3749 i
->unit_file_preset
= s
;
3750 else if (streq(name
, "Result"))
3757 case SD_BUS_TYPE_BOOLEAN
: {
3760 r
= sd_bus_message_read(m
, "b", &b
);
3762 return bus_log_parse_error(r
);
3764 if (streq(name
, "Accept"))
3766 else if (streq(name
, "NeedDaemonReload"))
3767 i
->need_daemon_reload
= b
;
3768 else if (streq(name
, "ConditionResult"))
3769 i
->condition_result
= b
;
3770 else if (streq(name
, "AssertResult"))
3771 i
->assert_result
= b
;
3776 case SD_BUS_TYPE_UINT32
: {
3779 r
= sd_bus_message_read(m
, "u", &u
);
3781 return bus_log_parse_error(r
);
3783 if (streq(name
, "MainPID")) {
3785 i
->main_pid
= (pid_t
) u
;
3788 } else if (streq(name
, "ControlPID"))
3789 i
->control_pid
= (pid_t
) u
;
3790 else if (streq(name
, "ExecMainPID")) {
3792 i
->main_pid
= (pid_t
) u
;
3793 } else if (streq(name
, "NAccepted"))
3795 else if (streq(name
, "NConnections"))
3796 i
->n_connections
= u
;
3801 case SD_BUS_TYPE_INT32
: {
3804 r
= sd_bus_message_read(m
, "i", &j
);
3806 return bus_log_parse_error(r
);
3808 if (streq(name
, "ExecMainCode"))
3809 i
->exit_code
= (int) j
;
3810 else if (streq(name
, "ExecMainStatus"))
3811 i
->exit_status
= (int) j
;
3812 else if (streq(name
, "StatusErrno"))
3813 i
->status_errno
= (int) j
;
3818 case SD_BUS_TYPE_UINT64
: {
3821 r
= sd_bus_message_read(m
, "t", &u
);
3823 return bus_log_parse_error(r
);
3825 if (streq(name
, "ExecMainStartTimestamp"))
3826 i
->start_timestamp
= (usec_t
) u
;
3827 else if (streq(name
, "ExecMainExitTimestamp"))
3828 i
->exit_timestamp
= (usec_t
) u
;
3829 else if (streq(name
, "ActiveEnterTimestamp"))
3830 i
->active_enter_timestamp
= (usec_t
) u
;
3831 else if (streq(name
, "InactiveEnterTimestamp"))
3832 i
->inactive_enter_timestamp
= (usec_t
) u
;
3833 else if (streq(name
, "InactiveExitTimestamp"))
3834 i
->inactive_exit_timestamp
= (usec_t
) u
;
3835 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3836 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3837 else if (streq(name
, "ActiveExitTimestamp"))
3838 i
->active_exit_timestamp
= (usec_t
) u
;
3839 else if (streq(name
, "ConditionTimestamp"))
3840 i
->condition_timestamp
= (usec_t
) u
;
3841 else if (streq(name
, "AssertTimestamp"))
3842 i
->assert_timestamp
= (usec_t
) u
;
3843 else if (streq(name
, "MemoryCurrent"))
3844 i
->memory_current
= u
;
3845 else if (streq(name
, "MemoryLimit"))
3846 i
->memory_limit
= u
;
3847 else if (streq(name
, "TasksCurrent"))
3848 i
->tasks_current
= u
;
3849 else if (streq(name
, "TasksMax"))
3851 else if (streq(name
, "CPUUsageNSec"))
3852 i
->cpu_usage_nsec
= u
;
3857 case SD_BUS_TYPE_ARRAY
:
3859 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3860 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3862 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3864 return bus_log_parse_error(r
);
3866 info
= new0(ExecStatusInfo
, 1);
3870 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3872 info
->name
= strdup(name
);
3876 LIST_PREPEND(exec
, i
->exec
, info
);
3878 info
= new0(ExecStatusInfo
, 1);
3884 return bus_log_parse_error(r
);
3886 r
= sd_bus_message_exit_container(m
);
3888 return bus_log_parse_error(r
);
3892 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3893 const char *type
, *path
;
3895 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3897 return bus_log_parse_error(r
);
3899 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3901 r
= strv_extend(&i
->listen
, type
);
3905 r
= strv_extend(&i
->listen
, path
);
3910 return bus_log_parse_error(r
);
3912 r
= sd_bus_message_exit_container(m
);
3914 return bus_log_parse_error(r
);
3918 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3920 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3922 return bus_log_parse_error(r
);
3924 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3926 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3928 return bus_log_parse_error(r
);
3930 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3931 const char *cond
, *param
;
3932 int trigger
, negate
;
3935 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3937 return bus_log_parse_error(r
);
3939 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3940 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3941 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3942 i
->failed_condition
= cond
;
3943 i
->failed_condition_trigger
= trigger
;
3944 i
->failed_condition_negate
= negate
;
3945 i
->failed_condition_parameter
= param
;
3949 return bus_log_parse_error(r
);
3951 r
= sd_bus_message_exit_container(m
);
3953 return bus_log_parse_error(r
);
3955 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
3956 const char *cond
, *param
;
3957 int trigger
, negate
;
3960 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3962 return bus_log_parse_error(r
);
3964 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3965 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3966 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
3967 i
->failed_assert
= cond
;
3968 i
->failed_assert_trigger
= trigger
;
3969 i
->failed_assert_negate
= negate
;
3970 i
->failed_assert_parameter
= param
;
3974 return bus_log_parse_error(r
);
3976 r
= sd_bus_message_exit_container(m
);
3978 return bus_log_parse_error(r
);
3985 case SD_BUS_TYPE_STRUCT_BEGIN
:
3987 if (streq(name
, "LoadError")) {
3988 const char *n
, *message
;
3990 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3992 return bus_log_parse_error(r
);
3994 if (!isempty(message
))
3995 i
->load_error
= message
;
4008 r
= sd_bus_message_skip(m
, contents
);
4010 return bus_log_parse_error(r
);
4015 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4021 /* This is a low-level property printer, see
4022 * print_status_info() for the nicer output */
4024 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4025 /* skip what we didn't read */
4026 r
= sd_bus_message_skip(m
, contents
);
4030 switch (contents
[0]) {
4032 case SD_BUS_TYPE_STRUCT_BEGIN
:
4034 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4037 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4039 return bus_log_parse_error(r
);
4042 printf("%s=%"PRIu32
"\n", name
, u
);
4044 printf("%s=\n", name
);
4048 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4051 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4053 return bus_log_parse_error(r
);
4055 if (arg_all
|| !isempty(s
))
4056 printf("%s=%s\n", name
, s
);
4060 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4061 const char *a
= NULL
, *b
= NULL
;
4063 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4065 return bus_log_parse_error(r
);
4067 if (arg_all
|| !isempty(a
) || !isempty(b
))
4068 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4071 } else if (streq_ptr(name
, "SystemCallFilter")) {
4072 _cleanup_strv_free_
char **l
= NULL
;
4075 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4077 return bus_log_parse_error(r
);
4079 r
= sd_bus_message_read(m
, "b", &whitelist
);
4081 return bus_log_parse_error(r
);
4083 r
= sd_bus_message_read_strv(m
, &l
);
4085 return bus_log_parse_error(r
);
4087 r
= sd_bus_message_exit_container(m
);
4089 return bus_log_parse_error(r
);
4091 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4095 fputs(name
, stdout
);
4101 STRV_FOREACH(i
, l
) {
4109 fputc('\n', stdout
);
4117 case SD_BUS_TYPE_ARRAY
:
4119 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4123 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4125 return bus_log_parse_error(r
);
4127 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4128 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4131 return bus_log_parse_error(r
);
4133 r
= sd_bus_message_exit_container(m
);
4135 return bus_log_parse_error(r
);
4139 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4140 const char *type
, *path
;
4142 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4144 return bus_log_parse_error(r
);
4146 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4147 printf("%s=%s\n", type
, path
);
4149 return bus_log_parse_error(r
);
4151 r
= sd_bus_message_exit_container(m
);
4153 return bus_log_parse_error(r
);
4157 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4158 const char *type
, *path
;
4160 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4162 return bus_log_parse_error(r
);
4164 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4165 printf("Listen%s=%s\n", type
, path
);
4167 return bus_log_parse_error(r
);
4169 r
= sd_bus_message_exit_container(m
);
4171 return bus_log_parse_error(r
);
4175 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4177 uint64_t value
, next_elapse
;
4179 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4181 return bus_log_parse_error(r
);
4183 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4184 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4186 printf("%s={ value=%s ; next_elapse=%s }\n",
4188 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4189 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4192 return bus_log_parse_error(r
);
4194 r
= sd_bus_message_exit_container(m
);
4196 return bus_log_parse_error(r
);
4200 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4201 ExecStatusInfo info
= {};
4203 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4205 return bus_log_parse_error(r
);
4207 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4208 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4209 _cleanup_free_
char *tt
;
4211 tt
= strv_join(info
.argv
, " ");
4213 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",
4217 yes_no(info
.ignore
),
4218 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4219 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4221 sigchld_code_to_string(info
.code
),
4223 info
.code
== CLD_EXITED
? "" : "/",
4224 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4227 strv_free(info
.argv
);
4231 r
= sd_bus_message_exit_container(m
);
4233 return bus_log_parse_error(r
);
4237 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4238 const char *path
, *rwm
;
4240 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4242 return bus_log_parse_error(r
);
4244 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4245 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4247 return bus_log_parse_error(r
);
4249 r
= sd_bus_message_exit_container(m
);
4251 return bus_log_parse_error(r
);
4255 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4259 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4261 return bus_log_parse_error(r
);
4263 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4264 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4266 return bus_log_parse_error(r
);
4268 r
= sd_bus_message_exit_container(m
);
4270 return bus_log_parse_error(r
);
4274 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4278 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4280 return bus_log_parse_error(r
);
4282 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4283 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4285 return bus_log_parse_error(r
);
4287 r
= sd_bus_message_exit_container(m
);
4289 return bus_log_parse_error(r
);
4297 r
= bus_print_property(name
, m
, arg_all
);
4299 return bus_log_parse_error(r
);
4302 r
= sd_bus_message_skip(m
, contents
);
4304 return bus_log_parse_error(r
);
4307 printf("%s=[unprintable]\n", name
);
4313 static int show_one(
4317 bool show_properties
,
4321 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4322 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4323 UnitStatusInfo info
= {
4324 .memory_current
= (uint64_t) -1,
4325 .memory_limit
= (uint64_t) -1,
4326 .cpu_usage_nsec
= (uint64_t) -1,
4327 .tasks_current
= (uint64_t) -1,
4328 .tasks_max
= (uint64_t) -1,
4336 log_debug("Showing one %s", path
);
4338 r
= sd_bus_call_method(
4340 "org.freedesktop.systemd1",
4342 "org.freedesktop.DBus.Properties",
4348 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4350 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4352 return bus_log_parse_error(r
);
4359 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4360 const char *name
, *contents
;
4362 r
= sd_bus_message_read(reply
, "s", &name
);
4364 return bus_log_parse_error(r
);
4366 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4368 return bus_log_parse_error(r
);
4370 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4372 return bus_log_parse_error(r
);
4374 if (show_properties
)
4375 r
= print_property(name
, reply
, contents
);
4377 r
= status_property(name
, reply
, &info
, contents
);
4381 r
= sd_bus_message_exit_container(reply
);
4383 return bus_log_parse_error(r
);
4385 r
= sd_bus_message_exit_container(reply
);
4387 return bus_log_parse_error(r
);
4390 return bus_log_parse_error(r
);
4392 r
= sd_bus_message_exit_container(reply
);
4394 return bus_log_parse_error(r
);
4398 if (!show_properties
) {
4399 if (streq(verb
, "help"))
4400 show_unit_help(&info
);
4402 print_status_info(&info
, ellipsized
);
4405 strv_free(info
.documentation
);
4406 strv_free(info
.dropin_paths
);
4407 strv_free(info
.listen
);
4409 if (!streq_ptr(info
.active_state
, "active") &&
4410 !streq_ptr(info
.active_state
, "reloading") &&
4411 streq(verb
, "status")) {
4412 /* According to LSB: "program not running" */
4413 /* 0: program is running or service is OK
4414 * 1: program is dead and /run PID file exists
4415 * 2: program is dead and /run/lock lock file exists
4416 * 3: program is not running
4417 * 4: program or service status is unknown
4419 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4425 while ((p
= info
.exec
)) {
4426 LIST_REMOVE(exec
, info
.exec
, p
);
4427 exec_status_info_free(p
);
4433 static int get_unit_dbus_path_by_pid(
4438 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4439 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4443 r
= sd_bus_call_method(
4445 "org.freedesktop.systemd1",
4446 "/org/freedesktop/systemd1",
4447 "org.freedesktop.systemd1.Manager",
4453 log_error("Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4457 r
= sd_bus_message_read(reply
, "o", &u
);
4459 return bus_log_parse_error(r
);
4469 static int show_all(
4472 bool show_properties
,
4476 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4477 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4482 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4486 pager_open_if_enabled();
4490 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4492 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4493 _cleanup_free_
char *p
= NULL
;
4495 p
= unit_dbus_path_from_name(u
->id
);
4499 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4502 else if (r
> 0 && ret
== 0)
4509 static int show_system_status(sd_bus
*bus
) {
4510 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4511 _cleanup_free_
char *hn
= NULL
;
4512 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4513 const char *on
, *off
;
4516 hn
= gethostname_malloc();
4520 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4522 return log_error_errno(r
, "Failed to read server status: %m");
4524 if (streq_ptr(mi
.state
, "degraded")) {
4525 on
= ansi_highlight_red();
4526 off
= ansi_normal();
4527 } else if (!streq_ptr(mi
.state
, "running")) {
4528 on
= ansi_highlight_yellow();
4529 off
= ansi_normal();
4533 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4535 printf(" State: %s%s%s\n",
4536 on
, strna(mi
.state
), off
);
4538 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4539 printf(" Failed: %u units\n", mi
.n_failed_units
);
4541 printf(" Since: %s; %s\n",
4542 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4543 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4545 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4546 if (IN_SET(arg_transport
,
4547 BUS_TRANSPORT_LOCAL
,
4548 BUS_TRANSPORT_MACHINE
)) {
4549 static const char prefix
[] = " ";
4553 if (c
> sizeof(prefix
) - 1)
4554 c
-= sizeof(prefix
) - 1;
4558 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4564 static int show(sd_bus
*bus
, char **args
) {
4565 bool show_properties
, show_status
, new_line
= false;
4566 bool ellipsized
= false;
4572 show_properties
= streq(args
[0], "show");
4573 show_status
= streq(args
[0], "status");
4575 if (show_properties
)
4576 pager_open_if_enabled();
4579 /* Increase max number of open files to 16K if we can, we
4580 * might needs this when browsing journal files, which might
4581 * be split up into many files. */
4582 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4584 /* If no argument is specified inspect the manager itself */
4586 if (show_properties
&& strv_length(args
) <= 1)
4587 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4589 if (show_status
&& strv_length(args
) <= 1) {
4591 pager_open_if_enabled();
4592 show_system_status(bus
);
4596 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
4598 _cleanup_free_
char **patterns
= NULL
;
4601 STRV_FOREACH(name
, args
+ 1) {
4602 _cleanup_free_
char *unit
= NULL
;
4605 if (safe_atou32(*name
, &id
) < 0) {
4606 if (strv_push(&patterns
, *name
) < 0)
4610 } else if (show_properties
) {
4611 /* Interpret as job id */
4612 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4616 /* Interpret as PID */
4617 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4624 r
= show_one(args
[0], bus
, unit
, show_properties
,
4625 &new_line
, &ellipsized
);
4628 else if (r
> 0 && ret
== 0)
4632 if (!strv_isempty(patterns
)) {
4633 _cleanup_strv_free_
char **names
= NULL
;
4635 r
= expand_names(bus
, patterns
, NULL
, &names
);
4637 log_error_errno(r
, "Failed to expand names: %m");
4639 STRV_FOREACH(name
, names
) {
4640 _cleanup_free_
char *unit
;
4642 unit
= unit_dbus_path_from_name(*name
);
4646 r
= show_one(args
[0], bus
, unit
, show_properties
,
4647 &new_line
, &ellipsized
);
4650 else if (r
> 0 && ret
== 0)
4656 if (ellipsized
&& !arg_quiet
)
4657 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4662 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4666 assert(user_runtime
);
4669 if (arg_scope
== UNIT_FILE_USER
) {
4670 r
= user_config_home(user_home
);
4672 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4674 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4676 r
= user_runtime_dir(user_runtime
);
4678 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4680 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4683 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4685 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4690 static int cat_file(const char *filename
, bool newline
) {
4691 _cleanup_close_
int fd
;
4693 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4697 printf("%s%s# %s%s\n",
4698 newline
? "\n" : "",
4699 ansi_highlight_blue(),
4704 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4707 static int cat(sd_bus
*bus
, char **args
) {
4708 _cleanup_free_
char *user_home
= NULL
;
4709 _cleanup_free_
char *user_runtime
= NULL
;
4710 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4711 _cleanup_strv_free_
char **names
= NULL
;
4713 bool first
= true, avoid_bus_cache
;
4718 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4719 log_error("Cannot remotely cat units");
4723 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4727 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4729 return log_error_errno(r
, "Failed to expand names: %m");
4731 avoid_bus_cache
= !bus
|| avoid_bus();
4733 pager_open_if_enabled();
4735 STRV_FOREACH(name
, names
) {
4736 _cleanup_free_
char *fragment_path
= NULL
;
4737 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4740 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &fragment_path
, &dropin_paths
);
4751 if (fragment_path
) {
4752 r
= cat_file(fragment_path
, false);
4754 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4757 STRV_FOREACH(path
, dropin_paths
) {
4758 r
= cat_file(*path
, path
== dropin_paths
);
4760 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4767 static int set_property(sd_bus
*bus
, char **args
) {
4768 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4769 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4770 _cleanup_free_
char *n
= NULL
;
4774 polkit_agent_open_if_enabled();
4776 r
= sd_bus_message_new_method_call(
4779 "org.freedesktop.systemd1",
4780 "/org/freedesktop/systemd1",
4781 "org.freedesktop.systemd1.Manager",
4782 "SetUnitProperties");
4784 return bus_log_create_error(r
);
4786 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &n
);
4788 return log_error_errno(r
, "Failed to mangle unit name: %m");
4790 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4792 return bus_log_create_error(r
);
4794 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4796 return bus_log_create_error(r
);
4798 STRV_FOREACH(i
, args
+ 2) {
4799 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4801 return bus_log_create_error(r
);
4803 r
= bus_append_unit_property_assignment(m
, *i
);
4807 r
= sd_bus_message_close_container(m
);
4809 return bus_log_create_error(r
);
4812 r
= sd_bus_message_close_container(m
);
4814 return bus_log_create_error(r
);
4816 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4818 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4825 static int snapshot(sd_bus
*bus
, char **args
) {
4826 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4827 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4828 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4832 polkit_agent_open_if_enabled();
4834 if (strv_length(args
) > 1) {
4835 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4837 return log_error_errno(r
, "Failed to generate unit name: %m");
4844 r
= sd_bus_call_method(
4846 "org.freedesktop.systemd1",
4847 "/org/freedesktop/systemd1",
4848 "org.freedesktop.systemd1.Manager",
4854 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
4858 r
= sd_bus_message_read(reply
, "o", &path
);
4860 return bus_log_parse_error(r
);
4862 r
= sd_bus_get_property_string(
4864 "org.freedesktop.systemd1",
4866 "org.freedesktop.systemd1.Unit",
4871 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4881 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4882 _cleanup_strv_free_
char **names
= NULL
;
4888 polkit_agent_open_if_enabled();
4890 r
= expand_names(bus
, args
+ 1, ".snapshot", &names
);
4892 log_error_errno(r
, "Failed to expand names: %m");
4894 STRV_FOREACH(name
, names
) {
4895 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4898 q
= sd_bus_call_method(
4900 "org.freedesktop.systemd1",
4901 "/org/freedesktop/systemd1",
4902 "org.freedesktop.systemd1.Manager",
4908 log_error("Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4917 static int daemon_reload(sd_bus
*bus
, char **args
) {
4918 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4922 polkit_agent_open_if_enabled();
4924 if (arg_action
== ACTION_RELOAD
)
4926 else if (arg_action
== ACTION_REEXEC
)
4927 method
= "Reexecute";
4929 assert(arg_action
== ACTION_SYSTEMCTL
);
4932 streq(args
[0], "clear-jobs") ||
4933 streq(args
[0], "cancel") ? "ClearJobs" :
4934 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4935 streq(args
[0], "reset-failed") ? "ResetFailed" :
4936 streq(args
[0], "halt") ? "Halt" :
4937 streq(args
[0], "poweroff") ? "PowerOff" :
4938 streq(args
[0], "reboot") ? "Reboot" :
4939 streq(args
[0], "kexec") ? "KExec" :
4940 streq(args
[0], "exit") ? "Exit" :
4941 /* "daemon-reload" */ "Reload";
4944 r
= sd_bus_call_method(
4946 "org.freedesktop.systemd1",
4947 "/org/freedesktop/systemd1",
4948 "org.freedesktop.systemd1.Manager",
4953 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4954 /* There's always a fallback possible for
4955 * legacy actions. */
4957 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4958 /* On reexecution, we expect a disconnect, not a
4962 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4964 return r
< 0 ? r
: 0;
4967 static int reset_failed(sd_bus
*bus
, char **args
) {
4968 _cleanup_strv_free_
char **names
= NULL
;
4972 if (strv_length(args
) <= 1)
4973 return daemon_reload(bus
, args
);
4975 polkit_agent_open_if_enabled();
4977 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4979 log_error_errno(r
, "Failed to expand names: %m");
4981 STRV_FOREACH(name
, names
) {
4982 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4984 q
= sd_bus_call_method(
4986 "org.freedesktop.systemd1",
4987 "/org/freedesktop/systemd1",
4988 "org.freedesktop.systemd1.Manager",
4994 log_error("Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5003 static int show_environment(sd_bus
*bus
, char **args
) {
5004 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5005 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5009 pager_open_if_enabled();
5011 r
= sd_bus_get_property(
5013 "org.freedesktop.systemd1",
5014 "/org/freedesktop/systemd1",
5015 "org.freedesktop.systemd1.Manager",
5021 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
5025 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5027 return bus_log_parse_error(r
);
5029 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5032 return bus_log_parse_error(r
);
5034 r
= sd_bus_message_exit_container(reply
);
5036 return bus_log_parse_error(r
);
5041 static int switch_root(sd_bus
*bus
, char **args
) {
5042 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5043 _cleanup_free_
char *cmdline_init
= NULL
;
5044 const char *root
, *init
;
5048 l
= strv_length(args
);
5049 if (l
< 2 || l
> 3) {
5050 log_error("Wrong number of arguments.");
5059 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5060 "init", &cmdline_init
,
5063 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5065 init
= cmdline_init
;
5072 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5074 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5075 root_init_path
= strjoina(root
, "/", init
);
5077 /* If the passed init is actually the same as the
5078 * systemd binary, then let's suppress it. */
5079 if (files_same(root_init_path
, root_systemd_path
) > 0)
5083 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5085 r
= sd_bus_call_method(
5087 "org.freedesktop.systemd1",
5088 "/org/freedesktop/systemd1",
5089 "org.freedesktop.systemd1.Manager",
5095 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
5102 static int set_environment(sd_bus
*bus
, char **args
) {
5103 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5104 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5111 polkit_agent_open_if_enabled();
5113 method
= streq(args
[0], "set-environment")
5115 : "UnsetEnvironment";
5117 r
= sd_bus_message_new_method_call(
5120 "org.freedesktop.systemd1",
5121 "/org/freedesktop/systemd1",
5122 "org.freedesktop.systemd1.Manager",
5125 return bus_log_create_error(r
);
5127 r
= sd_bus_message_append_strv(m
, args
+ 1);
5129 return bus_log_create_error(r
);
5131 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5133 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
5140 static int import_environment(sd_bus
*bus
, char **args
) {
5141 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5142 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5148 polkit_agent_open_if_enabled();
5150 r
= sd_bus_message_new_method_call(
5153 "org.freedesktop.systemd1",
5154 "/org/freedesktop/systemd1",
5155 "org.freedesktop.systemd1.Manager",
5158 return bus_log_create_error(r
);
5160 if (strv_isempty(args
+ 1))
5161 r
= sd_bus_message_append_strv(m
, environ
);
5165 r
= sd_bus_message_open_container(m
, 'a', "s");
5167 return bus_log_create_error(r
);
5169 STRV_FOREACH(a
, args
+ 1) {
5171 if (!env_name_is_valid(*a
)) {
5172 log_error("Not a valid environment variable name: %s", *a
);
5176 STRV_FOREACH(b
, environ
) {
5179 eq
= startswith(*b
, *a
);
5180 if (eq
&& *eq
== '=') {
5182 r
= sd_bus_message_append(m
, "s", *b
);
5184 return bus_log_create_error(r
);
5191 r
= sd_bus_message_close_container(m
);
5194 return bus_log_create_error(r
);
5196 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5198 log_error("Failed to import environment: %s", bus_error_message(&error
, r
));
5205 static int enable_sysv_units(const char *verb
, char **args
) {
5208 #if defined(HAVE_SYSV_COMPAT)
5210 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5212 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5215 if (!STR_IN_SET(verb
,
5221 /* Processes all SysV units, and reshuffles the array so that
5222 * afterwards only the native units remain */
5224 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5231 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5232 bool found_native
= false, found_sysv
;
5234 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5242 if (!endswith(name
, ".service"))
5245 if (path_is_absolute(name
))
5248 STRV_FOREACH(k
, paths
.unit_path
) {
5249 _cleanup_free_
char *path
= NULL
;
5251 path
= path_join(arg_root
, *k
, name
);
5255 found_native
= access(path
, F_OK
) >= 0;
5260 /* If we have both a native unit and a SysV script,
5261 * enable/disable them both (below); for is-enabled, prefer the
5263 if (found_native
&& streq(verb
, "is-enabled"))
5266 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5270 p
[strlen(p
) - strlen(".service")] = 0;
5271 found_sysv
= access(p
, F_OK
) >= 0;
5276 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5278 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5280 if (!isempty(arg_root
))
5281 argv
[c
++] = q
= strappend("--root=", arg_root
);
5284 argv
[c
++] = basename(p
);
5287 l
= strv_join((char**)argv
, " ");
5291 log_info("Executing %s", l
);
5295 return log_error_errno(errno
, "Failed to fork: %m");
5296 else if (pid
== 0) {
5299 (void) reset_all_signal_handlers();
5300 (void) reset_signal_mask();
5302 execv(argv
[0], (char**) argv
);
5303 log_error("Failed to execute %s: %m", argv
[0]);
5304 _exit(EXIT_FAILURE
);
5307 j
= wait_for_terminate(pid
, &status
);
5309 log_error_errno(r
, "Failed to wait for child: %m");
5313 if (status
.si_code
== CLD_EXITED
) {
5314 if (streq(verb
, "is-enabled")) {
5315 if (status
.si_status
== 0) {
5324 } else if (status
.si_status
!= 0)
5332 /* Remove this entry, so that we don't try enabling it as native unit */
5335 assert(args
[f
] == name
);
5336 strv_remove(args
, name
);
5343 static int mangle_names(char **original_names
, char ***mangled_names
) {
5344 char **i
, **l
, **name
;
5347 l
= i
= new(char*, strv_length(original_names
) + 1);
5351 STRV_FOREACH(name
, original_names
) {
5353 /* When enabling units qualified path names are OK,
5354 * too, hence allow them explicitly. */
5356 if (is_path(*name
)) {
5363 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5366 return log_error_errno(r
, "Failed to mangle unit name: %m");
5379 static int enable_unit(sd_bus
*bus
, char **args
) {
5380 _cleanup_strv_free_
char **names
= NULL
;
5381 const char *verb
= args
[0];
5382 UnitFileChange
*changes
= NULL
;
5383 unsigned n_changes
= 0;
5384 int carries_install_info
= -1;
5390 r
= mangle_names(args
+1, &names
);
5394 r
= enable_sysv_units(verb
, names
);
5398 /* If the operation was fully executed by the SysV compat,
5399 * let's finish early */
5400 if (strv_isempty(names
))
5403 if (!bus
|| avoid_bus()) {
5404 if (streq(verb
, "enable")) {
5405 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5406 carries_install_info
= r
;
5407 } else if (streq(verb
, "disable"))
5408 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5409 else if (streq(verb
, "reenable")) {
5410 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5411 carries_install_info
= r
;
5412 } else if (streq(verb
, "link"))
5413 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5414 else if (streq(verb
, "preset")) {
5415 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5416 carries_install_info
= r
;
5417 } else if (streq(verb
, "mask"))
5418 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5419 else if (streq(verb
, "unmask"))
5420 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5422 assert_not_reached("Unknown verb");
5425 log_error_errno(r
, "Operation failed: %m");
5430 dump_unit_file_changes(changes
, n_changes
);
5434 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5435 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5436 int expect_carries_install_info
= false;
5437 bool send_force
= true, send_preset_mode
= false;
5440 polkit_agent_open_if_enabled();
5442 if (streq(verb
, "enable")) {
5443 method
= "EnableUnitFiles";
5444 expect_carries_install_info
= true;
5445 } else if (streq(verb
, "disable")) {
5446 method
= "DisableUnitFiles";
5448 } else if (streq(verb
, "reenable")) {
5449 method
= "ReenableUnitFiles";
5450 expect_carries_install_info
= true;
5451 } else if (streq(verb
, "link"))
5452 method
= "LinkUnitFiles";
5453 else if (streq(verb
, "preset")) {
5455 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5456 method
= "PresetUnitFilesWithMode";
5457 send_preset_mode
= true;
5459 method
= "PresetUnitFiles";
5461 expect_carries_install_info
= true;
5462 } else if (streq(verb
, "mask"))
5463 method
= "MaskUnitFiles";
5464 else if (streq(verb
, "unmask")) {
5465 method
= "UnmaskUnitFiles";
5468 assert_not_reached("Unknown verb");
5470 r
= sd_bus_message_new_method_call(
5473 "org.freedesktop.systemd1",
5474 "/org/freedesktop/systemd1",
5475 "org.freedesktop.systemd1.Manager",
5478 return bus_log_create_error(r
);
5480 r
= sd_bus_message_append_strv(m
, names
);
5482 return bus_log_create_error(r
);
5484 if (send_preset_mode
) {
5485 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5487 return bus_log_create_error(r
);
5490 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5492 return bus_log_create_error(r
);
5495 r
= sd_bus_message_append(m
, "b", arg_force
);
5497 return bus_log_create_error(r
);
5500 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5502 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5506 if (expect_carries_install_info
) {
5507 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5509 return bus_log_parse_error(r
);
5512 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5516 /* Try to reload if enabled */
5518 r
= daemon_reload(bus
, args
);
5523 if (carries_install_info
== 0)
5524 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5525 "using systemctl.\n"
5526 "Possible reasons for having this kind of units are:\n"
5527 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5528 " .wants/ or .requires/ directory.\n"
5529 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5530 " a requirement dependency on it.\n"
5531 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5532 " D-Bus, udev, scripted systemctl call, ...).\n");
5534 if (arg_now
&& n_changes
> 0 && STR_IN_SET(args
[0], "enable", "disable", "mask")) {
5535 char *new_args
[n_changes
+ 2];
5538 new_args
[0] = streq(args
[0], "enable") ? (char *)"start" : (char *)"stop";
5539 for (i
= 0; i
< n_changes
; i
++)
5540 new_args
[i
+ 1] = basename(changes
[i
].path
);
5541 new_args
[i
+ 1] = NULL
;
5543 r
= start_unit(bus
, new_args
);
5547 unit_file_changes_free(changes
, n_changes
);
5552 static int add_dependency(sd_bus
*bus
, char **args
) {
5553 _cleanup_strv_free_
char **names
= NULL
;
5554 _cleanup_free_
char *target
= NULL
;
5555 const char *verb
= args
[0];
5562 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5564 return log_error_errno(r
, "Failed to mangle unit name: %m");
5566 r
= mangle_names(args
+2, &names
);
5570 if (streq(verb
, "add-wants"))
5572 else if (streq(verb
, "add-requires"))
5573 dep
= UNIT_REQUIRES
;
5575 assert_not_reached("Unknown verb");
5577 if (!bus
|| avoid_bus()) {
5578 UnitFileChange
*changes
= NULL
;
5579 unsigned n_changes
= 0;
5581 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5584 return log_error_errno(r
, "Can't add dependency: %m");
5587 dump_unit_file_changes(changes
, n_changes
);
5589 unit_file_changes_free(changes
, n_changes
);
5592 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5593 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5595 polkit_agent_open_if_enabled();
5597 r
= sd_bus_message_new_method_call(
5600 "org.freedesktop.systemd1",
5601 "/org/freedesktop/systemd1",
5602 "org.freedesktop.systemd1.Manager",
5603 "AddDependencyUnitFiles");
5605 return bus_log_create_error(r
);
5607 r
= sd_bus_message_append_strv(m
, names
);
5609 return bus_log_create_error(r
);
5611 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5613 return bus_log_create_error(r
);
5615 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5617 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5621 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5626 r
= daemon_reload(bus
, args
);
5634 static int preset_all(sd_bus
*bus
, char **args
) {
5635 UnitFileChange
*changes
= NULL
;
5636 unsigned n_changes
= 0;
5639 if (!bus
|| avoid_bus()) {
5641 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5643 log_error_errno(r
, "Operation failed: %m");
5648 dump_unit_file_changes(changes
, n_changes
);
5653 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5654 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5656 polkit_agent_open_if_enabled();
5658 r
= sd_bus_call_method(
5660 "org.freedesktop.systemd1",
5661 "/org/freedesktop/systemd1",
5662 "org.freedesktop.systemd1.Manager",
5663 "PresetAllUnitFiles",
5667 unit_file_preset_mode_to_string(arg_preset_mode
),
5671 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5675 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5680 r
= daemon_reload(bus
, args
);
5686 unit_file_changes_free(changes
, n_changes
);
5691 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
5693 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5694 _cleanup_strv_free_
char **names
= NULL
;
5699 r
= mangle_names(args
+1, &names
);
5703 r
= enable_sysv_units(args
[0], names
);
5709 if (!bus
|| avoid_bus()) {
5711 STRV_FOREACH(name
, names
) {
5712 UnitFileState state
;
5714 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5716 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5720 UNIT_FILE_ENABLED_RUNTIME
,
5722 UNIT_FILE_INDIRECT
))
5726 puts(unit_file_state_to_string(state
));
5730 STRV_FOREACH(name
, names
) {
5731 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5734 r
= sd_bus_call_method(
5736 "org.freedesktop.systemd1",
5737 "/org/freedesktop/systemd1",
5738 "org.freedesktop.systemd1.Manager",
5744 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5748 r
= sd_bus_message_read(reply
, "s", &s
);
5750 return bus_log_parse_error(r
);
5752 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5763 static int is_system_running(sd_bus
*bus
, char **args
) {
5764 _cleanup_free_
char *state
= NULL
;
5767 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5770 return EXIT_FAILURE
;
5773 r
= sd_bus_get_property_string(
5775 "org.freedesktop.systemd1",
5776 "/org/freedesktop/systemd1",
5777 "org.freedesktop.systemd1.Manager",
5790 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5793 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5798 assert(original_path
);
5801 r
= tempfn_random(new_path
, NULL
, &t
);
5803 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5805 r
= mkdir_parents(new_path
, 0755);
5807 log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5812 r
= copy_file(original_path
, t
, 0, 0644, 0);
5816 log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5821 log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5831 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5832 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5834 switch (arg_scope
) {
5835 case UNIT_FILE_SYSTEM
:
5836 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5838 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5840 case UNIT_FILE_GLOBAL
:
5841 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5843 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5845 case UNIT_FILE_USER
:
5847 assert(user_runtime
);
5849 path
= path_join(arg_root
, user_home
, name
);
5851 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5854 run
= path_join(arg_root
, user_runtime
, name
);
5858 assert_not_reached("Invalid scope");
5860 if (!path
|| (arg_runtime
&& !run
))
5864 if (access(path
, F_OK
) >= 0)
5865 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5867 if (path2
&& access(path2
, F_OK
) >= 0)
5868 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5880 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
) {
5881 char *tmp_new_path
, *ending
;
5886 assert(ret_new_path
);
5887 assert(ret_tmp_path
);
5889 ending
= strjoina(unit_name
, ".d/override.conf");
5890 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5894 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5900 *ret_new_path
= tmp_new_path
;
5901 *ret_tmp_path
= tmp_tmp_path
;
5906 static int unit_file_create_copy(
5907 const char *unit_name
,
5908 const char *fragment_path
,
5909 const char *user_home
,
5910 const char *user_runtime
,
5911 char **ret_new_path
,
5912 char **ret_tmp_path
) {
5918 assert(fragment_path
);
5920 assert(ret_new_path
);
5921 assert(ret_tmp_path
);
5923 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5927 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5930 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5935 if (response
!= 'y') {
5936 log_warning("%s ignored", unit_name
);
5942 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5944 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5949 *ret_new_path
= tmp_new_path
;
5950 *ret_tmp_path
= tmp_tmp_path
;
5955 static int run_editor(char **paths
) {
5963 log_error_errno(errno
, "Failed to fork: %m");
5969 char *editor
, **editor_args
= NULL
;
5970 char **tmp_path
, **original_path
, *p
;
5971 unsigned n_editor_args
= 0, i
= 1;
5974 (void) reset_all_signal_handlers();
5975 (void) reset_signal_mask();
5977 argc
= strv_length(paths
)/2 + 1;
5979 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5980 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5981 * we try to execute well known editors
5983 editor
= getenv("SYSTEMD_EDITOR");
5985 editor
= getenv("EDITOR");
5987 editor
= getenv("VISUAL");
5989 if (!isempty(editor
)) {
5990 editor_args
= strv_split(editor
, WHITESPACE
);
5993 _exit(EXIT_FAILURE
);
5995 n_editor_args
= strv_length(editor_args
);
5996 argc
+= n_editor_args
- 1;
5998 args
= newa(const char*, argc
+ 1);
6000 if (n_editor_args
> 0) {
6001 args
[0] = editor_args
[0];
6002 for (; i
< n_editor_args
; i
++)
6003 args
[i
] = editor_args
[i
];
6006 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6007 args
[i
] = *tmp_path
;
6012 if (n_editor_args
> 0)
6013 execvp(args
[0], (char* const*) args
);
6015 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6017 execvp(p
, (char* const*) args
);
6018 /* We do not fail if the editor doesn't exist
6019 * because we want to try each one of them before
6022 if (errno
!= ENOENT
) {
6023 log_error("Failed to execute %s: %m", editor
);
6024 _exit(EXIT_FAILURE
);
6028 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6029 _exit(EXIT_FAILURE
);
6032 r
= wait_for_terminate_and_warn("editor", pid
, true);
6034 return log_error_errno(r
, "Failed to wait for child: %m");
6039 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6040 _cleanup_free_
char *user_home
= NULL
;
6041 _cleanup_free_
char *user_runtime
= NULL
;
6042 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6043 bool avoid_bus_cache
;
6050 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6054 avoid_bus_cache
= !bus
|| avoid_bus();
6056 STRV_FOREACH(name
, names
) {
6057 _cleanup_free_
char *path
= NULL
;
6058 char *new_path
, *tmp_path
;
6060 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &path
, NULL
);
6066 // FIXME: support units with path==NULL (no FragmentPath)
6067 log_error("No fragment exists for %s.", *name
);
6072 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6074 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6078 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6086 static int edit(sd_bus
*bus
, char **args
) {
6087 _cleanup_strv_free_
char **names
= NULL
;
6088 _cleanup_strv_free_
char **paths
= NULL
;
6089 char **original
, **tmp
;
6095 log_error("Cannot edit units if not on a tty");
6099 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6100 log_error("Cannot remotely edit units");
6104 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
6106 return log_error_errno(r
, "Failed to expand names: %m");
6108 r
= find_paths_to_edit(bus
, names
, &paths
);
6112 if (strv_isempty(paths
))
6115 r
= run_editor(paths
);
6119 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6120 /* If the temporary file is empty we ignore it.
6121 * It's useful if the user wants to cancel its modification
6123 if (null_or_empty_path(*tmp
)) {
6124 log_warning("Editing \"%s\" canceled: temporary file is empty", *original
);
6127 r
= rename(*tmp
, *original
);
6129 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6134 if (!arg_no_reload
&& bus
&& !avoid_bus())
6135 r
= daemon_reload(bus
, args
);
6138 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6139 unlink_noerrno(*tmp
);
6144 static void systemctl_help(void) {
6146 pager_open_if_enabled();
6148 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6149 "Query or send control commands to the systemd manager.\n\n"
6150 " -h --help Show this help\n"
6151 " --version Show package version\n"
6152 " --system Connect to system manager\n"
6153 " --user Connect to user service manager\n"
6154 " -H --host=[USER@]HOST\n"
6155 " Operate on remote host\n"
6156 " -M --machine=CONTAINER\n"
6157 " Operate on local container\n"
6158 " -t --type=TYPE List units of a particular type\n"
6159 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6160 " -p --property=NAME Show only properties by this name\n"
6161 " -a --all Show all loaded units/properties, including dead/empty\n"
6162 " ones. To list all units installed on the system, use\n"
6163 " the 'list-unit-files' command instead.\n"
6164 " -l --full Don't ellipsize unit names on output\n"
6165 " -r --recursive Show unit list of host and local containers\n"
6166 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6167 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6168 " queueing a new job\n"
6169 " --show-types When showing sockets, explicitly show their type\n"
6170 " -i --ignore-inhibitors\n"
6171 " When shutting down or sleeping, ignore inhibitors\n"
6172 " --kill-who=WHO Who to send signal to\n"
6173 " -s --signal=SIGNAL Which signal to send\n"
6174 " --now Start or stop unit in addition to enabling or disabling it\n"
6175 " -q --quiet Suppress output\n"
6176 " --no-block Do not wait until operation finished\n"
6177 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6178 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6179 " --no-legend Do not print a legend (column headers and hints)\n"
6180 " --no-pager Do not pipe output into a pager\n"
6181 " --no-ask-password\n"
6182 " Do not ask for system passwords\n"
6183 " --global Enable/disable unit files globally\n"
6184 " --runtime Enable unit files only temporarily until next reboot\n"
6185 " -f --force When enabling unit files, override existing symlinks\n"
6186 " When shutting down, execute action immediately\n"
6187 " --preset-mode= Apply only enable, only disable, or all presets\n"
6188 " --root=PATH Enable unit files in the specified root directory\n"
6189 " -n --lines=INTEGER Number of journal entries to show\n"
6190 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6191 " short-precise, short-monotonic, verbose,\n"
6192 " export, json, json-pretty, json-sse, cat)\n"
6193 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6194 " --plain Print unit dependencies as a list instead of a tree\n\n"
6196 " list-units [PATTERN...] List loaded units\n"
6197 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6198 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6199 " start NAME... Start (activate) one or more units\n"
6200 " stop NAME... Stop (deactivate) one or more units\n"
6201 " reload NAME... Reload one or more units\n"
6202 " restart NAME... Start or restart one or more units\n"
6203 " try-restart NAME... Restart one or more units if active\n"
6204 " reload-or-restart NAME... Reload one or more units if possible,\n"
6205 " otherwise start or restart\n"
6206 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6207 " otherwise restart if active\n"
6208 " isolate NAME Start one unit and stop all others\n"
6209 " kill NAME... Send signal to processes of a unit\n"
6210 " is-active PATTERN... Check whether units are active\n"
6211 " is-failed PATTERN... Check whether units are failed\n"
6212 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6213 " show [PATTERN...|JOB...] Show properties of one or more\n"
6214 " units/jobs or the manager\n"
6215 " cat PATTERN... Show files and drop-ins of one or more units\n"
6216 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6217 " help PATTERN...|PID... Show manual for one or more units\n"
6218 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6220 " list-dependencies [NAME] Recursively show units which are required\n"
6221 " or wanted by this unit or by which this\n"
6222 " unit is required or wanted\n\n"
6223 "Unit File Commands:\n"
6224 " list-unit-files [PATTERN...] List installed unit files\n"
6225 " enable NAME... Enable one or more unit files\n"
6226 " disable NAME... Disable one or more unit files\n"
6227 " reenable NAME... Reenable one or more unit files\n"
6228 " preset NAME... Enable/disable one or more unit files\n"
6229 " based on preset configuration\n"
6230 " preset-all Enable/disable all unit files based on\n"
6231 " preset configuration\n"
6232 " is-enabled NAME... Check whether unit files are enabled\n"
6233 " mask NAME... Mask one or more units\n"
6234 " unmask NAME... Unmask one or more units\n"
6235 " link PATH... Link one or more units files into\n"
6236 " the search path\n"
6237 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6238 " on specified one or more units\n"
6239 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6240 " on specified one or more units\n"
6241 " edit NAME... Edit one or more unit files\n"
6242 " get-default Get the name of the default target\n"
6243 " set-default NAME Set the default target\n\n"
6244 "Machine Commands:\n"
6245 " list-machines [PATTERN...] List local containers and host\n\n"
6247 " list-jobs [PATTERN...] List jobs\n"
6248 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6249 "Snapshot Commands:\n"
6250 " snapshot [NAME] Create a snapshot\n"
6251 " delete NAME... Remove one or more snapshots\n\n"
6252 "Environment Commands:\n"
6253 " show-environment Dump environment\n"
6254 " set-environment NAME=VALUE... Set one or more environment variables\n"
6255 " unset-environment NAME... Unset one or more environment variables\n"
6256 " import-environment [NAME...] Import all or some environment variables\n\n"
6257 "Manager Lifecycle Commands:\n"
6258 " daemon-reload Reload systemd manager configuration\n"
6259 " daemon-reexec Reexecute systemd manager\n\n"
6260 "System Commands:\n"
6261 " is-system-running Check whether system is fully running\n"
6262 " default Enter system default mode\n"
6263 " rescue Enter system rescue mode\n"
6264 " emergency Enter system emergency mode\n"
6265 " halt Shut down and halt the system\n"
6266 " poweroff Shut down and power-off the system\n"
6267 " reboot [ARG] Shut down and reboot the system\n"
6268 " kexec Shut down and reboot the system with kexec\n"
6269 " exit [EXIT_CODE] Request user instance or container exit\n"
6270 " switch-root ROOT [INIT] Change to a different root file system\n"
6271 " suspend Suspend the system\n"
6272 " hibernate Hibernate the system\n"
6273 " hybrid-sleep Hibernate and suspend the system\n",
6274 program_invocation_short_name
);
6277 static void halt_help(void) {
6278 printf("%s [OPTIONS...]%s\n\n"
6279 "%s the system.\n\n"
6280 " --help Show this help\n"
6281 " --halt Halt the machine\n"
6282 " -p --poweroff Switch off the machine\n"
6283 " --reboot Reboot the machine\n"
6284 " -f --force Force immediate halt/power-off/reboot\n"
6285 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6286 " -d --no-wtmp Don't write wtmp record\n"
6287 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6288 program_invocation_short_name
,
6289 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6290 arg_action
== ACTION_REBOOT
? "Reboot" :
6291 arg_action
== ACTION_POWEROFF
? "Power off" :
6295 static void shutdown_help(void) {
6296 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6297 "Shut down the system.\n\n"
6298 " --help Show this help\n"
6299 " -H --halt Halt the machine\n"
6300 " -P --poweroff Power-off the machine\n"
6301 " -r --reboot Reboot the machine\n"
6302 " -h Equivalent to --poweroff, overridden by --halt\n"
6303 " -k Don't halt/power-off/reboot, just send warnings\n"
6304 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6305 " -c Cancel a pending shutdown\n",
6306 program_invocation_short_name
);
6309 static void telinit_help(void) {
6310 printf("%s [OPTIONS...] {COMMAND}\n\n"
6311 "Send control commands to the init daemon.\n\n"
6312 " --help Show this help\n"
6313 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6315 " 0 Power-off the machine\n"
6316 " 6 Reboot the machine\n"
6317 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6318 " 1, s, S Enter rescue mode\n"
6319 " q, Q Reload init daemon configuration\n"
6320 " u, U Reexecute init daemon\n",
6321 program_invocation_short_name
);
6324 static void runlevel_help(void) {
6325 printf("%s [OPTIONS...]\n\n"
6326 "Prints the previous and current runlevel of the init system.\n\n"
6327 " --help Show this help\n",
6328 program_invocation_short_name
);
6331 static void help_types(void) {
6336 puts("Available unit types:");
6337 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
6338 t
= unit_type_to_string(i
);
6344 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6353 ARG_IGNORE_DEPENDENCIES
,
6365 ARG_NO_ASK_PASSWORD
,
6378 static const struct option options
[] = {
6379 { "help", no_argument
, NULL
, 'h' },
6380 { "version", no_argument
, NULL
, ARG_VERSION
},
6381 { "type", required_argument
, NULL
, 't' },
6382 { "property", required_argument
, NULL
, 'p' },
6383 { "all", no_argument
, NULL
, 'a' },
6384 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6385 { "after", no_argument
, NULL
, ARG_AFTER
},
6386 { "before", no_argument
, NULL
, ARG_BEFORE
},
6387 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6388 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6389 { "full", no_argument
, NULL
, 'l' },
6390 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6391 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6392 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6393 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6394 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6395 { "user", no_argument
, NULL
, ARG_USER
},
6396 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6397 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6398 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6399 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6400 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6401 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6402 { "quiet", no_argument
, NULL
, 'q' },
6403 { "root", required_argument
, NULL
, ARG_ROOT
},
6404 { "force", no_argument
, NULL
, ARG_FORCE
},
6405 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6406 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6407 { "signal", required_argument
, NULL
, 's' },
6408 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6409 { "host", required_argument
, NULL
, 'H' },
6410 { "machine", required_argument
, NULL
, 'M' },
6411 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6412 { "lines", required_argument
, NULL
, 'n' },
6413 { "output", required_argument
, NULL
, 'o' },
6414 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6415 { "state", required_argument
, NULL
, ARG_STATE
},
6416 { "recursive", no_argument
, NULL
, 'r' },
6417 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6418 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6419 { "now", no_argument
, NULL
, ARG_NOW
},
6420 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6429 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6430 arg_ask_password
= true;
6432 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6444 const char *word
, *state
;
6447 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6448 _cleanup_free_
char *type
;
6450 type
= strndup(word
, size
);
6454 if (streq(type
, "help")) {
6459 if (unit_type_from_string(type
) >= 0) {
6460 if (strv_push(&arg_types
, type
))
6466 /* It's much nicer to use --state= for
6467 * load states, but let's support this
6468 * in --types= too for compatibility
6469 * with old versions */
6470 if (unit_load_state_from_string(optarg
) >= 0) {
6471 if (strv_push(&arg_states
, type
) < 0)
6477 log_error("Unknown unit type or load state '%s'.", type
);
6478 log_info("Use -t help to see a list of allowed values.");
6486 /* Make sure that if the empty property list
6487 was specified, we won't show any properties. */
6488 if (isempty(optarg
) && !arg_properties
) {
6489 arg_properties
= new0(char*, 1);
6490 if (!arg_properties
)
6493 const char *word
, *state
;
6496 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6499 prop
= strndup(word
, size
);
6503 if (strv_consume(&arg_properties
, prop
) < 0)
6508 /* If the user asked for a particular
6509 * property, show it to him, even if it is
6521 arg_dependency
= DEPENDENCY_REVERSE
;
6525 arg_dependency
= DEPENDENCY_AFTER
;
6529 arg_dependency
= DEPENDENCY_BEFORE
;
6532 case ARG_SHOW_TYPES
:
6533 arg_show_types
= true;
6537 arg_job_mode
= optarg
;
6541 arg_job_mode
= "fail";
6544 case ARG_IRREVERSIBLE
:
6545 arg_job_mode
= "replace-irreversibly";
6548 case ARG_IGNORE_DEPENDENCIES
:
6549 arg_job_mode
= "ignore-dependencies";
6553 arg_scope
= UNIT_FILE_USER
;
6557 arg_scope
= UNIT_FILE_SYSTEM
;
6561 arg_scope
= UNIT_FILE_GLOBAL
;
6565 arg_no_block
= true;
6569 arg_no_legend
= true;
6573 arg_no_pager
= true;
6589 if (strv_extend(&arg_states
, "failed") < 0)
6607 arg_no_reload
= true;
6611 arg_kill_who
= optarg
;
6615 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
6616 log_error("Failed to parse signal string %s.", optarg
);
6621 case ARG_NO_ASK_PASSWORD
:
6622 arg_ask_password
= false;
6626 arg_transport
= BUS_TRANSPORT_REMOTE
;
6631 arg_transport
= BUS_TRANSPORT_MACHINE
;
6640 if (safe_atou(optarg
, &arg_lines
) < 0) {
6641 log_error("Failed to parse lines '%s'", optarg
);
6647 arg_output
= output_mode_from_string(optarg
);
6648 if (arg_output
< 0) {
6649 log_error("Unknown output '%s'.", optarg
);
6655 arg_ignore_inhibitors
= true;
6662 case ARG_FIRMWARE_SETUP
:
6663 arg_firmware_setup
= true;
6667 const char *word
, *state
;
6670 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6673 s
= strndup(word
, size
);
6677 if (strv_consume(&arg_states
, s
) < 0)
6684 if (geteuid() != 0) {
6685 log_error("--recursive requires root privileges.");
6689 arg_recursive
= true;
6692 case ARG_PRESET_MODE
:
6694 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6695 if (arg_preset_mode
< 0) {
6696 log_error("Failed to parse preset mode: %s.", optarg
);
6707 if (strv_extend(&arg_wall
, optarg
) < 0)
6715 assert_not_reached("Unhandled option");
6718 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6719 log_error("Cannot access user instance remotely.");
6726 static int halt_parse_argv(int argc
, char *argv
[]) {
6735 static const struct option options
[] = {
6736 { "help", no_argument
, NULL
, ARG_HELP
},
6737 { "halt", no_argument
, NULL
, ARG_HALT
},
6738 { "poweroff", no_argument
, NULL
, 'p' },
6739 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6740 { "force", no_argument
, NULL
, 'f' },
6741 { "wtmp-only", no_argument
, NULL
, 'w' },
6742 { "no-wtmp", no_argument
, NULL
, 'd' },
6743 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6752 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6753 if (runlevel
== '0' || runlevel
== '6')
6756 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6764 arg_action
= ACTION_HALT
;
6768 if (arg_action
!= ACTION_REBOOT
)
6769 arg_action
= ACTION_POWEROFF
;
6773 arg_action
= ACTION_REBOOT
;
6795 /* Compatibility nops */
6802 assert_not_reached("Unhandled option");
6805 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6806 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6809 } else if (optind
< argc
) {
6810 log_error("Too many arguments.");
6817 static int parse_time_spec(const char *t
, usec_t
*_u
) {
6821 if (streq(t
, "now"))
6823 else if (!strchr(t
, ':')) {
6826 if (safe_atou64(t
, &u
) < 0)
6829 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6838 hour
= strtol(t
, &e
, 10);
6839 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6842 minute
= strtol(e
+1, &e
, 10);
6843 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6846 n
= now(CLOCK_REALTIME
);
6847 s
= (time_t) (n
/ USEC_PER_SEC
);
6849 assert_se(localtime_r(&s
, &tm
));
6851 tm
.tm_hour
= (int) hour
;
6852 tm
.tm_min
= (int) minute
;
6855 assert_se(s
= mktime(&tm
));
6857 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6860 *_u
+= USEC_PER_DAY
;
6866 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6873 static const struct option options
[] = {
6874 { "help", no_argument
, NULL
, ARG_HELP
},
6875 { "halt", no_argument
, NULL
, 'H' },
6876 { "poweroff", no_argument
, NULL
, 'P' },
6877 { "reboot", no_argument
, NULL
, 'r' },
6878 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6879 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6888 while ((c
= getopt_long(argc
, argv
, "HPrhkKt:afFc", options
, NULL
)) >= 0)
6896 arg_action
= ACTION_HALT
;
6900 arg_action
= ACTION_POWEROFF
;
6905 arg_action
= ACTION_KEXEC
;
6907 arg_action
= ACTION_REBOOT
;
6911 arg_action
= ACTION_KEXEC
;
6915 if (arg_action
!= ACTION_HALT
)
6916 arg_action
= ACTION_POWEROFF
;
6931 /* Compatibility nops */
6935 arg_action
= ACTION_CANCEL_SHUTDOWN
;
6942 assert_not_reached("Unhandled option");
6945 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
6946 r
= parse_time_spec(argv
[optind
], &arg_when
);
6948 log_error("Failed to parse time specification: %s", argv
[optind
]);
6952 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
6954 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
6955 /* No time argument for shutdown cancel */
6956 arg_wall
= argv
+ optind
;
6957 else if (argc
> optind
+ 1)
6958 /* We skip the time argument */
6959 arg_wall
= argv
+ optind
+ 1;
6966 static int telinit_parse_argv(int argc
, char *argv
[]) {
6973 static const struct option options
[] = {
6974 { "help", no_argument
, NULL
, ARG_HELP
},
6975 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6979 static const struct {
6983 { '0', ACTION_POWEROFF
},
6984 { '6', ACTION_REBOOT
},
6985 { '1', ACTION_RESCUE
},
6986 { '2', ACTION_RUNLEVEL2
},
6987 { '3', ACTION_RUNLEVEL3
},
6988 { '4', ACTION_RUNLEVEL4
},
6989 { '5', ACTION_RUNLEVEL5
},
6990 { 's', ACTION_RESCUE
},
6991 { 'S', ACTION_RESCUE
},
6992 { 'q', ACTION_RELOAD
},
6993 { 'Q', ACTION_RELOAD
},
6994 { 'u', ACTION_REEXEC
},
6995 { 'U', ACTION_REEXEC
}
7004 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7019 assert_not_reached("Unhandled option");
7022 if (optind
>= argc
) {
7023 log_error("%s: required argument missing.",
7024 program_invocation_short_name
);
7028 if (optind
+ 1 < argc
) {
7029 log_error("Too many arguments.");
7033 if (strlen(argv
[optind
]) != 1) {
7034 log_error("Expected single character argument.");
7038 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7039 if (table
[i
].from
== argv
[optind
][0])
7042 if (i
>= ELEMENTSOF(table
)) {
7043 log_error("Unknown command '%s'.", argv
[optind
]);
7047 arg_action
= table
[i
].to
;
7054 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7060 static const struct option options
[] = {
7061 { "help", no_argument
, NULL
, ARG_HELP
},
7070 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7081 assert_not_reached("Unhandled option");
7084 if (optind
< argc
) {
7085 log_error("Too many arguments.");
7092 static int parse_argv(int argc
, char *argv
[]) {
7096 if (program_invocation_short_name
) {
7098 if (strstr(program_invocation_short_name
, "halt")) {
7099 arg_action
= ACTION_HALT
;
7100 return halt_parse_argv(argc
, argv
);
7101 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7102 arg_action
= ACTION_POWEROFF
;
7103 return halt_parse_argv(argc
, argv
);
7104 } else if (strstr(program_invocation_short_name
, "reboot")) {
7106 arg_action
= ACTION_KEXEC
;
7108 arg_action
= ACTION_REBOOT
;
7109 return halt_parse_argv(argc
, argv
);
7110 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7111 arg_action
= ACTION_POWEROFF
;
7112 return shutdown_parse_argv(argc
, argv
);
7113 } else if (strstr(program_invocation_short_name
, "init")) {
7115 if (sd_booted() > 0) {
7116 arg_action
= _ACTION_INVALID
;
7117 return telinit_parse_argv(argc
, argv
);
7119 /* Hmm, so some other init system is
7120 * running, we need to forward this
7121 * request to it. For now we simply
7122 * guess that it is Upstart. */
7124 execv(TELINIT
, argv
);
7126 log_error("Couldn't find an alternative telinit implementation to spawn.");
7130 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7131 arg_action
= ACTION_RUNLEVEL
;
7132 return runlevel_parse_argv(argc
, argv
);
7136 arg_action
= ACTION_SYSTEMCTL
;
7137 return systemctl_parse_argv(argc
, argv
);
7140 _pure_
static int action_to_runlevel(void) {
7142 static const char table
[_ACTION_MAX
] = {
7143 [ACTION_HALT
] = '0',
7144 [ACTION_POWEROFF
] = '0',
7145 [ACTION_REBOOT
] = '6',
7146 [ACTION_RUNLEVEL2
] = '2',
7147 [ACTION_RUNLEVEL3
] = '3',
7148 [ACTION_RUNLEVEL4
] = '4',
7149 [ACTION_RUNLEVEL5
] = '5',
7150 [ACTION_RESCUE
] = '1'
7153 assert(arg_action
< _ACTION_MAX
);
7155 return table
[arg_action
];
7158 static int talk_initctl(void) {
7160 struct init_request request
= {
7161 .magic
= INIT_MAGIC
,
7163 .cmd
= INIT_CMD_RUNLVL
7166 _cleanup_close_
int fd
= -1;
7170 rl
= action_to_runlevel();
7174 request
.runlevel
= rl
;
7176 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7178 if (errno
== ENOENT
)
7181 log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7185 r
= loop_write(fd
, &request
, sizeof(request
), false);
7187 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7192 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
7194 static const struct {
7202 int (* const dispatch
)(sd_bus
*bus
, char **args
);
7208 { "list-units", MORE
, 0, list_units
},
7209 { "list-unit-files", MORE
, 1, list_unit_files
, NOBUS
},
7210 { "list-sockets", MORE
, 1, list_sockets
},
7211 { "list-timers", MORE
, 1, list_timers
},
7212 { "list-jobs", MORE
, 1, list_jobs
},
7213 { "list-machines", MORE
, 1, list_machines
},
7214 { "clear-jobs", EQUAL
, 1, daemon_reload
},
7215 { "cancel", MORE
, 2, cancel_job
},
7216 { "start", MORE
, 2, start_unit
},
7217 { "stop", MORE
, 2, start_unit
},
7218 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7219 { "reload", MORE
, 2, start_unit
},
7220 { "restart", MORE
, 2, start_unit
},
7221 { "try-restart", MORE
, 2, start_unit
},
7222 { "reload-or-restart", MORE
, 2, start_unit
},
7223 { "reload-or-try-restart", MORE
, 2, start_unit
},
7224 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
7225 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7226 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
7227 { "isolate", EQUAL
, 2, start_unit
},
7228 { "kill", MORE
, 2, kill_unit
},
7229 { "is-active", MORE
, 2, check_unit_active
},
7230 { "check", MORE
, 2, check_unit_active
},
7231 { "is-failed", MORE
, 2, check_unit_failed
},
7232 { "show", MORE
, 1, show
},
7233 { "cat", MORE
, 2, cat
, NOBUS
},
7234 { "status", MORE
, 1, show
},
7235 { "help", MORE
, 2, show
},
7236 { "snapshot", LESS
, 2, snapshot
},
7237 { "delete", MORE
, 2, delete_snapshot
},
7238 { "daemon-reload", EQUAL
, 1, daemon_reload
},
7239 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
7240 { "show-environment", EQUAL
, 1, show_environment
},
7241 { "set-environment", MORE
, 2, set_environment
},
7242 { "unset-environment", MORE
, 2, set_environment
},
7243 { "import-environment", MORE
, 1, import_environment
},
7244 { "halt", EQUAL
, 1, start_special
, FORCE
},
7245 { "poweroff", EQUAL
, 1, start_special
, FORCE
},
7246 { "reboot", MORE
, 1, start_special
, FORCE
},
7247 { "kexec", EQUAL
, 1, start_special
},
7248 { "suspend", EQUAL
, 1, start_special
},
7249 { "hibernate", EQUAL
, 1, start_special
},
7250 { "hybrid-sleep", EQUAL
, 1, start_special
},
7251 { "default", EQUAL
, 1, start_special
},
7252 { "rescue", EQUAL
, 1, start_special
},
7253 { "emergency", EQUAL
, 1, start_special
},
7254 { "exit", LESS
, 2, start_special
},
7255 { "reset-failed", MORE
, 1, reset_failed
},
7256 { "enable", MORE
, 2, enable_unit
, NOBUS
},
7257 { "disable", MORE
, 2, enable_unit
, NOBUS
},
7258 { "is-enabled", MORE
, 2, unit_is_enabled
, NOBUS
},
7259 { "reenable", MORE
, 2, enable_unit
, NOBUS
},
7260 { "preset", MORE
, 2, enable_unit
, NOBUS
},
7261 { "preset-all", EQUAL
, 1, preset_all
, NOBUS
},
7262 { "mask", MORE
, 2, enable_unit
, NOBUS
},
7263 { "unmask", MORE
, 2, enable_unit
, NOBUS
},
7264 { "link", MORE
, 2, enable_unit
, NOBUS
},
7265 { "switch-root", MORE
, 2, switch_root
},
7266 { "list-dependencies", LESS
, 2, list_dependencies
},
7267 { "set-default", EQUAL
, 2, set_default
, NOBUS
},
7268 { "get-default", EQUAL
, 1, get_default
, NOBUS
},
7269 { "set-property", MORE
, 3, set_property
},
7270 { "is-system-running", EQUAL
, 1, is_system_running
},
7271 { "add-wants", MORE
, 3, add_dependency
, NOBUS
},
7272 { "add-requires", MORE
, 3, add_dependency
, NOBUS
},
7273 { "edit", MORE
, 2, edit
, NOBUS
},
7282 left
= argc
- optind
;
7284 /* Special rule: no arguments (left == 0) means "list-units" */
7286 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
7287 log_error("This command expects one or more "
7288 "unit names. Did you mean --help?");
7292 for (; verb
->verb
; verb
++)
7293 if (streq(argv
[optind
], verb
->verb
))
7296 log_error("Unknown operation '%s'.", argv
[optind
]);
7301 switch (verb
->argc_cmp
) {
7304 if (left
!= verb
->argc
) {
7305 log_error("Invalid number of arguments.");
7312 if (left
< verb
->argc
) {
7313 log_error("Too few arguments.");
7320 if (left
> verb
->argc
) {
7321 log_error("Too many arguments.");
7328 assert_not_reached("Unknown comparison operator.");
7331 /* Require a bus connection for all operations but
7333 if (verb
->bus
== NOBUS
) {
7334 if (!bus
&& !avoid_bus()) {
7335 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7340 if (running_in_chroot() > 0) {
7341 log_info("Running in chroot, ignoring request.");
7345 if ((verb
->bus
!= FORCE
|| arg_force
<= 0) && !bus
) {
7346 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7351 return verb
->dispatch(bus
, argv
+ optind
);
7354 static int reload_with_fallback(sd_bus
*bus
) {
7357 /* First, try systemd via D-Bus. */
7358 if (daemon_reload(bus
, NULL
) >= 0)
7362 /* Nothing else worked, so let's try signals */
7363 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7365 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7366 return log_error_errno(errno
, "kill() failed: %m");
7371 static int start_with_fallback(sd_bus
*bus
) {
7374 /* First, try systemd via D-Bus. */
7375 if (start_unit(bus
, NULL
) >= 0)
7379 /* Nothing else worked, so let's try
7381 if (talk_initctl() > 0)
7384 log_error("Failed to talk to init daemon.");
7388 warn_wall(arg_action
);
7392 static int halt_now(enum action a
) {
7394 /* The kernel will automaticall flush ATA disks and suchlike
7395 * on reboot(), but the file systems need to be synce'd
7396 * explicitly in advance. */
7399 /* Make sure C-A-D is handled by the kernel from this point
7401 reboot(RB_ENABLE_CAD
);
7406 log_info("Halting.");
7407 reboot(RB_HALT_SYSTEM
);
7410 case ACTION_POWEROFF
:
7411 log_info("Powering off.");
7412 reboot(RB_POWER_OFF
);
7416 case ACTION_REBOOT
: {
7417 _cleanup_free_
char *param
= NULL
;
7419 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7420 log_info("Rebooting with argument '%s'.", param
);
7421 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
7422 LINUX_REBOOT_CMD_RESTART2
, param
);
7425 log_info("Rebooting.");
7426 reboot(RB_AUTOBOOT
);
7431 assert_not_reached("Unknown action.");
7435 static int halt_main(sd_bus
*bus
) {
7438 r
= check_inhibitors(bus
, arg_action
);
7442 if (geteuid() != 0) {
7446 log_error("Must be root.");
7450 /* Try logind if we are a normal user and no special
7451 * mode applies. Maybe PolicyKit allows us to shutdown
7453 if (IN_SET(arg_action
,
7456 r
= reboot_with_logind(bus
, arg_action
);
7459 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7460 /* requested operation is not supported or already in progress */
7462 /* on all other errors, try low-level operation */
7467 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7468 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7471 assert(geteuid() == 0);
7474 log_error("Unable to perform operation without bus connection.");
7478 r
= sd_bus_open_system(&b
);
7480 return log_error_errno(r
, "Unable to open system bus: %m");
7482 (void) set_wall_message(b
);
7484 switch (arg_action
) {
7488 case ACTION_POWEROFF
:
7489 action
= "poweroff";
7500 action
= strjoina("dry-", action
);
7502 r
= sd_bus_call_method(
7504 "org.freedesktop.login1",
7505 "/org/freedesktop/login1",
7506 "org.freedesktop.login1.Manager",
7514 log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s",
7515 bus_error_message(&error
, r
));
7517 char date
[FORMAT_TIMESTAMP_MAX
];
7519 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7520 format_timestamp(date
, sizeof(date
), arg_when
));
7525 if (!arg_dry
&& !arg_force
)
7526 return start_with_fallback(bus
);
7528 assert(geteuid() == 0);
7531 if (sd_booted() > 0)
7532 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7534 r
= utmp_put_shutdown();
7536 log_warning_errno(r
, "Failed to write utmp record: %m");
7543 r
= halt_now(arg_action
);
7544 log_error_errno(r
, "Failed to reboot: %m");
7549 static int runlevel_main(void) {
7550 int r
, runlevel
, previous
;
7552 r
= utmp_get_runlevel(&runlevel
, &previous
);
7559 previous
<= 0 ? 'N' : previous
,
7560 runlevel
<= 0 ? 'N' : runlevel
);
7565 int main(int argc
, char*argv
[]) {
7566 _cleanup_bus_flush_close_unref_ sd_bus
*bus
= NULL
;
7569 setlocale(LC_ALL
, "");
7570 log_parse_environment();
7573 /* Explicitly not on_tty() to avoid setting cached value.
7574 * This becomes relevant for piping output which might be
7576 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7578 r
= parse_argv(argc
, argv
);
7582 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7583 log_info("Running in chroot, ignoring request.");
7589 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
7592 sd_bus_set_allow_interactive_authorization(bus
, arg_ask_password
);
7594 /* systemctl_main() will print an error message for the bus
7595 * connection, but only if it needs to */
7597 switch (arg_action
) {
7599 case ACTION_SYSTEMCTL
:
7600 r
= systemctl_main(bus
, argc
, argv
, r
);
7604 case ACTION_POWEROFF
:
7610 case ACTION_RUNLEVEL2
:
7611 case ACTION_RUNLEVEL3
:
7612 case ACTION_RUNLEVEL4
:
7613 case ACTION_RUNLEVEL5
:
7615 case ACTION_EMERGENCY
:
7616 case ACTION_DEFAULT
:
7617 r
= start_with_fallback(bus
);
7622 r
= reload_with_fallback(bus
);
7625 case ACTION_CANCEL_SHUTDOWN
: {
7626 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7627 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7630 log_error("Unable to perform operation without bus connection.");
7634 r
= sd_bus_open_system(&b
);
7636 return log_error_errno(r
, "Unable to open system bus: %m");
7638 (void) set_wall_message(b
);
7640 r
= sd_bus_call_method(
7642 "org.freedesktop.login1",
7643 "/org/freedesktop/login1",
7644 "org.freedesktop.login1.Manager",
7645 "CancelScheduledShutdown",
7649 log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s",
7650 bus_error_message(&error
, r
));
7654 case ACTION_RUNLEVEL
:
7655 r
= runlevel_main();
7658 case _ACTION_INVALID
:
7660 assert_not_reached("Unknown action");
7665 ask_password_agent_close();
7666 polkit_agent_close();
7668 strv_free(arg_types
);
7669 strv_free(arg_states
);
7670 strv_free(arg_properties
);
7672 sd_bus_default_flush_close();
7674 return r
< 0 ? EXIT_FAILURE
: r
;