1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
23 #include <sys/reboot.h>
24 #include <linux/reboot.h>
33 #include <sys/socket.h>
36 #include "sd-daemon.h"
43 #include "utmp-wtmp.h"
46 #include "path-util.h"
48 #include "cgroup-show.h"
49 #include "cgroup-util.h"
51 #include "path-lookup.h"
52 #include "exit-status.h"
54 #include "unit-name.h"
56 #include "spawn-ask-password-agent.h"
57 #include "spawn-polkit-agent.h"
59 #include "logs-show.h"
60 #include "socket-util.h"
65 #include "bus-message.h"
66 #include "bus-error.h"
67 #include "bus-common-errors.h"
71 #include "formats-util.h"
72 #include "process-util.h"
73 #include "terminal-util.h"
74 #include "hostname-util.h"
75 #include "signal-util.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
= true;
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 if (running_in_chroot() > 0)
272 if (sd_booted() <= 0)
275 if (!isempty(arg_root
))
278 if (arg_scope
== UNIT_FILE_GLOBAL
)
284 static int compare_unit_info(const void *a
, const void *b
) {
285 const UnitInfo
*u
= a
, *v
= b
;
289 /* First, order by machine */
290 if (!u
->machine
&& v
->machine
)
292 if (u
->machine
&& !v
->machine
)
294 if (u
->machine
&& v
->machine
) {
295 r
= strcasecmp(u
->machine
, v
->machine
);
300 /* Second, order by unit type */
301 d1
= strrchr(u
->id
, '.');
302 d2
= strrchr(v
->id
, '.');
304 r
= strcasecmp(d1
, d2
);
309 /* Third, order by name */
310 return strcasecmp(u
->id
, v
->id
);
313 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
314 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
320 dot
= strrchr(u
->id
, '.');
324 if (!strv_find(arg_types
, dot
+1))
334 if (streq(u
->active_state
, "inactive") || u
->following
[0])
340 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
341 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
343 unsigned n_shown
= 0;
346 max_id_len
= strlen("UNIT");
347 load_len
= strlen("LOAD");
348 active_len
= strlen("ACTIVE");
349 sub_len
= strlen("SUB");
350 job_len
= strlen("JOB");
353 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
354 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
355 load_len
= MAX(load_len
, strlen(u
->load_state
));
356 active_len
= MAX(active_len
, strlen(u
->active_state
));
357 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
359 if (u
->job_id
!= 0) {
360 job_len
= MAX(job_len
, strlen(u
->job_type
));
364 if (!arg_no_legend
&&
365 (streq(u
->active_state
, "failed") ||
366 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
370 if (!arg_full
&& original_stdout_is_tty
) {
373 id_len
= MIN(max_id_len
, 25u);
374 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
377 basic_len
+= job_len
+ 1;
379 if (basic_len
< (unsigned) columns()) {
380 unsigned extra_len
, incr
;
381 extra_len
= columns() - basic_len
;
383 /* Either UNIT already got 25, or is fully satisfied.
384 * Grant up to 25 to DESC now. */
385 incr
= MIN(extra_len
, 25u);
389 /* split the remaining space between UNIT and DESC,
390 * but do not give UNIT more than it needs. */
392 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
394 desc_len
+= extra_len
- incr
;
400 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
401 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
402 const char *on_loaded
= "", *off_loaded
= "";
403 const char *on_active
= "", *off_active
= "";
404 const char *on_circle
= "", *off_circle
= "";
408 if (!n_shown
&& !arg_no_legend
) {
413 printf("%-*s %-*s %-*s %-*s ",
416 active_len
, "ACTIVE",
420 printf("%-*s ", job_len
, "JOB");
422 if (!arg_full
&& arg_no_pager
)
423 printf("%.*s\n", desc_len
, "DESCRIPTION");
425 printf("%s\n", "DESCRIPTION");
430 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
431 on_loaded
= ansi_highlight_red();
432 on_circle
= ansi_highlight_yellow();
433 off_loaded
= off_circle
= ansi_highlight_off();
435 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
436 on_circle
= on_active
= ansi_highlight_red();
437 off_circle
= off_active
= ansi_highlight_off();
442 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
451 e
= ellipsize(id
, id_len
, 33);
459 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
461 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
462 on_active
, id_len
, id
, off_active
,
463 on_loaded
, load_len
, u
->load_state
, off_loaded
,
464 on_active
, active_len
, u
->active_state
,
465 sub_len
, u
->sub_state
, off_active
,
466 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
469 printf("%.*s\n", desc_len
, u
->description
);
471 printf("%s\n", u
->description
);
474 if (!arg_no_legend
) {
475 const char *on
, *off
;
479 "LOAD = Reflects whether the unit definition was properly loaded.\n"
480 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
481 "SUB = The low-level unit activation state, values depend on unit type.");
482 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
483 on
= ansi_highlight();
484 off
= ansi_highlight_off();
486 on
= ansi_highlight_red();
487 off
= ansi_highlight_off();
491 printf("%s%u loaded units listed.%s\n"
492 "To show all installed unit files use 'systemctl list-unit-files'.\n",
495 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
496 "To show all installed unit files use 'systemctl list-unit-files'.\n",
503 static int get_unit_list(
507 UnitInfo
**unit_infos
,
509 sd_bus_message
**_reply
) {
511 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
512 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
513 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
522 r
= sd_bus_message_new_method_call(
525 "org.freedesktop.systemd1",
526 "/org/freedesktop/systemd1",
527 "org.freedesktop.systemd1.Manager",
528 "ListUnitsFiltered");
531 return bus_log_create_error(r
);
533 r
= sd_bus_message_append_strv(m
, arg_states
);
535 return bus_log_create_error(r
);
537 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
539 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
541 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
543 return bus_log_parse_error(r
);
545 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
548 if (!output_show_unit(&u
, patterns
))
551 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
554 (*unit_infos
)[c
++] = u
;
557 return bus_log_parse_error(r
);
559 r
= sd_bus_message_exit_container(reply
);
561 return bus_log_parse_error(r
);
569 static void message_set_freep(Set
**set
) {
572 while ((m
= set_steal_first(*set
)))
573 sd_bus_message_unref(m
);
578 static int get_unit_list_recursive(
581 UnitInfo
**_unit_infos
,
585 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
586 _cleanup_(message_set_freep
) Set
*replies
;
587 sd_bus_message
*reply
;
595 replies
= set_new(NULL
);
599 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
603 r
= set_put(replies
, reply
);
605 sd_bus_message_unref(reply
);
610 _cleanup_strv_free_
char **machines
= NULL
;
613 r
= sd_get_machine_names(&machines
);
615 return log_error_errno(r
, "Failed to get machine names: %m");
617 STRV_FOREACH(i
, machines
) {
618 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
621 r
= sd_bus_open_system_machine(&container
, *i
);
623 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
627 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
633 r
= set_put(replies
, reply
);
635 sd_bus_message_unref(reply
);
640 *_machines
= machines
;
645 *_unit_infos
= unit_infos
;
654 static int list_units(sd_bus
*bus
, char **args
) {
655 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
656 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
657 _cleanup_strv_free_
char **machines
= NULL
;
660 pager_open_if_enabled();
662 r
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
666 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
667 return output_units_list(unit_infos
, r
);
670 static int get_triggered_units(
675 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
678 r
= sd_bus_get_property_strv(
680 "org.freedesktop.systemd1",
682 "org.freedesktop.systemd1.Unit",
688 log_error("Failed to determine triggers: %s", bus_error_message(&error
, r
));
693 static int get_listening(
695 const char* unit_path
,
698 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
699 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
700 const char *type
, *path
;
703 r
= sd_bus_get_property(
705 "org.freedesktop.systemd1",
707 "org.freedesktop.systemd1.Socket",
713 log_error("Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
717 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
719 return bus_log_parse_error(r
);
721 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
723 r
= strv_extend(listening
, type
);
727 r
= strv_extend(listening
, path
);
734 return bus_log_parse_error(r
);
736 r
= sd_bus_message_exit_container(reply
);
738 return bus_log_parse_error(r
);
750 /* Note: triggered is a list here, although it almost certainly
751 * will always be one unit. Nevertheless, dbus API allows for multiple
752 * values, so let's follow that. */
755 /* The strv above is shared. free is set only in the first one. */
759 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
765 if (!a
->machine
&& b
->machine
)
767 if (a
->machine
&& !b
->machine
)
769 if (a
->machine
&& b
->machine
) {
770 o
= strcasecmp(a
->machine
, b
->machine
);
775 o
= strcmp(a
->path
, b
->path
);
777 o
= strcmp(a
->type
, b
->type
);
782 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
783 struct socket_info
*s
;
784 unsigned pathlen
= strlen("LISTEN"),
785 typelen
= strlen("TYPE") * arg_show_types
,
786 socklen
= strlen("UNIT"),
787 servlen
= strlen("ACTIVATES");
788 const char *on
, *off
;
790 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
794 socklen
= MAX(socklen
, strlen(s
->id
));
796 typelen
= MAX(typelen
, strlen(s
->type
));
797 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
799 STRV_FOREACH(a
, s
->triggered
)
800 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
801 servlen
= MAX(servlen
, tmp
);
806 printf("%-*s %-*.*s%-*s %s\n",
808 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
812 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
813 _cleanup_free_
char *j
= NULL
;
818 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
826 printf("%-*s %-*s %-*s",
827 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
830 pathlen
, path
, socklen
, s
->id
);
831 STRV_FOREACH(a
, s
->triggered
)
833 a
== s
->triggered
? "" : ",", *a
);
837 on
= ansi_highlight();
838 off
= ansi_highlight_off();
842 on
= ansi_highlight_red();
843 off
= ansi_highlight_off();
846 if (!arg_no_legend
) {
847 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
849 printf("Pass --all to see loaded but inactive sockets, too.\n");
855 static int list_sockets(sd_bus
*bus
, char **args
) {
856 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
857 _cleanup_strv_free_
char **machines
= NULL
;
858 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
859 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
861 struct socket_info
*s
;
866 pager_open_if_enabled();
868 n
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
872 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
873 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
876 if (!endswith(u
->id
, ".socket"))
879 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
883 c
= get_listening(bus
, u
->unit_path
, &listening
);
889 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
894 for (i
= 0; i
< c
; i
++)
895 socket_infos
[cs
+ i
] = (struct socket_info
) {
896 .machine
= u
->machine
,
898 .type
= listening
[i
*2],
899 .path
= listening
[i
*2 + 1],
900 .triggered
= triggered
,
901 .own_triggered
= i
==0,
904 /* from this point on we will cleanup those socket_infos */
907 listening
= triggered
= NULL
; /* avoid cleanup */
910 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
911 (__compar_fn_t
) socket_info_compare
);
913 output_sockets_list(socket_infos
, cs
);
916 assert(cs
== 0 || socket_infos
);
917 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
920 if (s
->own_triggered
)
921 strv_free(s
->triggered
);
927 static int get_next_elapse(
930 dual_timestamp
*next
) {
932 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
940 r
= sd_bus_get_property_trivial(
942 "org.freedesktop.systemd1",
944 "org.freedesktop.systemd1.Timer",
945 "NextElapseUSecMonotonic",
950 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
954 r
= sd_bus_get_property_trivial(
956 "org.freedesktop.systemd1",
958 "org.freedesktop.systemd1.Timer",
959 "NextElapseUSecRealtime",
964 log_error("Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
972 static int get_last_trigger(
977 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
984 r
= sd_bus_get_property_trivial(
986 "org.freedesktop.systemd1",
988 "org.freedesktop.systemd1.Timer",
994 log_error("Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1002 const char* machine
;
1005 usec_t last_trigger
;
1009 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1015 if (!a
->machine
&& b
->machine
)
1017 if (a
->machine
&& !b
->machine
)
1019 if (a
->machine
&& b
->machine
) {
1020 o
= strcasecmp(a
->machine
, b
->machine
);
1025 if (a
->next_elapse
< b
->next_elapse
)
1027 if (a
->next_elapse
> b
->next_elapse
)
1030 return strcmp(a
->id
, b
->id
);
1033 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1034 struct timer_info
*t
;
1036 nextlen
= strlen("NEXT"),
1037 leftlen
= strlen("LEFT"),
1038 lastlen
= strlen("LAST"),
1039 passedlen
= strlen("PASSED"),
1040 unitlen
= strlen("UNIT"),
1041 activatelen
= strlen("ACTIVATES");
1043 const char *on
, *off
;
1045 assert(timer_infos
|| n
== 0);
1047 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1051 if (t
->next_elapse
> 0) {
1052 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1054 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1055 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1057 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1058 leftlen
= MAX(leftlen
, strlen(trel
));
1061 if (t
->last_trigger
> 0) {
1062 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1064 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1065 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1067 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1068 passedlen
= MAX(passedlen
, strlen(trel
));
1071 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1073 STRV_FOREACH(a
, t
->triggered
)
1074 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1076 activatelen
= MAX(activatelen
, ul
);
1081 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1085 passedlen
, "PASSED",
1089 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1090 _cleanup_free_
char *j
= NULL
;
1092 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1093 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1096 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1097 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1099 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1100 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1103 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1110 printf("%-*s %-*s %-*s %-*s %-*s",
1111 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1113 STRV_FOREACH(a
, t
->triggered
)
1115 a
== t
->triggered
? "" : ",", *a
);
1119 on
= ansi_highlight();
1120 off
= ansi_highlight_off();
1124 on
= ansi_highlight_red();
1125 off
= ansi_highlight_off();
1128 if (!arg_no_legend
) {
1129 printf("%s%u timers listed.%s\n", on
, n
, off
);
1131 printf("Pass --all to see loaded but inactive timers, too.\n");
1137 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1143 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1146 if (next
->monotonic
> nw
->monotonic
)
1147 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1149 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1151 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1152 next_elapse
= MIN(converted
, next
->realtime
);
1154 next_elapse
= converted
;
1157 next_elapse
= next
->realtime
;
1162 static int list_timers(sd_bus
*bus
, char **args
) {
1163 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1164 _cleanup_strv_free_
char **machines
= NULL
;
1165 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1166 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1167 struct timer_info
*t
;
1174 pager_open_if_enabled();
1176 n
= get_unit_list_recursive(bus
, strv_skip_first(args
), &unit_infos
, &replies
, &machines
);
1180 dual_timestamp_get(&nw
);
1182 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1183 _cleanup_strv_free_
char **triggered
= NULL
;
1184 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1187 if (!endswith(u
->id
, ".timer"))
1190 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1194 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1198 get_last_trigger(bus
, u
->unit_path
, &last
);
1200 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1205 m
= calc_next_elapse(&nw
, &next
);
1207 timer_infos
[c
++] = (struct timer_info
) {
1208 .machine
= u
->machine
,
1211 .last_trigger
= last
,
1212 .triggered
= triggered
,
1215 triggered
= NULL
; /* avoid cleanup */
1218 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1219 (__compar_fn_t
) timer_info_compare
);
1221 output_timers_list(timer_infos
, c
);
1224 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1225 strv_free(t
->triggered
);
1230 static int compare_unit_file_list(const void *a
, const void *b
) {
1231 const char *d1
, *d2
;
1232 const UnitFileList
*u
= a
, *v
= b
;
1234 d1
= strrchr(u
->path
, '.');
1235 d2
= strrchr(v
->path
, '.');
1240 r
= strcasecmp(d1
, d2
);
1245 return strcasecmp(basename(u
->path
), basename(v
->path
));
1248 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1249 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1252 if (!strv_isempty(arg_types
)) {
1255 dot
= strrchr(u
->path
, '.');
1259 if (!strv_find(arg_types
, dot
+1))
1263 if (!strv_isempty(arg_states
) &&
1264 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1270 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1271 unsigned max_id_len
, id_cols
, state_cols
;
1272 const UnitFileList
*u
;
1274 max_id_len
= strlen("UNIT FILE");
1275 state_cols
= strlen("STATE");
1277 for (u
= units
; u
< units
+ c
; u
++) {
1278 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1279 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1283 unsigned basic_cols
;
1285 id_cols
= MIN(max_id_len
, 25u);
1286 basic_cols
= 1 + id_cols
+ state_cols
;
1287 if (basic_cols
< (unsigned) columns())
1288 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1290 id_cols
= max_id_len
;
1293 printf("%-*s %-*s\n",
1294 id_cols
, "UNIT FILE",
1295 state_cols
, "STATE");
1297 for (u
= units
; u
< units
+ c
; u
++) {
1298 _cleanup_free_
char *e
= NULL
;
1299 const char *on
, *off
;
1302 if (u
->state
== UNIT_FILE_MASKED
||
1303 u
->state
== UNIT_FILE_MASKED_RUNTIME
||
1304 u
->state
== UNIT_FILE_DISABLED
||
1305 u
->state
== UNIT_FILE_INVALID
) {
1306 on
= ansi_highlight_red();
1307 off
= ansi_highlight_off();
1308 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1309 on
= ansi_highlight_green();
1310 off
= ansi_highlight_off();
1314 id
= basename(u
->path
);
1316 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1318 printf("%-*s %s%-*s%s\n",
1319 id_cols
, e
? e
: id
,
1320 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1324 printf("\n%u unit files listed.\n", c
);
1327 static int list_unit_files(sd_bus
*bus
, char **args
) {
1328 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1329 _cleanup_free_ UnitFileList
*units
= NULL
;
1337 pager_open_if_enabled();
1345 h
= hashmap_new(&string_hash_ops
);
1349 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1351 unit_file_list_free(h
);
1352 log_error_errno(r
, "Failed to get unit file list: %m");
1356 n_units
= hashmap_size(h
);
1358 units
= new(UnitFileList
, n_units
);
1359 if (!units
&& n_units
> 0) {
1360 unit_file_list_free(h
);
1364 HASHMAP_FOREACH(u
, h
, i
) {
1365 if (!output_show_unit_file(u
, strv_skip_first(args
)))
1372 assert(c
<= n_units
);
1375 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1377 r
= sd_bus_call_method(
1379 "org.freedesktop.systemd1",
1380 "/org/freedesktop/systemd1",
1381 "org.freedesktop.systemd1.Manager",
1387 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1391 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1393 return bus_log_parse_error(r
);
1395 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1397 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1400 units
[c
] = (struct UnitFileList
) {
1402 unit_file_state_from_string(state
)
1405 if (output_show_unit_file(&units
[c
], strv_skip_first(args
)))
1410 return bus_log_parse_error(r
);
1412 r
= sd_bus_message_exit_container(reply
);
1414 return bus_log_parse_error(r
);
1417 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1418 output_unit_file_list(units
, c
);
1421 for (unit
= units
; unit
< units
+ c
; unit
++)
1428 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1429 _cleanup_free_
char *n
= NULL
;
1430 size_t max_len
= MAX(columns(),20u);
1436 for (i
= level
- 1; i
>= 0; i
--) {
1438 if (len
> max_len
- 3 && !arg_full
) {
1439 printf("%s...\n",max_len
% 2 ? "" : " ");
1442 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1446 if (len
> max_len
- 3 && !arg_full
) {
1447 printf("%s...\n",max_len
% 2 ? "" : " ");
1451 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1455 printf("%s\n", name
);
1459 n
= ellipsize(name
, max_len
-len
, 100);
1467 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1469 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1470 [DEPENDENCY_FORWARD
] = "Requires\0"
1471 "RequiresOverridable\0"
1473 "RequisiteOverridable\0"
1477 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1478 "RequiredByOverridable\0"
1482 [DEPENDENCY_AFTER
] = "After\0",
1483 [DEPENDENCY_BEFORE
] = "Before\0",
1486 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1487 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1488 _cleanup_strv_free_
char **ret
= NULL
;
1489 _cleanup_free_
char *path
= NULL
;
1495 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1497 path
= unit_dbus_path_from_name(name
);
1501 r
= sd_bus_call_method(
1503 "org.freedesktop.systemd1",
1505 "org.freedesktop.DBus.Properties",
1509 "s", "org.freedesktop.systemd1.Unit");
1511 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1515 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1517 return bus_log_parse_error(r
);
1519 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1522 r
= sd_bus_message_read(reply
, "s", &prop
);
1524 return bus_log_parse_error(r
);
1526 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1527 r
= sd_bus_message_skip(reply
, "v");
1529 return bus_log_parse_error(r
);
1532 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1534 return bus_log_parse_error(r
);
1536 r
= bus_message_read_strv_extend(reply
, &ret
);
1538 return bus_log_parse_error(r
);
1540 r
= sd_bus_message_exit_container(reply
);
1542 return bus_log_parse_error(r
);
1545 r
= sd_bus_message_exit_container(reply
);
1547 return bus_log_parse_error(r
);
1551 return bus_log_parse_error(r
);
1553 r
= sd_bus_message_exit_container(reply
);
1555 return bus_log_parse_error(r
);
1563 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1564 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1566 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1568 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1571 return strcasecmp(*a
, *b
);
1574 static int list_dependencies_one(
1579 unsigned int branches
) {
1581 _cleanup_strv_free_
char **deps
= NULL
;
1589 r
= strv_extend(units
, name
);
1593 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1597 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1599 STRV_FOREACH(c
, deps
) {
1600 if (strv_contains(*units
, *c
)) {
1602 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1615 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1616 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1617 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_highlight_off());
1620 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1624 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1625 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1632 strv_remove(*units
, name
);
1637 static int list_dependencies(sd_bus
*bus
, char **args
) {
1638 _cleanup_strv_free_
char **units
= NULL
;
1639 _cleanup_free_
char *unit
= NULL
;
1646 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &unit
);
1648 return log_error_errno(r
, "Failed to mangle unit name: %m");
1652 u
= SPECIAL_DEFAULT_TARGET
;
1654 pager_open_if_enabled();
1658 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1661 struct machine_info
{
1665 char *control_group
;
1666 uint32_t n_failed_units
;
1671 static const struct bus_properties_map machine_info_property_map
[] = {
1672 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1673 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1674 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1675 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1676 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1680 static void machine_info_clear(struct machine_info
*info
) {
1684 free(info
->control_group
);
1689 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1695 for (i
= 0; i
< n
; i
++)
1696 machine_info_clear(&machine_infos
[i
]);
1698 free(machine_infos
);
1701 static int compare_machine_info(const void *a
, const void *b
) {
1702 const struct machine_info
*u
= a
, *v
= b
;
1704 if (u
->is_host
!= v
->is_host
)
1705 return u
->is_host
> v
->is_host
? -1 : 1;
1707 return strcasecmp(u
->name
, v
->name
);
1710 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1711 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1717 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1724 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1731 static bool output_show_machine(const char *name
, char **patterns
) {
1732 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1735 static int get_machine_list(
1737 struct machine_info
**_machine_infos
,
1740 struct machine_info
*machine_infos
= NULL
;
1741 _cleanup_strv_free_
char **m
= NULL
;
1742 _cleanup_free_
char *hn
= NULL
;
1747 hn
= gethostname_malloc();
1751 if (output_show_machine(hn
, patterns
)) {
1752 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1755 machine_infos
[c
].is_host
= true;
1756 machine_infos
[c
].name
= hn
;
1759 get_machine_properties(bus
, &machine_infos
[c
]);
1763 r
= sd_get_machine_names(&m
);
1765 return log_error_errno(r
, "Failed to get machine list: %m");
1767 STRV_FOREACH(i
, m
) {
1768 _cleanup_free_
char *class = NULL
;
1770 if (!output_show_machine(*i
, patterns
))
1773 sd_machine_get_class(*i
, &class);
1774 if (!streq_ptr(class, "container"))
1777 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1778 free_machines_list(machine_infos
, c
);
1782 machine_infos
[c
].is_host
= false;
1783 machine_infos
[c
].name
= strdup(*i
);
1784 if (!machine_infos
[c
].name
) {
1785 free_machines_list(machine_infos
, c
);
1789 get_machine_properties(NULL
, &machine_infos
[c
]);
1793 *_machine_infos
= machine_infos
;
1797 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1798 struct machine_info
*m
;
1801 namelen
= sizeof("NAME") - 1,
1802 statelen
= sizeof("STATE") - 1,
1803 failedlen
= sizeof("FAILED") - 1,
1804 jobslen
= sizeof("JOBS") - 1;
1806 assert(machine_infos
|| n
== 0);
1808 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1809 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1810 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1811 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1812 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1814 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1818 if (!arg_no_legend
) {
1822 printf("%-*s %-*s %-*s %-*s\n",
1825 failedlen
, "FAILED",
1829 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1830 const char *on_state
= "", *off_state
= "";
1831 const char *on_failed
= "", *off_failed
= "";
1832 bool circle
= false;
1834 if (streq_ptr(m
->state
, "degraded")) {
1835 on_state
= ansi_highlight_red();
1836 off_state
= ansi_highlight_off();
1838 } else if (!streq_ptr(m
->state
, "running")) {
1839 on_state
= ansi_highlight_yellow();
1840 off_state
= ansi_highlight_off();
1844 if (m
->n_failed_units
> 0) {
1845 on_failed
= ansi_highlight_red();
1846 off_failed
= ansi_highlight_off();
1848 on_failed
= off_failed
= "";
1851 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1854 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1855 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1856 on_state
, statelen
, strna(m
->state
), off_state
,
1857 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1858 jobslen
, m
->n_jobs
);
1860 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1861 namelen
, strna(m
->name
),
1862 on_state
, statelen
, strna(m
->state
), off_state
,
1863 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1864 jobslen
, m
->n_jobs
);
1868 printf("\n%u machines listed.\n", n
);
1871 static int list_machines(sd_bus
*bus
, char **args
) {
1872 struct machine_info
*machine_infos
= NULL
;
1877 if (geteuid() != 0) {
1878 log_error("Must be root.");
1882 pager_open_if_enabled();
1884 r
= get_machine_list(bus
, &machine_infos
, strv_skip_first(args
));
1888 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1889 output_machines_list(machine_infos
, r
);
1890 free_machines_list(machine_infos
, r
);
1895 static int get_default(sd_bus
*bus
, char **args
) {
1896 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1897 _cleanup_free_
char *_path
= NULL
;
1901 if (!bus
|| avoid_bus()) {
1902 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1904 return log_error_errno(r
, "Failed to get default target: %m");
1908 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1910 r
= sd_bus_call_method(
1912 "org.freedesktop.systemd1",
1913 "/org/freedesktop/systemd1",
1914 "org.freedesktop.systemd1.Manager",
1920 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1924 r
= sd_bus_message_read(reply
, "s", &path
);
1926 return bus_log_parse_error(r
);
1930 printf("%s\n", path
);
1935 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1938 assert(changes
|| n_changes
== 0);
1940 for (i
= 0; i
< n_changes
; i
++) {
1941 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1942 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1944 log_info("Removed symlink %s.", changes
[i
].path
);
1948 static int set_default(sd_bus
*bus
, char **args
) {
1949 _cleanup_free_
char *unit
= NULL
;
1950 UnitFileChange
*changes
= NULL
;
1951 unsigned n_changes
= 0;
1954 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1956 return log_error_errno(r
, "Failed to mangle unit name: %m");
1958 if (!bus
|| avoid_bus()) {
1959 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1961 return log_error_errno(r
, "Failed to set default target: %m");
1964 dump_unit_file_changes(changes
, n_changes
);
1968 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1969 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1971 polkit_agent_open_if_enabled();
1973 r
= sd_bus_call_method(
1975 "org.freedesktop.systemd1",
1976 "/org/freedesktop/systemd1",
1977 "org.freedesktop.systemd1.Manager",
1983 log_error("Failed to set default target: %s", bus_error_message(&error
, -r
));
1987 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
1991 /* Try to reload if enabled */
1993 r
= daemon_reload(bus
, args
);
1998 unit_file_changes_free(changes
, n_changes
);
2005 const char *name
, *type
, *state
;
2008 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2009 unsigned id_len
, unit_len
, type_len
, state_len
;
2010 const struct job_info
*j
;
2011 const char *on
, *off
;
2012 bool shorten
= false;
2014 assert(n
== 0 || jobs
);
2017 if (!arg_no_legend
) {
2018 on
= ansi_highlight_green();
2019 off
= ansi_highlight_off();
2021 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2026 pager_open_if_enabled();
2028 id_len
= strlen("JOB");
2029 unit_len
= strlen("UNIT");
2030 type_len
= strlen("TYPE");
2031 state_len
= strlen("STATE");
2033 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2034 uint32_t id
= j
->id
;
2035 assert(j
->name
&& j
->type
&& j
->state
);
2037 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2038 unit_len
= MAX(unit_len
, strlen(j
->name
));
2039 type_len
= MAX(type_len
, strlen(j
->type
));
2040 state_len
= MAX(state_len
, strlen(j
->state
));
2043 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2044 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2049 printf("%*s %-*s %-*s %-*s\n",
2053 state_len
, "STATE");
2055 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2056 _cleanup_free_
char *e
= NULL
;
2058 if (streq(j
->state
, "running")) {
2059 on
= ansi_highlight();
2060 off
= ansi_highlight_off();
2064 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2065 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2067 on
, unit_len
, e
? e
: j
->name
, off
,
2069 on
, state_len
, j
->state
, off
);
2072 if (!arg_no_legend
) {
2073 on
= ansi_highlight();
2074 off
= ansi_highlight_off();
2076 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2080 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2081 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2084 static int list_jobs(sd_bus
*bus
, char **args
) {
2085 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2086 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2087 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2088 _cleanup_free_
struct job_info
*jobs
= NULL
;
2093 bool skipped
= false;
2095 r
= sd_bus_call_method(
2097 "org.freedesktop.systemd1",
2098 "/org/freedesktop/systemd1",
2099 "org.freedesktop.systemd1.Manager",
2105 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
2109 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2111 return bus_log_parse_error(r
);
2113 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2114 struct job_info job
= { id
, name
, type
, state
};
2116 if (!output_show_job(&job
, strv_skip_first(args
))) {
2121 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2127 return bus_log_parse_error(r
);
2129 r
= sd_bus_message_exit_container(reply
);
2131 return bus_log_parse_error(r
);
2133 output_jobs_list(jobs
, c
, skipped
);
2137 static int cancel_job(sd_bus
*bus
, char **args
) {
2143 if (strv_length(args
) <= 1)
2144 return daemon_reload(bus
, args
);
2146 polkit_agent_open_if_enabled();
2148 STRV_FOREACH(name
, args
+1) {
2149 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2153 q
= safe_atou32(*name
, &id
);
2155 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2157 q
= sd_bus_call_method(
2159 "org.freedesktop.systemd1",
2160 "/org/freedesktop/systemd1",
2161 "org.freedesktop.systemd1.Manager",
2167 log_error("Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2176 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2177 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2181 /* We ignore all errors here, since this is used to show a
2184 /* We don't use unit_dbus_path_from_name() directly since we
2185 * don't want to load the unit if it isn't loaded. */
2187 r
= sd_bus_call_method(
2189 "org.freedesktop.systemd1",
2190 "/org/freedesktop/systemd1",
2191 "org.freedesktop.systemd1.Manager",
2199 r
= sd_bus_message_read(reply
, "o", &path
);
2203 r
= sd_bus_get_property_trivial(
2205 "org.freedesktop.systemd1",
2207 "org.freedesktop.systemd1.Unit",
2217 static void warn_unit_file_changed(const char *name
) {
2218 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2219 ansi_highlight_red(),
2220 ansi_highlight_off(),
2222 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2225 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2232 STRV_FOREACH(p
, lp
->unit_path
) {
2233 _cleanup_free_
char *path
;
2235 path
= path_join(arg_root
, *p
, unit_name
);
2239 if (access(path
, F_OK
) == 0) {
2249 static int unit_find_paths(
2251 const char *unit_name
,
2252 bool avoid_bus_cache
,
2254 char **fragment_path
,
2255 char ***dropin_paths
) {
2257 _cleanup_free_
char *path
= NULL
;
2258 _cleanup_strv_free_
char **dropins
= NULL
;
2262 * Finds where the unit is defined on disk. Returns 0 if the unit
2263 * is not found. Returns 1 if it is found, and sets
2264 * - the path to the unit in *path, if it exists on disk,
2265 * - and a strv of existing drop-ins in *dropins,
2266 * if the arg is not NULL and any dropins were found.
2270 assert(fragment_path
);
2273 if (!avoid_bus_cache
&& !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2274 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2275 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2276 _cleanup_free_
char *unit
= NULL
;
2277 char *unit_load_error_name
, *unit_load_error_message
;
2279 unit
= unit_dbus_path_from_name(unit_name
);
2283 if (need_daemon_reload(bus
, unit_name
) > 0)
2284 warn_unit_file_changed(unit_name
);
2286 r
= sd_bus_get_property(
2288 "org.freedesktop.systemd1",
2290 "org.freedesktop.systemd1.Unit",
2296 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2298 r
= sd_bus_message_read(
2301 &unit_load_error_name
,
2302 &unit_load_error_message
);
2304 return bus_log_parse_error(r
);
2306 if (!isempty(unit_load_error_name
)) {
2307 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2311 r
= sd_bus_get_property_string(
2313 "org.freedesktop.systemd1",
2315 "org.freedesktop.systemd1.Unit",
2320 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2323 r
= sd_bus_get_property_strv(
2325 "org.freedesktop.systemd1",
2327 "org.freedesktop.systemd1.Unit",
2332 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2335 _cleanup_set_free_ Set
*names
;
2337 names
= set_new(NULL
);
2341 r
= set_put(names
, unit_name
);
2343 return log_error_errno(r
, "Failed to add unit name: %m");
2345 r
= unit_file_find_path(lp
, unit_name
, &path
);
2350 _cleanup_free_
char *template = NULL
;
2352 r
= unit_name_template(unit_name
, &template);
2353 if (r
< 0 && r
!= -EINVAL
)
2354 return log_error_errno(r
, "Failed to determine template name: %m");
2356 r
= unit_file_find_path(lp
, template, &path
);
2363 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2371 if (!isempty(path
)) {
2372 *fragment_path
= path
;
2377 if (dropin_paths
&& !strv_isempty(dropins
)) {
2378 *dropin_paths
= dropins
;
2384 log_error("No files found for %s.", unit_name
);
2389 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2390 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2391 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2397 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2399 return log_error_errno(r
, "Failed to mangle unit name: %m");
2401 /* We don't use unit_dbus_path_from_name() directly since we
2402 * don't want to load the unit if it isn't loaded. */
2404 r
= sd_bus_call_method(
2406 "org.freedesktop.systemd1",
2407 "/org/freedesktop/systemd1",
2408 "org.freedesktop.systemd1.Manager",
2419 r
= sd_bus_message_read(reply
, "o", &path
);
2421 return bus_log_parse_error(r
);
2423 r
= sd_bus_get_property_string(
2425 "org.freedesktop.systemd1",
2427 "org.freedesktop.systemd1.Unit",
2440 return nulstr_contains(good_states
, state
);
2443 static int check_triggering_units(
2447 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2448 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2449 _cleanup_strv_free_
char **triggered_by
= NULL
;
2450 bool print_warning_label
= true;
2454 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2456 return log_error_errno(r
, "Failed to mangle unit name: %m");
2458 path
= unit_dbus_path_from_name(n
);
2462 r
= sd_bus_get_property_string(
2464 "org.freedesktop.systemd1",
2466 "org.freedesktop.systemd1.Unit",
2471 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2475 if (streq(state
, "masked"))
2478 r
= sd_bus_get_property_strv(
2480 "org.freedesktop.systemd1",
2482 "org.freedesktop.systemd1.Unit",
2487 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2491 STRV_FOREACH(i
, triggered_by
) {
2492 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2494 return log_error_errno(r
, "Failed to check unit: %m");
2499 if (print_warning_label
) {
2500 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2501 print_warning_label
= false;
2504 log_warning(" %s", *i
);
2510 static const struct {
2513 } unit_actions
[] = {
2514 { "start", "StartUnit" },
2515 { "stop", "StopUnit" },
2516 { "condstop", "StopUnit" },
2517 { "reload", "ReloadUnit" },
2518 { "restart", "RestartUnit" },
2519 { "try-restart", "TryRestartUnit" },
2520 { "condrestart", "TryRestartUnit" },
2521 { "reload-or-restart", "ReloadOrRestartUnit" },
2522 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2523 { "condreload", "ReloadOrTryRestartUnit" },
2524 { "force-reload", "ReloadOrTryRestartUnit" }
2527 static const char *verb_to_method(const char *verb
) {
2530 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2531 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2532 return unit_actions
[i
].method
;
2537 static const char *method_to_verb(const char *method
) {
2540 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2541 if (streq_ptr(unit_actions
[i
].method
, method
))
2542 return unit_actions
[i
].verb
;
2547 static int start_unit_one(
2552 sd_bus_error
*error
,
2553 BusWaitForJobs
*w
) {
2555 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2564 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2566 r
= sd_bus_call_method(
2568 "org.freedesktop.systemd1",
2569 "/org/freedesktop/systemd1",
2570 "org.freedesktop.systemd1.Manager",
2578 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2579 /* There's always a fallback possible for
2580 * legacy actions. */
2581 return -EADDRNOTAVAIL
;
2583 verb
= method_to_verb(method
);
2585 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2589 r
= sd_bus_message_read(reply
, "o", &path
);
2591 return bus_log_parse_error(r
);
2593 if (need_daemon_reload(bus
, name
) > 0)
2594 warn_unit_file_changed(name
);
2597 log_debug("Adding %s to the set", path
);
2598 r
= bus_wait_for_jobs_add(w
, path
);
2606 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2608 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2612 STRV_FOREACH(name
, names
) {
2616 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2618 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2620 return log_error_errno(r
, "Failed to mangle name: %m");
2622 if (string_is_glob(t
))
2623 r
= strv_consume(&globs
, t
);
2625 r
= strv_consume(&mangled
, t
);
2630 /* Query the manager only if any of the names are a glob, since
2631 * this is fairly expensive */
2632 if (!strv_isempty(globs
)) {
2633 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2634 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2637 return log_error_errno(EOPNOTSUPP
, "Unit name globbing without bus is not implemented.");
2639 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2643 for (i
= 0; i
< r
; i
++)
2644 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2649 mangled
= NULL
; /* do not free */
2654 static const struct {
2658 } action_table
[_ACTION_MAX
] = {
2659 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2660 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2661 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2662 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2663 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2664 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2665 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2666 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2667 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2668 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2669 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2670 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2671 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2672 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2673 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2676 static enum action
verb_to_action(const char *verb
) {
2679 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2680 if (streq_ptr(action_table
[i
].verb
, verb
))
2683 return _ACTION_INVALID
;
2686 static int start_unit(sd_bus
*bus
, char **args
) {
2687 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2688 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2689 _cleanup_strv_free_
char **names
= NULL
;
2695 ask_password_agent_open_if_enabled();
2696 polkit_agent_open_if_enabled();
2698 if (arg_action
== ACTION_SYSTEMCTL
) {
2700 method
= verb_to_method(args
[0]);
2701 action
= verb_to_action(args
[0]);
2703 if (streq(args
[0], "isolate")) {
2707 mode
= action_table
[action
].mode
?: arg_job_mode
;
2709 one_name
= action_table
[action
].target
;
2711 assert(arg_action
< ELEMENTSOF(action_table
));
2712 assert(action_table
[arg_action
].target
);
2714 method
= "StartUnit";
2716 mode
= action_table
[arg_action
].mode
;
2717 one_name
= action_table
[arg_action
].target
;
2721 names
= strv_new(one_name
, NULL
);
2723 r
= expand_names(bus
, args
+ 1, suffix
, &names
);
2725 log_error_errno(r
, "Failed to expand names: %m");
2728 if (!arg_no_block
) {
2729 r
= bus_wait_for_jobs_new(bus
, &w
);
2731 return log_error_errno(r
, "Could not watch jobs: %m");
2734 STRV_FOREACH(name
, names
) {
2735 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2738 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2739 if (r
>= 0 && q
< 0)
2740 r
= translate_bus_error_to_exit_status(q
, &error
);
2743 if (!arg_no_block
) {
2746 q
= bus_wait_for_jobs(w
, arg_quiet
);
2750 /* When stopping units, warn if they can still be triggered by
2751 * another active unit (socket, path, timer) */
2752 if (!arg_quiet
&& streq(method
, "StopUnit"))
2753 STRV_FOREACH(name
, names
)
2754 check_triggering_units(bus
, *name
);
2760 /* Ask systemd-logind, which might grant access to unprivileged users
2761 * through PolicyKit */
2762 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
2764 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2771 polkit_agent_open_if_enabled();
2779 case ACTION_POWEROFF
:
2780 method
= "PowerOff";
2783 case ACTION_SUSPEND
:
2787 case ACTION_HIBERNATE
:
2788 method
= "Hibernate";
2791 case ACTION_HYBRID_SLEEP
:
2792 method
= "HybridSleep";
2799 if (!strv_isempty(arg_wall
)) {
2800 _cleanup_free_
char *m
;
2802 m
= strv_join(arg_wall
, " ");
2806 r
= sd_bus_call_method(
2808 "org.freedesktop.login1",
2809 "/org/freedesktop/login1",
2810 "org.freedesktop.login1.Manager",
2819 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
2820 bus_error_message(&error
, r
));
2821 sd_bus_error_free(&error
);
2826 r
= sd_bus_call_method(
2828 "org.freedesktop.login1",
2829 "/org/freedesktop/login1",
2830 "org.freedesktop.login1.Manager",
2834 "b", arg_ask_password
);
2836 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
2844 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
2846 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2847 _cleanup_strv_free_
char **sessions
= NULL
;
2848 const char *what
, *who
, *why
, *mode
;
2857 if (arg_ignore_inhibitors
|| arg_force
> 0)
2869 r
= sd_bus_call_method(
2871 "org.freedesktop.login1",
2872 "/org/freedesktop/login1",
2873 "org.freedesktop.login1.Manager",
2879 /* If logind is not around, then there are no inhibitors... */
2882 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2884 return bus_log_parse_error(r
);
2886 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2887 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2888 _cleanup_strv_free_
char **sv
= NULL
;
2890 if (!streq(mode
, "block"))
2893 sv
= strv_split(what
, ":");
2897 if ((pid_t
) pid
< 0)
2898 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2900 if (!strv_contains(sv
,
2902 a
== ACTION_POWEROFF
||
2903 a
== ACTION_REBOOT
||
2904 a
== ACTION_KEXEC
? "shutdown" : "sleep"))
2907 get_process_comm(pid
, &comm
);
2908 user
= uid_to_name(uid
);
2910 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2911 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2916 return bus_log_parse_error(r
);
2918 r
= sd_bus_message_exit_container(reply
);
2920 return bus_log_parse_error(r
);
2922 /* Check for current sessions */
2923 sd_get_sessions(&sessions
);
2924 STRV_FOREACH(s
, sessions
) {
2925 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2927 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2930 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2933 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2936 sd_session_get_tty(*s
, &tty
);
2937 sd_session_get_seat(*s
, &seat
);
2938 sd_session_get_service(*s
, &service
);
2939 user
= uid_to_name(uid
);
2941 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2948 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2949 action_table
[a
].verb
);
2957 static int prepare_firmware_setup(sd_bus
*bus
) {
2959 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2963 if (!arg_firmware_setup
)
2966 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
2968 r
= efi_set_reboot_to_firmware(true);
2970 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
2976 r
= sd_bus_call_method(
2978 "org.freedesktop.login1",
2979 "/org/freedesktop/login1",
2980 "org.freedesktop.login1.Manager",
2981 "SetRebootToFirmwareSetup",
2986 log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
2992 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
2997 static int start_special(sd_bus
*bus
, char **args
) {
3003 a
= verb_to_action(args
[0]);
3005 r
= check_inhibitors(bus
, a
);
3009 if (arg_force
>= 2 && geteuid() != 0) {
3010 log_error("Must be root.");
3014 r
= prepare_firmware_setup(bus
);
3018 if (a
== ACTION_REBOOT
&& args
[1]) {
3019 r
= update_reboot_param_file(args
[1]);
3024 if (arg_force
>= 2 &&
3025 (a
== ACTION_HALT
||
3026 a
== ACTION_POWEROFF
||
3027 a
== ACTION_REBOOT
))
3030 if (arg_force
>= 1 &&
3031 (a
== ACTION_HALT
||
3032 a
== ACTION_POWEROFF
||
3033 a
== ACTION_REBOOT
||
3034 a
== ACTION_KEXEC
||
3036 return daemon_reload(bus
, args
);
3038 /* first try logind, to allow authentication with polkit */
3039 if (geteuid() != 0 &&
3040 (a
== ACTION_POWEROFF
||
3041 a
== ACTION_REBOOT
||
3042 a
== ACTION_SUSPEND
||
3043 a
== ACTION_HIBERNATE
||
3044 a
== ACTION_HYBRID_SLEEP
)) {
3045 r
= reboot_with_logind(bus
, a
);
3046 if (r
>= 0 || IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3050 r
= start_unit(bus
, args
);
3051 if (r
== EXIT_SUCCESS
)
3057 static int check_unit_generic(sd_bus
*bus
, int code
, const char *good_states
, char **args
) {
3058 _cleanup_strv_free_
char **names
= NULL
;
3065 r
= expand_names(bus
, args
, NULL
, &names
);
3067 return log_error_errno(r
, "Failed to expand names: %m");
3069 STRV_FOREACH(name
, names
) {
3072 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3082 static int check_unit_active(sd_bus
*bus
, char **args
) {
3083 /* According to LSB: 3, "program is not running" */
3084 return check_unit_generic(bus
, 3, "active\0reloading\0", args
+ 1);
3087 static int check_unit_failed(sd_bus
*bus
, char **args
) {
3088 return check_unit_generic(bus
, 1, "failed\0", args
+ 1);
3091 static int kill_unit(sd_bus
*bus
, char **args
) {
3092 _cleanup_strv_free_
char **names
= NULL
;
3099 polkit_agent_open_if_enabled();
3102 arg_kill_who
= "all";
3104 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
3106 log_error_errno(r
, "Failed to expand names: %m");
3108 STRV_FOREACH(name
, names
) {
3109 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3111 q
= sd_bus_call_method(
3113 "org.freedesktop.systemd1",
3114 "/org/freedesktop/systemd1",
3115 "org.freedesktop.systemd1.Manager",
3119 "ssi", *names
, arg_kill_who
, arg_signal
);
3121 log_error("Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3130 typedef struct ExecStatusInfo
{
3138 usec_t start_timestamp
;
3139 usec_t exit_timestamp
;
3144 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3147 static void exec_status_info_free(ExecStatusInfo
*i
) {
3156 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3157 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3160 int32_t code
, status
;
3166 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3168 return bus_log_parse_error(r
);
3172 r
= sd_bus_message_read(m
, "s", &path
);
3174 return bus_log_parse_error(r
);
3176 i
->path
= strdup(path
);
3180 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3182 return bus_log_parse_error(r
);
3184 r
= sd_bus_message_read(m
,
3187 &start_timestamp
, &start_timestamp_monotonic
,
3188 &exit_timestamp
, &exit_timestamp_monotonic
,
3192 return bus_log_parse_error(r
);
3195 i
->start_timestamp
= (usec_t
) start_timestamp
;
3196 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3197 i
->pid
= (pid_t
) pid
;
3201 r
= sd_bus_message_exit_container(m
);
3203 return bus_log_parse_error(r
);
3208 typedef struct UnitStatusInfo
{
3210 const char *load_state
;
3211 const char *active_state
;
3212 const char *sub_state
;
3213 const char *unit_file_state
;
3214 const char *unit_file_preset
;
3216 const char *description
;
3217 const char *following
;
3219 char **documentation
;
3221 const char *fragment_path
;
3222 const char *source_path
;
3223 const char *control_group
;
3225 char **dropin_paths
;
3227 const char *load_error
;
3230 usec_t inactive_exit_timestamp
;
3231 usec_t inactive_exit_timestamp_monotonic
;
3232 usec_t active_enter_timestamp
;
3233 usec_t active_exit_timestamp
;
3234 usec_t inactive_enter_timestamp
;
3236 bool need_daemon_reload
;
3241 const char *status_text
;
3242 const char *pid_file
;
3246 usec_t start_timestamp
;
3247 usec_t exit_timestamp
;
3249 int exit_code
, exit_status
;
3251 usec_t condition_timestamp
;
3252 bool condition_result
;
3253 bool failed_condition_trigger
;
3254 bool failed_condition_negate
;
3255 const char *failed_condition
;
3256 const char *failed_condition_parameter
;
3258 usec_t assert_timestamp
;
3260 bool failed_assert_trigger
;
3261 bool failed_assert_negate
;
3262 const char *failed_assert
;
3263 const char *failed_assert_parameter
;
3266 unsigned n_accepted
;
3267 unsigned n_connections
;
3270 /* Pairs of type, path */
3274 const char *sysfs_path
;
3276 /* Mount, Automount */
3283 uint64_t memory_current
;
3284 uint64_t memory_limit
;
3285 uint64_t cpu_usage_nsec
;
3287 LIST_HEAD(ExecStatusInfo
, exec
);
3290 static void print_status_info(
3295 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3297 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3298 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3304 /* This shows pretty information about a unit. See
3305 * print_property() for a low-level property printer */
3307 if (streq_ptr(i
->active_state
, "failed")) {
3308 active_on
= ansi_highlight_red();
3309 active_off
= ansi_highlight_off();
3310 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3311 active_on
= ansi_highlight_green();
3312 active_off
= ansi_highlight_off();
3314 active_on
= active_off
= "";
3316 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3318 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3319 printf(" - %s", i
->description
);
3324 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3326 if (streq_ptr(i
->load_state
, "error")) {
3327 on
= ansi_highlight_red();
3328 off
= ansi_highlight_off();
3332 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3335 printf(" Loaded: %s%s%s (Reason: %s)\n",
3336 on
, strna(i
->load_state
), off
, i
->load_error
);
3337 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3338 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3339 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3340 else if (path
&& !isempty(i
->unit_file_state
))
3341 printf(" Loaded: %s%s%s (%s; %s)\n",
3342 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3344 printf(" Loaded: %s%s%s (%s)\n",
3345 on
, strna(i
->load_state
), off
, path
);
3347 printf(" Loaded: %s%s%s\n",
3348 on
, strna(i
->load_state
), off
);
3350 if (!strv_isempty(i
->dropin_paths
)) {
3351 _cleanup_free_
char *dir
= NULL
;
3355 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3356 if (! dir
|| last
) {
3357 printf(dir
? " " : " Drop-In: ");
3361 if (path_get_parent(*dropin
, &dir
) < 0) {
3366 printf("%s\n %s", dir
,
3367 draw_special_char(DRAW_TREE_RIGHT
));
3370 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3372 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3376 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3378 printf(" Active: %s%s (%s)%s",
3379 active_on
, strna(i
->active_state
), ss
, active_off
);
3381 printf(" Active: %s%s%s",
3382 active_on
, strna(i
->active_state
), active_off
);
3384 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3385 printf(" (Result: %s)", i
->result
);
3387 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3388 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3389 (streq_ptr(i
->active_state
, "inactive") ||
3390 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3391 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3392 i
->active_exit_timestamp
;
3394 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3395 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3398 printf(" since %s; %s\n", s2
, s1
);
3400 printf(" since %s\n", s2
);
3404 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3405 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3406 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3408 printf("Condition: start %scondition failed%s at %s%s%s\n",
3409 ansi_highlight_yellow(), ansi_highlight_off(),
3410 s2
, s1
? "; " : "", s1
? s1
: "");
3411 if (i
->failed_condition_trigger
)
3412 printf(" none of the trigger conditions were met\n");
3413 else if (i
->failed_condition
)
3414 printf(" %s=%s%s was not met\n",
3415 i
->failed_condition
,
3416 i
->failed_condition_negate
? "!" : "",
3417 i
->failed_condition_parameter
);
3420 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3421 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3422 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3424 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3425 ansi_highlight_red(), ansi_highlight_off(),
3426 s2
, s1
? "; " : "", s1
? s1
: "");
3427 if (i
->failed_assert_trigger
)
3428 printf(" none of the trigger assertions were met\n");
3429 else if (i
->failed_assert
)
3430 printf(" %s=%s%s was not met\n",
3432 i
->failed_assert_negate
? "!" : "",
3433 i
->failed_assert_parameter
);
3437 printf(" Device: %s\n", i
->sysfs_path
);
3439 printf(" Where: %s\n", i
->where
);
3441 printf(" What: %s\n", i
->what
);
3443 STRV_FOREACH(t
, i
->documentation
)
3444 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3446 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3447 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3450 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3452 LIST_FOREACH(exec
, p
, i
->exec
) {
3453 _cleanup_free_
char *argv
= NULL
;
3456 /* Only show exited processes here */
3460 argv
= strv_join(p
->argv
, " ");
3461 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3463 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3465 on
= ansi_highlight_red();
3466 off
= ansi_highlight_off();
3470 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3472 if (p
->code
== CLD_EXITED
) {
3475 printf("status=%i", p
->status
);
3477 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3482 printf("signal=%s", signal_to_string(p
->status
));
3484 printf(")%s\n", off
);
3486 if (i
->main_pid
== p
->pid
&&
3487 i
->start_timestamp
== p
->start_timestamp
&&
3488 i
->exit_timestamp
== p
->start_timestamp
)
3489 /* Let's not show this twice */
3492 if (p
->pid
== i
->control_pid
)
3496 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3497 if (i
->main_pid
> 0) {
3498 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3501 _cleanup_free_
char *comm
= NULL
;
3502 get_process_comm(i
->main_pid
, &comm
);
3504 printf(" (%s)", comm
);
3505 } else if (i
->exit_code
> 0) {
3506 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3508 if (i
->exit_code
== CLD_EXITED
) {
3511 printf("status=%i", i
->exit_status
);
3513 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3518 printf("signal=%s", signal_to_string(i
->exit_status
));
3522 if (i
->control_pid
> 0)
3526 if (i
->control_pid
> 0) {
3527 _cleanup_free_
char *c
= NULL
;
3529 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3531 get_process_comm(i
->control_pid
, &c
);
3540 printf(" Status: \"%s\"\n", i
->status_text
);
3541 if (i
->status_errno
> 0)
3542 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3544 if (i
->memory_current
!= (uint64_t) -1) {
3545 char buf
[FORMAT_BYTES_MAX
];
3547 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3549 if (i
->memory_limit
!= (uint64_t) -1)
3550 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3555 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3556 char buf
[FORMAT_TIMESPAN_MAX
];
3557 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3560 if (i
->control_group
&&
3561 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3562 ((arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_transport
!= BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3565 printf(" CGroup: %s\n", i
->control_group
);
3567 if (arg_transport
== BUS_TRANSPORT_LOCAL
|| arg_transport
== BUS_TRANSPORT_MACHINE
) {
3570 static const char prefix
[] = " ";
3573 if (c
> sizeof(prefix
) - 1)
3574 c
-= sizeof(prefix
) - 1;
3578 if (i
->main_pid
> 0)
3579 extra
[k
++] = i
->main_pid
;
3581 if (i
->control_pid
> 0)
3582 extra
[k
++] = i
->control_pid
;
3584 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3588 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
) {
3589 show_journal_by_unit(
3594 i
->inactive_exit_timestamp_monotonic
,
3597 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3598 SD_JOURNAL_LOCAL_ONLY
,
3599 arg_scope
== UNIT_FILE_SYSTEM
,
3603 if (i
->need_daemon_reload
)
3604 warn_unit_file_changed(i
->id
);
3607 static void show_unit_help(UnitStatusInfo
*i
) {
3612 if (!i
->documentation
) {
3613 log_info("Documentation for %s not known.", i
->id
);
3617 STRV_FOREACH(p
, i
->documentation
)
3618 if (startswith(*p
, "man:"))
3619 show_man_page(*p
+ 4, false);
3621 log_info("Can't show: %s", *p
);
3624 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3631 switch (contents
[0]) {
3633 case SD_BUS_TYPE_STRING
: {
3636 r
= sd_bus_message_read(m
, "s", &s
);
3638 return bus_log_parse_error(r
);
3641 if (streq(name
, "Id"))
3643 else if (streq(name
, "LoadState"))
3645 else if (streq(name
, "ActiveState"))
3646 i
->active_state
= s
;
3647 else if (streq(name
, "SubState"))
3649 else if (streq(name
, "Description"))
3651 else if (streq(name
, "FragmentPath"))
3652 i
->fragment_path
= s
;
3653 else if (streq(name
, "SourcePath"))
3656 else if (streq(name
, "DefaultControlGroup")) {
3658 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3660 i
->control_group
= e
;
3663 else if (streq(name
, "ControlGroup"))
3664 i
->control_group
= s
;
3665 else if (streq(name
, "StatusText"))
3667 else if (streq(name
, "PIDFile"))
3669 else if (streq(name
, "SysFSPath"))
3671 else if (streq(name
, "Where"))
3673 else if (streq(name
, "What"))
3675 else if (streq(name
, "Following"))
3677 else if (streq(name
, "UnitFileState"))
3678 i
->unit_file_state
= s
;
3679 else if (streq(name
, "UnitFilePreset"))
3680 i
->unit_file_preset
= s
;
3681 else if (streq(name
, "Result"))
3688 case SD_BUS_TYPE_BOOLEAN
: {
3691 r
= sd_bus_message_read(m
, "b", &b
);
3693 return bus_log_parse_error(r
);
3695 if (streq(name
, "Accept"))
3697 else if (streq(name
, "NeedDaemonReload"))
3698 i
->need_daemon_reload
= b
;
3699 else if (streq(name
, "ConditionResult"))
3700 i
->condition_result
= b
;
3701 else if (streq(name
, "AssertResult"))
3702 i
->assert_result
= b
;
3707 case SD_BUS_TYPE_UINT32
: {
3710 r
= sd_bus_message_read(m
, "u", &u
);
3712 return bus_log_parse_error(r
);
3714 if (streq(name
, "MainPID")) {
3716 i
->main_pid
= (pid_t
) u
;
3719 } else if (streq(name
, "ControlPID"))
3720 i
->control_pid
= (pid_t
) u
;
3721 else if (streq(name
, "ExecMainPID")) {
3723 i
->main_pid
= (pid_t
) u
;
3724 } else if (streq(name
, "NAccepted"))
3726 else if (streq(name
, "NConnections"))
3727 i
->n_connections
= u
;
3732 case SD_BUS_TYPE_INT32
: {
3735 r
= sd_bus_message_read(m
, "i", &j
);
3737 return bus_log_parse_error(r
);
3739 if (streq(name
, "ExecMainCode"))
3740 i
->exit_code
= (int) j
;
3741 else if (streq(name
, "ExecMainStatus"))
3742 i
->exit_status
= (int) j
;
3743 else if (streq(name
, "StatusErrno"))
3744 i
->status_errno
= (int) j
;
3749 case SD_BUS_TYPE_UINT64
: {
3752 r
= sd_bus_message_read(m
, "t", &u
);
3754 return bus_log_parse_error(r
);
3756 if (streq(name
, "ExecMainStartTimestamp"))
3757 i
->start_timestamp
= (usec_t
) u
;
3758 else if (streq(name
, "ExecMainExitTimestamp"))
3759 i
->exit_timestamp
= (usec_t
) u
;
3760 else if (streq(name
, "ActiveEnterTimestamp"))
3761 i
->active_enter_timestamp
= (usec_t
) u
;
3762 else if (streq(name
, "InactiveEnterTimestamp"))
3763 i
->inactive_enter_timestamp
= (usec_t
) u
;
3764 else if (streq(name
, "InactiveExitTimestamp"))
3765 i
->inactive_exit_timestamp
= (usec_t
) u
;
3766 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3767 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3768 else if (streq(name
, "ActiveExitTimestamp"))
3769 i
->active_exit_timestamp
= (usec_t
) u
;
3770 else if (streq(name
, "ConditionTimestamp"))
3771 i
->condition_timestamp
= (usec_t
) u
;
3772 else if (streq(name
, "AssertTimestamp"))
3773 i
->assert_timestamp
= (usec_t
) u
;
3774 else if (streq(name
, "MemoryCurrent"))
3775 i
->memory_current
= u
;
3776 else if (streq(name
, "MemoryLimit"))
3777 i
->memory_limit
= u
;
3778 else if (streq(name
, "CPUUsageNSec"))
3779 i
->cpu_usage_nsec
= u
;
3784 case SD_BUS_TYPE_ARRAY
:
3786 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3787 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3789 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3791 return bus_log_parse_error(r
);
3793 info
= new0(ExecStatusInfo
, 1);
3797 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3799 info
->name
= strdup(name
);
3803 LIST_PREPEND(exec
, i
->exec
, info
);
3805 info
= new0(ExecStatusInfo
, 1);
3811 return bus_log_parse_error(r
);
3813 r
= sd_bus_message_exit_container(m
);
3815 return bus_log_parse_error(r
);
3819 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3820 const char *type
, *path
;
3822 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3824 return bus_log_parse_error(r
);
3826 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3828 r
= strv_extend(&i
->listen
, type
);
3832 r
= strv_extend(&i
->listen
, path
);
3837 return bus_log_parse_error(r
);
3839 r
= sd_bus_message_exit_container(m
);
3841 return bus_log_parse_error(r
);
3845 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3847 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3849 return bus_log_parse_error(r
);
3851 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3853 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3855 return bus_log_parse_error(r
);
3857 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3858 const char *cond
, *param
;
3859 int trigger
, negate
;
3862 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3864 return bus_log_parse_error(r
);
3866 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3867 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3868 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3869 i
->failed_condition
= cond
;
3870 i
->failed_condition_trigger
= trigger
;
3871 i
->failed_condition_negate
= negate
;
3872 i
->failed_condition_parameter
= param
;
3876 return bus_log_parse_error(r
);
3878 r
= sd_bus_message_exit_container(m
);
3880 return bus_log_parse_error(r
);
3882 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
3883 const char *cond
, *param
;
3884 int trigger
, negate
;
3887 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3889 return bus_log_parse_error(r
);
3891 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3892 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3893 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
3894 i
->failed_assert
= cond
;
3895 i
->failed_assert_trigger
= trigger
;
3896 i
->failed_assert_negate
= negate
;
3897 i
->failed_assert_parameter
= param
;
3901 return bus_log_parse_error(r
);
3903 r
= sd_bus_message_exit_container(m
);
3905 return bus_log_parse_error(r
);
3912 case SD_BUS_TYPE_STRUCT_BEGIN
:
3914 if (streq(name
, "LoadError")) {
3915 const char *n
, *message
;
3917 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3919 return bus_log_parse_error(r
);
3921 if (!isempty(message
))
3922 i
->load_error
= message
;
3935 r
= sd_bus_message_skip(m
, contents
);
3937 return bus_log_parse_error(r
);
3942 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
3948 /* This is a low-level property printer, see
3949 * print_status_info() for the nicer output */
3951 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
3952 /* skip what we didn't read */
3953 r
= sd_bus_message_skip(m
, contents
);
3957 switch (contents
[0]) {
3959 case SD_BUS_TYPE_STRUCT_BEGIN
:
3961 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
3964 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
3966 return bus_log_parse_error(r
);
3969 printf("%s=%"PRIu32
"\n", name
, u
);
3971 printf("%s=\n", name
);
3975 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
3978 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
3980 return bus_log_parse_error(r
);
3982 if (arg_all
|| !isempty(s
))
3983 printf("%s=%s\n", name
, s
);
3987 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
3988 const char *a
= NULL
, *b
= NULL
;
3990 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
3992 return bus_log_parse_error(r
);
3994 if (arg_all
|| !isempty(a
) || !isempty(b
))
3995 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
3998 } else if (streq_ptr(name
, "SystemCallFilter")) {
3999 _cleanup_strv_free_
char **l
= NULL
;
4002 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4004 return bus_log_parse_error(r
);
4006 r
= sd_bus_message_read(m
, "b", &whitelist
);
4008 return bus_log_parse_error(r
);
4010 r
= sd_bus_message_read_strv(m
, &l
);
4012 return bus_log_parse_error(r
);
4014 r
= sd_bus_message_exit_container(m
);
4016 return bus_log_parse_error(r
);
4018 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4022 fputs(name
, stdout
);
4028 STRV_FOREACH(i
, l
) {
4036 fputc('\n', stdout
);
4044 case SD_BUS_TYPE_ARRAY
:
4046 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4050 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4052 return bus_log_parse_error(r
);
4054 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4055 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4058 return bus_log_parse_error(r
);
4060 r
= sd_bus_message_exit_container(m
);
4062 return bus_log_parse_error(r
);
4066 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4067 const char *type
, *path
;
4069 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4071 return bus_log_parse_error(r
);
4073 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4074 printf("%s=%s\n", type
, path
);
4076 return bus_log_parse_error(r
);
4078 r
= sd_bus_message_exit_container(m
);
4080 return bus_log_parse_error(r
);
4084 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4085 const char *type
, *path
;
4087 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4089 return bus_log_parse_error(r
);
4091 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4092 printf("Listen%s=%s\n", type
, path
);
4094 return bus_log_parse_error(r
);
4096 r
= sd_bus_message_exit_container(m
);
4098 return bus_log_parse_error(r
);
4102 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4104 uint64_t value
, next_elapse
;
4106 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4108 return bus_log_parse_error(r
);
4110 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4111 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4113 printf("%s={ value=%s ; next_elapse=%s }\n",
4115 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4116 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4119 return bus_log_parse_error(r
);
4121 r
= sd_bus_message_exit_container(m
);
4123 return bus_log_parse_error(r
);
4127 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4128 ExecStatusInfo info
= {};
4130 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4132 return bus_log_parse_error(r
);
4134 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4135 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4136 _cleanup_free_
char *tt
;
4138 tt
= strv_join(info
.argv
, " ");
4140 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",
4144 yes_no(info
.ignore
),
4145 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4146 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4148 sigchld_code_to_string(info
.code
),
4150 info
.code
== CLD_EXITED
? "" : "/",
4151 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4154 strv_free(info
.argv
);
4158 r
= sd_bus_message_exit_container(m
);
4160 return bus_log_parse_error(r
);
4164 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4165 const char *path
, *rwm
;
4167 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4169 return bus_log_parse_error(r
);
4171 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4172 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4174 return bus_log_parse_error(r
);
4176 r
= sd_bus_message_exit_container(m
);
4178 return bus_log_parse_error(r
);
4182 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4186 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4188 return bus_log_parse_error(r
);
4190 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4191 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4193 return bus_log_parse_error(r
);
4195 r
= sd_bus_message_exit_container(m
);
4197 return bus_log_parse_error(r
);
4201 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4205 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4207 return bus_log_parse_error(r
);
4209 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4210 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4212 return bus_log_parse_error(r
);
4214 r
= sd_bus_message_exit_container(m
);
4216 return bus_log_parse_error(r
);
4224 r
= bus_print_property(name
, m
, arg_all
);
4226 return bus_log_parse_error(r
);
4229 r
= sd_bus_message_skip(m
, contents
);
4231 return bus_log_parse_error(r
);
4234 printf("%s=[unprintable]\n", name
);
4240 static int show_one(
4244 bool show_properties
,
4248 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4249 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4250 UnitStatusInfo info
= {
4251 .memory_current
= (uint64_t) -1,
4252 .memory_limit
= (uint64_t) -1,
4253 .cpu_usage_nsec
= (uint64_t) -1,
4261 log_debug("Showing one %s", path
);
4263 r
= sd_bus_call_method(
4265 "org.freedesktop.systemd1",
4267 "org.freedesktop.DBus.Properties",
4273 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4275 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4277 return bus_log_parse_error(r
);
4284 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4285 const char *name
, *contents
;
4287 r
= sd_bus_message_read(reply
, "s", &name
);
4289 return bus_log_parse_error(r
);
4291 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4293 return bus_log_parse_error(r
);
4295 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4297 return bus_log_parse_error(r
);
4299 if (show_properties
)
4300 r
= print_property(name
, reply
, contents
);
4302 r
= status_property(name
, reply
, &info
, contents
);
4306 r
= sd_bus_message_exit_container(reply
);
4308 return bus_log_parse_error(r
);
4310 r
= sd_bus_message_exit_container(reply
);
4312 return bus_log_parse_error(r
);
4315 return bus_log_parse_error(r
);
4317 r
= sd_bus_message_exit_container(reply
);
4319 return bus_log_parse_error(r
);
4323 if (!show_properties
) {
4324 if (streq(verb
, "help"))
4325 show_unit_help(&info
);
4327 print_status_info(&info
, ellipsized
);
4330 strv_free(info
.documentation
);
4331 strv_free(info
.dropin_paths
);
4332 strv_free(info
.listen
);
4334 if (!streq_ptr(info
.active_state
, "active") &&
4335 !streq_ptr(info
.active_state
, "reloading") &&
4336 streq(verb
, "status")) {
4337 /* According to LSB: "program not running" */
4338 /* 0: program is running or service is OK
4339 * 1: program is dead and /run PID file exists
4340 * 2: program is dead and /run/lock lock file exists
4341 * 3: program is not running
4342 * 4: program or service status is unknown
4344 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4350 while ((p
= info
.exec
)) {
4351 LIST_REMOVE(exec
, info
.exec
, p
);
4352 exec_status_info_free(p
);
4358 static int get_unit_dbus_path_by_pid(
4363 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4364 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4368 r
= sd_bus_call_method(
4370 "org.freedesktop.systemd1",
4371 "/org/freedesktop/systemd1",
4372 "org.freedesktop.systemd1.Manager",
4378 log_error("Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4382 r
= sd_bus_message_read(reply
, "o", &u
);
4384 return bus_log_parse_error(r
);
4394 static int show_all(
4397 bool show_properties
,
4401 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4402 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4407 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4411 pager_open_if_enabled();
4415 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4417 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4418 _cleanup_free_
char *p
= NULL
;
4420 p
= unit_dbus_path_from_name(u
->id
);
4424 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4427 else if (r
> 0 && ret
== 0)
4434 static int show_system_status(sd_bus
*bus
) {
4435 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4436 _cleanup_free_
char *hn
= NULL
;
4437 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4438 const char *on
, *off
;
4441 hn
= gethostname_malloc();
4445 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4447 return log_error_errno(r
, "Failed to read server status: %m");
4449 if (streq_ptr(mi
.state
, "degraded")) {
4450 on
= ansi_highlight_red();
4451 off
= ansi_highlight_off();
4452 } else if (!streq_ptr(mi
.state
, "running")) {
4453 on
= ansi_highlight_yellow();
4454 off
= ansi_highlight_off();
4458 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4460 printf(" State: %s%s%s\n",
4461 on
, strna(mi
.state
), off
);
4463 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4464 printf(" Failed: %u units\n", mi
.n_failed_units
);
4466 printf(" Since: %s; %s\n",
4467 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4468 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4470 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4471 if (arg_transport
== BUS_TRANSPORT_LOCAL
|| arg_transport
== BUS_TRANSPORT_MACHINE
) {
4472 static const char prefix
[] = " ";
4476 if (c
> sizeof(prefix
) - 1)
4477 c
-= sizeof(prefix
) - 1;
4481 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4487 static int show(sd_bus
*bus
, char **args
) {
4488 bool show_properties
, show_status
, new_line
= false;
4489 bool ellipsized
= false;
4495 show_properties
= streq(args
[0], "show");
4496 show_status
= streq(args
[0], "status");
4498 if (show_properties
)
4499 pager_open_if_enabled();
4502 /* Increase max number of open files to 16K if we can, we
4503 * might needs this when browsing journal files, which might
4504 * be split up into many files. */
4505 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4507 /* If no argument is specified inspect the manager itself */
4509 if (show_properties
&& strv_length(args
) <= 1)
4510 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4512 if (show_status
&& strv_length(args
) <= 1) {
4514 pager_open_if_enabled();
4515 show_system_status(bus
);
4519 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
4521 _cleanup_free_
char **patterns
= NULL
;
4524 STRV_FOREACH(name
, args
+ 1) {
4525 _cleanup_free_
char *unit
= NULL
;
4528 if (safe_atou32(*name
, &id
) < 0) {
4529 if (strv_push(&patterns
, *name
) < 0)
4533 } else if (show_properties
) {
4534 /* Interpret as job id */
4535 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4539 /* Interpret as PID */
4540 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4547 r
= show_one(args
[0], bus
, unit
, show_properties
,
4548 &new_line
, &ellipsized
);
4551 else if (r
> 0 && ret
== 0)
4555 if (!strv_isempty(patterns
)) {
4556 _cleanup_strv_free_
char **names
= NULL
;
4558 r
= expand_names(bus
, patterns
, NULL
, &names
);
4560 log_error_errno(r
, "Failed to expand names: %m");
4562 STRV_FOREACH(name
, names
) {
4563 _cleanup_free_
char *unit
;
4565 unit
= unit_dbus_path_from_name(*name
);
4569 r
= show_one(args
[0], bus
, unit
, show_properties
,
4570 &new_line
, &ellipsized
);
4573 else if (r
> 0 && ret
== 0)
4579 if (ellipsized
&& !arg_quiet
)
4580 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4585 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4589 assert(user_runtime
);
4592 if (arg_scope
== UNIT_FILE_USER
) {
4593 r
= user_config_home(user_home
);
4595 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4597 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4599 r
= user_runtime_dir(user_runtime
);
4601 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4603 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4606 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4608 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4613 static int cat_file(const char *filename
, bool newline
) {
4614 _cleanup_close_
int fd
;
4616 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4620 printf("%s%s# %s%s\n",
4621 newline
? "\n" : "",
4622 ansi_highlight_blue(),
4624 ansi_highlight_off());
4627 return copy_bytes(fd
, STDOUT_FILENO
, (off_t
) -1, false);
4630 static int cat(sd_bus
*bus
, char **args
) {
4631 _cleanup_free_
char *user_home
= NULL
;
4632 _cleanup_free_
char *user_runtime
= NULL
;
4633 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4634 _cleanup_strv_free_
char **names
= NULL
;
4636 bool first
= true, avoid_bus_cache
;
4641 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4642 log_error("Cannot remotely cat units");
4646 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4650 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4652 return log_error_errno(r
, "Failed to expand names: %m");
4654 avoid_bus_cache
= !bus
|| avoid_bus();
4656 pager_open_if_enabled();
4658 STRV_FOREACH(name
, names
) {
4659 _cleanup_free_
char *fragment_path
= NULL
;
4660 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4663 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &fragment_path
, &dropin_paths
);
4674 if (fragment_path
) {
4675 r
= cat_file(fragment_path
, false);
4677 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4680 STRV_FOREACH(path
, dropin_paths
) {
4681 r
= cat_file(*path
, path
== dropin_paths
);
4683 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4690 static int set_property(sd_bus
*bus
, char **args
) {
4691 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4692 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4693 _cleanup_free_
char *n
= NULL
;
4697 polkit_agent_open_if_enabled();
4699 r
= sd_bus_message_new_method_call(
4702 "org.freedesktop.systemd1",
4703 "/org/freedesktop/systemd1",
4704 "org.freedesktop.systemd1.Manager",
4705 "SetUnitProperties");
4707 return bus_log_create_error(r
);
4709 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &n
);
4711 return log_error_errno(r
, "Failed to mangle unit name: %m");
4713 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4715 return bus_log_create_error(r
);
4717 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4719 return bus_log_create_error(r
);
4721 STRV_FOREACH(i
, args
+ 2) {
4722 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4724 return bus_log_create_error(r
);
4726 r
= bus_append_unit_property_assignment(m
, *i
);
4730 r
= sd_bus_message_close_container(m
);
4732 return bus_log_create_error(r
);
4735 r
= sd_bus_message_close_container(m
);
4737 return bus_log_create_error(r
);
4739 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4741 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4748 static int snapshot(sd_bus
*bus
, char **args
) {
4749 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4750 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4751 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4755 polkit_agent_open_if_enabled();
4757 if (strv_length(args
) > 1) {
4758 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4760 return log_error_errno(r
, "Failed to generate unit name: %m");
4767 r
= sd_bus_call_method(
4769 "org.freedesktop.systemd1",
4770 "/org/freedesktop/systemd1",
4771 "org.freedesktop.systemd1.Manager",
4777 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
4781 r
= sd_bus_message_read(reply
, "o", &path
);
4783 return bus_log_parse_error(r
);
4785 r
= sd_bus_get_property_string(
4787 "org.freedesktop.systemd1",
4789 "org.freedesktop.systemd1.Unit",
4794 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4804 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4805 _cleanup_strv_free_
char **names
= NULL
;
4811 polkit_agent_open_if_enabled();
4813 r
= expand_names(bus
, args
+ 1, ".snapshot", &names
);
4815 log_error_errno(r
, "Failed to expand names: %m");
4817 STRV_FOREACH(name
, names
) {
4818 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4821 q
= sd_bus_call_method(
4823 "org.freedesktop.systemd1",
4824 "/org/freedesktop/systemd1",
4825 "org.freedesktop.systemd1.Manager",
4831 log_error("Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4840 static int daemon_reload(sd_bus
*bus
, char **args
) {
4841 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4845 polkit_agent_open_if_enabled();
4847 if (arg_action
== ACTION_RELOAD
)
4849 else if (arg_action
== ACTION_REEXEC
)
4850 method
= "Reexecute";
4852 assert(arg_action
== ACTION_SYSTEMCTL
);
4855 streq(args
[0], "clear-jobs") ||
4856 streq(args
[0], "cancel") ? "ClearJobs" :
4857 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4858 streq(args
[0], "reset-failed") ? "ResetFailed" :
4859 streq(args
[0], "halt") ? "Halt" :
4860 streq(args
[0], "poweroff") ? "PowerOff" :
4861 streq(args
[0], "reboot") ? "Reboot" :
4862 streq(args
[0], "kexec") ? "KExec" :
4863 streq(args
[0], "exit") ? "Exit" :
4864 /* "daemon-reload" */ "Reload";
4867 r
= sd_bus_call_method(
4869 "org.freedesktop.systemd1",
4870 "/org/freedesktop/systemd1",
4871 "org.freedesktop.systemd1.Manager",
4876 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4877 /* There's always a fallback possible for
4878 * legacy actions. */
4880 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4881 /* On reexecution, we expect a disconnect, not a
4885 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4887 return r
< 0 ? r
: 0;
4890 static int reset_failed(sd_bus
*bus
, char **args
) {
4891 _cleanup_strv_free_
char **names
= NULL
;
4895 if (strv_length(args
) <= 1)
4896 return daemon_reload(bus
, args
);
4898 polkit_agent_open_if_enabled();
4900 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4902 log_error_errno(r
, "Failed to expand names: %m");
4904 STRV_FOREACH(name
, names
) {
4905 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4907 q
= sd_bus_call_method(
4909 "org.freedesktop.systemd1",
4910 "/org/freedesktop/systemd1",
4911 "org.freedesktop.systemd1.Manager",
4917 log_error("Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4926 static int show_environment(sd_bus
*bus
, char **args
) {
4927 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4928 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4932 pager_open_if_enabled();
4934 r
= sd_bus_get_property(
4936 "org.freedesktop.systemd1",
4937 "/org/freedesktop/systemd1",
4938 "org.freedesktop.systemd1.Manager",
4944 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
4948 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
4950 return bus_log_parse_error(r
);
4952 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
4955 return bus_log_parse_error(r
);
4957 r
= sd_bus_message_exit_container(reply
);
4959 return bus_log_parse_error(r
);
4964 static int switch_root(sd_bus
*bus
, char **args
) {
4965 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4966 _cleanup_free_
char *cmdline_init
= NULL
;
4967 const char *root
, *init
;
4971 l
= strv_length(args
);
4972 if (l
< 2 || l
> 3) {
4973 log_error("Wrong number of arguments.");
4982 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
4983 "init", &cmdline_init
,
4986 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
4988 init
= cmdline_init
;
4995 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
4997 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
4998 root_init_path
= strjoina(root
, "/", init
);
5000 /* If the passed init is actually the same as the
5001 * systemd binary, then let's suppress it. */
5002 if (files_same(root_init_path
, root_systemd_path
) > 0)
5006 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5008 r
= sd_bus_call_method(
5010 "org.freedesktop.systemd1",
5011 "/org/freedesktop/systemd1",
5012 "org.freedesktop.systemd1.Manager",
5018 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
5025 static int set_environment(sd_bus
*bus
, char **args
) {
5026 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5027 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5034 polkit_agent_open_if_enabled();
5036 method
= streq(args
[0], "set-environment")
5038 : "UnsetEnvironment";
5040 r
= sd_bus_message_new_method_call(
5043 "org.freedesktop.systemd1",
5044 "/org/freedesktop/systemd1",
5045 "org.freedesktop.systemd1.Manager",
5048 return bus_log_create_error(r
);
5050 r
= sd_bus_message_append_strv(m
, args
+ 1);
5052 return bus_log_create_error(r
);
5054 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5056 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
5063 static int import_environment(sd_bus
*bus
, char **args
) {
5064 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5065 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5071 polkit_agent_open_if_enabled();
5073 r
= sd_bus_message_new_method_call(
5076 "org.freedesktop.systemd1",
5077 "/org/freedesktop/systemd1",
5078 "org.freedesktop.systemd1.Manager",
5081 return bus_log_create_error(r
);
5083 if (strv_isempty(args
+ 1))
5084 r
= sd_bus_message_append_strv(m
, environ
);
5088 r
= sd_bus_message_open_container(m
, 'a', "s");
5090 return bus_log_create_error(r
);
5092 STRV_FOREACH(a
, args
+ 1) {
5094 if (!env_name_is_valid(*a
)) {
5095 log_error("Not a valid environment variable name: %s", *a
);
5099 STRV_FOREACH(b
, environ
) {
5102 eq
= startswith(*b
, *a
);
5103 if (eq
&& *eq
== '=') {
5105 r
= sd_bus_message_append(m
, "s", *b
);
5107 return bus_log_create_error(r
);
5114 r
= sd_bus_message_close_container(m
);
5117 return bus_log_create_error(r
);
5119 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5121 log_error("Failed to import environment: %s", bus_error_message(&error
, r
));
5128 static int enable_sysv_units(const char *verb
, char **args
) {
5131 #if defined(HAVE_SYSV_COMPAT)
5133 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5135 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5138 if (!streq(verb
, "enable") &&
5139 !streq(verb
, "disable") &&
5140 !streq(verb
, "is-enabled"))
5143 /* Processes all SysV units, and reshuffles the array so that
5144 * afterwards only the native units remain */
5146 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5153 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5154 bool found_native
= false, found_sysv
;
5156 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5164 if (!endswith(name
, ".service"))
5167 if (path_is_absolute(name
))
5170 STRV_FOREACH(k
, paths
.unit_path
) {
5171 _cleanup_free_
char *path
= NULL
;
5173 path
= path_join(arg_root
, *k
, name
);
5177 found_native
= access(path
, F_OK
) >= 0;
5182 /* If we have both a native unit and a SysV script,
5183 * enable/disable them both (below); for is-enabled, prefer the
5185 if (found_native
&& streq(verb
, "is-enabled"))
5188 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5192 p
[strlen(p
) - strlen(".service")] = 0;
5193 found_sysv
= access(p
, F_OK
) >= 0;
5198 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5200 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5202 if (!isempty(arg_root
))
5203 argv
[c
++] = q
= strappend("--root=", arg_root
);
5206 argv
[c
++] = basename(p
);
5209 l
= strv_join((char**)argv
, " ");
5213 log_info("Executing %s", l
);
5217 return log_error_errno(errno
, "Failed to fork: %m");
5218 else if (pid
== 0) {
5221 (void) reset_all_signal_handlers();
5222 (void) reset_signal_mask();
5224 execv(argv
[0], (char**) argv
);
5225 log_error("Failed to execute %s: %m", argv
[0]);
5226 _exit(EXIT_FAILURE
);
5229 j
= wait_for_terminate(pid
, &status
);
5231 log_error_errno(r
, "Failed to wait for child: %m");
5235 if (status
.si_code
== CLD_EXITED
) {
5236 if (streq(verb
, "is-enabled")) {
5237 if (status
.si_status
== 0) {
5246 } else if (status
.si_status
!= 0)
5254 /* Remove this entry, so that we don't try enabling it as native unit */
5257 assert(args
[f
] == name
);
5258 strv_remove(args
, name
);
5265 static int mangle_names(char **original_names
, char ***mangled_names
) {
5266 char **i
, **l
, **name
;
5269 l
= i
= new(char*, strv_length(original_names
) + 1);
5273 STRV_FOREACH(name
, original_names
) {
5275 /* When enabling units qualified path names are OK,
5276 * too, hence allow them explicitly. */
5278 if (is_path(*name
)) {
5285 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5288 return log_error_errno(r
, "Failed to mangle unit name: %m");
5301 static int enable_unit(sd_bus
*bus
, char **args
) {
5302 _cleanup_strv_free_
char **names
= NULL
;
5303 const char *verb
= args
[0];
5304 UnitFileChange
*changes
= NULL
;
5305 unsigned n_changes
= 0;
5306 int carries_install_info
= -1;
5312 r
= mangle_names(args
+1, &names
);
5316 r
= enable_sysv_units(verb
, names
);
5320 /* If the operation was fully executed by the SysV compat,
5321 * let's finish early */
5322 if (strv_isempty(names
))
5325 if (!bus
|| avoid_bus()) {
5326 if (streq(verb
, "enable")) {
5327 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5328 carries_install_info
= r
;
5329 } else if (streq(verb
, "disable"))
5330 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5331 else if (streq(verb
, "reenable")) {
5332 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5333 carries_install_info
= r
;
5334 } else if (streq(verb
, "link"))
5335 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5336 else if (streq(verb
, "preset")) {
5337 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5338 carries_install_info
= r
;
5339 } else if (streq(verb
, "mask"))
5340 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5341 else if (streq(verb
, "unmask"))
5342 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5344 assert_not_reached("Unknown verb");
5347 log_error_errno(r
, "Operation failed: %m");
5352 dump_unit_file_changes(changes
, n_changes
);
5356 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5357 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5358 int expect_carries_install_info
= false;
5359 bool send_force
= true, send_preset_mode
= false;
5362 polkit_agent_open_if_enabled();
5364 if (streq(verb
, "enable")) {
5365 method
= "EnableUnitFiles";
5366 expect_carries_install_info
= true;
5367 } else if (streq(verb
, "disable")) {
5368 method
= "DisableUnitFiles";
5370 } else if (streq(verb
, "reenable")) {
5371 method
= "ReenableUnitFiles";
5372 expect_carries_install_info
= true;
5373 } else if (streq(verb
, "link"))
5374 method
= "LinkUnitFiles";
5375 else if (streq(verb
, "preset")) {
5377 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5378 method
= "PresetUnitFilesWithMode";
5379 send_preset_mode
= true;
5381 method
= "PresetUnitFiles";
5383 expect_carries_install_info
= true;
5384 } else if (streq(verb
, "mask"))
5385 method
= "MaskUnitFiles";
5386 else if (streq(verb
, "unmask")) {
5387 method
= "UnmaskUnitFiles";
5390 assert_not_reached("Unknown verb");
5392 r
= sd_bus_message_new_method_call(
5395 "org.freedesktop.systemd1",
5396 "/org/freedesktop/systemd1",
5397 "org.freedesktop.systemd1.Manager",
5400 return bus_log_create_error(r
);
5402 r
= sd_bus_message_append_strv(m
, names
);
5404 return bus_log_create_error(r
);
5406 if (send_preset_mode
) {
5407 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5409 return bus_log_create_error(r
);
5412 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5414 return bus_log_create_error(r
);
5417 r
= sd_bus_message_append(m
, "b", arg_force
);
5419 return bus_log_create_error(r
);
5422 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5424 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5428 if (expect_carries_install_info
) {
5429 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5431 return bus_log_parse_error(r
);
5434 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5438 /* Try to reload if enabled */
5440 r
= daemon_reload(bus
, args
);
5445 if (carries_install_info
== 0)
5446 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5447 "using systemctl.\n"
5448 "Possible reasons for having this kind of units are:\n"
5449 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5450 " .wants/ or .requires/ directory.\n"
5451 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5452 " a requirement dependency on it.\n"
5453 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5454 " D-Bus, udev, scripted systemctl call, ...).\n");
5456 if (arg_now
&& n_changes
> 0 && STR_IN_SET(args
[0], "enable", "disable", "mask")) {
5457 char *new_args
[n_changes
+ 2];
5460 new_args
[0] = streq(args
[0], "enable") ? (char *)"start" : (char *)"stop";
5461 for (i
= 0; i
< n_changes
; i
++)
5462 new_args
[i
+ 1] = basename(changes
[i
].path
);
5463 new_args
[i
+ 1] = NULL
;
5465 r
= start_unit(bus
, new_args
);
5469 unit_file_changes_free(changes
, n_changes
);
5474 static int add_dependency(sd_bus
*bus
, char **args
) {
5475 _cleanup_strv_free_
char **names
= NULL
;
5476 _cleanup_free_
char *target
= NULL
;
5477 const char *verb
= args
[0];
5484 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5486 return log_error_errno(r
, "Failed to mangle unit name: %m");
5488 r
= mangle_names(args
+2, &names
);
5492 if (streq(verb
, "add-wants"))
5494 else if (streq(verb
, "add-requires"))
5495 dep
= UNIT_REQUIRES
;
5497 assert_not_reached("Unknown verb");
5499 if (!bus
|| avoid_bus()) {
5500 UnitFileChange
*changes
= NULL
;
5501 unsigned n_changes
= 0;
5503 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5506 return log_error_errno(r
, "Can't add dependency: %m");
5509 dump_unit_file_changes(changes
, n_changes
);
5511 unit_file_changes_free(changes
, n_changes
);
5514 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5515 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5517 polkit_agent_open_if_enabled();
5519 r
= sd_bus_message_new_method_call(
5522 "org.freedesktop.systemd1",
5523 "/org/freedesktop/systemd1",
5524 "org.freedesktop.systemd1.Manager",
5525 "AddDependencyUnitFiles");
5527 return bus_log_create_error(r
);
5529 r
= sd_bus_message_append_strv(m
, names
);
5531 return bus_log_create_error(r
);
5533 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5535 return bus_log_create_error(r
);
5537 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5539 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5543 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5548 r
= daemon_reload(bus
, args
);
5556 static int preset_all(sd_bus
*bus
, char **args
) {
5557 UnitFileChange
*changes
= NULL
;
5558 unsigned n_changes
= 0;
5561 if (!bus
|| avoid_bus()) {
5563 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5565 log_error_errno(r
, "Operation failed: %m");
5570 dump_unit_file_changes(changes
, n_changes
);
5575 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5576 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5578 polkit_agent_open_if_enabled();
5580 r
= sd_bus_call_method(
5582 "org.freedesktop.systemd1",
5583 "/org/freedesktop/systemd1",
5584 "org.freedesktop.systemd1.Manager",
5585 "PresetAllUnitFiles",
5589 unit_file_preset_mode_to_string(arg_preset_mode
),
5593 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5597 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5602 r
= daemon_reload(bus
, args
);
5608 unit_file_changes_free(changes
, n_changes
);
5613 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
5615 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5616 _cleanup_strv_free_
char **names
= NULL
;
5621 r
= mangle_names(args
+1, &names
);
5625 r
= enable_sysv_units(args
[0], names
);
5631 if (!bus
|| avoid_bus()) {
5633 STRV_FOREACH(name
, names
) {
5634 UnitFileState state
;
5636 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5638 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5640 if (state
== UNIT_FILE_ENABLED
||
5641 state
== UNIT_FILE_ENABLED_RUNTIME
||
5642 state
== UNIT_FILE_STATIC
||
5643 state
== UNIT_FILE_INDIRECT
)
5647 puts(unit_file_state_to_string(state
));
5651 STRV_FOREACH(name
, names
) {
5652 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5655 r
= sd_bus_call_method(
5657 "org.freedesktop.systemd1",
5658 "/org/freedesktop/systemd1",
5659 "org.freedesktop.systemd1.Manager",
5665 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5669 r
= sd_bus_message_read(reply
, "s", &s
);
5671 return bus_log_parse_error(r
);
5673 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5684 static int is_system_running(sd_bus
*bus
, char **args
) {
5685 _cleanup_free_
char *state
= NULL
;
5688 r
= sd_bus_get_property_string(
5690 "org.freedesktop.systemd1",
5691 "/org/freedesktop/systemd1",
5692 "org.freedesktop.systemd1.Manager",
5705 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5708 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5713 assert(original_path
);
5716 r
= tempfn_random(new_path
, NULL
, &t
);
5718 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5720 r
= mkdir_parents(new_path
, 0755);
5722 log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5727 r
= copy_file(original_path
, t
, 0, 0644, 0);
5731 log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5736 log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5746 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5747 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5749 switch (arg_scope
) {
5750 case UNIT_FILE_SYSTEM
:
5751 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5753 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5755 case UNIT_FILE_GLOBAL
:
5756 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5758 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5760 case UNIT_FILE_USER
:
5762 assert(user_runtime
);
5764 path
= path_join(arg_root
, user_home
, name
);
5766 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5769 run
= path_join(arg_root
, user_runtime
, name
);
5773 assert_not_reached("Invalid scope");
5775 if (!path
|| (arg_runtime
&& !run
))
5779 if (access(path
, F_OK
) >= 0)
5780 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5782 if (path2
&& access(path2
, F_OK
) >= 0)
5783 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5795 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
) {
5796 char *tmp_new_path
, *ending
;
5801 assert(ret_new_path
);
5802 assert(ret_tmp_path
);
5804 ending
= strjoina(unit_name
, ".d/override.conf");
5805 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5809 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5815 *ret_new_path
= tmp_new_path
;
5816 *ret_tmp_path
= tmp_tmp_path
;
5821 static int unit_file_create_copy(
5822 const char *unit_name
,
5823 const char *fragment_path
,
5824 const char *user_home
,
5825 const char *user_runtime
,
5826 char **ret_new_path
,
5827 char **ret_tmp_path
) {
5833 assert(fragment_path
);
5835 assert(ret_new_path
);
5836 assert(ret_tmp_path
);
5838 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5842 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5845 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5850 if (response
!= 'y') {
5851 log_warning("%s ignored", unit_name
);
5857 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5859 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5864 *ret_new_path
= tmp_new_path
;
5865 *ret_tmp_path
= tmp_tmp_path
;
5870 static int run_editor(char **paths
) {
5878 log_error_errno(errno
, "Failed to fork: %m");
5884 char *editor
, **editor_args
= NULL
;
5885 char **tmp_path
, **original_path
, *p
;
5886 unsigned n_editor_args
= 0, i
= 1;
5889 (void) reset_all_signal_handlers();
5890 (void) reset_signal_mask();
5892 argc
= strv_length(paths
)/2 + 1;
5894 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5895 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5896 * we try to execute well known editors
5898 editor
= getenv("SYSTEMD_EDITOR");
5900 editor
= getenv("EDITOR");
5902 editor
= getenv("VISUAL");
5904 if (!isempty(editor
)) {
5905 editor_args
= strv_split(editor
, WHITESPACE
);
5908 _exit(EXIT_FAILURE
);
5910 n_editor_args
= strv_length(editor_args
);
5911 argc
+= n_editor_args
- 1;
5913 args
= newa(const char*, argc
+ 1);
5915 if (n_editor_args
> 0) {
5916 args
[0] = editor_args
[0];
5917 for (; i
< n_editor_args
; i
++)
5918 args
[i
] = editor_args
[i
];
5921 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
5922 args
[i
] = *tmp_path
;
5927 if (n_editor_args
> 0)
5928 execvp(args
[0], (char* const*) args
);
5930 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
5932 execvp(p
, (char* const*) args
);
5933 /* We do not fail if the editor doesn't exist
5934 * because we want to try each one of them before
5937 if (errno
!= ENOENT
) {
5938 log_error("Failed to execute %s: %m", editor
);
5939 _exit(EXIT_FAILURE
);
5943 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
5944 _exit(EXIT_FAILURE
);
5947 r
= wait_for_terminate_and_warn("editor", pid
, true);
5949 return log_error_errno(r
, "Failed to wait for child: %m");
5954 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
5955 _cleanup_free_
char *user_home
= NULL
;
5956 _cleanup_free_
char *user_runtime
= NULL
;
5957 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5958 bool avoid_bus_cache
;
5965 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
5969 avoid_bus_cache
= !bus
|| avoid_bus();
5971 STRV_FOREACH(name
, names
) {
5972 _cleanup_free_
char *path
= NULL
;
5973 char *new_path
, *tmp_path
;
5975 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &path
, NULL
);
5981 // FIXME: support units with path==NULL (no FragmentPath)
5982 log_error("No fragment exists for %s.", *name
);
5987 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
5989 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
5993 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6001 static int edit(sd_bus
*bus
, char **args
) {
6002 _cleanup_strv_free_
char **names
= NULL
;
6003 _cleanup_strv_free_
char **paths
= NULL
;
6004 char **original
, **tmp
;
6010 log_error("Cannot edit units if not on a tty");
6014 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6015 log_error("Cannot remotely edit units");
6019 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
6021 return log_error_errno(r
, "Failed to expand names: %m");
6023 r
= find_paths_to_edit(bus
, names
, &paths
);
6027 if (strv_isempty(paths
))
6030 r
= run_editor(paths
);
6034 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6035 /* If the temporary file is empty we ignore it.
6036 * It's useful if the user wants to cancel its modification
6038 if (null_or_empty_path(*tmp
)) {
6039 log_warning("Editing \"%s\" canceled: temporary file is empty", *original
);
6042 r
= rename(*tmp
, *original
);
6044 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6049 if (!arg_no_reload
&& bus
&& !avoid_bus())
6050 r
= daemon_reload(bus
, args
);
6053 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6054 unlink_noerrno(*tmp
);
6059 static void systemctl_help(void) {
6061 pager_open_if_enabled();
6063 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6064 "Query or send control commands to the systemd manager.\n\n"
6065 " -h --help Show this help\n"
6066 " --version Show package version\n"
6067 " --system Connect to system manager\n"
6068 " --user Connect to user service manager\n"
6069 " -H --host=[USER@]HOST\n"
6070 " Operate on remote host\n"
6071 " -M --machine=CONTAINER\n"
6072 " Operate on local container\n"
6073 " -t --type=TYPE List units of a particular type\n"
6074 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6075 " -p --property=NAME Show only properties by this name\n"
6076 " -a --all Show all loaded units/properties, including dead/empty\n"
6077 " ones. To list all units installed on the system, use\n"
6078 " the 'list-unit-files' command instead.\n"
6079 " -l --full Don't ellipsize unit names on output\n"
6080 " -r --recursive Show unit list of host and local containers\n"
6081 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6082 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6083 " queueing a new job\n"
6084 " --show-types When showing sockets, explicitly show their type\n"
6085 " -i --ignore-inhibitors\n"
6086 " When shutting down or sleeping, ignore inhibitors\n"
6087 " --kill-who=WHO Who to send signal to\n"
6088 " -s --signal=SIGNAL Which signal to send\n"
6089 " --now Start or stop unit in addition to enabling or disabling it\n"
6090 " -q --quiet Suppress output\n"
6091 " --no-block Do not wait until operation finished\n"
6092 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6093 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6094 " --no-legend Do not print a legend (column headers and hints)\n"
6095 " --no-pager Do not pipe output into a pager\n"
6096 " --no-ask-password\n"
6097 " Do not ask for system passwords\n"
6098 " --global Enable/disable unit files globally\n"
6099 " --runtime Enable unit files only temporarily until next reboot\n"
6100 " -f --force When enabling unit files, override existing symlinks\n"
6101 " When shutting down, execute action immediately\n"
6102 " --preset-mode= Apply only enable, only disable, or all presets\n"
6103 " --root=PATH Enable unit files in the specified root directory\n"
6104 " -n --lines=INTEGER Number of journal entries to show\n"
6105 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6106 " short-precise, short-monotonic, verbose,\n"
6107 " export, json, json-pretty, json-sse, cat)\n"
6108 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6109 " --plain Print unit dependencies as a list instead of a tree\n\n"
6111 " list-units [PATTERN...] List loaded units\n"
6112 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6113 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6114 " start NAME... Start (activate) one or more units\n"
6115 " stop NAME... Stop (deactivate) one or more units\n"
6116 " reload NAME... Reload one or more units\n"
6117 " restart NAME... Start or restart one or more units\n"
6118 " try-restart NAME... Restart one or more units if active\n"
6119 " reload-or-restart NAME... Reload one or more units if possible,\n"
6120 " otherwise start or restart\n"
6121 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6122 " otherwise restart if active\n"
6123 " isolate NAME Start one unit and stop all others\n"
6124 " kill NAME... Send signal to processes of a unit\n"
6125 " is-active PATTERN... Check whether units are active\n"
6126 " is-failed PATTERN... Check whether units are failed\n"
6127 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6128 " show [PATTERN...|JOB...] Show properties of one or more\n"
6129 " units/jobs or the manager\n"
6130 " cat PATTERN... Show files and drop-ins of one or more units\n"
6131 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6132 " help PATTERN...|PID... Show manual for one or more units\n"
6133 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6135 " list-dependencies [NAME] Recursively show units which are required\n"
6136 " or wanted by this unit or by which this\n"
6137 " unit is required or wanted\n\n"
6138 "Unit File Commands:\n"
6139 " list-unit-files [PATTERN...] List installed unit files\n"
6140 " enable NAME... Enable one or more unit files\n"
6141 " disable NAME... Disable one or more unit files\n"
6142 " reenable NAME... Reenable one or more unit files\n"
6143 " preset NAME... Enable/disable one or more unit files\n"
6144 " based on preset configuration\n"
6145 " preset-all Enable/disable all unit files based on\n"
6146 " preset configuration\n"
6147 " is-enabled NAME... Check whether unit files are enabled\n"
6148 " mask NAME... Mask one or more units\n"
6149 " unmask NAME... Unmask one or more units\n"
6150 " link PATH... Link one or more units files into\n"
6151 " the search path\n"
6152 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6153 " on specified one or more units\n"
6154 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6155 " on specified one or more units\n"
6156 " edit NAME... Edit one or more unit files\n"
6157 " get-default Get the name of the default target\n"
6158 " set-default NAME Set the default target\n\n"
6159 "Machine Commands:\n"
6160 " list-machines [PATTERN...] List local containers and host\n\n"
6162 " list-jobs [PATTERN...] List jobs\n"
6163 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6164 "Snapshot Commands:\n"
6165 " snapshot [NAME] Create a snapshot\n"
6166 " delete NAME... Remove one or more snapshots\n\n"
6167 "Environment Commands:\n"
6168 " show-environment Dump environment\n"
6169 " set-environment NAME=VALUE... Set one or more environment variables\n"
6170 " unset-environment NAME... Unset one or more environment variables\n"
6171 " import-environment [NAME...] Import all or some environment variables\n\n"
6172 "Manager Lifecycle Commands:\n"
6173 " daemon-reload Reload systemd manager configuration\n"
6174 " daemon-reexec Reexecute systemd manager\n\n"
6175 "System Commands:\n"
6176 " is-system-running Check whether system is fully running\n"
6177 " default Enter system default mode\n"
6178 " rescue Enter system rescue mode\n"
6179 " emergency Enter system emergency mode\n"
6180 " halt Shut down and halt the system\n"
6181 " poweroff Shut down and power-off the system\n"
6182 " reboot [ARG] Shut down and reboot the system\n"
6183 " kexec Shut down and reboot the system with kexec\n"
6184 " exit Request user instance exit\n"
6185 " switch-root ROOT [INIT] Change to a different root file system\n"
6186 " suspend Suspend the system\n"
6187 " hibernate Hibernate the system\n"
6188 " hybrid-sleep Hibernate and suspend the system\n",
6189 program_invocation_short_name
);
6192 static void halt_help(void) {
6193 printf("%s [OPTIONS...]%s\n\n"
6194 "%s the system.\n\n"
6195 " --help Show this help\n"
6196 " --halt Halt the machine\n"
6197 " -p --poweroff Switch off the machine\n"
6198 " --reboot Reboot the machine\n"
6199 " -f --force Force immediate halt/power-off/reboot\n"
6200 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6201 " -d --no-wtmp Don't write wtmp record\n"
6202 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6203 program_invocation_short_name
,
6204 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6205 arg_action
== ACTION_REBOOT
? "Reboot" :
6206 arg_action
== ACTION_POWEROFF
? "Power off" :
6210 static void shutdown_help(void) {
6211 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6212 "Shut down the system.\n\n"
6213 " --help Show this help\n"
6214 " -H --halt Halt the machine\n"
6215 " -P --poweroff Power-off the machine\n"
6216 " -r --reboot Reboot the machine\n"
6217 " -h Equivalent to --poweroff, overridden by --halt\n"
6218 " -k Don't halt/power-off/reboot, just send warnings\n"
6219 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6220 " -c Cancel a pending shutdown\n",
6221 program_invocation_short_name
);
6224 static void telinit_help(void) {
6225 printf("%s [OPTIONS...] {COMMAND}\n\n"
6226 "Send control commands to the init daemon.\n\n"
6227 " --help Show this help\n"
6228 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6230 " 0 Power-off the machine\n"
6231 " 6 Reboot the machine\n"
6232 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6233 " 1, s, S Enter rescue mode\n"
6234 " q, Q Reload init daemon configuration\n"
6235 " u, U Reexecute init daemon\n",
6236 program_invocation_short_name
);
6239 static void runlevel_help(void) {
6240 printf("%s [OPTIONS...]\n\n"
6241 "Prints the previous and current runlevel of the init system.\n\n"
6242 " --help Show this help\n",
6243 program_invocation_short_name
);
6246 static void help_types(void) {
6251 puts("Available unit types:");
6252 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
6253 t
= unit_type_to_string(i
);
6259 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6268 ARG_IGNORE_DEPENDENCIES
,
6280 ARG_NO_ASK_PASSWORD
,
6293 static const struct option options
[] = {
6294 { "help", no_argument
, NULL
, 'h' },
6295 { "version", no_argument
, NULL
, ARG_VERSION
},
6296 { "type", required_argument
, NULL
, 't' },
6297 { "property", required_argument
, NULL
, 'p' },
6298 { "all", no_argument
, NULL
, 'a' },
6299 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6300 { "after", no_argument
, NULL
, ARG_AFTER
},
6301 { "before", no_argument
, NULL
, ARG_BEFORE
},
6302 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6303 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6304 { "full", no_argument
, NULL
, 'l' },
6305 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6306 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6307 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6308 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6309 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6310 { "user", no_argument
, NULL
, ARG_USER
},
6311 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6312 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6313 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6314 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6315 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6316 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6317 { "quiet", no_argument
, NULL
, 'q' },
6318 { "root", required_argument
, NULL
, ARG_ROOT
},
6319 { "force", no_argument
, NULL
, ARG_FORCE
},
6320 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6321 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6322 { "signal", required_argument
, NULL
, 's' },
6323 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6324 { "host", required_argument
, NULL
, 'H' },
6325 { "machine", required_argument
, NULL
, 'M' },
6326 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6327 { "lines", required_argument
, NULL
, 'n' },
6328 { "output", required_argument
, NULL
, 'o' },
6329 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6330 { "state", required_argument
, NULL
, ARG_STATE
},
6331 { "recursive", no_argument
, NULL
, 'r' },
6332 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6333 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6334 { "now", no_argument
, NULL
, ARG_NOW
},
6335 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6344 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6353 puts(PACKAGE_STRING
);
6354 puts(SYSTEMD_FEATURES
);
6358 const char *word
, *state
;
6361 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6362 _cleanup_free_
char *type
;
6364 type
= strndup(word
, size
);
6368 if (streq(type
, "help")) {
6373 if (unit_type_from_string(type
) >= 0) {
6374 if (strv_push(&arg_types
, type
))
6380 /* It's much nicer to use --state= for
6381 * load states, but let's support this
6382 * in --types= too for compatibility
6383 * with old versions */
6384 if (unit_load_state_from_string(optarg
) >= 0) {
6385 if (strv_push(&arg_states
, type
) < 0)
6391 log_error("Unknown unit type or load state '%s'.", type
);
6392 log_info("Use -t help to see a list of allowed values.");
6400 /* Make sure that if the empty property list
6401 was specified, we won't show any properties. */
6402 if (isempty(optarg
) && !arg_properties
) {
6403 arg_properties
= new0(char*, 1);
6404 if (!arg_properties
)
6407 const char *word
, *state
;
6410 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6413 prop
= strndup(word
, size
);
6417 if (strv_consume(&arg_properties
, prop
) < 0)
6422 /* If the user asked for a particular
6423 * property, show it to him, even if it is
6435 arg_dependency
= DEPENDENCY_REVERSE
;
6439 arg_dependency
= DEPENDENCY_AFTER
;
6443 arg_dependency
= DEPENDENCY_BEFORE
;
6446 case ARG_SHOW_TYPES
:
6447 arg_show_types
= true;
6451 arg_job_mode
= optarg
;
6455 arg_job_mode
= "fail";
6458 case ARG_IRREVERSIBLE
:
6459 arg_job_mode
= "replace-irreversibly";
6462 case ARG_IGNORE_DEPENDENCIES
:
6463 arg_job_mode
= "ignore-dependencies";
6467 arg_scope
= UNIT_FILE_USER
;
6471 arg_scope
= UNIT_FILE_SYSTEM
;
6475 arg_scope
= UNIT_FILE_GLOBAL
;
6479 arg_no_block
= true;
6483 arg_no_legend
= true;
6487 arg_no_pager
= true;
6503 if (strv_extend(&arg_states
, "failed") < 0)
6521 arg_no_reload
= true;
6525 arg_kill_who
= optarg
;
6529 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
6530 log_error("Failed to parse signal string %s.", optarg
);
6535 case ARG_NO_ASK_PASSWORD
:
6536 arg_ask_password
= false;
6540 arg_transport
= BUS_TRANSPORT_REMOTE
;
6545 arg_transport
= BUS_TRANSPORT_MACHINE
;
6554 if (safe_atou(optarg
, &arg_lines
) < 0) {
6555 log_error("Failed to parse lines '%s'", optarg
);
6561 arg_output
= output_mode_from_string(optarg
);
6562 if (arg_output
< 0) {
6563 log_error("Unknown output '%s'.", optarg
);
6569 arg_ignore_inhibitors
= true;
6576 case ARG_FIRMWARE_SETUP
:
6577 arg_firmware_setup
= true;
6581 const char *word
, *state
;
6584 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6587 s
= strndup(word
, size
);
6591 if (strv_consume(&arg_states
, s
) < 0)
6598 if (geteuid() != 0) {
6599 log_error("--recursive requires root privileges.");
6603 arg_recursive
= true;
6606 case ARG_PRESET_MODE
:
6608 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6609 if (arg_preset_mode
< 0) {
6610 log_error("Failed to parse preset mode: %s.", optarg
);
6621 if (strv_extend(&arg_wall
, optarg
) < 0)
6629 assert_not_reached("Unhandled option");
6632 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6633 log_error("Cannot access user instance remotely.");
6640 static int halt_parse_argv(int argc
, char *argv
[]) {
6649 static const struct option options
[] = {
6650 { "help", no_argument
, NULL
, ARG_HELP
},
6651 { "halt", no_argument
, NULL
, ARG_HALT
},
6652 { "poweroff", no_argument
, NULL
, 'p' },
6653 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6654 { "force", no_argument
, NULL
, 'f' },
6655 { "wtmp-only", no_argument
, NULL
, 'w' },
6656 { "no-wtmp", no_argument
, NULL
, 'd' },
6657 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6666 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6667 if (runlevel
== '0' || runlevel
== '6')
6670 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6678 arg_action
= ACTION_HALT
;
6682 if (arg_action
!= ACTION_REBOOT
)
6683 arg_action
= ACTION_POWEROFF
;
6687 arg_action
= ACTION_REBOOT
;
6709 /* Compatibility nops */
6716 assert_not_reached("Unhandled option");
6719 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6720 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6723 } else if (optind
< argc
) {
6724 log_error("Too many arguments.");
6731 static int parse_time_spec(const char *t
, usec_t
*_u
) {
6735 if (streq(t
, "now"))
6737 else if (!strchr(t
, ':')) {
6740 if (safe_atou64(t
, &u
) < 0)
6743 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6752 hour
= strtol(t
, &e
, 10);
6753 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6756 minute
= strtol(e
+1, &e
, 10);
6757 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6760 n
= now(CLOCK_REALTIME
);
6761 s
= (time_t) (n
/ USEC_PER_SEC
);
6763 assert_se(localtime_r(&s
, &tm
));
6765 tm
.tm_hour
= (int) hour
;
6766 tm
.tm_min
= (int) minute
;
6769 assert_se(s
= mktime(&tm
));
6771 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6774 *_u
+= USEC_PER_DAY
;
6780 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6787 static const struct option options
[] = {
6788 { "help", no_argument
, NULL
, ARG_HELP
},
6789 { "halt", no_argument
, NULL
, 'H' },
6790 { "poweroff", no_argument
, NULL
, 'P' },
6791 { "reboot", no_argument
, NULL
, 'r' },
6792 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6793 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6802 while ((c
= getopt_long(argc
, argv
, "HPrhkKt:afFc", options
, NULL
)) >= 0)
6810 arg_action
= ACTION_HALT
;
6814 arg_action
= ACTION_POWEROFF
;
6819 arg_action
= ACTION_KEXEC
;
6821 arg_action
= ACTION_REBOOT
;
6825 arg_action
= ACTION_KEXEC
;
6829 if (arg_action
!= ACTION_HALT
)
6830 arg_action
= ACTION_POWEROFF
;
6845 /* Compatibility nops */
6849 arg_action
= ACTION_CANCEL_SHUTDOWN
;
6856 assert_not_reached("Unhandled option");
6859 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
6860 r
= parse_time_spec(argv
[optind
], &arg_when
);
6862 log_error("Failed to parse time specification: %s", argv
[optind
]);
6866 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
6868 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
6869 /* No time argument for shutdown cancel */
6870 arg_wall
= argv
+ optind
;
6871 else if (argc
> optind
+ 1)
6872 /* We skip the time argument */
6873 arg_wall
= argv
+ optind
+ 1;
6880 static int telinit_parse_argv(int argc
, char *argv
[]) {
6887 static const struct option options
[] = {
6888 { "help", no_argument
, NULL
, ARG_HELP
},
6889 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6893 static const struct {
6897 { '0', ACTION_POWEROFF
},
6898 { '6', ACTION_REBOOT
},
6899 { '1', ACTION_RESCUE
},
6900 { '2', ACTION_RUNLEVEL2
},
6901 { '3', ACTION_RUNLEVEL3
},
6902 { '4', ACTION_RUNLEVEL4
},
6903 { '5', ACTION_RUNLEVEL5
},
6904 { 's', ACTION_RESCUE
},
6905 { 'S', ACTION_RESCUE
},
6906 { 'q', ACTION_RELOAD
},
6907 { 'Q', ACTION_RELOAD
},
6908 { 'u', ACTION_REEXEC
},
6909 { 'U', ACTION_REEXEC
}
6918 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
6933 assert_not_reached("Unhandled option");
6936 if (optind
>= argc
) {
6937 log_error("%s: required argument missing.",
6938 program_invocation_short_name
);
6942 if (optind
+ 1 < argc
) {
6943 log_error("Too many arguments.");
6947 if (strlen(argv
[optind
]) != 1) {
6948 log_error("Expected single character argument.");
6952 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
6953 if (table
[i
].from
== argv
[optind
][0])
6956 if (i
>= ELEMENTSOF(table
)) {
6957 log_error("Unknown command '%s'.", argv
[optind
]);
6961 arg_action
= table
[i
].to
;
6968 static int runlevel_parse_argv(int argc
, char *argv
[]) {
6974 static const struct option options
[] = {
6975 { "help", no_argument
, NULL
, ARG_HELP
},
6984 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
6995 assert_not_reached("Unhandled option");
6998 if (optind
< argc
) {
6999 log_error("Too many arguments.");
7006 static int parse_argv(int argc
, char *argv
[]) {
7010 if (program_invocation_short_name
) {
7012 if (strstr(program_invocation_short_name
, "halt")) {
7013 arg_action
= ACTION_HALT
;
7014 return halt_parse_argv(argc
, argv
);
7015 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7016 arg_action
= ACTION_POWEROFF
;
7017 return halt_parse_argv(argc
, argv
);
7018 } else if (strstr(program_invocation_short_name
, "reboot")) {
7020 arg_action
= ACTION_KEXEC
;
7022 arg_action
= ACTION_REBOOT
;
7023 return halt_parse_argv(argc
, argv
);
7024 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7025 arg_action
= ACTION_POWEROFF
;
7026 return shutdown_parse_argv(argc
, argv
);
7027 } else if (strstr(program_invocation_short_name
, "init")) {
7029 if (sd_booted() > 0) {
7030 arg_action
= _ACTION_INVALID
;
7031 return telinit_parse_argv(argc
, argv
);
7033 /* Hmm, so some other init system is
7034 * running, we need to forward this
7035 * request to it. For now we simply
7036 * guess that it is Upstart. */
7038 execv(TELINIT
, argv
);
7040 log_error("Couldn't find an alternative telinit implementation to spawn.");
7044 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7045 arg_action
= ACTION_RUNLEVEL
;
7046 return runlevel_parse_argv(argc
, argv
);
7050 arg_action
= ACTION_SYSTEMCTL
;
7051 return systemctl_parse_argv(argc
, argv
);
7054 _pure_
static int action_to_runlevel(void) {
7056 static const char table
[_ACTION_MAX
] = {
7057 [ACTION_HALT
] = '0',
7058 [ACTION_POWEROFF
] = '0',
7059 [ACTION_REBOOT
] = '6',
7060 [ACTION_RUNLEVEL2
] = '2',
7061 [ACTION_RUNLEVEL3
] = '3',
7062 [ACTION_RUNLEVEL4
] = '4',
7063 [ACTION_RUNLEVEL5
] = '5',
7064 [ACTION_RESCUE
] = '1'
7067 assert(arg_action
< _ACTION_MAX
);
7069 return table
[arg_action
];
7072 static int talk_initctl(void) {
7074 struct init_request request
= {
7075 .magic
= INIT_MAGIC
,
7077 .cmd
= INIT_CMD_RUNLVL
7080 _cleanup_close_
int fd
= -1;
7084 rl
= action_to_runlevel();
7088 request
.runlevel
= rl
;
7090 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7092 if (errno
== ENOENT
)
7095 log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7099 r
= loop_write(fd
, &request
, sizeof(request
), false);
7101 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7106 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
7108 static const struct {
7116 int (* const dispatch
)(sd_bus
*bus
, char **args
);
7122 { "list-units", MORE
, 0, list_units
},
7123 { "list-unit-files", MORE
, 1, list_unit_files
, NOBUS
},
7124 { "list-sockets", MORE
, 1, list_sockets
},
7125 { "list-timers", MORE
, 1, list_timers
},
7126 { "list-jobs", MORE
, 1, list_jobs
},
7127 { "list-machines", MORE
, 1, list_machines
},
7128 { "clear-jobs", EQUAL
, 1, daemon_reload
},
7129 { "cancel", MORE
, 2, cancel_job
},
7130 { "start", MORE
, 2, start_unit
},
7131 { "stop", MORE
, 2, start_unit
},
7132 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7133 { "reload", MORE
, 2, start_unit
},
7134 { "restart", MORE
, 2, start_unit
},
7135 { "try-restart", MORE
, 2, start_unit
},
7136 { "reload-or-restart", MORE
, 2, start_unit
},
7137 { "reload-or-try-restart", MORE
, 2, start_unit
},
7138 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
7139 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7140 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
7141 { "isolate", EQUAL
, 2, start_unit
},
7142 { "kill", MORE
, 2, kill_unit
},
7143 { "is-active", MORE
, 2, check_unit_active
},
7144 { "check", MORE
, 2, check_unit_active
},
7145 { "is-failed", MORE
, 2, check_unit_failed
},
7146 { "show", MORE
, 1, show
},
7147 { "cat", MORE
, 2, cat
, NOBUS
},
7148 { "status", MORE
, 1, show
},
7149 { "help", MORE
, 2, show
},
7150 { "snapshot", LESS
, 2, snapshot
},
7151 { "delete", MORE
, 2, delete_snapshot
},
7152 { "daemon-reload", EQUAL
, 1, daemon_reload
},
7153 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
7154 { "show-environment", EQUAL
, 1, show_environment
},
7155 { "set-environment", MORE
, 2, set_environment
},
7156 { "unset-environment", MORE
, 2, set_environment
},
7157 { "import-environment", MORE
, 1, import_environment
},
7158 { "halt", EQUAL
, 1, start_special
, FORCE
},
7159 { "poweroff", EQUAL
, 1, start_special
, FORCE
},
7160 { "reboot", MORE
, 1, start_special
, FORCE
},
7161 { "kexec", EQUAL
, 1, start_special
},
7162 { "suspend", EQUAL
, 1, start_special
},
7163 { "hibernate", EQUAL
, 1, start_special
},
7164 { "hybrid-sleep", EQUAL
, 1, start_special
},
7165 { "default", EQUAL
, 1, start_special
},
7166 { "rescue", EQUAL
, 1, start_special
},
7167 { "emergency", EQUAL
, 1, start_special
},
7168 { "exit", EQUAL
, 1, start_special
},
7169 { "reset-failed", MORE
, 1, reset_failed
},
7170 { "enable", MORE
, 2, enable_unit
, NOBUS
},
7171 { "disable", MORE
, 2, enable_unit
, NOBUS
},
7172 { "is-enabled", MORE
, 2, unit_is_enabled
, NOBUS
},
7173 { "reenable", MORE
, 2, enable_unit
, NOBUS
},
7174 { "preset", MORE
, 2, enable_unit
, NOBUS
},
7175 { "preset-all", EQUAL
, 1, preset_all
, NOBUS
},
7176 { "mask", MORE
, 2, enable_unit
, NOBUS
},
7177 { "unmask", MORE
, 2, enable_unit
, NOBUS
},
7178 { "link", MORE
, 2, enable_unit
, NOBUS
},
7179 { "switch-root", MORE
, 2, switch_root
},
7180 { "list-dependencies", LESS
, 2, list_dependencies
},
7181 { "set-default", EQUAL
, 2, set_default
, NOBUS
},
7182 { "get-default", EQUAL
, 1, get_default
, NOBUS
},
7183 { "set-property", MORE
, 3, set_property
},
7184 { "is-system-running", EQUAL
, 1, is_system_running
},
7185 { "add-wants", MORE
, 3, add_dependency
, NOBUS
},
7186 { "add-requires", MORE
, 3, add_dependency
, NOBUS
},
7187 { "edit", MORE
, 2, edit
, NOBUS
},
7196 left
= argc
- optind
;
7198 /* Special rule: no arguments (left == 0) means "list-units" */
7200 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
7201 log_error("This command expects one or more "
7202 "unit names. Did you mean --help?");
7206 for (; verb
->verb
; verb
++)
7207 if (streq(argv
[optind
], verb
->verb
))
7210 log_error("Unknown operation '%s'.", argv
[optind
]);
7215 switch (verb
->argc_cmp
) {
7218 if (left
!= verb
->argc
) {
7219 log_error("Invalid number of arguments.");
7226 if (left
< verb
->argc
) {
7227 log_error("Too few arguments.");
7234 if (left
> verb
->argc
) {
7235 log_error("Too many arguments.");
7242 assert_not_reached("Unknown comparison operator.");
7245 /* Require a bus connection for all operations but
7247 if (verb
->bus
== NOBUS
) {
7248 if (!bus
&& !avoid_bus()) {
7249 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7254 if (running_in_chroot() > 0) {
7255 log_info("Running in chroot, ignoring request.");
7259 if ((verb
->bus
!= FORCE
|| arg_force
<= 0) && !bus
) {
7260 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7265 return verb
->dispatch(bus
, argv
+ optind
);
7268 static int reload_with_fallback(sd_bus
*bus
) {
7271 /* First, try systemd via D-Bus. */
7272 if (daemon_reload(bus
, NULL
) >= 0)
7276 /* Nothing else worked, so let's try signals */
7277 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7279 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7280 return log_error_errno(errno
, "kill() failed: %m");
7285 static int start_with_fallback(sd_bus
*bus
) {
7288 /* First, try systemd via D-Bus. */
7289 if (start_unit(bus
, NULL
) >= 0)
7293 /* Nothing else worked, so let's try
7295 if (talk_initctl() > 0)
7298 log_error("Failed to talk to init daemon.");
7302 warn_wall(arg_action
);
7306 static int halt_now(enum action a
) {
7308 /* The kernel will automaticall flush ATA disks and suchlike
7309 * on reboot(), but the file systems need to be synce'd
7310 * explicitly in advance. */
7313 /* Make sure C-A-D is handled by the kernel from this point
7315 reboot(RB_ENABLE_CAD
);
7320 log_info("Halting.");
7321 reboot(RB_HALT_SYSTEM
);
7324 case ACTION_POWEROFF
:
7325 log_info("Powering off.");
7326 reboot(RB_POWER_OFF
);
7330 case ACTION_REBOOT
: {
7331 _cleanup_free_
char *param
= NULL
;
7333 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7334 log_info("Rebooting with argument '%s'.", param
);
7335 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
7336 LINUX_REBOOT_CMD_RESTART2
, param
);
7339 log_info("Rebooting.");
7340 reboot(RB_AUTOBOOT
);
7345 assert_not_reached("Unknown action.");
7349 static int halt_main(sd_bus
*bus
) {
7352 r
= check_inhibitors(bus
, arg_action
);
7356 if (geteuid() != 0) {
7357 /* Try logind if we are a normal user and no special
7358 * mode applies. Maybe PolicyKit allows us to shutdown
7361 if (arg_when
<= 0 &&
7364 (arg_action
== ACTION_POWEROFF
||
7365 arg_action
== ACTION_REBOOT
)) {
7366 r
= reboot_with_logind(bus
, arg_action
);
7371 log_error("Must be root.");
7376 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7377 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7378 _cleanup_free_
char *m
= NULL
;
7381 log_error("Unable to perform operation without bus connection.");
7385 r
= sd_bus_open_system(&b
);
7387 return log_error_errno(r
, "Unable to open system bus: %m");
7389 m
= strv_join(arg_wall
, " ");
7393 r
= sd_bus_call_method(
7395 "org.freedesktop.login1",
7396 "/org/freedesktop/login1",
7397 "org.freedesktop.login1.Manager",
7406 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7407 bus_error_message(&error
, r
));
7408 sd_bus_error_free(&error
);
7411 r
= sd_bus_call_method(
7413 "org.freedesktop.login1",
7414 "/org/freedesktop/login1",
7415 "org.freedesktop.login1.Manager",
7420 arg_action
== ACTION_HALT
? "halt" :
7421 arg_action
== ACTION_POWEROFF
? "poweroff" :
7422 arg_action
== ACTION_KEXEC
? "kexec" :
7426 log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s",
7427 bus_error_message(&error
, r
));
7429 char date
[FORMAT_TIMESTAMP_MAX
];
7431 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7432 format_timestamp(date
, sizeof(date
), arg_when
));
7437 if (!arg_dry
&& !arg_force
)
7438 return start_with_fallback(bus
);
7441 if (sd_booted() > 0)
7442 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7444 r
= utmp_put_shutdown();
7446 log_warning_errno(r
, "Failed to write utmp record: %m");
7453 r
= halt_now(arg_action
);
7454 log_error_errno(r
, "Failed to reboot: %m");
7459 static int runlevel_main(void) {
7460 int r
, runlevel
, previous
;
7462 r
= utmp_get_runlevel(&runlevel
, &previous
);
7469 previous
<= 0 ? 'N' : previous
,
7470 runlevel
<= 0 ? 'N' : runlevel
);
7475 int main(int argc
, char*argv
[]) {
7476 _cleanup_bus_flush_close_unref_ sd_bus
*bus
= NULL
;
7479 setlocale(LC_ALL
, "");
7480 log_parse_environment();
7483 /* Explicitly not on_tty() to avoid setting cached value.
7484 * This becomes relevant for piping output which might be
7486 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7488 r
= parse_argv(argc
, argv
);
7492 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7493 * let's shortcut this */
7494 if (arg_action
== ACTION_RUNLEVEL
) {
7495 r
= runlevel_main();
7499 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7500 log_info("Running in chroot, ignoring request.");
7506 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
7509 sd_bus_set_allow_interactive_authorization(bus
, arg_ask_password
);
7511 /* systemctl_main() will print an error message for the bus
7512 * connection, but only if it needs to */
7514 switch (arg_action
) {
7516 case ACTION_SYSTEMCTL
:
7517 r
= systemctl_main(bus
, argc
, argv
, r
);
7521 case ACTION_POWEROFF
:
7527 case ACTION_RUNLEVEL2
:
7528 case ACTION_RUNLEVEL3
:
7529 case ACTION_RUNLEVEL4
:
7530 case ACTION_RUNLEVEL5
:
7532 case ACTION_EMERGENCY
:
7533 case ACTION_DEFAULT
:
7534 r
= start_with_fallback(bus
);
7539 r
= reload_with_fallback(bus
);
7542 case ACTION_CANCEL_SHUTDOWN
: {
7543 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7544 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7545 _cleanup_free_
char *m
= NULL
;
7548 log_error("Unable to perform operation without bus connection.");
7552 r
= sd_bus_open_system(&b
);
7554 return log_error_errno(r
, "Unable to open system bus: %m");
7557 m
= strv_join(arg_wall
, " ");
7564 r
= sd_bus_call_method(
7566 "org.freedesktop.login1",
7567 "/org/freedesktop/login1",
7568 "org.freedesktop.login1.Manager",
7577 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7578 bus_error_message(&error
, r
));
7579 sd_bus_error_free(&error
);
7582 r
= sd_bus_call_method(
7584 "org.freedesktop.login1",
7585 "/org/freedesktop/login1",
7586 "org.freedesktop.login1.Manager",
7587 "CancelScheduledShutdown",
7591 log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s",
7592 bus_error_message(&error
, r
));
7596 case ACTION_RUNLEVEL
:
7597 case _ACTION_INVALID
:
7599 assert_not_reached("Unknown action");
7604 ask_password_agent_close();
7605 polkit_agent_close();
7607 strv_free(arg_types
);
7608 strv_free(arg_states
);
7609 strv_free(arg_properties
);
7611 return r
< 0 ? EXIT_FAILURE
: r
;