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
,
3602 if (i
->need_daemon_reload
)
3603 warn_unit_file_changed(i
->id
);
3606 static void show_unit_help(UnitStatusInfo
*i
) {
3611 if (!i
->documentation
) {
3612 log_info("Documentation for %s not known.", i
->id
);
3616 STRV_FOREACH(p
, i
->documentation
)
3617 if (startswith(*p
, "man:"))
3618 show_man_page(*p
+ 4, false);
3620 log_info("Can't show: %s", *p
);
3623 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3630 switch (contents
[0]) {
3632 case SD_BUS_TYPE_STRING
: {
3635 r
= sd_bus_message_read(m
, "s", &s
);
3637 return bus_log_parse_error(r
);
3640 if (streq(name
, "Id"))
3642 else if (streq(name
, "LoadState"))
3644 else if (streq(name
, "ActiveState"))
3645 i
->active_state
= s
;
3646 else if (streq(name
, "SubState"))
3648 else if (streq(name
, "Description"))
3650 else if (streq(name
, "FragmentPath"))
3651 i
->fragment_path
= s
;
3652 else if (streq(name
, "SourcePath"))
3655 else if (streq(name
, "DefaultControlGroup")) {
3657 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3659 i
->control_group
= e
;
3662 else if (streq(name
, "ControlGroup"))
3663 i
->control_group
= s
;
3664 else if (streq(name
, "StatusText"))
3666 else if (streq(name
, "PIDFile"))
3668 else if (streq(name
, "SysFSPath"))
3670 else if (streq(name
, "Where"))
3672 else if (streq(name
, "What"))
3674 else if (streq(name
, "Following"))
3676 else if (streq(name
, "UnitFileState"))
3677 i
->unit_file_state
= s
;
3678 else if (streq(name
, "UnitFilePreset"))
3679 i
->unit_file_preset
= s
;
3680 else if (streq(name
, "Result"))
3687 case SD_BUS_TYPE_BOOLEAN
: {
3690 r
= sd_bus_message_read(m
, "b", &b
);
3692 return bus_log_parse_error(r
);
3694 if (streq(name
, "Accept"))
3696 else if (streq(name
, "NeedDaemonReload"))
3697 i
->need_daemon_reload
= b
;
3698 else if (streq(name
, "ConditionResult"))
3699 i
->condition_result
= b
;
3700 else if (streq(name
, "AssertResult"))
3701 i
->assert_result
= b
;
3706 case SD_BUS_TYPE_UINT32
: {
3709 r
= sd_bus_message_read(m
, "u", &u
);
3711 return bus_log_parse_error(r
);
3713 if (streq(name
, "MainPID")) {
3715 i
->main_pid
= (pid_t
) u
;
3718 } else if (streq(name
, "ControlPID"))
3719 i
->control_pid
= (pid_t
) u
;
3720 else if (streq(name
, "ExecMainPID")) {
3722 i
->main_pid
= (pid_t
) u
;
3723 } else if (streq(name
, "NAccepted"))
3725 else if (streq(name
, "NConnections"))
3726 i
->n_connections
= u
;
3731 case SD_BUS_TYPE_INT32
: {
3734 r
= sd_bus_message_read(m
, "i", &j
);
3736 return bus_log_parse_error(r
);
3738 if (streq(name
, "ExecMainCode"))
3739 i
->exit_code
= (int) j
;
3740 else if (streq(name
, "ExecMainStatus"))
3741 i
->exit_status
= (int) j
;
3742 else if (streq(name
, "StatusErrno"))
3743 i
->status_errno
= (int) j
;
3748 case SD_BUS_TYPE_UINT64
: {
3751 r
= sd_bus_message_read(m
, "t", &u
);
3753 return bus_log_parse_error(r
);
3755 if (streq(name
, "ExecMainStartTimestamp"))
3756 i
->start_timestamp
= (usec_t
) u
;
3757 else if (streq(name
, "ExecMainExitTimestamp"))
3758 i
->exit_timestamp
= (usec_t
) u
;
3759 else if (streq(name
, "ActiveEnterTimestamp"))
3760 i
->active_enter_timestamp
= (usec_t
) u
;
3761 else if (streq(name
, "InactiveEnterTimestamp"))
3762 i
->inactive_enter_timestamp
= (usec_t
) u
;
3763 else if (streq(name
, "InactiveExitTimestamp"))
3764 i
->inactive_exit_timestamp
= (usec_t
) u
;
3765 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3766 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3767 else if (streq(name
, "ActiveExitTimestamp"))
3768 i
->active_exit_timestamp
= (usec_t
) u
;
3769 else if (streq(name
, "ConditionTimestamp"))
3770 i
->condition_timestamp
= (usec_t
) u
;
3771 else if (streq(name
, "AssertTimestamp"))
3772 i
->assert_timestamp
= (usec_t
) u
;
3773 else if (streq(name
, "MemoryCurrent"))
3774 i
->memory_current
= u
;
3775 else if (streq(name
, "MemoryLimit"))
3776 i
->memory_limit
= u
;
3777 else if (streq(name
, "CPUUsageNSec"))
3778 i
->cpu_usage_nsec
= u
;
3783 case SD_BUS_TYPE_ARRAY
:
3785 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3786 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3788 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3790 return bus_log_parse_error(r
);
3792 info
= new0(ExecStatusInfo
, 1);
3796 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3798 info
->name
= strdup(name
);
3802 LIST_PREPEND(exec
, i
->exec
, info
);
3804 info
= new0(ExecStatusInfo
, 1);
3810 return bus_log_parse_error(r
);
3812 r
= sd_bus_message_exit_container(m
);
3814 return bus_log_parse_error(r
);
3818 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3819 const char *type
, *path
;
3821 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3823 return bus_log_parse_error(r
);
3825 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3827 r
= strv_extend(&i
->listen
, type
);
3831 r
= strv_extend(&i
->listen
, path
);
3836 return bus_log_parse_error(r
);
3838 r
= sd_bus_message_exit_container(m
);
3840 return bus_log_parse_error(r
);
3844 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3846 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3848 return bus_log_parse_error(r
);
3850 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3852 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3854 return bus_log_parse_error(r
);
3856 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3857 const char *cond
, *param
;
3858 int trigger
, negate
;
3861 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3863 return bus_log_parse_error(r
);
3865 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3866 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3867 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3868 i
->failed_condition
= cond
;
3869 i
->failed_condition_trigger
= trigger
;
3870 i
->failed_condition_negate
= negate
;
3871 i
->failed_condition_parameter
= param
;
3875 return bus_log_parse_error(r
);
3877 r
= sd_bus_message_exit_container(m
);
3879 return bus_log_parse_error(r
);
3881 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
3882 const char *cond
, *param
;
3883 int trigger
, negate
;
3886 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3888 return bus_log_parse_error(r
);
3890 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3891 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3892 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
3893 i
->failed_assert
= cond
;
3894 i
->failed_assert_trigger
= trigger
;
3895 i
->failed_assert_negate
= negate
;
3896 i
->failed_assert_parameter
= param
;
3900 return bus_log_parse_error(r
);
3902 r
= sd_bus_message_exit_container(m
);
3904 return bus_log_parse_error(r
);
3911 case SD_BUS_TYPE_STRUCT_BEGIN
:
3913 if (streq(name
, "LoadError")) {
3914 const char *n
, *message
;
3916 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3918 return bus_log_parse_error(r
);
3920 if (!isempty(message
))
3921 i
->load_error
= message
;
3934 r
= sd_bus_message_skip(m
, contents
);
3936 return bus_log_parse_error(r
);
3941 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
3947 /* This is a low-level property printer, see
3948 * print_status_info() for the nicer output */
3950 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
3951 /* skip what we didn't read */
3952 r
= sd_bus_message_skip(m
, contents
);
3956 switch (contents
[0]) {
3958 case SD_BUS_TYPE_STRUCT_BEGIN
:
3960 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
3963 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
3965 return bus_log_parse_error(r
);
3968 printf("%s=%"PRIu32
"\n", name
, u
);
3970 printf("%s=\n", name
);
3974 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
3977 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
3979 return bus_log_parse_error(r
);
3981 if (arg_all
|| !isempty(s
))
3982 printf("%s=%s\n", name
, s
);
3986 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
3987 const char *a
= NULL
, *b
= NULL
;
3989 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
3991 return bus_log_parse_error(r
);
3993 if (arg_all
|| !isempty(a
) || !isempty(b
))
3994 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
3997 } else if (streq_ptr(name
, "SystemCallFilter")) {
3998 _cleanup_strv_free_
char **l
= NULL
;
4001 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4003 return bus_log_parse_error(r
);
4005 r
= sd_bus_message_read(m
, "b", &whitelist
);
4007 return bus_log_parse_error(r
);
4009 r
= sd_bus_message_read_strv(m
, &l
);
4011 return bus_log_parse_error(r
);
4013 r
= sd_bus_message_exit_container(m
);
4015 return bus_log_parse_error(r
);
4017 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4021 fputs(name
, stdout
);
4027 STRV_FOREACH(i
, l
) {
4035 fputc('\n', stdout
);
4043 case SD_BUS_TYPE_ARRAY
:
4045 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4049 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4051 return bus_log_parse_error(r
);
4053 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4054 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4057 return bus_log_parse_error(r
);
4059 r
= sd_bus_message_exit_container(m
);
4061 return bus_log_parse_error(r
);
4065 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4066 const char *type
, *path
;
4068 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4070 return bus_log_parse_error(r
);
4072 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4073 printf("%s=%s\n", type
, path
);
4075 return bus_log_parse_error(r
);
4077 r
= sd_bus_message_exit_container(m
);
4079 return bus_log_parse_error(r
);
4083 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4084 const char *type
, *path
;
4086 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4088 return bus_log_parse_error(r
);
4090 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4091 printf("Listen%s=%s\n", type
, path
);
4093 return bus_log_parse_error(r
);
4095 r
= sd_bus_message_exit_container(m
);
4097 return bus_log_parse_error(r
);
4101 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4103 uint64_t value
, next_elapse
;
4105 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4107 return bus_log_parse_error(r
);
4109 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4110 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4112 printf("%s={ value=%s ; next_elapse=%s }\n",
4114 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4115 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4118 return bus_log_parse_error(r
);
4120 r
= sd_bus_message_exit_container(m
);
4122 return bus_log_parse_error(r
);
4126 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4127 ExecStatusInfo info
= {};
4129 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4131 return bus_log_parse_error(r
);
4133 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4134 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4135 _cleanup_free_
char *tt
;
4137 tt
= strv_join(info
.argv
, " ");
4139 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",
4143 yes_no(info
.ignore
),
4144 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4145 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4147 sigchld_code_to_string(info
.code
),
4149 info
.code
== CLD_EXITED
? "" : "/",
4150 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4153 strv_free(info
.argv
);
4157 r
= sd_bus_message_exit_container(m
);
4159 return bus_log_parse_error(r
);
4163 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4164 const char *path
, *rwm
;
4166 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4168 return bus_log_parse_error(r
);
4170 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4171 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4173 return bus_log_parse_error(r
);
4175 r
= sd_bus_message_exit_container(m
);
4177 return bus_log_parse_error(r
);
4181 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4185 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4187 return bus_log_parse_error(r
);
4189 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4190 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4192 return bus_log_parse_error(r
);
4194 r
= sd_bus_message_exit_container(m
);
4196 return bus_log_parse_error(r
);
4200 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4204 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4206 return bus_log_parse_error(r
);
4208 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4209 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4211 return bus_log_parse_error(r
);
4213 r
= sd_bus_message_exit_container(m
);
4215 return bus_log_parse_error(r
);
4223 r
= bus_print_property(name
, m
, arg_all
);
4225 return bus_log_parse_error(r
);
4228 r
= sd_bus_message_skip(m
, contents
);
4230 return bus_log_parse_error(r
);
4233 printf("%s=[unprintable]\n", name
);
4239 static int show_one(
4243 bool show_properties
,
4247 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4248 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4249 UnitStatusInfo info
= {
4250 .memory_current
= (uint64_t) -1,
4251 .memory_limit
= (uint64_t) -1,
4252 .cpu_usage_nsec
= (uint64_t) -1,
4260 log_debug("Showing one %s", path
);
4262 r
= sd_bus_call_method(
4264 "org.freedesktop.systemd1",
4266 "org.freedesktop.DBus.Properties",
4272 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4274 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4276 return bus_log_parse_error(r
);
4283 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4284 const char *name
, *contents
;
4286 r
= sd_bus_message_read(reply
, "s", &name
);
4288 return bus_log_parse_error(r
);
4290 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4292 return bus_log_parse_error(r
);
4294 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4296 return bus_log_parse_error(r
);
4298 if (show_properties
)
4299 r
= print_property(name
, reply
, contents
);
4301 r
= status_property(name
, reply
, &info
, contents
);
4305 r
= sd_bus_message_exit_container(reply
);
4307 return bus_log_parse_error(r
);
4309 r
= sd_bus_message_exit_container(reply
);
4311 return bus_log_parse_error(r
);
4314 return bus_log_parse_error(r
);
4316 r
= sd_bus_message_exit_container(reply
);
4318 return bus_log_parse_error(r
);
4322 if (!show_properties
) {
4323 if (streq(verb
, "help"))
4324 show_unit_help(&info
);
4326 print_status_info(&info
, ellipsized
);
4329 strv_free(info
.documentation
);
4330 strv_free(info
.dropin_paths
);
4331 strv_free(info
.listen
);
4333 if (!streq_ptr(info
.active_state
, "active") &&
4334 !streq_ptr(info
.active_state
, "reloading") &&
4335 streq(verb
, "status")) {
4336 /* According to LSB: "program not running" */
4337 /* 0: program is running or service is OK
4338 * 1: program is dead and /run PID file exists
4339 * 2: program is dead and /run/lock lock file exists
4340 * 3: program is not running
4341 * 4: program or service status is unknown
4343 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4349 while ((p
= info
.exec
)) {
4350 LIST_REMOVE(exec
, info
.exec
, p
);
4351 exec_status_info_free(p
);
4357 static int get_unit_dbus_path_by_pid(
4362 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4363 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4367 r
= sd_bus_call_method(
4369 "org.freedesktop.systemd1",
4370 "/org/freedesktop/systemd1",
4371 "org.freedesktop.systemd1.Manager",
4377 log_error("Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4381 r
= sd_bus_message_read(reply
, "o", &u
);
4383 return bus_log_parse_error(r
);
4393 static int show_all(
4396 bool show_properties
,
4400 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4401 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4406 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4410 pager_open_if_enabled();
4414 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4416 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4417 _cleanup_free_
char *p
= NULL
;
4419 p
= unit_dbus_path_from_name(u
->id
);
4423 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4426 else if (r
> 0 && ret
== 0)
4433 static int show_system_status(sd_bus
*bus
) {
4434 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4435 _cleanup_free_
char *hn
= NULL
;
4436 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4437 const char *on
, *off
;
4440 hn
= gethostname_malloc();
4444 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4446 return log_error_errno(r
, "Failed to read server status: %m");
4448 if (streq_ptr(mi
.state
, "degraded")) {
4449 on
= ansi_highlight_red();
4450 off
= ansi_highlight_off();
4451 } else if (!streq_ptr(mi
.state
, "running")) {
4452 on
= ansi_highlight_yellow();
4453 off
= ansi_highlight_off();
4457 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4459 printf(" State: %s%s%s\n",
4460 on
, strna(mi
.state
), off
);
4462 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4463 printf(" Failed: %u units\n", mi
.n_failed_units
);
4465 printf(" Since: %s; %s\n",
4466 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4467 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4469 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4470 if (arg_transport
== BUS_TRANSPORT_LOCAL
|| arg_transport
== BUS_TRANSPORT_MACHINE
) {
4471 static const char prefix
[] = " ";
4475 if (c
> sizeof(prefix
) - 1)
4476 c
-= sizeof(prefix
) - 1;
4480 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4486 static int show(sd_bus
*bus
, char **args
) {
4487 bool show_properties
, show_status
, new_line
= false;
4488 bool ellipsized
= false;
4494 show_properties
= streq(args
[0], "show");
4495 show_status
= streq(args
[0], "status");
4497 if (show_properties
)
4498 pager_open_if_enabled();
4501 /* Increase max number of open files to 16K if we can, we
4502 * might needs this when browsing journal files, which might
4503 * be split up into many files. */
4504 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4506 /* If no argument is specified inspect the manager itself */
4508 if (show_properties
&& strv_length(args
) <= 1)
4509 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4511 if (show_status
&& strv_length(args
) <= 1) {
4513 pager_open_if_enabled();
4514 show_system_status(bus
);
4518 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
4520 _cleanup_free_
char **patterns
= NULL
;
4523 STRV_FOREACH(name
, args
+ 1) {
4524 _cleanup_free_
char *unit
= NULL
;
4527 if (safe_atou32(*name
, &id
) < 0) {
4528 if (strv_push(&patterns
, *name
) < 0)
4532 } else if (show_properties
) {
4533 /* Interpret as job id */
4534 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4538 /* Interpret as PID */
4539 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4546 r
= show_one(args
[0], bus
, unit
, show_properties
,
4547 &new_line
, &ellipsized
);
4550 else if (r
> 0 && ret
== 0)
4554 if (!strv_isempty(patterns
)) {
4555 _cleanup_strv_free_
char **names
= NULL
;
4557 r
= expand_names(bus
, patterns
, NULL
, &names
);
4559 log_error_errno(r
, "Failed to expand names: %m");
4561 STRV_FOREACH(name
, names
) {
4562 _cleanup_free_
char *unit
;
4564 unit
= unit_dbus_path_from_name(*name
);
4568 r
= show_one(args
[0], bus
, unit
, show_properties
,
4569 &new_line
, &ellipsized
);
4572 else if (r
> 0 && ret
== 0)
4578 if (ellipsized
&& !arg_quiet
)
4579 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4584 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4588 assert(user_runtime
);
4591 if (arg_scope
== UNIT_FILE_USER
) {
4592 r
= user_config_home(user_home
);
4594 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4596 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4598 r
= user_runtime_dir(user_runtime
);
4600 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4602 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4605 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4607 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4612 static int cat_file(const char *filename
, bool newline
) {
4613 _cleanup_close_
int fd
;
4615 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4619 printf("%s%s# %s%s\n",
4620 newline
? "\n" : "",
4621 ansi_highlight_blue(),
4623 ansi_highlight_off());
4626 return copy_bytes(fd
, STDOUT_FILENO
, (off_t
) -1, false);
4629 static int cat(sd_bus
*bus
, char **args
) {
4630 _cleanup_free_
char *user_home
= NULL
;
4631 _cleanup_free_
char *user_runtime
= NULL
;
4632 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4633 _cleanup_strv_free_
char **names
= NULL
;
4635 bool first
= true, avoid_bus_cache
;
4640 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4641 log_error("Cannot remotely cat units");
4645 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4649 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4651 return log_error_errno(r
, "Failed to expand names: %m");
4653 avoid_bus_cache
= !bus
|| avoid_bus();
4655 pager_open_if_enabled();
4657 STRV_FOREACH(name
, names
) {
4658 _cleanup_free_
char *fragment_path
= NULL
;
4659 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4662 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &fragment_path
, &dropin_paths
);
4673 if (fragment_path
) {
4674 r
= cat_file(fragment_path
, false);
4676 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4679 STRV_FOREACH(path
, dropin_paths
) {
4680 r
= cat_file(*path
, path
== dropin_paths
);
4682 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4689 static int set_property(sd_bus
*bus
, char **args
) {
4690 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4691 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4692 _cleanup_free_
char *n
= NULL
;
4696 polkit_agent_open_if_enabled();
4698 r
= sd_bus_message_new_method_call(
4701 "org.freedesktop.systemd1",
4702 "/org/freedesktop/systemd1",
4703 "org.freedesktop.systemd1.Manager",
4704 "SetUnitProperties");
4706 return bus_log_create_error(r
);
4708 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &n
);
4710 return log_error_errno(r
, "Failed to mangle unit name: %m");
4712 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4714 return bus_log_create_error(r
);
4716 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4718 return bus_log_create_error(r
);
4720 STRV_FOREACH(i
, args
+ 2) {
4721 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4723 return bus_log_create_error(r
);
4725 r
= bus_append_unit_property_assignment(m
, *i
);
4729 r
= sd_bus_message_close_container(m
);
4731 return bus_log_create_error(r
);
4734 r
= sd_bus_message_close_container(m
);
4736 return bus_log_create_error(r
);
4738 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4740 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4747 static int snapshot(sd_bus
*bus
, char **args
) {
4748 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4749 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4750 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4754 polkit_agent_open_if_enabled();
4756 if (strv_length(args
) > 1) {
4757 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4759 return log_error_errno(r
, "Failed to generate unit name: %m");
4766 r
= sd_bus_call_method(
4768 "org.freedesktop.systemd1",
4769 "/org/freedesktop/systemd1",
4770 "org.freedesktop.systemd1.Manager",
4776 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
4780 r
= sd_bus_message_read(reply
, "o", &path
);
4782 return bus_log_parse_error(r
);
4784 r
= sd_bus_get_property_string(
4786 "org.freedesktop.systemd1",
4788 "org.freedesktop.systemd1.Unit",
4793 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4803 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4804 _cleanup_strv_free_
char **names
= NULL
;
4810 polkit_agent_open_if_enabled();
4812 r
= expand_names(bus
, args
+ 1, ".snapshot", &names
);
4814 log_error_errno(r
, "Failed to expand names: %m");
4816 STRV_FOREACH(name
, names
) {
4817 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4820 q
= sd_bus_call_method(
4822 "org.freedesktop.systemd1",
4823 "/org/freedesktop/systemd1",
4824 "org.freedesktop.systemd1.Manager",
4830 log_error("Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4839 static int daemon_reload(sd_bus
*bus
, char **args
) {
4840 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4844 polkit_agent_open_if_enabled();
4846 if (arg_action
== ACTION_RELOAD
)
4848 else if (arg_action
== ACTION_REEXEC
)
4849 method
= "Reexecute";
4851 assert(arg_action
== ACTION_SYSTEMCTL
);
4854 streq(args
[0], "clear-jobs") ||
4855 streq(args
[0], "cancel") ? "ClearJobs" :
4856 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4857 streq(args
[0], "reset-failed") ? "ResetFailed" :
4858 streq(args
[0], "halt") ? "Halt" :
4859 streq(args
[0], "poweroff") ? "PowerOff" :
4860 streq(args
[0], "reboot") ? "Reboot" :
4861 streq(args
[0], "kexec") ? "KExec" :
4862 streq(args
[0], "exit") ? "Exit" :
4863 /* "daemon-reload" */ "Reload";
4866 r
= sd_bus_call_method(
4868 "org.freedesktop.systemd1",
4869 "/org/freedesktop/systemd1",
4870 "org.freedesktop.systemd1.Manager",
4875 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4876 /* There's always a fallback possible for
4877 * legacy actions. */
4879 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4880 /* On reexecution, we expect a disconnect, not a
4884 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4886 return r
< 0 ? r
: 0;
4889 static int reset_failed(sd_bus
*bus
, char **args
) {
4890 _cleanup_strv_free_
char **names
= NULL
;
4894 if (strv_length(args
) <= 1)
4895 return daemon_reload(bus
, args
);
4897 polkit_agent_open_if_enabled();
4899 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4901 log_error_errno(r
, "Failed to expand names: %m");
4903 STRV_FOREACH(name
, names
) {
4904 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4906 q
= sd_bus_call_method(
4908 "org.freedesktop.systemd1",
4909 "/org/freedesktop/systemd1",
4910 "org.freedesktop.systemd1.Manager",
4916 log_error("Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4925 static int show_environment(sd_bus
*bus
, char **args
) {
4926 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4927 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4931 pager_open_if_enabled();
4933 r
= sd_bus_get_property(
4935 "org.freedesktop.systemd1",
4936 "/org/freedesktop/systemd1",
4937 "org.freedesktop.systemd1.Manager",
4943 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
4947 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
4949 return bus_log_parse_error(r
);
4951 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
4954 return bus_log_parse_error(r
);
4956 r
= sd_bus_message_exit_container(reply
);
4958 return bus_log_parse_error(r
);
4963 static int switch_root(sd_bus
*bus
, char **args
) {
4964 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4965 _cleanup_free_
char *cmdline_init
= NULL
;
4966 const char *root
, *init
;
4970 l
= strv_length(args
);
4971 if (l
< 2 || l
> 3) {
4972 log_error("Wrong number of arguments.");
4981 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
4982 "init", &cmdline_init
,
4985 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
4987 init
= cmdline_init
;
4994 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
4996 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
4997 root_init_path
= strjoina(root
, "/", init
);
4999 /* If the passed init is actually the same as the
5000 * systemd binary, then let's suppress it. */
5001 if (files_same(root_init_path
, root_systemd_path
) > 0)
5005 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5007 r
= sd_bus_call_method(
5009 "org.freedesktop.systemd1",
5010 "/org/freedesktop/systemd1",
5011 "org.freedesktop.systemd1.Manager",
5017 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
5024 static int set_environment(sd_bus
*bus
, char **args
) {
5025 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5026 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5033 polkit_agent_open_if_enabled();
5035 method
= streq(args
[0], "set-environment")
5037 : "UnsetEnvironment";
5039 r
= sd_bus_message_new_method_call(
5042 "org.freedesktop.systemd1",
5043 "/org/freedesktop/systemd1",
5044 "org.freedesktop.systemd1.Manager",
5047 return bus_log_create_error(r
);
5049 r
= sd_bus_message_append_strv(m
, args
+ 1);
5051 return bus_log_create_error(r
);
5053 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5055 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
5062 static int import_environment(sd_bus
*bus
, char **args
) {
5063 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5064 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5070 polkit_agent_open_if_enabled();
5072 r
= sd_bus_message_new_method_call(
5075 "org.freedesktop.systemd1",
5076 "/org/freedesktop/systemd1",
5077 "org.freedesktop.systemd1.Manager",
5080 return bus_log_create_error(r
);
5082 if (strv_isempty(args
+ 1))
5083 r
= sd_bus_message_append_strv(m
, environ
);
5087 r
= sd_bus_message_open_container(m
, 'a', "s");
5089 return bus_log_create_error(r
);
5091 STRV_FOREACH(a
, args
+ 1) {
5093 if (!env_name_is_valid(*a
)) {
5094 log_error("Not a valid environment variable name: %s", *a
);
5098 STRV_FOREACH(b
, environ
) {
5101 eq
= startswith(*b
, *a
);
5102 if (eq
&& *eq
== '=') {
5104 r
= sd_bus_message_append(m
, "s", *b
);
5106 return bus_log_create_error(r
);
5113 r
= sd_bus_message_close_container(m
);
5116 return bus_log_create_error(r
);
5118 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5120 log_error("Failed to import environment: %s", bus_error_message(&error
, r
));
5127 static int enable_sysv_units(const char *verb
, char **args
) {
5130 #if defined(HAVE_SYSV_COMPAT)
5132 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5134 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5137 if (!streq(verb
, "enable") &&
5138 !streq(verb
, "disable") &&
5139 !streq(verb
, "is-enabled"))
5142 /* Processes all SysV units, and reshuffles the array so that
5143 * afterwards only the native units remain */
5145 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5152 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5153 bool found_native
= false, found_sysv
;
5155 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5163 if (!endswith(name
, ".service"))
5166 if (path_is_absolute(name
))
5169 STRV_FOREACH(k
, paths
.unit_path
) {
5170 _cleanup_free_
char *path
= NULL
;
5172 path
= path_join(arg_root
, *k
, name
);
5176 found_native
= access(path
, F_OK
) >= 0;
5181 /* If we have both a native unit and a SysV script,
5182 * enable/disable them both (below); for is-enabled, prefer the
5184 if (found_native
&& streq(verb
, "is-enabled"))
5187 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5191 p
[strlen(p
) - strlen(".service")] = 0;
5192 found_sysv
= access(p
, F_OK
) >= 0;
5197 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5199 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5201 if (!isempty(arg_root
))
5202 argv
[c
++] = q
= strappend("--root=", arg_root
);
5205 argv
[c
++] = basename(p
);
5208 l
= strv_join((char**)argv
, " ");
5212 log_info("Executing %s", l
);
5216 return log_error_errno(errno
, "Failed to fork: %m");
5217 else if (pid
== 0) {
5220 (void) reset_all_signal_handlers();
5221 (void) reset_signal_mask();
5223 execv(argv
[0], (char**) argv
);
5224 log_error("Failed to execute %s: %m", argv
[0]);
5225 _exit(EXIT_FAILURE
);
5228 j
= wait_for_terminate(pid
, &status
);
5230 log_error_errno(r
, "Failed to wait for child: %m");
5234 if (status
.si_code
== CLD_EXITED
) {
5235 if (streq(verb
, "is-enabled")) {
5236 if (status
.si_status
== 0) {
5245 } else if (status
.si_status
!= 0)
5253 /* Remove this entry, so that we don't try enabling it as native unit */
5256 assert(args
[f
] == name
);
5257 strv_remove(args
, name
);
5264 static int mangle_names(char **original_names
, char ***mangled_names
) {
5265 char **i
, **l
, **name
;
5268 l
= i
= new(char*, strv_length(original_names
) + 1);
5272 STRV_FOREACH(name
, original_names
) {
5274 /* When enabling units qualified path names are OK,
5275 * too, hence allow them explicitly. */
5277 if (is_path(*name
)) {
5284 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5287 return log_error_errno(r
, "Failed to mangle unit name: %m");
5300 static int enable_unit(sd_bus
*bus
, char **args
) {
5301 _cleanup_strv_free_
char **names
= NULL
;
5302 const char *verb
= args
[0];
5303 UnitFileChange
*changes
= NULL
;
5304 unsigned n_changes
= 0;
5305 int carries_install_info
= -1;
5311 r
= mangle_names(args
+1, &names
);
5315 r
= enable_sysv_units(verb
, names
);
5319 /* If the operation was fully executed by the SysV compat,
5320 * let's finish early */
5321 if (strv_isempty(names
))
5324 if (!bus
|| avoid_bus()) {
5325 if (streq(verb
, "enable")) {
5326 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5327 carries_install_info
= r
;
5328 } else if (streq(verb
, "disable"))
5329 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5330 else if (streq(verb
, "reenable")) {
5331 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5332 carries_install_info
= r
;
5333 } else if (streq(verb
, "link"))
5334 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5335 else if (streq(verb
, "preset")) {
5336 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5337 carries_install_info
= r
;
5338 } else if (streq(verb
, "mask"))
5339 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5340 else if (streq(verb
, "unmask"))
5341 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5343 assert_not_reached("Unknown verb");
5346 log_error_errno(r
, "Operation failed: %m");
5351 dump_unit_file_changes(changes
, n_changes
);
5355 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5356 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5357 int expect_carries_install_info
= false;
5358 bool send_force
= true, send_preset_mode
= false;
5361 polkit_agent_open_if_enabled();
5363 if (streq(verb
, "enable")) {
5364 method
= "EnableUnitFiles";
5365 expect_carries_install_info
= true;
5366 } else if (streq(verb
, "disable")) {
5367 method
= "DisableUnitFiles";
5369 } else if (streq(verb
, "reenable")) {
5370 method
= "ReenableUnitFiles";
5371 expect_carries_install_info
= true;
5372 } else if (streq(verb
, "link"))
5373 method
= "LinkUnitFiles";
5374 else if (streq(verb
, "preset")) {
5376 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5377 method
= "PresetUnitFilesWithMode";
5378 send_preset_mode
= true;
5380 method
= "PresetUnitFiles";
5382 expect_carries_install_info
= true;
5383 } else if (streq(verb
, "mask"))
5384 method
= "MaskUnitFiles";
5385 else if (streq(verb
, "unmask")) {
5386 method
= "UnmaskUnitFiles";
5389 assert_not_reached("Unknown verb");
5391 r
= sd_bus_message_new_method_call(
5394 "org.freedesktop.systemd1",
5395 "/org/freedesktop/systemd1",
5396 "org.freedesktop.systemd1.Manager",
5399 return bus_log_create_error(r
);
5401 r
= sd_bus_message_append_strv(m
, names
);
5403 return bus_log_create_error(r
);
5405 if (send_preset_mode
) {
5406 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5408 return bus_log_create_error(r
);
5411 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5413 return bus_log_create_error(r
);
5416 r
= sd_bus_message_append(m
, "b", arg_force
);
5418 return bus_log_create_error(r
);
5421 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5423 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5427 if (expect_carries_install_info
) {
5428 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5430 return bus_log_parse_error(r
);
5433 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5437 /* Try to reload if enabled */
5439 r
= daemon_reload(bus
, args
);
5444 if (carries_install_info
== 0)
5445 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5446 "using systemctl.\n"
5447 "Possible reasons for having this kind of units are:\n"
5448 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5449 " .wants/ or .requires/ directory.\n"
5450 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5451 " a requirement dependency on it.\n"
5452 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5453 " D-Bus, udev, scripted systemctl call, ...).\n");
5455 if (arg_now
&& n_changes
> 0 && STR_IN_SET(args
[0], "enable", "disable", "mask")) {
5456 char *new_args
[n_changes
+ 2];
5459 new_args
[0] = streq(args
[0], "enable") ? (char *)"start" : (char *)"stop";
5460 for (i
= 0; i
< n_changes
; i
++)
5461 new_args
[i
+ 1] = basename(changes
[i
].path
);
5462 new_args
[i
+ 1] = NULL
;
5464 r
= start_unit(bus
, new_args
);
5468 unit_file_changes_free(changes
, n_changes
);
5473 static int add_dependency(sd_bus
*bus
, char **args
) {
5474 _cleanup_strv_free_
char **names
= NULL
;
5475 _cleanup_free_
char *target
= NULL
;
5476 const char *verb
= args
[0];
5483 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5485 return log_error_errno(r
, "Failed to mangle unit name: %m");
5487 r
= mangle_names(args
+2, &names
);
5491 if (streq(verb
, "add-wants"))
5493 else if (streq(verb
, "add-requires"))
5494 dep
= UNIT_REQUIRES
;
5496 assert_not_reached("Unknown verb");
5498 if (!bus
|| avoid_bus()) {
5499 UnitFileChange
*changes
= NULL
;
5500 unsigned n_changes
= 0;
5502 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5505 return log_error_errno(r
, "Can't add dependency: %m");
5508 dump_unit_file_changes(changes
, n_changes
);
5510 unit_file_changes_free(changes
, n_changes
);
5513 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5514 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5516 polkit_agent_open_if_enabled();
5518 r
= sd_bus_message_new_method_call(
5521 "org.freedesktop.systemd1",
5522 "/org/freedesktop/systemd1",
5523 "org.freedesktop.systemd1.Manager",
5524 "AddDependencyUnitFiles");
5526 return bus_log_create_error(r
);
5528 r
= sd_bus_message_append_strv(m
, names
);
5530 return bus_log_create_error(r
);
5532 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5534 return bus_log_create_error(r
);
5536 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5538 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5542 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5547 r
= daemon_reload(bus
, args
);
5555 static int preset_all(sd_bus
*bus
, char **args
) {
5556 UnitFileChange
*changes
= NULL
;
5557 unsigned n_changes
= 0;
5560 if (!bus
|| avoid_bus()) {
5562 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5564 log_error_errno(r
, "Operation failed: %m");
5569 dump_unit_file_changes(changes
, n_changes
);
5574 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5575 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5577 polkit_agent_open_if_enabled();
5579 r
= sd_bus_call_method(
5581 "org.freedesktop.systemd1",
5582 "/org/freedesktop/systemd1",
5583 "org.freedesktop.systemd1.Manager",
5584 "PresetAllUnitFiles",
5588 unit_file_preset_mode_to_string(arg_preset_mode
),
5592 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5596 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5601 r
= daemon_reload(bus
, args
);
5607 unit_file_changes_free(changes
, n_changes
);
5612 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
5614 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5615 _cleanup_strv_free_
char **names
= NULL
;
5620 r
= mangle_names(args
+1, &names
);
5624 r
= enable_sysv_units(args
[0], names
);
5630 if (!bus
|| avoid_bus()) {
5632 STRV_FOREACH(name
, names
) {
5633 UnitFileState state
;
5635 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5637 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5639 if (state
== UNIT_FILE_ENABLED
||
5640 state
== UNIT_FILE_ENABLED_RUNTIME
||
5641 state
== UNIT_FILE_STATIC
||
5642 state
== UNIT_FILE_INDIRECT
)
5646 puts(unit_file_state_to_string(state
));
5650 STRV_FOREACH(name
, names
) {
5651 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5654 r
= sd_bus_call_method(
5656 "org.freedesktop.systemd1",
5657 "/org/freedesktop/systemd1",
5658 "org.freedesktop.systemd1.Manager",
5664 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5668 r
= sd_bus_message_read(reply
, "s", &s
);
5670 return bus_log_parse_error(r
);
5672 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5683 static int is_system_running(sd_bus
*bus
, char **args
) {
5684 _cleanup_free_
char *state
= NULL
;
5687 r
= sd_bus_get_property_string(
5689 "org.freedesktop.systemd1",
5690 "/org/freedesktop/systemd1",
5691 "org.freedesktop.systemd1.Manager",
5704 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5707 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5712 assert(original_path
);
5715 r
= tempfn_random(new_path
, NULL
, &t
);
5717 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5719 r
= mkdir_parents(new_path
, 0755);
5721 log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5726 r
= copy_file(original_path
, t
, 0, 0644, 0);
5730 log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5735 log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5745 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5746 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5748 switch (arg_scope
) {
5749 case UNIT_FILE_SYSTEM
:
5750 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5752 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5754 case UNIT_FILE_GLOBAL
:
5755 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5757 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5759 case UNIT_FILE_USER
:
5761 assert(user_runtime
);
5763 path
= path_join(arg_root
, user_home
, name
);
5765 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5768 run
= path_join(arg_root
, user_runtime
, name
);
5772 assert_not_reached("Invalid scope");
5774 if (!path
|| (arg_runtime
&& !run
))
5778 if (access(path
, F_OK
) >= 0)
5779 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5781 if (path2
&& access(path2
, F_OK
) >= 0)
5782 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5794 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
) {
5795 char *tmp_new_path
, *ending
;
5800 assert(ret_new_path
);
5801 assert(ret_tmp_path
);
5803 ending
= strjoina(unit_name
, ".d/override.conf");
5804 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5808 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5814 *ret_new_path
= tmp_new_path
;
5815 *ret_tmp_path
= tmp_tmp_path
;
5820 static int unit_file_create_copy(
5821 const char *unit_name
,
5822 const char *fragment_path
,
5823 const char *user_home
,
5824 const char *user_runtime
,
5825 char **ret_new_path
,
5826 char **ret_tmp_path
) {
5832 assert(fragment_path
);
5834 assert(ret_new_path
);
5835 assert(ret_tmp_path
);
5837 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5841 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5844 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5849 if (response
!= 'y') {
5850 log_warning("%s ignored", unit_name
);
5856 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5858 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5863 *ret_new_path
= tmp_new_path
;
5864 *ret_tmp_path
= tmp_tmp_path
;
5869 static int run_editor(char **paths
) {
5877 log_error_errno(errno
, "Failed to fork: %m");
5883 char *editor
, **editor_args
= NULL
;
5884 char **tmp_path
, **original_path
, *p
;
5885 unsigned n_editor_args
= 0, i
= 1;
5888 (void) reset_all_signal_handlers();
5889 (void) reset_signal_mask();
5891 argc
= strv_length(paths
)/2 + 1;
5893 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5894 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5895 * we try to execute well known editors
5897 editor
= getenv("SYSTEMD_EDITOR");
5899 editor
= getenv("EDITOR");
5901 editor
= getenv("VISUAL");
5903 if (!isempty(editor
)) {
5904 editor_args
= strv_split(editor
, WHITESPACE
);
5907 _exit(EXIT_FAILURE
);
5909 n_editor_args
= strv_length(editor_args
);
5910 argc
+= n_editor_args
- 1;
5912 args
= newa(const char*, argc
+ 1);
5914 if (n_editor_args
> 0) {
5915 args
[0] = editor_args
[0];
5916 for (; i
< n_editor_args
; i
++)
5917 args
[i
] = editor_args
[i
];
5920 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
5921 args
[i
] = *tmp_path
;
5926 if (n_editor_args
> 0)
5927 execvp(args
[0], (char* const*) args
);
5929 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
5931 execvp(p
, (char* const*) args
);
5932 /* We do not fail if the editor doesn't exist
5933 * because we want to try each one of them before
5936 if (errno
!= ENOENT
) {
5937 log_error("Failed to execute %s: %m", editor
);
5938 _exit(EXIT_FAILURE
);
5942 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
5943 _exit(EXIT_FAILURE
);
5946 r
= wait_for_terminate_and_warn("editor", pid
, true);
5948 return log_error_errno(r
, "Failed to wait for child: %m");
5953 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
5954 _cleanup_free_
char *user_home
= NULL
;
5955 _cleanup_free_
char *user_runtime
= NULL
;
5956 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
5957 bool avoid_bus_cache
;
5964 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
5968 avoid_bus_cache
= !bus
|| avoid_bus();
5970 STRV_FOREACH(name
, names
) {
5971 _cleanup_free_
char *path
= NULL
;
5972 char *new_path
, *tmp_path
;
5974 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &path
, NULL
);
5980 // FIXME: support units with path==NULL (no FragmentPath)
5981 log_error("No fragment exists for %s.", *name
);
5986 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
5988 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
5992 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6000 static int edit(sd_bus
*bus
, char **args
) {
6001 _cleanup_strv_free_
char **names
= NULL
;
6002 _cleanup_strv_free_
char **paths
= NULL
;
6003 char **original
, **tmp
;
6009 log_error("Cannot edit units if not on a tty");
6013 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6014 log_error("Cannot remotely edit units");
6018 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
6020 return log_error_errno(r
, "Failed to expand names: %m");
6022 r
= find_paths_to_edit(bus
, names
, &paths
);
6026 if (strv_isempty(paths
))
6029 r
= run_editor(paths
);
6033 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6034 /* If the temporary file is empty we ignore it.
6035 * It's useful if the user wants to cancel its modification
6037 if (null_or_empty_path(*tmp
)) {
6038 log_warning("Editing \"%s\" canceled: temporary file is empty", *original
);
6041 r
= rename(*tmp
, *original
);
6043 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6048 if (!arg_no_reload
&& bus
&& !avoid_bus())
6049 r
= daemon_reload(bus
, args
);
6052 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6053 unlink_noerrno(*tmp
);
6058 static void systemctl_help(void) {
6060 pager_open_if_enabled();
6062 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6063 "Query or send control commands to the systemd manager.\n\n"
6064 " -h --help Show this help\n"
6065 " --version Show package version\n"
6066 " --system Connect to system manager\n"
6067 " --user Connect to user service manager\n"
6068 " -H --host=[USER@]HOST\n"
6069 " Operate on remote host\n"
6070 " -M --machine=CONTAINER\n"
6071 " Operate on local container\n"
6072 " -t --type=TYPE List units of a particular type\n"
6073 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6074 " -p --property=NAME Show only properties by this name\n"
6075 " -a --all Show all loaded units/properties, including dead/empty\n"
6076 " ones. To list all units installed on the system, use\n"
6077 " the 'list-unit-files' command instead.\n"
6078 " -l --full Don't ellipsize unit names on output\n"
6079 " -r --recursive Show unit list of host and local containers\n"
6080 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6081 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6082 " queueing a new job\n"
6083 " --show-types When showing sockets, explicitly show their type\n"
6084 " -i --ignore-inhibitors\n"
6085 " When shutting down or sleeping, ignore inhibitors\n"
6086 " --kill-who=WHO Who to send signal to\n"
6087 " -s --signal=SIGNAL Which signal to send\n"
6088 " --now Start or stop unit in addition to enabling or disabling it\n"
6089 " -q --quiet Suppress output\n"
6090 " --no-block Do not wait until operation finished\n"
6091 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6092 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6093 " --no-legend Do not print a legend (column headers and hints)\n"
6094 " --no-pager Do not pipe output into a pager\n"
6095 " --no-ask-password\n"
6096 " Do not ask for system passwords\n"
6097 " --global Enable/disable unit files globally\n"
6098 " --runtime Enable unit files only temporarily until next reboot\n"
6099 " -f --force When enabling unit files, override existing symlinks\n"
6100 " When shutting down, execute action immediately\n"
6101 " --preset-mode= Apply only enable, only disable, or all presets\n"
6102 " --root=PATH Enable unit files in the specified root directory\n"
6103 " -n --lines=INTEGER Number of journal entries to show\n"
6104 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6105 " short-precise, short-monotonic, verbose,\n"
6106 " export, json, json-pretty, json-sse, cat)\n"
6107 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6108 " --plain Print unit dependencies as a list instead of a tree\n\n"
6110 " list-units [PATTERN...] List loaded units\n"
6111 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6112 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6113 " start NAME... Start (activate) one or more units\n"
6114 " stop NAME... Stop (deactivate) one or more units\n"
6115 " reload NAME... Reload one or more units\n"
6116 " restart NAME... Start or restart one or more units\n"
6117 " try-restart NAME... Restart one or more units if active\n"
6118 " reload-or-restart NAME... Reload one or more units if possible,\n"
6119 " otherwise start or restart\n"
6120 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6121 " otherwise restart if active\n"
6122 " isolate NAME Start one unit and stop all others\n"
6123 " kill NAME... Send signal to processes of a unit\n"
6124 " is-active PATTERN... Check whether units are active\n"
6125 " is-failed PATTERN... Check whether units are failed\n"
6126 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6127 " show [PATTERN...|JOB...] Show properties of one or more\n"
6128 " units/jobs or the manager\n"
6129 " cat PATTERN... Show files and drop-ins of one or more units\n"
6130 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6131 " help PATTERN...|PID... Show manual for one or more units\n"
6132 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6134 " list-dependencies [NAME] Recursively show units which are required\n"
6135 " or wanted by this unit or by which this\n"
6136 " unit is required or wanted\n\n"
6137 "Unit File Commands:\n"
6138 " list-unit-files [PATTERN...] List installed unit files\n"
6139 " enable NAME... Enable one or more unit files\n"
6140 " disable NAME... Disable one or more unit files\n"
6141 " reenable NAME... Reenable one or more unit files\n"
6142 " preset NAME... Enable/disable one or more unit files\n"
6143 " based on preset configuration\n"
6144 " preset-all Enable/disable all unit files based on\n"
6145 " preset configuration\n"
6146 " is-enabled NAME... Check whether unit files are enabled\n"
6147 " mask NAME... Mask one or more units\n"
6148 " unmask NAME... Unmask one or more units\n"
6149 " link PATH... Link one or more units files into\n"
6150 " the search path\n"
6151 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6152 " on specified one or more units\n"
6153 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6154 " on specified one or more units\n"
6155 " edit NAME... Edit one or more unit files\n"
6156 " get-default Get the name of the default target\n"
6157 " set-default NAME Set the default target\n\n"
6158 "Machine Commands:\n"
6159 " list-machines [PATTERN...] List local containers and host\n\n"
6161 " list-jobs [PATTERN...] List jobs\n"
6162 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6163 "Snapshot Commands:\n"
6164 " snapshot [NAME] Create a snapshot\n"
6165 " delete NAME... Remove one or more snapshots\n\n"
6166 "Environment Commands:\n"
6167 " show-environment Dump environment\n"
6168 " set-environment NAME=VALUE... Set one or more environment variables\n"
6169 " unset-environment NAME... Unset one or more environment variables\n"
6170 " import-environment [NAME...] Import all or some environment variables\n\n"
6171 "Manager Lifecycle Commands:\n"
6172 " daemon-reload Reload systemd manager configuration\n"
6173 " daemon-reexec Reexecute systemd manager\n\n"
6174 "System Commands:\n"
6175 " is-system-running Check whether system is fully running\n"
6176 " default Enter system default mode\n"
6177 " rescue Enter system rescue mode\n"
6178 " emergency Enter system emergency mode\n"
6179 " halt Shut down and halt the system\n"
6180 " poweroff Shut down and power-off the system\n"
6181 " reboot [ARG] Shut down and reboot the system\n"
6182 " kexec Shut down and reboot the system with kexec\n"
6183 " exit Request user instance exit\n"
6184 " switch-root ROOT [INIT] Change to a different root file system\n"
6185 " suspend Suspend the system\n"
6186 " hibernate Hibernate the system\n"
6187 " hybrid-sleep Hibernate and suspend the system\n",
6188 program_invocation_short_name
);
6191 static void halt_help(void) {
6192 printf("%s [OPTIONS...]%s\n\n"
6193 "%s the system.\n\n"
6194 " --help Show this help\n"
6195 " --halt Halt the machine\n"
6196 " -p --poweroff Switch off the machine\n"
6197 " --reboot Reboot the machine\n"
6198 " -f --force Force immediate halt/power-off/reboot\n"
6199 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6200 " -d --no-wtmp Don't write wtmp record\n"
6201 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6202 program_invocation_short_name
,
6203 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6204 arg_action
== ACTION_REBOOT
? "Reboot" :
6205 arg_action
== ACTION_POWEROFF
? "Power off" :
6209 static void shutdown_help(void) {
6210 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6211 "Shut down the system.\n\n"
6212 " --help Show this help\n"
6213 " -H --halt Halt the machine\n"
6214 " -P --poweroff Power-off the machine\n"
6215 " -r --reboot Reboot the machine\n"
6216 " -h Equivalent to --poweroff, overridden by --halt\n"
6217 " -k Don't halt/power-off/reboot, just send warnings\n"
6218 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6219 " -c Cancel a pending shutdown\n",
6220 program_invocation_short_name
);
6223 static void telinit_help(void) {
6224 printf("%s [OPTIONS...] {COMMAND}\n\n"
6225 "Send control commands to the init daemon.\n\n"
6226 " --help Show this help\n"
6227 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6229 " 0 Power-off the machine\n"
6230 " 6 Reboot the machine\n"
6231 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6232 " 1, s, S Enter rescue mode\n"
6233 " q, Q Reload init daemon configuration\n"
6234 " u, U Reexecute init daemon\n",
6235 program_invocation_short_name
);
6238 static void runlevel_help(void) {
6239 printf("%s [OPTIONS...]\n\n"
6240 "Prints the previous and current runlevel of the init system.\n\n"
6241 " --help Show this help\n",
6242 program_invocation_short_name
);
6245 static void help_types(void) {
6250 puts("Available unit types:");
6251 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
6252 t
= unit_type_to_string(i
);
6258 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6267 ARG_IGNORE_DEPENDENCIES
,
6279 ARG_NO_ASK_PASSWORD
,
6292 static const struct option options
[] = {
6293 { "help", no_argument
, NULL
, 'h' },
6294 { "version", no_argument
, NULL
, ARG_VERSION
},
6295 { "type", required_argument
, NULL
, 't' },
6296 { "property", required_argument
, NULL
, 'p' },
6297 { "all", no_argument
, NULL
, 'a' },
6298 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6299 { "after", no_argument
, NULL
, ARG_AFTER
},
6300 { "before", no_argument
, NULL
, ARG_BEFORE
},
6301 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6302 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6303 { "full", no_argument
, NULL
, 'l' },
6304 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6305 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6306 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6307 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6308 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6309 { "user", no_argument
, NULL
, ARG_USER
},
6310 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6311 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6312 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6313 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6314 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6315 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6316 { "quiet", no_argument
, NULL
, 'q' },
6317 { "root", required_argument
, NULL
, ARG_ROOT
},
6318 { "force", no_argument
, NULL
, ARG_FORCE
},
6319 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6320 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6321 { "signal", required_argument
, NULL
, 's' },
6322 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6323 { "host", required_argument
, NULL
, 'H' },
6324 { "machine", required_argument
, NULL
, 'M' },
6325 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6326 { "lines", required_argument
, NULL
, 'n' },
6327 { "output", required_argument
, NULL
, 'o' },
6328 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6329 { "state", required_argument
, NULL
, ARG_STATE
},
6330 { "recursive", no_argument
, NULL
, 'r' },
6331 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6332 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6333 { "now", no_argument
, NULL
, ARG_NOW
},
6334 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6343 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6352 puts(PACKAGE_STRING
);
6353 puts(SYSTEMD_FEATURES
);
6357 const char *word
, *state
;
6360 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6361 _cleanup_free_
char *type
;
6363 type
= strndup(word
, size
);
6367 if (streq(type
, "help")) {
6372 if (unit_type_from_string(type
) >= 0) {
6373 if (strv_push(&arg_types
, type
))
6379 /* It's much nicer to use --state= for
6380 * load states, but let's support this
6381 * in --types= too for compatibility
6382 * with old versions */
6383 if (unit_load_state_from_string(optarg
) >= 0) {
6384 if (strv_push(&arg_states
, type
) < 0)
6390 log_error("Unknown unit type or load state '%s'.", type
);
6391 log_info("Use -t help to see a list of allowed values.");
6399 /* Make sure that if the empty property list
6400 was specified, we won't show any properties. */
6401 if (isempty(optarg
) && !arg_properties
) {
6402 arg_properties
= new0(char*, 1);
6403 if (!arg_properties
)
6406 const char *word
, *state
;
6409 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6412 prop
= strndup(word
, size
);
6416 if (strv_consume(&arg_properties
, prop
) < 0)
6421 /* If the user asked for a particular
6422 * property, show it to him, even if it is
6434 arg_dependency
= DEPENDENCY_REVERSE
;
6438 arg_dependency
= DEPENDENCY_AFTER
;
6442 arg_dependency
= DEPENDENCY_BEFORE
;
6445 case ARG_SHOW_TYPES
:
6446 arg_show_types
= true;
6450 arg_job_mode
= optarg
;
6454 arg_job_mode
= "fail";
6457 case ARG_IRREVERSIBLE
:
6458 arg_job_mode
= "replace-irreversibly";
6461 case ARG_IGNORE_DEPENDENCIES
:
6462 arg_job_mode
= "ignore-dependencies";
6466 arg_scope
= UNIT_FILE_USER
;
6470 arg_scope
= UNIT_FILE_SYSTEM
;
6474 arg_scope
= UNIT_FILE_GLOBAL
;
6478 arg_no_block
= true;
6482 arg_no_legend
= true;
6486 arg_no_pager
= true;
6502 if (strv_extend(&arg_states
, "failed") < 0)
6520 arg_no_reload
= true;
6524 arg_kill_who
= optarg
;
6528 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
6529 log_error("Failed to parse signal string %s.", optarg
);
6534 case ARG_NO_ASK_PASSWORD
:
6535 arg_ask_password
= false;
6539 arg_transport
= BUS_TRANSPORT_REMOTE
;
6544 arg_transport
= BUS_TRANSPORT_MACHINE
;
6553 if (safe_atou(optarg
, &arg_lines
) < 0) {
6554 log_error("Failed to parse lines '%s'", optarg
);
6560 arg_output
= output_mode_from_string(optarg
);
6561 if (arg_output
< 0) {
6562 log_error("Unknown output '%s'.", optarg
);
6568 arg_ignore_inhibitors
= true;
6575 case ARG_FIRMWARE_SETUP
:
6576 arg_firmware_setup
= true;
6580 const char *word
, *state
;
6583 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6586 s
= strndup(word
, size
);
6590 if (strv_consume(&arg_states
, s
) < 0)
6597 if (geteuid() != 0) {
6598 log_error("--recursive requires root privileges.");
6602 arg_recursive
= true;
6605 case ARG_PRESET_MODE
:
6607 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6608 if (arg_preset_mode
< 0) {
6609 log_error("Failed to parse preset mode: %s.", optarg
);
6620 if (strv_extend(&arg_wall
, optarg
) < 0)
6628 assert_not_reached("Unhandled option");
6631 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6632 log_error("Cannot access user instance remotely.");
6639 static int halt_parse_argv(int argc
, char *argv
[]) {
6648 static const struct option options
[] = {
6649 { "help", no_argument
, NULL
, ARG_HELP
},
6650 { "halt", no_argument
, NULL
, ARG_HALT
},
6651 { "poweroff", no_argument
, NULL
, 'p' },
6652 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6653 { "force", no_argument
, NULL
, 'f' },
6654 { "wtmp-only", no_argument
, NULL
, 'w' },
6655 { "no-wtmp", no_argument
, NULL
, 'd' },
6656 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6665 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6666 if (runlevel
== '0' || runlevel
== '6')
6669 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6677 arg_action
= ACTION_HALT
;
6681 if (arg_action
!= ACTION_REBOOT
)
6682 arg_action
= ACTION_POWEROFF
;
6686 arg_action
= ACTION_REBOOT
;
6708 /* Compatibility nops */
6715 assert_not_reached("Unhandled option");
6718 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6719 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6722 } else if (optind
< argc
) {
6723 log_error("Too many arguments.");
6730 static int parse_time_spec(const char *t
, usec_t
*_u
) {
6734 if (streq(t
, "now"))
6736 else if (!strchr(t
, ':')) {
6739 if (safe_atou64(t
, &u
) < 0)
6742 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6751 hour
= strtol(t
, &e
, 10);
6752 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6755 minute
= strtol(e
+1, &e
, 10);
6756 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6759 n
= now(CLOCK_REALTIME
);
6760 s
= (time_t) (n
/ USEC_PER_SEC
);
6762 assert_se(localtime_r(&s
, &tm
));
6764 tm
.tm_hour
= (int) hour
;
6765 tm
.tm_min
= (int) minute
;
6768 assert_se(s
= mktime(&tm
));
6770 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6773 *_u
+= USEC_PER_DAY
;
6779 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6786 static const struct option options
[] = {
6787 { "help", no_argument
, NULL
, ARG_HELP
},
6788 { "halt", no_argument
, NULL
, 'H' },
6789 { "poweroff", no_argument
, NULL
, 'P' },
6790 { "reboot", no_argument
, NULL
, 'r' },
6791 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6792 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6801 while ((c
= getopt_long(argc
, argv
, "HPrhkKt:afFc", options
, NULL
)) >= 0)
6809 arg_action
= ACTION_HALT
;
6813 arg_action
= ACTION_POWEROFF
;
6818 arg_action
= ACTION_KEXEC
;
6820 arg_action
= ACTION_REBOOT
;
6824 arg_action
= ACTION_KEXEC
;
6828 if (arg_action
!= ACTION_HALT
)
6829 arg_action
= ACTION_POWEROFF
;
6844 /* Compatibility nops */
6848 arg_action
= ACTION_CANCEL_SHUTDOWN
;
6855 assert_not_reached("Unhandled option");
6858 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
6859 r
= parse_time_spec(argv
[optind
], &arg_when
);
6861 log_error("Failed to parse time specification: %s", argv
[optind
]);
6865 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
6867 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
6868 /* No time argument for shutdown cancel */
6869 arg_wall
= argv
+ optind
;
6870 else if (argc
> optind
+ 1)
6871 /* We skip the time argument */
6872 arg_wall
= argv
+ optind
+ 1;
6879 static int telinit_parse_argv(int argc
, char *argv
[]) {
6886 static const struct option options
[] = {
6887 { "help", no_argument
, NULL
, ARG_HELP
},
6888 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6892 static const struct {
6896 { '0', ACTION_POWEROFF
},
6897 { '6', ACTION_REBOOT
},
6898 { '1', ACTION_RESCUE
},
6899 { '2', ACTION_RUNLEVEL2
},
6900 { '3', ACTION_RUNLEVEL3
},
6901 { '4', ACTION_RUNLEVEL4
},
6902 { '5', ACTION_RUNLEVEL5
},
6903 { 's', ACTION_RESCUE
},
6904 { 'S', ACTION_RESCUE
},
6905 { 'q', ACTION_RELOAD
},
6906 { 'Q', ACTION_RELOAD
},
6907 { 'u', ACTION_REEXEC
},
6908 { 'U', ACTION_REEXEC
}
6917 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
6932 assert_not_reached("Unhandled option");
6935 if (optind
>= argc
) {
6936 log_error("%s: required argument missing.",
6937 program_invocation_short_name
);
6941 if (optind
+ 1 < argc
) {
6942 log_error("Too many arguments.");
6946 if (strlen(argv
[optind
]) != 1) {
6947 log_error("Expected single character argument.");
6951 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
6952 if (table
[i
].from
== argv
[optind
][0])
6955 if (i
>= ELEMENTSOF(table
)) {
6956 log_error("Unknown command '%s'.", argv
[optind
]);
6960 arg_action
= table
[i
].to
;
6967 static int runlevel_parse_argv(int argc
, char *argv
[]) {
6973 static const struct option options
[] = {
6974 { "help", no_argument
, NULL
, ARG_HELP
},
6983 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
6994 assert_not_reached("Unhandled option");
6997 if (optind
< argc
) {
6998 log_error("Too many arguments.");
7005 static int parse_argv(int argc
, char *argv
[]) {
7009 if (program_invocation_short_name
) {
7011 if (strstr(program_invocation_short_name
, "halt")) {
7012 arg_action
= ACTION_HALT
;
7013 return halt_parse_argv(argc
, argv
);
7014 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7015 arg_action
= ACTION_POWEROFF
;
7016 return halt_parse_argv(argc
, argv
);
7017 } else if (strstr(program_invocation_short_name
, "reboot")) {
7019 arg_action
= ACTION_KEXEC
;
7021 arg_action
= ACTION_REBOOT
;
7022 return halt_parse_argv(argc
, argv
);
7023 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7024 arg_action
= ACTION_POWEROFF
;
7025 return shutdown_parse_argv(argc
, argv
);
7026 } else if (strstr(program_invocation_short_name
, "init")) {
7028 if (sd_booted() > 0) {
7029 arg_action
= _ACTION_INVALID
;
7030 return telinit_parse_argv(argc
, argv
);
7032 /* Hmm, so some other init system is
7033 * running, we need to forward this
7034 * request to it. For now we simply
7035 * guess that it is Upstart. */
7037 execv(TELINIT
, argv
);
7039 log_error("Couldn't find an alternative telinit implementation to spawn.");
7043 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7044 arg_action
= ACTION_RUNLEVEL
;
7045 return runlevel_parse_argv(argc
, argv
);
7049 arg_action
= ACTION_SYSTEMCTL
;
7050 return systemctl_parse_argv(argc
, argv
);
7053 _pure_
static int action_to_runlevel(void) {
7055 static const char table
[_ACTION_MAX
] = {
7056 [ACTION_HALT
] = '0',
7057 [ACTION_POWEROFF
] = '0',
7058 [ACTION_REBOOT
] = '6',
7059 [ACTION_RUNLEVEL2
] = '2',
7060 [ACTION_RUNLEVEL3
] = '3',
7061 [ACTION_RUNLEVEL4
] = '4',
7062 [ACTION_RUNLEVEL5
] = '5',
7063 [ACTION_RESCUE
] = '1'
7066 assert(arg_action
< _ACTION_MAX
);
7068 return table
[arg_action
];
7071 static int talk_initctl(void) {
7073 struct init_request request
= {
7074 .magic
= INIT_MAGIC
,
7076 .cmd
= INIT_CMD_RUNLVL
7079 _cleanup_close_
int fd
= -1;
7083 rl
= action_to_runlevel();
7087 request
.runlevel
= rl
;
7089 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7091 if (errno
== ENOENT
)
7094 log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7098 r
= loop_write(fd
, &request
, sizeof(request
), false);
7100 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7105 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
7107 static const struct {
7115 int (* const dispatch
)(sd_bus
*bus
, char **args
);
7121 { "list-units", MORE
, 0, list_units
},
7122 { "list-unit-files", MORE
, 1, list_unit_files
, NOBUS
},
7123 { "list-sockets", MORE
, 1, list_sockets
},
7124 { "list-timers", MORE
, 1, list_timers
},
7125 { "list-jobs", MORE
, 1, list_jobs
},
7126 { "list-machines", MORE
, 1, list_machines
},
7127 { "clear-jobs", EQUAL
, 1, daemon_reload
},
7128 { "cancel", MORE
, 2, cancel_job
},
7129 { "start", MORE
, 2, start_unit
},
7130 { "stop", MORE
, 2, start_unit
},
7131 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7132 { "reload", MORE
, 2, start_unit
},
7133 { "restart", MORE
, 2, start_unit
},
7134 { "try-restart", MORE
, 2, start_unit
},
7135 { "reload-or-restart", MORE
, 2, start_unit
},
7136 { "reload-or-try-restart", MORE
, 2, start_unit
},
7137 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
7138 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7139 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
7140 { "isolate", EQUAL
, 2, start_unit
},
7141 { "kill", MORE
, 2, kill_unit
},
7142 { "is-active", MORE
, 2, check_unit_active
},
7143 { "check", MORE
, 2, check_unit_active
},
7144 { "is-failed", MORE
, 2, check_unit_failed
},
7145 { "show", MORE
, 1, show
},
7146 { "cat", MORE
, 2, cat
, NOBUS
},
7147 { "status", MORE
, 1, show
},
7148 { "help", MORE
, 2, show
},
7149 { "snapshot", LESS
, 2, snapshot
},
7150 { "delete", MORE
, 2, delete_snapshot
},
7151 { "daemon-reload", EQUAL
, 1, daemon_reload
},
7152 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
7153 { "show-environment", EQUAL
, 1, show_environment
},
7154 { "set-environment", MORE
, 2, set_environment
},
7155 { "unset-environment", MORE
, 2, set_environment
},
7156 { "import-environment", MORE
, 1, import_environment
},
7157 { "halt", EQUAL
, 1, start_special
, FORCE
},
7158 { "poweroff", EQUAL
, 1, start_special
, FORCE
},
7159 { "reboot", MORE
, 1, start_special
, FORCE
},
7160 { "kexec", EQUAL
, 1, start_special
},
7161 { "suspend", EQUAL
, 1, start_special
},
7162 { "hibernate", EQUAL
, 1, start_special
},
7163 { "hybrid-sleep", EQUAL
, 1, start_special
},
7164 { "default", EQUAL
, 1, start_special
},
7165 { "rescue", EQUAL
, 1, start_special
},
7166 { "emergency", EQUAL
, 1, start_special
},
7167 { "exit", EQUAL
, 1, start_special
},
7168 { "reset-failed", MORE
, 1, reset_failed
},
7169 { "enable", MORE
, 2, enable_unit
, NOBUS
},
7170 { "disable", MORE
, 2, enable_unit
, NOBUS
},
7171 { "is-enabled", MORE
, 2, unit_is_enabled
, NOBUS
},
7172 { "reenable", MORE
, 2, enable_unit
, NOBUS
},
7173 { "preset", MORE
, 2, enable_unit
, NOBUS
},
7174 { "preset-all", EQUAL
, 1, preset_all
, NOBUS
},
7175 { "mask", MORE
, 2, enable_unit
, NOBUS
},
7176 { "unmask", MORE
, 2, enable_unit
, NOBUS
},
7177 { "link", MORE
, 2, enable_unit
, NOBUS
},
7178 { "switch-root", MORE
, 2, switch_root
},
7179 { "list-dependencies", LESS
, 2, list_dependencies
},
7180 { "set-default", EQUAL
, 2, set_default
, NOBUS
},
7181 { "get-default", EQUAL
, 1, get_default
, NOBUS
},
7182 { "set-property", MORE
, 3, set_property
},
7183 { "is-system-running", EQUAL
, 1, is_system_running
},
7184 { "add-wants", MORE
, 3, add_dependency
, NOBUS
},
7185 { "add-requires", MORE
, 3, add_dependency
, NOBUS
},
7186 { "edit", MORE
, 2, edit
, NOBUS
},
7195 left
= argc
- optind
;
7197 /* Special rule: no arguments (left == 0) means "list-units" */
7199 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
7200 log_error("This command expects one or more "
7201 "unit names. Did you mean --help?");
7205 for (; verb
->verb
; verb
++)
7206 if (streq(argv
[optind
], verb
->verb
))
7209 log_error("Unknown operation '%s'.", argv
[optind
]);
7214 switch (verb
->argc_cmp
) {
7217 if (left
!= verb
->argc
) {
7218 log_error("Invalid number of arguments.");
7225 if (left
< verb
->argc
) {
7226 log_error("Too few arguments.");
7233 if (left
> verb
->argc
) {
7234 log_error("Too many arguments.");
7241 assert_not_reached("Unknown comparison operator.");
7244 /* Require a bus connection for all operations but
7246 if (verb
->bus
== NOBUS
) {
7247 if (!bus
&& !avoid_bus()) {
7248 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7253 if (running_in_chroot() > 0) {
7254 log_info("Running in chroot, ignoring request.");
7258 if ((verb
->bus
!= FORCE
|| arg_force
<= 0) && !bus
) {
7259 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7264 return verb
->dispatch(bus
, argv
+ optind
);
7267 static int reload_with_fallback(sd_bus
*bus
) {
7270 /* First, try systemd via D-Bus. */
7271 if (daemon_reload(bus
, NULL
) >= 0)
7275 /* Nothing else worked, so let's try signals */
7276 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7278 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7279 return log_error_errno(errno
, "kill() failed: %m");
7284 static int start_with_fallback(sd_bus
*bus
) {
7287 /* First, try systemd via D-Bus. */
7288 if (start_unit(bus
, NULL
) >= 0)
7292 /* Nothing else worked, so let's try
7294 if (talk_initctl() > 0)
7297 log_error("Failed to talk to init daemon.");
7301 warn_wall(arg_action
);
7305 static int halt_now(enum action a
) {
7307 /* The kernel will automaticall flush ATA disks and suchlike
7308 * on reboot(), but the file systems need to be synce'd
7309 * explicitly in advance. */
7312 /* Make sure C-A-D is handled by the kernel from this point
7314 reboot(RB_ENABLE_CAD
);
7319 log_info("Halting.");
7320 reboot(RB_HALT_SYSTEM
);
7323 case ACTION_POWEROFF
:
7324 log_info("Powering off.");
7325 reboot(RB_POWER_OFF
);
7329 case ACTION_REBOOT
: {
7330 _cleanup_free_
char *param
= NULL
;
7332 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7333 log_info("Rebooting with argument '%s'.", param
);
7334 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
7335 LINUX_REBOOT_CMD_RESTART2
, param
);
7338 log_info("Rebooting.");
7339 reboot(RB_AUTOBOOT
);
7344 assert_not_reached("Unknown action.");
7348 static int halt_main(sd_bus
*bus
) {
7351 r
= check_inhibitors(bus
, arg_action
);
7355 if (geteuid() != 0) {
7356 /* Try logind if we are a normal user and no special
7357 * mode applies. Maybe PolicyKit allows us to shutdown
7360 if (arg_when
<= 0 &&
7363 (arg_action
== ACTION_POWEROFF
||
7364 arg_action
== ACTION_REBOOT
)) {
7365 r
= reboot_with_logind(bus
, arg_action
);
7370 log_error("Must be root.");
7375 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7376 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7377 _cleanup_free_
char *m
= NULL
;
7380 log_error("Unable to perform operation without bus connection.");
7384 r
= sd_bus_open_system(&b
);
7386 return log_error_errno(r
, "Unable to open system bus: %m");
7388 m
= strv_join(arg_wall
, " ");
7392 r
= sd_bus_call_method(
7394 "org.freedesktop.login1",
7395 "/org/freedesktop/login1",
7396 "org.freedesktop.login1.Manager",
7405 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7406 bus_error_message(&error
, r
));
7407 sd_bus_error_free(&error
);
7410 r
= sd_bus_call_method(
7412 "org.freedesktop.login1",
7413 "/org/freedesktop/login1",
7414 "org.freedesktop.login1.Manager",
7419 arg_action
== ACTION_HALT
? "halt" :
7420 arg_action
== ACTION_POWEROFF
? "poweroff" :
7421 arg_action
== ACTION_KEXEC
? "kexec" :
7425 log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s",
7426 bus_error_message(&error
, r
));
7428 char date
[FORMAT_TIMESTAMP_MAX
];
7430 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7431 format_timestamp(date
, sizeof(date
), arg_when
));
7436 if (!arg_dry
&& !arg_force
)
7437 return start_with_fallback(bus
);
7440 if (sd_booted() > 0)
7441 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7443 r
= utmp_put_shutdown();
7445 log_warning_errno(r
, "Failed to write utmp record: %m");
7452 r
= halt_now(arg_action
);
7453 log_error_errno(r
, "Failed to reboot: %m");
7458 static int runlevel_main(void) {
7459 int r
, runlevel
, previous
;
7461 r
= utmp_get_runlevel(&runlevel
, &previous
);
7468 previous
<= 0 ? 'N' : previous
,
7469 runlevel
<= 0 ? 'N' : runlevel
);
7474 int main(int argc
, char*argv
[]) {
7475 _cleanup_bus_flush_close_unref_ sd_bus
*bus
= NULL
;
7478 setlocale(LC_ALL
, "");
7479 log_parse_environment();
7482 /* Explicitly not on_tty() to avoid setting cached value.
7483 * This becomes relevant for piping output which might be
7485 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7487 r
= parse_argv(argc
, argv
);
7491 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7492 * let's shortcut this */
7493 if (arg_action
== ACTION_RUNLEVEL
) {
7494 r
= runlevel_main();
7498 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7499 log_info("Running in chroot, ignoring request.");
7505 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
7508 sd_bus_set_allow_interactive_authorization(bus
, arg_ask_password
);
7510 /* systemctl_main() will print an error message for the bus
7511 * connection, but only if it needs to */
7513 switch (arg_action
) {
7515 case ACTION_SYSTEMCTL
:
7516 r
= systemctl_main(bus
, argc
, argv
, r
);
7520 case ACTION_POWEROFF
:
7526 case ACTION_RUNLEVEL2
:
7527 case ACTION_RUNLEVEL3
:
7528 case ACTION_RUNLEVEL4
:
7529 case ACTION_RUNLEVEL5
:
7531 case ACTION_EMERGENCY
:
7532 case ACTION_DEFAULT
:
7533 r
= start_with_fallback(bus
);
7538 r
= reload_with_fallback(bus
);
7541 case ACTION_CANCEL_SHUTDOWN
: {
7542 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7543 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7544 _cleanup_free_
char *m
= NULL
;
7547 log_error("Unable to perform operation without bus connection.");
7551 r
= sd_bus_open_system(&b
);
7553 return log_error_errno(r
, "Unable to open system bus: %m");
7556 m
= strv_join(arg_wall
, " ");
7563 r
= sd_bus_call_method(
7565 "org.freedesktop.login1",
7566 "/org/freedesktop/login1",
7567 "org.freedesktop.login1.Manager",
7576 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7577 bus_error_message(&error
, r
));
7578 sd_bus_error_free(&error
);
7581 r
= sd_bus_call_method(
7583 "org.freedesktop.login1",
7584 "/org/freedesktop/login1",
7585 "org.freedesktop.login1.Manager",
7586 "CancelScheduledShutdown",
7590 log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s",
7591 bus_error_message(&error
, r
));
7595 case ACTION_RUNLEVEL
:
7596 case _ACTION_INVALID
:
7598 assert_not_reached("Unknown action");
7603 ask_password_agent_close();
7604 polkit_agent_close();
7606 strv_free(arg_types
);
7607 strv_free(arg_states
);
7608 strv_free(arg_properties
);
7610 return r
< 0 ? EXIT_FAILURE
: r
;