1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <linux/reboot.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
37 #include "sd-daemon.h"
40 #include "bus-common-errors.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
50 #include "exit-status.h"
52 #include "formats-util.h"
53 #include "hostname-util.h"
58 #include "logs-show.h"
62 #include "path-lookup.h"
63 #include "path-util.h"
64 #include "process-util.h"
66 #include "signal-util.h"
67 #include "socket-util.h"
68 #include "spawn-ask-password-agent.h"
69 #include "spawn-polkit-agent.h"
72 #include "terminal-util.h"
73 #include "unit-name.h"
75 #include "utmp-wtmp.h"
77 static char **arg_types
= NULL
;
78 static char **arg_states
= NULL
;
79 static char **arg_properties
= NULL
;
80 static bool arg_all
= false;
81 static enum dependency
{
87 } arg_dependency
= DEPENDENCY_FORWARD
;
88 static const char *arg_job_mode
= "replace";
89 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
90 static bool arg_no_block
= false;
91 static bool arg_no_legend
= false;
92 static bool arg_no_pager
= false;
93 static bool arg_no_wtmp
= false;
94 static bool arg_no_wall
= false;
95 static bool arg_no_reload
= false;
96 static bool arg_show_types
= false;
97 static bool arg_ignore_inhibitors
= false;
98 static bool arg_dry
= false;
99 static bool arg_quiet
= false;
100 static bool arg_full
= false;
101 static bool arg_recursive
= false;
102 static int arg_force
= 0;
103 static bool arg_ask_password
= false;
104 static bool arg_runtime
= false;
105 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
106 static char **arg_wall
= NULL
;
107 static const char *arg_kill_who
= NULL
;
108 static int arg_signal
= SIGTERM
;
109 static const char *arg_root
= NULL
;
110 static usec_t arg_when
= 0;
132 ACTION_CANCEL_SHUTDOWN
,
134 } arg_action
= ACTION_SYSTEMCTL
;
135 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
136 static char *arg_host
= NULL
;
137 static unsigned arg_lines
= 10;
138 static OutputMode arg_output
= OUTPUT_SHORT
;
139 static bool arg_plain
= false;
140 static bool arg_firmware_setup
= false;
141 static bool arg_now
= false;
143 static bool original_stdout_is_tty
;
145 static int daemon_reload(sd_bus
*bus
, char **args
);
146 static int halt_now(enum action a
);
147 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
149 static char** strv_skip_first(char **strv
) {
150 if (strv_length(strv
) > 0)
155 static void pager_open_if_enabled(void) {
163 static void ask_password_agent_open_if_enabled(void) {
165 /* Open the password agent as a child process if necessary */
167 if (!arg_ask_password
)
170 if (arg_scope
!= UNIT_FILE_SYSTEM
)
173 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
176 ask_password_agent_open();
179 static void polkit_agent_open_if_enabled(void) {
181 /* Open the polkit agent as a child process if necessary */
183 if (!arg_ask_password
)
186 if (arg_scope
!= UNIT_FILE_SYSTEM
)
189 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
195 static OutputFlags
get_output_flags(void) {
197 arg_all
* OUTPUT_SHOW_ALL
|
198 arg_full
* OUTPUT_FULL_WIDTH
|
199 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
200 on_tty() * OUTPUT_COLOR
|
201 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
204 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
207 if (!sd_bus_error_is_set(error
))
210 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
211 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
212 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
213 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
214 return EXIT_NOPERMISSION
;
216 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
217 return EXIT_NOTINSTALLED
;
219 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
220 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
221 return EXIT_NOTIMPLEMENTED
;
223 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
224 return EXIT_NOTCONFIGURED
;
232 static void warn_wall(enum action a
) {
233 static const char *table
[_ACTION_MAX
] = {
234 [ACTION_HALT
] = "The system is going down for system halt NOW!",
235 [ACTION_REBOOT
] = "The system is going down for reboot NOW!",
236 [ACTION_POWEROFF
] = "The system is going down for power-off NOW!",
237 [ACTION_KEXEC
] = "The system is going down for kexec reboot NOW!",
238 [ACTION_RESCUE
] = "The system is going down to rescue mode NOW!",
239 [ACTION_EMERGENCY
] = "The system is going down to emergency mode NOW!",
240 [ACTION_CANCEL_SHUTDOWN
] = "The system shutdown has been cancelled NOW!"
247 _cleanup_free_
char *p
;
249 p
= strv_join(arg_wall
, " ");
256 utmp_wall(p
, NULL
, NULL
, NULL
, NULL
);
264 utmp_wall(table
[a
], NULL
, NULL
, NULL
, NULL
);
267 static bool avoid_bus(void) {
269 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_normal();
435 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
436 on_circle
= on_active
= ansi_highlight_red();
437 off_circle
= off_active
= ansi_normal();
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();
486 on
= ansi_highlight_red();
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();
842 on
= ansi_highlight_red();
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_normal();
1124 on
= ansi_highlight_red();
1125 off
= ansi_normal();
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 (IN_SET(u
->state
,
1304 UNIT_FILE_MASKED_RUNTIME
,
1306 UNIT_FILE_INVALID
)) {
1307 on
= ansi_highlight_red();
1308 off
= ansi_normal();
1309 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1310 on
= ansi_highlight_green();
1311 off
= ansi_normal();
1315 id
= basename(u
->path
);
1317 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1319 printf("%-*s %s%-*s%s\n",
1320 id_cols
, e
? e
: id
,
1321 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1325 printf("\n%u unit files listed.\n", c
);
1328 static int list_unit_files(sd_bus
*bus
, char **args
) {
1329 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1330 _cleanup_free_ UnitFileList
*units
= NULL
;
1338 pager_open_if_enabled();
1346 h
= hashmap_new(&string_hash_ops
);
1350 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1352 unit_file_list_free(h
);
1353 log_error_errno(r
, "Failed to get unit file list: %m");
1357 n_units
= hashmap_size(h
);
1359 units
= new(UnitFileList
, n_units
);
1360 if (!units
&& n_units
> 0) {
1361 unit_file_list_free(h
);
1365 HASHMAP_FOREACH(u
, h
, i
) {
1366 if (!output_show_unit_file(u
, strv_skip_first(args
)))
1373 assert(c
<= n_units
);
1376 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1378 r
= sd_bus_call_method(
1380 "org.freedesktop.systemd1",
1381 "/org/freedesktop/systemd1",
1382 "org.freedesktop.systemd1.Manager",
1388 log_error("Failed to list unit files: %s", bus_error_message(&error
, r
));
1392 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1394 return bus_log_parse_error(r
);
1396 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1398 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1401 units
[c
] = (struct UnitFileList
) {
1403 unit_file_state_from_string(state
)
1406 if (output_show_unit_file(&units
[c
], strv_skip_first(args
)))
1411 return bus_log_parse_error(r
);
1413 r
= sd_bus_message_exit_container(reply
);
1415 return bus_log_parse_error(r
);
1418 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1419 output_unit_file_list(units
, c
);
1422 for (unit
= units
; unit
< units
+ c
; unit
++)
1429 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1430 _cleanup_free_
char *n
= NULL
;
1431 size_t max_len
= MAX(columns(),20u);
1437 for (i
= level
- 1; i
>= 0; i
--) {
1439 if (len
> max_len
- 3 && !arg_full
) {
1440 printf("%s...\n",max_len
% 2 ? "" : " ");
1443 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1447 if (len
> max_len
- 3 && !arg_full
) {
1448 printf("%s...\n",max_len
% 2 ? "" : " ");
1452 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1456 printf("%s\n", name
);
1460 n
= ellipsize(name
, max_len
-len
, 100);
1468 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1470 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1471 [DEPENDENCY_FORWARD
] = "Requires\0"
1472 "RequiresOverridable\0"
1474 "RequisiteOverridable\0"
1478 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1479 "RequiredByOverridable\0"
1481 "RequisiteOfOverridable\0"
1485 [DEPENDENCY_AFTER
] = "After\0",
1486 [DEPENDENCY_BEFORE
] = "Before\0",
1489 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1490 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1491 _cleanup_strv_free_
char **ret
= NULL
;
1492 _cleanup_free_
char *path
= NULL
;
1498 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1500 path
= unit_dbus_path_from_name(name
);
1504 r
= sd_bus_call_method(
1506 "org.freedesktop.systemd1",
1508 "org.freedesktop.DBus.Properties",
1512 "s", "org.freedesktop.systemd1.Unit");
1514 log_error("Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1518 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1520 return bus_log_parse_error(r
);
1522 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1525 r
= sd_bus_message_read(reply
, "s", &prop
);
1527 return bus_log_parse_error(r
);
1529 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1530 r
= sd_bus_message_skip(reply
, "v");
1532 return bus_log_parse_error(r
);
1535 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1537 return bus_log_parse_error(r
);
1539 r
= bus_message_read_strv_extend(reply
, &ret
);
1541 return bus_log_parse_error(r
);
1543 r
= sd_bus_message_exit_container(reply
);
1545 return bus_log_parse_error(r
);
1548 r
= sd_bus_message_exit_container(reply
);
1550 return bus_log_parse_error(r
);
1554 return bus_log_parse_error(r
);
1556 r
= sd_bus_message_exit_container(reply
);
1558 return bus_log_parse_error(r
);
1566 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1567 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1569 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1571 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1574 return strcasecmp(*a
, *b
);
1577 static int list_dependencies_one(
1582 unsigned int branches
) {
1584 _cleanup_strv_free_
char **deps
= NULL
;
1592 r
= strv_extend(units
, name
);
1596 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1600 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1602 STRV_FOREACH(c
, deps
) {
1603 if (strv_contains(*units
, *c
)) {
1605 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1618 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1619 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1620 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1623 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1627 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1628 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1635 strv_remove(*units
, name
);
1640 static int list_dependencies(sd_bus
*bus
, char **args
) {
1641 _cleanup_strv_free_
char **units
= NULL
;
1642 _cleanup_free_
char *unit
= NULL
;
1649 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &unit
);
1651 return log_error_errno(r
, "Failed to mangle unit name: %m");
1655 u
= SPECIAL_DEFAULT_TARGET
;
1657 pager_open_if_enabled();
1661 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1664 struct machine_info
{
1668 char *control_group
;
1669 uint32_t n_failed_units
;
1674 static const struct bus_properties_map machine_info_property_map
[] = {
1675 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1676 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1677 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1678 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1679 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1683 static void machine_info_clear(struct machine_info
*info
) {
1687 free(info
->control_group
);
1692 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1698 for (i
= 0; i
< n
; i
++)
1699 machine_info_clear(&machine_infos
[i
]);
1701 free(machine_infos
);
1704 static int compare_machine_info(const void *a
, const void *b
) {
1705 const struct machine_info
*u
= a
, *v
= b
;
1707 if (u
->is_host
!= v
->is_host
)
1708 return u
->is_host
> v
->is_host
? -1 : 1;
1710 return strcasecmp(u
->name
, v
->name
);
1713 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1714 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1720 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1727 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1734 static bool output_show_machine(const char *name
, char **patterns
) {
1735 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1738 static int get_machine_list(
1740 struct machine_info
**_machine_infos
,
1743 struct machine_info
*machine_infos
= NULL
;
1744 _cleanup_strv_free_
char **m
= NULL
;
1745 _cleanup_free_
char *hn
= NULL
;
1750 hn
= gethostname_malloc();
1754 if (output_show_machine(hn
, patterns
)) {
1755 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1758 machine_infos
[c
].is_host
= true;
1759 machine_infos
[c
].name
= hn
;
1762 get_machine_properties(bus
, &machine_infos
[c
]);
1766 r
= sd_get_machine_names(&m
);
1768 return log_error_errno(r
, "Failed to get machine list: %m");
1770 STRV_FOREACH(i
, m
) {
1771 _cleanup_free_
char *class = NULL
;
1773 if (!output_show_machine(*i
, patterns
))
1776 sd_machine_get_class(*i
, &class);
1777 if (!streq_ptr(class, "container"))
1780 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1781 free_machines_list(machine_infos
, c
);
1785 machine_infos
[c
].is_host
= false;
1786 machine_infos
[c
].name
= strdup(*i
);
1787 if (!machine_infos
[c
].name
) {
1788 free_machines_list(machine_infos
, c
);
1792 get_machine_properties(NULL
, &machine_infos
[c
]);
1796 *_machine_infos
= machine_infos
;
1800 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1801 struct machine_info
*m
;
1804 namelen
= sizeof("NAME") - 1,
1805 statelen
= sizeof("STATE") - 1,
1806 failedlen
= sizeof("FAILED") - 1,
1807 jobslen
= sizeof("JOBS") - 1;
1809 assert(machine_infos
|| n
== 0);
1811 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1812 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1813 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1814 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1815 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1817 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1821 if (!arg_no_legend
) {
1825 printf("%-*s %-*s %-*s %-*s\n",
1828 failedlen
, "FAILED",
1832 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1833 const char *on_state
= "", *off_state
= "";
1834 const char *on_failed
= "", *off_failed
= "";
1835 bool circle
= false;
1837 if (streq_ptr(m
->state
, "degraded")) {
1838 on_state
= ansi_highlight_red();
1839 off_state
= ansi_normal();
1841 } else if (!streq_ptr(m
->state
, "running")) {
1842 on_state
= ansi_highlight_yellow();
1843 off_state
= ansi_normal();
1847 if (m
->n_failed_units
> 0) {
1848 on_failed
= ansi_highlight_red();
1849 off_failed
= ansi_normal();
1851 on_failed
= off_failed
= "";
1854 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1857 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1858 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1859 on_state
, statelen
, strna(m
->state
), off_state
,
1860 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1861 jobslen
, m
->n_jobs
);
1863 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1864 namelen
, strna(m
->name
),
1865 on_state
, statelen
, strna(m
->state
), off_state
,
1866 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1867 jobslen
, m
->n_jobs
);
1871 printf("\n%u machines listed.\n", n
);
1874 static int list_machines(sd_bus
*bus
, char **args
) {
1875 struct machine_info
*machine_infos
= NULL
;
1880 if (geteuid() != 0) {
1881 log_error("Must be root.");
1885 pager_open_if_enabled();
1887 r
= get_machine_list(bus
, &machine_infos
, strv_skip_first(args
));
1891 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1892 output_machines_list(machine_infos
, r
);
1893 free_machines_list(machine_infos
, r
);
1898 static int get_default(sd_bus
*bus
, char **args
) {
1899 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1900 _cleanup_free_
char *_path
= NULL
;
1904 if (!bus
|| avoid_bus()) {
1905 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1907 return log_error_errno(r
, "Failed to get default target: %m");
1911 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1913 r
= sd_bus_call_method(
1915 "org.freedesktop.systemd1",
1916 "/org/freedesktop/systemd1",
1917 "org.freedesktop.systemd1.Manager",
1923 log_error("Failed to get default target: %s", bus_error_message(&error
, -r
));
1927 r
= sd_bus_message_read(reply
, "s", &path
);
1929 return bus_log_parse_error(r
);
1933 printf("%s\n", path
);
1938 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1941 assert(changes
|| n_changes
== 0);
1943 for (i
= 0; i
< n_changes
; i
++) {
1944 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1945 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1947 log_info("Removed symlink %s.", changes
[i
].path
);
1951 static int set_default(sd_bus
*bus
, char **args
) {
1952 _cleanup_free_
char *unit
= NULL
;
1953 UnitFileChange
*changes
= NULL
;
1954 unsigned n_changes
= 0;
1957 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1959 return log_error_errno(r
, "Failed to mangle unit name: %m");
1961 if (!bus
|| avoid_bus()) {
1962 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1964 return log_error_errno(r
, "Failed to set default target: %m");
1967 dump_unit_file_changes(changes
, n_changes
);
1971 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1972 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1974 polkit_agent_open_if_enabled();
1976 r
= sd_bus_call_method(
1978 "org.freedesktop.systemd1",
1979 "/org/freedesktop/systemd1",
1980 "org.freedesktop.systemd1.Manager",
1986 log_error("Failed to set default target: %s", bus_error_message(&error
, -r
));
1990 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
1994 /* Try to reload if enabled */
1996 r
= daemon_reload(bus
, args
);
2001 unit_file_changes_free(changes
, n_changes
);
2008 const char *name
, *type
, *state
;
2011 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2012 unsigned id_len
, unit_len
, type_len
, state_len
;
2013 const struct job_info
*j
;
2014 const char *on
, *off
;
2015 bool shorten
= false;
2017 assert(n
== 0 || jobs
);
2020 if (!arg_no_legend
) {
2021 on
= ansi_highlight_green();
2022 off
= ansi_normal();
2024 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2029 pager_open_if_enabled();
2031 id_len
= strlen("JOB");
2032 unit_len
= strlen("UNIT");
2033 type_len
= strlen("TYPE");
2034 state_len
= strlen("STATE");
2036 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2037 uint32_t id
= j
->id
;
2038 assert(j
->name
&& j
->type
&& j
->state
);
2040 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2041 unit_len
= MAX(unit_len
, strlen(j
->name
));
2042 type_len
= MAX(type_len
, strlen(j
->type
));
2043 state_len
= MAX(state_len
, strlen(j
->state
));
2046 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2047 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2052 printf("%*s %-*s %-*s %-*s\n",
2056 state_len
, "STATE");
2058 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2059 _cleanup_free_
char *e
= NULL
;
2061 if (streq(j
->state
, "running")) {
2062 on
= ansi_highlight();
2063 off
= ansi_normal();
2067 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2068 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2070 on
, unit_len
, e
? e
: j
->name
, off
,
2072 on
, state_len
, j
->state
, off
);
2075 if (!arg_no_legend
) {
2076 on
= ansi_highlight();
2077 off
= ansi_normal();
2079 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2083 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2084 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2087 static int list_jobs(sd_bus
*bus
, char **args
) {
2088 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2089 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2090 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2091 _cleanup_free_
struct job_info
*jobs
= NULL
;
2096 bool skipped
= false;
2098 r
= sd_bus_call_method(
2100 "org.freedesktop.systemd1",
2101 "/org/freedesktop/systemd1",
2102 "org.freedesktop.systemd1.Manager",
2108 log_error("Failed to list jobs: %s", bus_error_message(&error
, r
));
2112 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2114 return bus_log_parse_error(r
);
2116 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2117 struct job_info job
= { id
, name
, type
, state
};
2119 if (!output_show_job(&job
, strv_skip_first(args
))) {
2124 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2130 return bus_log_parse_error(r
);
2132 r
= sd_bus_message_exit_container(reply
);
2134 return bus_log_parse_error(r
);
2136 output_jobs_list(jobs
, c
, skipped
);
2140 static int cancel_job(sd_bus
*bus
, char **args
) {
2146 if (strv_length(args
) <= 1)
2147 return daemon_reload(bus
, args
);
2149 polkit_agent_open_if_enabled();
2151 STRV_FOREACH(name
, args
+1) {
2152 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2156 q
= safe_atou32(*name
, &id
);
2158 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2160 q
= sd_bus_call_method(
2162 "org.freedesktop.systemd1",
2163 "/org/freedesktop/systemd1",
2164 "org.freedesktop.systemd1.Manager",
2170 log_error("Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2179 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2180 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2184 /* We ignore all errors here, since this is used to show a
2187 /* We don't use unit_dbus_path_from_name() directly since we
2188 * don't want to load the unit if it isn't loaded. */
2190 r
= sd_bus_call_method(
2192 "org.freedesktop.systemd1",
2193 "/org/freedesktop/systemd1",
2194 "org.freedesktop.systemd1.Manager",
2202 r
= sd_bus_message_read(reply
, "o", &path
);
2206 r
= sd_bus_get_property_trivial(
2208 "org.freedesktop.systemd1",
2210 "org.freedesktop.systemd1.Unit",
2220 static void warn_unit_file_changed(const char *name
) {
2221 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2222 ansi_highlight_red(),
2225 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2228 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2235 STRV_FOREACH(p
, lp
->unit_path
) {
2236 _cleanup_free_
char *path
;
2238 path
= path_join(arg_root
, *p
, unit_name
);
2242 if (access(path
, F_OK
) == 0) {
2252 static int unit_find_paths(
2254 const char *unit_name
,
2255 bool avoid_bus_cache
,
2257 char **fragment_path
,
2258 char ***dropin_paths
) {
2260 _cleanup_free_
char *path
= NULL
;
2261 _cleanup_strv_free_
char **dropins
= NULL
;
2265 * Finds where the unit is defined on disk. Returns 0 if the unit
2266 * is not found. Returns 1 if it is found, and sets
2267 * - the path to the unit in *path, if it exists on disk,
2268 * - and a strv of existing drop-ins in *dropins,
2269 * if the arg is not NULL and any dropins were found.
2273 assert(fragment_path
);
2276 if (!avoid_bus_cache
&& !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2277 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2278 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2279 _cleanup_free_
char *unit
= NULL
;
2280 char *unit_load_error_name
, *unit_load_error_message
;
2282 unit
= unit_dbus_path_from_name(unit_name
);
2286 if (need_daemon_reload(bus
, unit_name
) > 0)
2287 warn_unit_file_changed(unit_name
);
2289 r
= sd_bus_get_property(
2291 "org.freedesktop.systemd1",
2293 "org.freedesktop.systemd1.Unit",
2299 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2301 r
= sd_bus_message_read(
2304 &unit_load_error_name
,
2305 &unit_load_error_message
);
2307 return bus_log_parse_error(r
);
2309 if (!isempty(unit_load_error_name
)) {
2310 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2314 r
= sd_bus_get_property_string(
2316 "org.freedesktop.systemd1",
2318 "org.freedesktop.systemd1.Unit",
2323 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2326 r
= sd_bus_get_property_strv(
2328 "org.freedesktop.systemd1",
2330 "org.freedesktop.systemd1.Unit",
2335 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2338 _cleanup_set_free_ Set
*names
;
2340 names
= set_new(NULL
);
2344 r
= set_put(names
, unit_name
);
2346 return log_error_errno(r
, "Failed to add unit name: %m");
2348 r
= unit_file_find_path(lp
, unit_name
, &path
);
2353 _cleanup_free_
char *template = NULL
;
2355 r
= unit_name_template(unit_name
, &template);
2356 if (r
< 0 && r
!= -EINVAL
)
2357 return log_error_errno(r
, "Failed to determine template name: %m");
2359 r
= unit_file_find_path(lp
, template, &path
);
2366 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2374 if (!isempty(path
)) {
2375 *fragment_path
= path
;
2380 if (dropin_paths
&& !strv_isempty(dropins
)) {
2381 *dropin_paths
= dropins
;
2387 log_error("No files found for %s.", unit_name
);
2392 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2393 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2394 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2400 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2402 return log_error_errno(r
, "Failed to mangle unit name: %m");
2404 /* We don't use unit_dbus_path_from_name() directly since we
2405 * don't want to load the unit if it isn't loaded. */
2407 r
= sd_bus_call_method(
2409 "org.freedesktop.systemd1",
2410 "/org/freedesktop/systemd1",
2411 "org.freedesktop.systemd1.Manager",
2422 r
= sd_bus_message_read(reply
, "o", &path
);
2424 return bus_log_parse_error(r
);
2426 r
= sd_bus_get_property_string(
2428 "org.freedesktop.systemd1",
2430 "org.freedesktop.systemd1.Unit",
2443 return nulstr_contains(good_states
, state
);
2446 static int check_triggering_units(
2450 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2451 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2452 _cleanup_strv_free_
char **triggered_by
= NULL
;
2453 bool print_warning_label
= true;
2457 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2459 return log_error_errno(r
, "Failed to mangle unit name: %m");
2461 path
= unit_dbus_path_from_name(n
);
2465 r
= sd_bus_get_property_string(
2467 "org.freedesktop.systemd1",
2469 "org.freedesktop.systemd1.Unit",
2474 log_error("Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2478 if (streq(state
, "masked"))
2481 r
= sd_bus_get_property_strv(
2483 "org.freedesktop.systemd1",
2485 "org.freedesktop.systemd1.Unit",
2490 log_error("Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2494 STRV_FOREACH(i
, triggered_by
) {
2495 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2497 return log_error_errno(r
, "Failed to check unit: %m");
2502 if (print_warning_label
) {
2503 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2504 print_warning_label
= false;
2507 log_warning(" %s", *i
);
2513 static const struct {
2516 } unit_actions
[] = {
2517 { "start", "StartUnit" },
2518 { "stop", "StopUnit" },
2519 { "condstop", "StopUnit" },
2520 { "reload", "ReloadUnit" },
2521 { "restart", "RestartUnit" },
2522 { "try-restart", "TryRestartUnit" },
2523 { "condrestart", "TryRestartUnit" },
2524 { "reload-or-restart", "ReloadOrRestartUnit" },
2525 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2526 { "condreload", "ReloadOrTryRestartUnit" },
2527 { "force-reload", "ReloadOrTryRestartUnit" }
2530 static const char *verb_to_method(const char *verb
) {
2533 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2534 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2535 return unit_actions
[i
].method
;
2540 static const char *method_to_verb(const char *method
) {
2543 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2544 if (streq_ptr(unit_actions
[i
].method
, method
))
2545 return unit_actions
[i
].verb
;
2550 static int start_unit_one(
2555 sd_bus_error
*error
,
2556 BusWaitForJobs
*w
) {
2558 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2567 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2569 r
= sd_bus_call_method(
2571 "org.freedesktop.systemd1",
2572 "/org/freedesktop/systemd1",
2573 "org.freedesktop.systemd1.Manager",
2581 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2582 /* There's always a fallback possible for
2583 * legacy actions. */
2584 return -EADDRNOTAVAIL
;
2586 verb
= method_to_verb(method
);
2588 log_error("Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2592 r
= sd_bus_message_read(reply
, "o", &path
);
2594 return bus_log_parse_error(r
);
2596 if (need_daemon_reload(bus
, name
) > 0)
2597 warn_unit_file_changed(name
);
2600 log_debug("Adding %s to the set", path
);
2601 r
= bus_wait_for_jobs_add(w
, path
);
2609 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2611 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2615 STRV_FOREACH(name
, names
) {
2619 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2621 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2623 return log_error_errno(r
, "Failed to mangle name: %m");
2625 if (string_is_glob(t
))
2626 r
= strv_consume(&globs
, t
);
2628 r
= strv_consume(&mangled
, t
);
2633 /* Query the manager only if any of the names are a glob, since
2634 * this is fairly expensive */
2635 if (!strv_isempty(globs
)) {
2636 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2637 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2640 return log_error_errno(EOPNOTSUPP
, "Unit name globbing without bus is not implemented.");
2642 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2646 for (i
= 0; i
< r
; i
++)
2647 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2652 mangled
= NULL
; /* do not free */
2657 static const struct {
2661 } action_table
[_ACTION_MAX
] = {
2662 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2663 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2664 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2665 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2666 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2667 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2668 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2669 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2670 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2671 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2672 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2673 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2674 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2675 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2676 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2679 static enum action
verb_to_action(const char *verb
) {
2682 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2683 if (streq_ptr(action_table
[i
].verb
, verb
))
2686 return _ACTION_INVALID
;
2689 static int start_unit(sd_bus
*bus
, char **args
) {
2690 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2691 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2692 _cleanup_strv_free_
char **names
= NULL
;
2698 ask_password_agent_open_if_enabled();
2699 polkit_agent_open_if_enabled();
2701 if (arg_action
== ACTION_SYSTEMCTL
) {
2703 method
= verb_to_method(args
[0]);
2704 action
= verb_to_action(args
[0]);
2706 if (streq(args
[0], "isolate")) {
2710 mode
= action_table
[action
].mode
?: arg_job_mode
;
2712 one_name
= action_table
[action
].target
;
2714 assert(arg_action
< ELEMENTSOF(action_table
));
2715 assert(action_table
[arg_action
].target
);
2717 method
= "StartUnit";
2719 mode
= action_table
[arg_action
].mode
;
2720 one_name
= action_table
[arg_action
].target
;
2724 names
= strv_new(one_name
, NULL
);
2726 r
= expand_names(bus
, args
+ 1, suffix
, &names
);
2728 log_error_errno(r
, "Failed to expand names: %m");
2731 if (!arg_no_block
) {
2732 r
= bus_wait_for_jobs_new(bus
, &w
);
2734 return log_error_errno(r
, "Could not watch jobs: %m");
2737 STRV_FOREACH(name
, names
) {
2738 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2741 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2742 if (r
>= 0 && q
< 0)
2743 r
= translate_bus_error_to_exit_status(q
, &error
);
2746 if (!arg_no_block
) {
2749 q
= bus_wait_for_jobs(w
, arg_quiet
);
2753 /* When stopping units, warn if they can still be triggered by
2754 * another active unit (socket, path, timer) */
2755 if (!arg_quiet
&& streq(method
, "StopUnit"))
2756 STRV_FOREACH(name
, names
)
2757 check_triggering_units(bus
, *name
);
2763 /* Ask systemd-logind, which might grant access to unprivileged users
2764 * through PolicyKit */
2765 static int reboot_with_logind(sd_bus
*bus
, enum action a
) {
2767 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2768 const char *method
, *description
;
2774 polkit_agent_open_if_enabled();
2780 description
= "reboot system";
2783 case ACTION_POWEROFF
:
2784 method
= "PowerOff";
2785 description
= "power off system";
2788 case ACTION_SUSPEND
:
2790 description
= "suspend system";
2793 case ACTION_HIBERNATE
:
2794 method
= "Hibernate";
2795 description
= "hibernate system";
2798 case ACTION_HYBRID_SLEEP
:
2799 method
= "HybridSleep";
2800 description
= "put system into hybrid sleep";
2807 if (!strv_isempty(arg_wall
)) {
2808 _cleanup_free_
char *m
;
2810 m
= strv_join(arg_wall
, " ");
2814 r
= sd_bus_call_method(
2816 "org.freedesktop.login1",
2817 "/org/freedesktop/login1",
2818 "org.freedesktop.login1.Manager",
2827 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
2828 bus_error_message(&error
, r
));
2829 sd_bus_error_free(&error
);
2834 r
= sd_bus_call_method(
2836 "org.freedesktop.login1",
2837 "/org/freedesktop/login1",
2838 "org.freedesktop.login1.Manager",
2842 "b", arg_ask_password
);
2844 log_error("Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2852 static int check_inhibitors(sd_bus
*bus
, enum action a
) {
2854 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2855 _cleanup_strv_free_
char **sessions
= NULL
;
2856 const char *what
, *who
, *why
, *mode
;
2865 if (arg_ignore_inhibitors
|| arg_force
> 0)
2877 r
= sd_bus_call_method(
2879 "org.freedesktop.login1",
2880 "/org/freedesktop/login1",
2881 "org.freedesktop.login1.Manager",
2887 /* If logind is not around, then there are no inhibitors... */
2890 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2892 return bus_log_parse_error(r
);
2894 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2895 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2896 _cleanup_strv_free_
char **sv
= NULL
;
2898 if (!streq(mode
, "block"))
2901 sv
= strv_split(what
, ":");
2905 if ((pid_t
) pid
< 0)
2906 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2908 if (!strv_contains(sv
,
2913 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2916 get_process_comm(pid
, &comm
);
2917 user
= uid_to_name(uid
);
2919 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2920 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2925 return bus_log_parse_error(r
);
2927 r
= sd_bus_message_exit_container(reply
);
2929 return bus_log_parse_error(r
);
2931 /* Check for current sessions */
2932 sd_get_sessions(&sessions
);
2933 STRV_FOREACH(s
, sessions
) {
2934 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2936 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2939 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2942 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2945 sd_session_get_tty(*s
, &tty
);
2946 sd_session_get_seat(*s
, &seat
);
2947 sd_session_get_service(*s
, &service
);
2948 user
= uid_to_name(uid
);
2950 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
2957 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
2958 action_table
[a
].verb
);
2966 static int prepare_firmware_setup(sd_bus
*bus
) {
2968 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2972 if (!arg_firmware_setup
)
2975 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
2977 r
= efi_set_reboot_to_firmware(true);
2979 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
2985 r
= sd_bus_call_method(
2987 "org.freedesktop.login1",
2988 "/org/freedesktop/login1",
2989 "org.freedesktop.login1.Manager",
2990 "SetRebootToFirmwareSetup",
2995 log_error("Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3001 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3006 static int start_special(sd_bus
*bus
, char **args
) {
3007 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3013 a
= verb_to_action(args
[0]);
3015 r
= check_inhibitors(bus
, a
);
3019 if (arg_force
>= 2 && geteuid() != 0) {
3020 log_error("Must be root.");
3024 r
= prepare_firmware_setup(bus
);
3028 if (a
== ACTION_REBOOT
&& args
[1]) {
3029 r
= update_reboot_param_file(args
[1]);
3032 } else if (a
== ACTION_EXIT
&& strv_length(args
) > 1) {
3033 /* If the exit code is not given on the command line, don't
3034 * reset it to zero: just keep it as it might have been set
3038 r
= safe_atou8(args
[1], &code
);
3040 log_error("Invalid exit code.");
3044 r
= sd_bus_call_method(
3046 "org.freedesktop.systemd1",
3047 "/org/freedesktop/systemd1",
3048 "org.freedesktop.systemd1.Manager",
3054 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
3059 if (arg_force
>= 2 &&
3066 if (arg_force
>= 1 &&
3073 return daemon_reload(bus
, args
);
3075 /* first try logind, to allow authentication with polkit */
3076 if (geteuid() != 0 &&
3082 ACTION_HYBRID_SLEEP
)) {
3083 r
= reboot_with_logind(bus
, a
);
3086 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3087 /* requested operation is not supported or already in progress */
3089 /* on all other errors, try low-level operation */
3092 r
= start_unit(bus
, args
);
3093 if (r
== EXIT_SUCCESS
)
3099 static int check_unit_generic(sd_bus
*bus
, int code
, const char *good_states
, char **args
) {
3100 _cleanup_strv_free_
char **names
= NULL
;
3107 r
= expand_names(bus
, args
, NULL
, &names
);
3109 return log_error_errno(r
, "Failed to expand names: %m");
3111 STRV_FOREACH(name
, names
) {
3114 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3124 static int check_unit_active(sd_bus
*bus
, char **args
) {
3125 /* According to LSB: 3, "program is not running" */
3126 return check_unit_generic(bus
, 3, "active\0reloading\0", args
+ 1);
3129 static int check_unit_failed(sd_bus
*bus
, char **args
) {
3130 return check_unit_generic(bus
, 1, "failed\0", args
+ 1);
3133 static int kill_unit(sd_bus
*bus
, char **args
) {
3134 _cleanup_strv_free_
char **names
= NULL
;
3135 char *kill_who
= NULL
, **name
;
3141 polkit_agent_open_if_enabled();
3144 arg_kill_who
= "all";
3146 /* --fail was specified */
3147 if (streq(arg_job_mode
, "fail"))
3148 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3150 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
3152 log_error_errno(r
, "Failed to expand names: %m");
3154 STRV_FOREACH(name
, names
) {
3155 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3157 q
= sd_bus_call_method(
3159 "org.freedesktop.systemd1",
3160 "/org/freedesktop/systemd1",
3161 "org.freedesktop.systemd1.Manager",
3165 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3167 log_error("Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3176 typedef struct ExecStatusInfo
{
3184 usec_t start_timestamp
;
3185 usec_t exit_timestamp
;
3190 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3193 static void exec_status_info_free(ExecStatusInfo
*i
) {
3202 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3203 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3206 int32_t code
, status
;
3212 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3214 return bus_log_parse_error(r
);
3218 r
= sd_bus_message_read(m
, "s", &path
);
3220 return bus_log_parse_error(r
);
3222 i
->path
= strdup(path
);
3226 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3228 return bus_log_parse_error(r
);
3230 r
= sd_bus_message_read(m
,
3233 &start_timestamp
, &start_timestamp_monotonic
,
3234 &exit_timestamp
, &exit_timestamp_monotonic
,
3238 return bus_log_parse_error(r
);
3241 i
->start_timestamp
= (usec_t
) start_timestamp
;
3242 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3243 i
->pid
= (pid_t
) pid
;
3247 r
= sd_bus_message_exit_container(m
);
3249 return bus_log_parse_error(r
);
3254 typedef struct UnitStatusInfo
{
3256 const char *load_state
;
3257 const char *active_state
;
3258 const char *sub_state
;
3259 const char *unit_file_state
;
3260 const char *unit_file_preset
;
3262 const char *description
;
3263 const char *following
;
3265 char **documentation
;
3267 const char *fragment_path
;
3268 const char *source_path
;
3269 const char *control_group
;
3271 char **dropin_paths
;
3273 const char *load_error
;
3276 usec_t inactive_exit_timestamp
;
3277 usec_t inactive_exit_timestamp_monotonic
;
3278 usec_t active_enter_timestamp
;
3279 usec_t active_exit_timestamp
;
3280 usec_t inactive_enter_timestamp
;
3282 bool need_daemon_reload
;
3287 const char *status_text
;
3288 const char *pid_file
;
3292 usec_t start_timestamp
;
3293 usec_t exit_timestamp
;
3295 int exit_code
, exit_status
;
3297 usec_t condition_timestamp
;
3298 bool condition_result
;
3299 bool failed_condition_trigger
;
3300 bool failed_condition_negate
;
3301 const char *failed_condition
;
3302 const char *failed_condition_parameter
;
3304 usec_t assert_timestamp
;
3306 bool failed_assert_trigger
;
3307 bool failed_assert_negate
;
3308 const char *failed_assert
;
3309 const char *failed_assert_parameter
;
3312 unsigned n_accepted
;
3313 unsigned n_connections
;
3316 /* Pairs of type, path */
3320 const char *sysfs_path
;
3322 /* Mount, Automount */
3329 uint64_t memory_current
;
3330 uint64_t memory_limit
;
3331 uint64_t cpu_usage_nsec
;
3332 uint64_t tasks_current
;
3335 LIST_HEAD(ExecStatusInfo
, exec
);
3338 static void print_status_info(
3343 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3345 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3346 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3352 /* This shows pretty information about a unit. See
3353 * print_property() for a low-level property printer */
3355 if (streq_ptr(i
->active_state
, "failed")) {
3356 active_on
= ansi_highlight_red();
3357 active_off
= ansi_normal();
3358 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3359 active_on
= ansi_highlight_green();
3360 active_off
= ansi_normal();
3362 active_on
= active_off
= "";
3364 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3366 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3367 printf(" - %s", i
->description
);
3372 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3374 if (streq_ptr(i
->load_state
, "error")) {
3375 on
= ansi_highlight_red();
3376 off
= ansi_normal();
3380 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3383 printf(" Loaded: %s%s%s (Reason: %s)\n",
3384 on
, strna(i
->load_state
), off
, i
->load_error
);
3385 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3386 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3387 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3388 else if (path
&& !isempty(i
->unit_file_state
))
3389 printf(" Loaded: %s%s%s (%s; %s)\n",
3390 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3392 printf(" Loaded: %s%s%s (%s)\n",
3393 on
, strna(i
->load_state
), off
, path
);
3395 printf(" Loaded: %s%s%s\n",
3396 on
, strna(i
->load_state
), off
);
3398 if (!strv_isempty(i
->dropin_paths
)) {
3399 _cleanup_free_
char *dir
= NULL
;
3403 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3404 if (! dir
|| last
) {
3405 printf(dir
? " " : " Drop-In: ");
3409 if (path_get_parent(*dropin
, &dir
) < 0) {
3414 printf("%s\n %s", dir
,
3415 draw_special_char(DRAW_TREE_RIGHT
));
3418 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3420 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3424 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3426 printf(" Active: %s%s (%s)%s",
3427 active_on
, strna(i
->active_state
), ss
, active_off
);
3429 printf(" Active: %s%s%s",
3430 active_on
, strna(i
->active_state
), active_off
);
3432 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3433 printf(" (Result: %s)", i
->result
);
3435 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3436 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3437 (streq_ptr(i
->active_state
, "inactive") ||
3438 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3439 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3440 i
->active_exit_timestamp
;
3442 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3443 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3446 printf(" since %s; %s\n", s2
, s1
);
3448 printf(" since %s\n", s2
);
3452 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3453 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3454 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3456 printf("Condition: start %scondition failed%s at %s%s%s\n",
3457 ansi_highlight_yellow(), ansi_normal(),
3458 s2
, s1
? "; " : "", s1
? s1
: "");
3459 if (i
->failed_condition_trigger
)
3460 printf(" none of the trigger conditions were met\n");
3461 else if (i
->failed_condition
)
3462 printf(" %s=%s%s was not met\n",
3463 i
->failed_condition
,
3464 i
->failed_condition_negate
? "!" : "",
3465 i
->failed_condition_parameter
);
3468 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3469 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3470 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3472 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3473 ansi_highlight_red(), ansi_normal(),
3474 s2
, s1
? "; " : "", s1
? s1
: "");
3475 if (i
->failed_assert_trigger
)
3476 printf(" none of the trigger assertions were met\n");
3477 else if (i
->failed_assert
)
3478 printf(" %s=%s%s was not met\n",
3480 i
->failed_assert_negate
? "!" : "",
3481 i
->failed_assert_parameter
);
3485 printf(" Device: %s\n", i
->sysfs_path
);
3487 printf(" Where: %s\n", i
->where
);
3489 printf(" What: %s\n", i
->what
);
3491 STRV_FOREACH(t
, i
->documentation
)
3492 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3494 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3495 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3498 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3500 LIST_FOREACH(exec
, p
, i
->exec
) {
3501 _cleanup_free_
char *argv
= NULL
;
3504 /* Only show exited processes here */
3508 argv
= strv_join(p
->argv
, " ");
3509 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3511 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3513 on
= ansi_highlight_red();
3514 off
= ansi_normal();
3518 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3520 if (p
->code
== CLD_EXITED
) {
3523 printf("status=%i", p
->status
);
3525 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3530 printf("signal=%s", signal_to_string(p
->status
));
3532 printf(")%s\n", off
);
3534 if (i
->main_pid
== p
->pid
&&
3535 i
->start_timestamp
== p
->start_timestamp
&&
3536 i
->exit_timestamp
== p
->start_timestamp
)
3537 /* Let's not show this twice */
3540 if (p
->pid
== i
->control_pid
)
3544 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3545 if (i
->main_pid
> 0) {
3546 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3549 _cleanup_free_
char *comm
= NULL
;
3550 get_process_comm(i
->main_pid
, &comm
);
3552 printf(" (%s)", comm
);
3553 } else if (i
->exit_code
> 0) {
3554 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3556 if (i
->exit_code
== CLD_EXITED
) {
3559 printf("status=%i", i
->exit_status
);
3561 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3566 printf("signal=%s", signal_to_string(i
->exit_status
));
3570 if (i
->control_pid
> 0)
3574 if (i
->control_pid
> 0) {
3575 _cleanup_free_
char *c
= NULL
;
3577 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3579 get_process_comm(i
->control_pid
, &c
);
3588 printf(" Status: \"%s\"\n", i
->status_text
);
3589 if (i
->status_errno
> 0)
3590 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3592 if (i
->tasks_current
!= (uint64_t) -1) {
3593 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3595 if (i
->tasks_max
!= (uint64_t) -1)
3596 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3601 if (i
->memory_current
!= (uint64_t) -1) {
3602 char buf
[FORMAT_BYTES_MAX
];
3604 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3606 if (i
->memory_limit
!= (uint64_t) -1)
3607 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3612 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3613 char buf
[FORMAT_TIMESPAN_MAX
];
3614 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3617 if (i
->control_group
&&
3618 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3619 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3622 printf(" CGroup: %s\n", i
->control_group
);
3624 if (IN_SET(arg_transport
,
3625 BUS_TRANSPORT_LOCAL
,
3626 BUS_TRANSPORT_MACHINE
)) {
3629 static const char prefix
[] = " ";
3632 if (c
> sizeof(prefix
) - 1)
3633 c
-= sizeof(prefix
) - 1;
3637 if (i
->main_pid
> 0)
3638 extra
[k
++] = i
->main_pid
;
3640 if (i
->control_pid
> 0)
3641 extra
[k
++] = i
->control_pid
;
3643 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3647 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3648 show_journal_by_unit(
3653 i
->inactive_exit_timestamp_monotonic
,
3656 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3657 SD_JOURNAL_LOCAL_ONLY
,
3658 arg_scope
== UNIT_FILE_SYSTEM
,
3661 if (i
->need_daemon_reload
)
3662 warn_unit_file_changed(i
->id
);
3665 static void show_unit_help(UnitStatusInfo
*i
) {
3670 if (!i
->documentation
) {
3671 log_info("Documentation for %s not known.", i
->id
);
3675 STRV_FOREACH(p
, i
->documentation
)
3676 if (startswith(*p
, "man:"))
3677 show_man_page(*p
+ 4, false);
3679 log_info("Can't show: %s", *p
);
3682 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3689 switch (contents
[0]) {
3691 case SD_BUS_TYPE_STRING
: {
3694 r
= sd_bus_message_read(m
, "s", &s
);
3696 return bus_log_parse_error(r
);
3699 if (streq(name
, "Id"))
3701 else if (streq(name
, "LoadState"))
3703 else if (streq(name
, "ActiveState"))
3704 i
->active_state
= s
;
3705 else if (streq(name
, "SubState"))
3707 else if (streq(name
, "Description"))
3709 else if (streq(name
, "FragmentPath"))
3710 i
->fragment_path
= s
;
3711 else if (streq(name
, "SourcePath"))
3714 else if (streq(name
, "DefaultControlGroup")) {
3716 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3718 i
->control_group
= e
;
3721 else if (streq(name
, "ControlGroup"))
3722 i
->control_group
= s
;
3723 else if (streq(name
, "StatusText"))
3725 else if (streq(name
, "PIDFile"))
3727 else if (streq(name
, "SysFSPath"))
3729 else if (streq(name
, "Where"))
3731 else if (streq(name
, "What"))
3733 else if (streq(name
, "Following"))
3735 else if (streq(name
, "UnitFileState"))
3736 i
->unit_file_state
= s
;
3737 else if (streq(name
, "UnitFilePreset"))
3738 i
->unit_file_preset
= s
;
3739 else if (streq(name
, "Result"))
3746 case SD_BUS_TYPE_BOOLEAN
: {
3749 r
= sd_bus_message_read(m
, "b", &b
);
3751 return bus_log_parse_error(r
);
3753 if (streq(name
, "Accept"))
3755 else if (streq(name
, "NeedDaemonReload"))
3756 i
->need_daemon_reload
= b
;
3757 else if (streq(name
, "ConditionResult"))
3758 i
->condition_result
= b
;
3759 else if (streq(name
, "AssertResult"))
3760 i
->assert_result
= b
;
3765 case SD_BUS_TYPE_UINT32
: {
3768 r
= sd_bus_message_read(m
, "u", &u
);
3770 return bus_log_parse_error(r
);
3772 if (streq(name
, "MainPID")) {
3774 i
->main_pid
= (pid_t
) u
;
3777 } else if (streq(name
, "ControlPID"))
3778 i
->control_pid
= (pid_t
) u
;
3779 else if (streq(name
, "ExecMainPID")) {
3781 i
->main_pid
= (pid_t
) u
;
3782 } else if (streq(name
, "NAccepted"))
3784 else if (streq(name
, "NConnections"))
3785 i
->n_connections
= u
;
3790 case SD_BUS_TYPE_INT32
: {
3793 r
= sd_bus_message_read(m
, "i", &j
);
3795 return bus_log_parse_error(r
);
3797 if (streq(name
, "ExecMainCode"))
3798 i
->exit_code
= (int) j
;
3799 else if (streq(name
, "ExecMainStatus"))
3800 i
->exit_status
= (int) j
;
3801 else if (streq(name
, "StatusErrno"))
3802 i
->status_errno
= (int) j
;
3807 case SD_BUS_TYPE_UINT64
: {
3810 r
= sd_bus_message_read(m
, "t", &u
);
3812 return bus_log_parse_error(r
);
3814 if (streq(name
, "ExecMainStartTimestamp"))
3815 i
->start_timestamp
= (usec_t
) u
;
3816 else if (streq(name
, "ExecMainExitTimestamp"))
3817 i
->exit_timestamp
= (usec_t
) u
;
3818 else if (streq(name
, "ActiveEnterTimestamp"))
3819 i
->active_enter_timestamp
= (usec_t
) u
;
3820 else if (streq(name
, "InactiveEnterTimestamp"))
3821 i
->inactive_enter_timestamp
= (usec_t
) u
;
3822 else if (streq(name
, "InactiveExitTimestamp"))
3823 i
->inactive_exit_timestamp
= (usec_t
) u
;
3824 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3825 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3826 else if (streq(name
, "ActiveExitTimestamp"))
3827 i
->active_exit_timestamp
= (usec_t
) u
;
3828 else if (streq(name
, "ConditionTimestamp"))
3829 i
->condition_timestamp
= (usec_t
) u
;
3830 else if (streq(name
, "AssertTimestamp"))
3831 i
->assert_timestamp
= (usec_t
) u
;
3832 else if (streq(name
, "MemoryCurrent"))
3833 i
->memory_current
= u
;
3834 else if (streq(name
, "MemoryLimit"))
3835 i
->memory_limit
= u
;
3836 else if (streq(name
, "TasksCurrent"))
3837 i
->tasks_current
= u
;
3838 else if (streq(name
, "TasksMax"))
3840 else if (streq(name
, "CPUUsageNSec"))
3841 i
->cpu_usage_nsec
= u
;
3846 case SD_BUS_TYPE_ARRAY
:
3848 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3849 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3851 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3853 return bus_log_parse_error(r
);
3855 info
= new0(ExecStatusInfo
, 1);
3859 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3861 info
->name
= strdup(name
);
3865 LIST_PREPEND(exec
, i
->exec
, info
);
3867 info
= new0(ExecStatusInfo
, 1);
3873 return bus_log_parse_error(r
);
3875 r
= sd_bus_message_exit_container(m
);
3877 return bus_log_parse_error(r
);
3881 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3882 const char *type
, *path
;
3884 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3886 return bus_log_parse_error(r
);
3888 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3890 r
= strv_extend(&i
->listen
, type
);
3894 r
= strv_extend(&i
->listen
, path
);
3899 return bus_log_parse_error(r
);
3901 r
= sd_bus_message_exit_container(m
);
3903 return bus_log_parse_error(r
);
3907 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3909 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3911 return bus_log_parse_error(r
);
3913 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3915 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3917 return bus_log_parse_error(r
);
3919 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3920 const char *cond
, *param
;
3921 int trigger
, negate
;
3924 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3926 return bus_log_parse_error(r
);
3928 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3929 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3930 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
3931 i
->failed_condition
= cond
;
3932 i
->failed_condition_trigger
= trigger
;
3933 i
->failed_condition_negate
= negate
;
3934 i
->failed_condition_parameter
= param
;
3938 return bus_log_parse_error(r
);
3940 r
= sd_bus_message_exit_container(m
);
3942 return bus_log_parse_error(r
);
3944 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
3945 const char *cond
, *param
;
3946 int trigger
, negate
;
3949 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3951 return bus_log_parse_error(r
);
3953 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3954 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
3955 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
3956 i
->failed_assert
= cond
;
3957 i
->failed_assert_trigger
= trigger
;
3958 i
->failed_assert_negate
= negate
;
3959 i
->failed_assert_parameter
= param
;
3963 return bus_log_parse_error(r
);
3965 r
= sd_bus_message_exit_container(m
);
3967 return bus_log_parse_error(r
);
3974 case SD_BUS_TYPE_STRUCT_BEGIN
:
3976 if (streq(name
, "LoadError")) {
3977 const char *n
, *message
;
3979 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
3981 return bus_log_parse_error(r
);
3983 if (!isempty(message
))
3984 i
->load_error
= message
;
3997 r
= sd_bus_message_skip(m
, contents
);
3999 return bus_log_parse_error(r
);
4004 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4010 /* This is a low-level property printer, see
4011 * print_status_info() for the nicer output */
4013 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4014 /* skip what we didn't read */
4015 r
= sd_bus_message_skip(m
, contents
);
4019 switch (contents
[0]) {
4021 case SD_BUS_TYPE_STRUCT_BEGIN
:
4023 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4026 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4028 return bus_log_parse_error(r
);
4031 printf("%s=%"PRIu32
"\n", name
, u
);
4033 printf("%s=\n", name
);
4037 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4040 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4042 return bus_log_parse_error(r
);
4044 if (arg_all
|| !isempty(s
))
4045 printf("%s=%s\n", name
, s
);
4049 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4050 const char *a
= NULL
, *b
= NULL
;
4052 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4054 return bus_log_parse_error(r
);
4056 if (arg_all
|| !isempty(a
) || !isempty(b
))
4057 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4060 } else if (streq_ptr(name
, "SystemCallFilter")) {
4061 _cleanup_strv_free_
char **l
= NULL
;
4064 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4066 return bus_log_parse_error(r
);
4068 r
= sd_bus_message_read(m
, "b", &whitelist
);
4070 return bus_log_parse_error(r
);
4072 r
= sd_bus_message_read_strv(m
, &l
);
4074 return bus_log_parse_error(r
);
4076 r
= sd_bus_message_exit_container(m
);
4078 return bus_log_parse_error(r
);
4080 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4084 fputs(name
, stdout
);
4090 STRV_FOREACH(i
, l
) {
4098 fputc('\n', stdout
);
4106 case SD_BUS_TYPE_ARRAY
:
4108 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4112 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4114 return bus_log_parse_error(r
);
4116 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4117 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4120 return bus_log_parse_error(r
);
4122 r
= sd_bus_message_exit_container(m
);
4124 return bus_log_parse_error(r
);
4128 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4129 const char *type
, *path
;
4131 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4133 return bus_log_parse_error(r
);
4135 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4136 printf("%s=%s\n", type
, path
);
4138 return bus_log_parse_error(r
);
4140 r
= sd_bus_message_exit_container(m
);
4142 return bus_log_parse_error(r
);
4146 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4147 const char *type
, *path
;
4149 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4151 return bus_log_parse_error(r
);
4153 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4154 printf("Listen%s=%s\n", type
, path
);
4156 return bus_log_parse_error(r
);
4158 r
= sd_bus_message_exit_container(m
);
4160 return bus_log_parse_error(r
);
4164 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4166 uint64_t value
, next_elapse
;
4168 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4170 return bus_log_parse_error(r
);
4172 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4173 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4175 printf("%s={ value=%s ; next_elapse=%s }\n",
4177 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4178 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4181 return bus_log_parse_error(r
);
4183 r
= sd_bus_message_exit_container(m
);
4185 return bus_log_parse_error(r
);
4189 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4190 ExecStatusInfo info
= {};
4192 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4194 return bus_log_parse_error(r
);
4196 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4197 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4198 _cleanup_free_
char *tt
;
4200 tt
= strv_join(info
.argv
, " ");
4202 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",
4206 yes_no(info
.ignore
),
4207 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4208 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4210 sigchld_code_to_string(info
.code
),
4212 info
.code
== CLD_EXITED
? "" : "/",
4213 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4216 strv_free(info
.argv
);
4220 r
= sd_bus_message_exit_container(m
);
4222 return bus_log_parse_error(r
);
4226 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4227 const char *path
, *rwm
;
4229 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4231 return bus_log_parse_error(r
);
4233 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4234 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4236 return bus_log_parse_error(r
);
4238 r
= sd_bus_message_exit_container(m
);
4240 return bus_log_parse_error(r
);
4244 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4248 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4250 return bus_log_parse_error(r
);
4252 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4253 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4255 return bus_log_parse_error(r
);
4257 r
= sd_bus_message_exit_container(m
);
4259 return bus_log_parse_error(r
);
4263 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4267 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4269 return bus_log_parse_error(r
);
4271 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4272 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4274 return bus_log_parse_error(r
);
4276 r
= sd_bus_message_exit_container(m
);
4278 return bus_log_parse_error(r
);
4286 r
= bus_print_property(name
, m
, arg_all
);
4288 return bus_log_parse_error(r
);
4291 r
= sd_bus_message_skip(m
, contents
);
4293 return bus_log_parse_error(r
);
4296 printf("%s=[unprintable]\n", name
);
4302 static int show_one(
4306 bool show_properties
,
4310 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4311 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4312 UnitStatusInfo info
= {
4313 .memory_current
= (uint64_t) -1,
4314 .memory_limit
= (uint64_t) -1,
4315 .cpu_usage_nsec
= (uint64_t) -1,
4316 .tasks_current
= (uint64_t) -1,
4317 .tasks_max
= (uint64_t) -1,
4325 log_debug("Showing one %s", path
);
4327 r
= sd_bus_call_method(
4329 "org.freedesktop.systemd1",
4331 "org.freedesktop.DBus.Properties",
4337 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4339 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4341 return bus_log_parse_error(r
);
4348 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4349 const char *name
, *contents
;
4351 r
= sd_bus_message_read(reply
, "s", &name
);
4353 return bus_log_parse_error(r
);
4355 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4357 return bus_log_parse_error(r
);
4359 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4361 return bus_log_parse_error(r
);
4363 if (show_properties
)
4364 r
= print_property(name
, reply
, contents
);
4366 r
= status_property(name
, reply
, &info
, contents
);
4370 r
= sd_bus_message_exit_container(reply
);
4372 return bus_log_parse_error(r
);
4374 r
= sd_bus_message_exit_container(reply
);
4376 return bus_log_parse_error(r
);
4379 return bus_log_parse_error(r
);
4381 r
= sd_bus_message_exit_container(reply
);
4383 return bus_log_parse_error(r
);
4387 if (!show_properties
) {
4388 if (streq(verb
, "help"))
4389 show_unit_help(&info
);
4391 print_status_info(&info
, ellipsized
);
4394 strv_free(info
.documentation
);
4395 strv_free(info
.dropin_paths
);
4396 strv_free(info
.listen
);
4398 if (!streq_ptr(info
.active_state
, "active") &&
4399 !streq_ptr(info
.active_state
, "reloading") &&
4400 streq(verb
, "status")) {
4401 /* According to LSB: "program not running" */
4402 /* 0: program is running or service is OK
4403 * 1: program is dead and /run PID file exists
4404 * 2: program is dead and /run/lock lock file exists
4405 * 3: program is not running
4406 * 4: program or service status is unknown
4408 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4414 while ((p
= info
.exec
)) {
4415 LIST_REMOVE(exec
, info
.exec
, p
);
4416 exec_status_info_free(p
);
4422 static int get_unit_dbus_path_by_pid(
4427 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4428 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4432 r
= sd_bus_call_method(
4434 "org.freedesktop.systemd1",
4435 "/org/freedesktop/systemd1",
4436 "org.freedesktop.systemd1.Manager",
4442 log_error("Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4446 r
= sd_bus_message_read(reply
, "o", &u
);
4448 return bus_log_parse_error(r
);
4458 static int show_all(
4461 bool show_properties
,
4465 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4466 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4471 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4475 pager_open_if_enabled();
4479 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4481 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4482 _cleanup_free_
char *p
= NULL
;
4484 p
= unit_dbus_path_from_name(u
->id
);
4488 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4491 else if (r
> 0 && ret
== 0)
4498 static int show_system_status(sd_bus
*bus
) {
4499 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4500 _cleanup_free_
char *hn
= NULL
;
4501 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4502 const char *on
, *off
;
4505 hn
= gethostname_malloc();
4509 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4511 return log_error_errno(r
, "Failed to read server status: %m");
4513 if (streq_ptr(mi
.state
, "degraded")) {
4514 on
= ansi_highlight_red();
4515 off
= ansi_normal();
4516 } else if (!streq_ptr(mi
.state
, "running")) {
4517 on
= ansi_highlight_yellow();
4518 off
= ansi_normal();
4522 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4524 printf(" State: %s%s%s\n",
4525 on
, strna(mi
.state
), off
);
4527 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4528 printf(" Failed: %u units\n", mi
.n_failed_units
);
4530 printf(" Since: %s; %s\n",
4531 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4532 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4534 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4535 if (IN_SET(arg_transport
,
4536 BUS_TRANSPORT_LOCAL
,
4537 BUS_TRANSPORT_MACHINE
)) {
4538 static const char prefix
[] = " ";
4542 if (c
> sizeof(prefix
) - 1)
4543 c
-= sizeof(prefix
) - 1;
4547 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4553 static int show(sd_bus
*bus
, char **args
) {
4554 bool show_properties
, show_status
, new_line
= false;
4555 bool ellipsized
= false;
4561 show_properties
= streq(args
[0], "show");
4562 show_status
= streq(args
[0], "status");
4564 if (show_properties
)
4565 pager_open_if_enabled();
4568 /* Increase max number of open files to 16K if we can, we
4569 * might needs this when browsing journal files, which might
4570 * be split up into many files. */
4571 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4573 /* If no argument is specified inspect the manager itself */
4575 if (show_properties
&& strv_length(args
) <= 1)
4576 return show_one(args
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4578 if (show_status
&& strv_length(args
) <= 1) {
4580 pager_open_if_enabled();
4581 show_system_status(bus
);
4585 ret
= show_all(args
[0], bus
, false, &new_line
, &ellipsized
);
4587 _cleanup_free_
char **patterns
= NULL
;
4590 STRV_FOREACH(name
, args
+ 1) {
4591 _cleanup_free_
char *unit
= NULL
;
4594 if (safe_atou32(*name
, &id
) < 0) {
4595 if (strv_push(&patterns
, *name
) < 0)
4599 } else if (show_properties
) {
4600 /* Interpret as job id */
4601 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4605 /* Interpret as PID */
4606 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4613 r
= show_one(args
[0], bus
, unit
, show_properties
,
4614 &new_line
, &ellipsized
);
4617 else if (r
> 0 && ret
== 0)
4621 if (!strv_isempty(patterns
)) {
4622 _cleanup_strv_free_
char **names
= NULL
;
4624 r
= expand_names(bus
, patterns
, NULL
, &names
);
4626 log_error_errno(r
, "Failed to expand names: %m");
4628 STRV_FOREACH(name
, names
) {
4629 _cleanup_free_
char *unit
;
4631 unit
= unit_dbus_path_from_name(*name
);
4635 r
= show_one(args
[0], bus
, unit
, show_properties
,
4636 &new_line
, &ellipsized
);
4639 else if (r
> 0 && ret
== 0)
4645 if (ellipsized
&& !arg_quiet
)
4646 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4651 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4655 assert(user_runtime
);
4658 if (arg_scope
== UNIT_FILE_USER
) {
4659 r
= user_config_home(user_home
);
4661 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4663 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4665 r
= user_runtime_dir(user_runtime
);
4667 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4669 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4672 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4674 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4679 static int cat_file(const char *filename
, bool newline
) {
4680 _cleanup_close_
int fd
;
4682 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4686 printf("%s%s# %s%s\n",
4687 newline
? "\n" : "",
4688 ansi_highlight_blue(),
4693 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4696 static int cat(sd_bus
*bus
, char **args
) {
4697 _cleanup_free_
char *user_home
= NULL
;
4698 _cleanup_free_
char *user_runtime
= NULL
;
4699 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4700 _cleanup_strv_free_
char **names
= NULL
;
4702 bool first
= true, avoid_bus_cache
;
4707 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4708 log_error("Cannot remotely cat units");
4712 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4716 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4718 return log_error_errno(r
, "Failed to expand names: %m");
4720 avoid_bus_cache
= !bus
|| avoid_bus();
4722 pager_open_if_enabled();
4724 STRV_FOREACH(name
, names
) {
4725 _cleanup_free_
char *fragment_path
= NULL
;
4726 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4729 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &fragment_path
, &dropin_paths
);
4740 if (fragment_path
) {
4741 r
= cat_file(fragment_path
, false);
4743 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4746 STRV_FOREACH(path
, dropin_paths
) {
4747 r
= cat_file(*path
, path
== dropin_paths
);
4749 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4756 static int set_property(sd_bus
*bus
, char **args
) {
4757 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4758 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4759 _cleanup_free_
char *n
= NULL
;
4763 polkit_agent_open_if_enabled();
4765 r
= sd_bus_message_new_method_call(
4768 "org.freedesktop.systemd1",
4769 "/org/freedesktop/systemd1",
4770 "org.freedesktop.systemd1.Manager",
4771 "SetUnitProperties");
4773 return bus_log_create_error(r
);
4775 r
= unit_name_mangle(args
[1], UNIT_NAME_NOGLOB
, &n
);
4777 return log_error_errno(r
, "Failed to mangle unit name: %m");
4779 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4781 return bus_log_create_error(r
);
4783 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4785 return bus_log_create_error(r
);
4787 STRV_FOREACH(i
, args
+ 2) {
4788 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4790 return bus_log_create_error(r
);
4792 r
= bus_append_unit_property_assignment(m
, *i
);
4796 r
= sd_bus_message_close_container(m
);
4798 return bus_log_create_error(r
);
4801 r
= sd_bus_message_close_container(m
);
4803 return bus_log_create_error(r
);
4805 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4807 log_error("Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4814 static int snapshot(sd_bus
*bus
, char **args
) {
4815 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4816 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4817 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4821 polkit_agent_open_if_enabled();
4823 if (strv_length(args
) > 1) {
4824 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4826 return log_error_errno(r
, "Failed to generate unit name: %m");
4833 r
= sd_bus_call_method(
4835 "org.freedesktop.systemd1",
4836 "/org/freedesktop/systemd1",
4837 "org.freedesktop.systemd1.Manager",
4843 log_error("Failed to create snapshot: %s", bus_error_message(&error
, r
));
4847 r
= sd_bus_message_read(reply
, "o", &path
);
4849 return bus_log_parse_error(r
);
4851 r
= sd_bus_get_property_string(
4853 "org.freedesktop.systemd1",
4855 "org.freedesktop.systemd1.Unit",
4860 log_error("Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4870 static int delete_snapshot(sd_bus
*bus
, char **args
) {
4871 _cleanup_strv_free_
char **names
= NULL
;
4877 polkit_agent_open_if_enabled();
4879 r
= expand_names(bus
, args
+ 1, ".snapshot", &names
);
4881 log_error_errno(r
, "Failed to expand names: %m");
4883 STRV_FOREACH(name
, names
) {
4884 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4887 q
= sd_bus_call_method(
4889 "org.freedesktop.systemd1",
4890 "/org/freedesktop/systemd1",
4891 "org.freedesktop.systemd1.Manager",
4897 log_error("Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4906 static int daemon_reload(sd_bus
*bus
, char **args
) {
4907 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4911 polkit_agent_open_if_enabled();
4913 if (arg_action
== ACTION_RELOAD
)
4915 else if (arg_action
== ACTION_REEXEC
)
4916 method
= "Reexecute";
4918 assert(arg_action
== ACTION_SYSTEMCTL
);
4921 streq(args
[0], "clear-jobs") ||
4922 streq(args
[0], "cancel") ? "ClearJobs" :
4923 streq(args
[0], "daemon-reexec") ? "Reexecute" :
4924 streq(args
[0], "reset-failed") ? "ResetFailed" :
4925 streq(args
[0], "halt") ? "Halt" :
4926 streq(args
[0], "poweroff") ? "PowerOff" :
4927 streq(args
[0], "reboot") ? "Reboot" :
4928 streq(args
[0], "kexec") ? "KExec" :
4929 streq(args
[0], "exit") ? "Exit" :
4930 /* "daemon-reload" */ "Reload";
4933 r
= sd_bus_call_method(
4935 "org.freedesktop.systemd1",
4936 "/org/freedesktop/systemd1",
4937 "org.freedesktop.systemd1.Manager",
4942 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4943 /* There's always a fallback possible for
4944 * legacy actions. */
4946 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4947 /* On reexecution, we expect a disconnect, not a
4951 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
4953 return r
< 0 ? r
: 0;
4956 static int reset_failed(sd_bus
*bus
, char **args
) {
4957 _cleanup_strv_free_
char **names
= NULL
;
4961 if (strv_length(args
) <= 1)
4962 return daemon_reload(bus
, args
);
4964 polkit_agent_open_if_enabled();
4966 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
4968 log_error_errno(r
, "Failed to expand names: %m");
4970 STRV_FOREACH(name
, names
) {
4971 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4973 q
= sd_bus_call_method(
4975 "org.freedesktop.systemd1",
4976 "/org/freedesktop/systemd1",
4977 "org.freedesktop.systemd1.Manager",
4983 log_error("Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
4992 static int show_environment(sd_bus
*bus
, char **args
) {
4993 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4994 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4998 pager_open_if_enabled();
5000 r
= sd_bus_get_property(
5002 "org.freedesktop.systemd1",
5003 "/org/freedesktop/systemd1",
5004 "org.freedesktop.systemd1.Manager",
5010 log_error("Failed to get environment: %s", bus_error_message(&error
, r
));
5014 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5016 return bus_log_parse_error(r
);
5018 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5021 return bus_log_parse_error(r
);
5023 r
= sd_bus_message_exit_container(reply
);
5025 return bus_log_parse_error(r
);
5030 static int switch_root(sd_bus
*bus
, char **args
) {
5031 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5032 _cleanup_free_
char *cmdline_init
= NULL
;
5033 const char *root
, *init
;
5037 l
= strv_length(args
);
5038 if (l
< 2 || l
> 3) {
5039 log_error("Wrong number of arguments.");
5048 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5049 "init", &cmdline_init
,
5052 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5054 init
= cmdline_init
;
5061 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5063 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5064 root_init_path
= strjoina(root
, "/", init
);
5066 /* If the passed init is actually the same as the
5067 * systemd binary, then let's suppress it. */
5068 if (files_same(root_init_path
, root_systemd_path
) > 0)
5072 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5074 r
= sd_bus_call_method(
5076 "org.freedesktop.systemd1",
5077 "/org/freedesktop/systemd1",
5078 "org.freedesktop.systemd1.Manager",
5084 log_error("Failed to switch root: %s", bus_error_message(&error
, r
));
5091 static int set_environment(sd_bus
*bus
, char **args
) {
5092 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5093 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5100 polkit_agent_open_if_enabled();
5102 method
= streq(args
[0], "set-environment")
5104 : "UnsetEnvironment";
5106 r
= sd_bus_message_new_method_call(
5109 "org.freedesktop.systemd1",
5110 "/org/freedesktop/systemd1",
5111 "org.freedesktop.systemd1.Manager",
5114 return bus_log_create_error(r
);
5116 r
= sd_bus_message_append_strv(m
, args
+ 1);
5118 return bus_log_create_error(r
);
5120 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5122 log_error("Failed to set environment: %s", bus_error_message(&error
, r
));
5129 static int import_environment(sd_bus
*bus
, char **args
) {
5130 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5131 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5137 polkit_agent_open_if_enabled();
5139 r
= sd_bus_message_new_method_call(
5142 "org.freedesktop.systemd1",
5143 "/org/freedesktop/systemd1",
5144 "org.freedesktop.systemd1.Manager",
5147 return bus_log_create_error(r
);
5149 if (strv_isempty(args
+ 1))
5150 r
= sd_bus_message_append_strv(m
, environ
);
5154 r
= sd_bus_message_open_container(m
, 'a', "s");
5156 return bus_log_create_error(r
);
5158 STRV_FOREACH(a
, args
+ 1) {
5160 if (!env_name_is_valid(*a
)) {
5161 log_error("Not a valid environment variable name: %s", *a
);
5165 STRV_FOREACH(b
, environ
) {
5168 eq
= startswith(*b
, *a
);
5169 if (eq
&& *eq
== '=') {
5171 r
= sd_bus_message_append(m
, "s", *b
);
5173 return bus_log_create_error(r
);
5180 r
= sd_bus_message_close_container(m
);
5183 return bus_log_create_error(r
);
5185 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5187 log_error("Failed to import environment: %s", bus_error_message(&error
, r
));
5194 static int enable_sysv_units(const char *verb
, char **args
) {
5197 #if defined(HAVE_SYSV_COMPAT)
5199 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5201 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5204 if (!STR_IN_SET(verb
,
5210 /* Processes all SysV units, and reshuffles the array so that
5211 * afterwards only the native units remain */
5213 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5220 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5221 bool found_native
= false, found_sysv
;
5223 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5231 if (!endswith(name
, ".service"))
5234 if (path_is_absolute(name
))
5237 STRV_FOREACH(k
, paths
.unit_path
) {
5238 _cleanup_free_
char *path
= NULL
;
5240 path
= path_join(arg_root
, *k
, name
);
5244 found_native
= access(path
, F_OK
) >= 0;
5249 /* If we have both a native unit and a SysV script,
5250 * enable/disable them both (below); for is-enabled, prefer the
5252 if (found_native
&& streq(verb
, "is-enabled"))
5255 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5259 p
[strlen(p
) - strlen(".service")] = 0;
5260 found_sysv
= access(p
, F_OK
) >= 0;
5265 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5267 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5269 if (!isempty(arg_root
))
5270 argv
[c
++] = q
= strappend("--root=", arg_root
);
5273 argv
[c
++] = basename(p
);
5276 l
= strv_join((char**)argv
, " ");
5280 log_info("Executing %s", l
);
5284 return log_error_errno(errno
, "Failed to fork: %m");
5285 else if (pid
== 0) {
5288 (void) reset_all_signal_handlers();
5289 (void) reset_signal_mask();
5291 execv(argv
[0], (char**) argv
);
5292 log_error("Failed to execute %s: %m", argv
[0]);
5293 _exit(EXIT_FAILURE
);
5296 j
= wait_for_terminate(pid
, &status
);
5298 log_error_errno(r
, "Failed to wait for child: %m");
5302 if (status
.si_code
== CLD_EXITED
) {
5303 if (streq(verb
, "is-enabled")) {
5304 if (status
.si_status
== 0) {
5313 } else if (status
.si_status
!= 0)
5321 /* Remove this entry, so that we don't try enabling it as native unit */
5324 assert(args
[f
] == name
);
5325 strv_remove(args
, name
);
5332 static int mangle_names(char **original_names
, char ***mangled_names
) {
5333 char **i
, **l
, **name
;
5336 l
= i
= new(char*, strv_length(original_names
) + 1);
5340 STRV_FOREACH(name
, original_names
) {
5342 /* When enabling units qualified path names are OK,
5343 * too, hence allow them explicitly. */
5345 if (is_path(*name
)) {
5352 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5355 return log_error_errno(r
, "Failed to mangle unit name: %m");
5368 static int enable_unit(sd_bus
*bus
, char **args
) {
5369 _cleanup_strv_free_
char **names
= NULL
;
5370 const char *verb
= args
[0];
5371 UnitFileChange
*changes
= NULL
;
5372 unsigned n_changes
= 0;
5373 int carries_install_info
= -1;
5379 r
= mangle_names(args
+1, &names
);
5383 r
= enable_sysv_units(verb
, names
);
5387 /* If the operation was fully executed by the SysV compat,
5388 * let's finish early */
5389 if (strv_isempty(names
))
5392 if (!bus
|| avoid_bus()) {
5393 if (streq(verb
, "enable")) {
5394 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5395 carries_install_info
= r
;
5396 } else if (streq(verb
, "disable"))
5397 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5398 else if (streq(verb
, "reenable")) {
5399 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5400 carries_install_info
= r
;
5401 } else if (streq(verb
, "link"))
5402 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5403 else if (streq(verb
, "preset")) {
5404 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5405 carries_install_info
= r
;
5406 } else if (streq(verb
, "mask"))
5407 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5408 else if (streq(verb
, "unmask"))
5409 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5411 assert_not_reached("Unknown verb");
5414 log_error_errno(r
, "Operation failed: %m");
5419 dump_unit_file_changes(changes
, n_changes
);
5423 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5424 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5425 int expect_carries_install_info
= false;
5426 bool send_force
= true, send_preset_mode
= false;
5429 polkit_agent_open_if_enabled();
5431 if (streq(verb
, "enable")) {
5432 method
= "EnableUnitFiles";
5433 expect_carries_install_info
= true;
5434 } else if (streq(verb
, "disable")) {
5435 method
= "DisableUnitFiles";
5437 } else if (streq(verb
, "reenable")) {
5438 method
= "ReenableUnitFiles";
5439 expect_carries_install_info
= true;
5440 } else if (streq(verb
, "link"))
5441 method
= "LinkUnitFiles";
5442 else if (streq(verb
, "preset")) {
5444 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5445 method
= "PresetUnitFilesWithMode";
5446 send_preset_mode
= true;
5448 method
= "PresetUnitFiles";
5450 expect_carries_install_info
= true;
5451 } else if (streq(verb
, "mask"))
5452 method
= "MaskUnitFiles";
5453 else if (streq(verb
, "unmask")) {
5454 method
= "UnmaskUnitFiles";
5457 assert_not_reached("Unknown verb");
5459 r
= sd_bus_message_new_method_call(
5462 "org.freedesktop.systemd1",
5463 "/org/freedesktop/systemd1",
5464 "org.freedesktop.systemd1.Manager",
5467 return bus_log_create_error(r
);
5469 r
= sd_bus_message_append_strv(m
, names
);
5471 return bus_log_create_error(r
);
5473 if (send_preset_mode
) {
5474 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5476 return bus_log_create_error(r
);
5479 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5481 return bus_log_create_error(r
);
5484 r
= sd_bus_message_append(m
, "b", arg_force
);
5486 return bus_log_create_error(r
);
5489 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5491 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5495 if (expect_carries_install_info
) {
5496 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5498 return bus_log_parse_error(r
);
5501 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5505 /* Try to reload if enabled */
5507 r
= daemon_reload(bus
, args
);
5512 if (carries_install_info
== 0)
5513 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5514 "using systemctl.\n"
5515 "Possible reasons for having this kind of units are:\n"
5516 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5517 " .wants/ or .requires/ directory.\n"
5518 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5519 " a requirement dependency on it.\n"
5520 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5521 " D-Bus, udev, scripted systemctl call, ...).\n");
5523 if (arg_now
&& n_changes
> 0 && STR_IN_SET(args
[0], "enable", "disable", "mask")) {
5524 char *new_args
[n_changes
+ 2];
5527 new_args
[0] = streq(args
[0], "enable") ? (char *)"start" : (char *)"stop";
5528 for (i
= 0; i
< n_changes
; i
++)
5529 new_args
[i
+ 1] = basename(changes
[i
].path
);
5530 new_args
[i
+ 1] = NULL
;
5532 r
= start_unit(bus
, new_args
);
5536 unit_file_changes_free(changes
, n_changes
);
5541 static int add_dependency(sd_bus
*bus
, char **args
) {
5542 _cleanup_strv_free_
char **names
= NULL
;
5543 _cleanup_free_
char *target
= NULL
;
5544 const char *verb
= args
[0];
5551 r
= unit_name_mangle_with_suffix(args
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5553 return log_error_errno(r
, "Failed to mangle unit name: %m");
5555 r
= mangle_names(args
+2, &names
);
5559 if (streq(verb
, "add-wants"))
5561 else if (streq(verb
, "add-requires"))
5562 dep
= UNIT_REQUIRES
;
5564 assert_not_reached("Unknown verb");
5566 if (!bus
|| avoid_bus()) {
5567 UnitFileChange
*changes
= NULL
;
5568 unsigned n_changes
= 0;
5570 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5573 return log_error_errno(r
, "Can't add dependency: %m");
5576 dump_unit_file_changes(changes
, n_changes
);
5578 unit_file_changes_free(changes
, n_changes
);
5581 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5582 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5584 polkit_agent_open_if_enabled();
5586 r
= sd_bus_message_new_method_call(
5589 "org.freedesktop.systemd1",
5590 "/org/freedesktop/systemd1",
5591 "org.freedesktop.systemd1.Manager",
5592 "AddDependencyUnitFiles");
5594 return bus_log_create_error(r
);
5596 r
= sd_bus_message_append_strv(m
, names
);
5598 return bus_log_create_error(r
);
5600 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5602 return bus_log_create_error(r
);
5604 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5606 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5610 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5615 r
= daemon_reload(bus
, args
);
5623 static int preset_all(sd_bus
*bus
, char **args
) {
5624 UnitFileChange
*changes
= NULL
;
5625 unsigned n_changes
= 0;
5628 if (!bus
|| avoid_bus()) {
5630 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5632 log_error_errno(r
, "Operation failed: %m");
5637 dump_unit_file_changes(changes
, n_changes
);
5642 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5643 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5645 polkit_agent_open_if_enabled();
5647 r
= sd_bus_call_method(
5649 "org.freedesktop.systemd1",
5650 "/org/freedesktop/systemd1",
5651 "org.freedesktop.systemd1.Manager",
5652 "PresetAllUnitFiles",
5656 unit_file_preset_mode_to_string(arg_preset_mode
),
5660 log_error("Failed to execute operation: %s", bus_error_message(&error
, r
));
5664 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5669 r
= daemon_reload(bus
, args
);
5675 unit_file_changes_free(changes
, n_changes
);
5680 static int unit_is_enabled(sd_bus
*bus
, char **args
) {
5682 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5683 _cleanup_strv_free_
char **names
= NULL
;
5688 r
= mangle_names(args
+1, &names
);
5692 r
= enable_sysv_units(args
[0], names
);
5698 if (!bus
|| avoid_bus()) {
5700 STRV_FOREACH(name
, names
) {
5701 UnitFileState state
;
5703 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5705 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5709 UNIT_FILE_ENABLED_RUNTIME
,
5711 UNIT_FILE_INDIRECT
))
5715 puts(unit_file_state_to_string(state
));
5719 STRV_FOREACH(name
, names
) {
5720 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5723 r
= sd_bus_call_method(
5725 "org.freedesktop.systemd1",
5726 "/org/freedesktop/systemd1",
5727 "org.freedesktop.systemd1.Manager",
5733 log_error("Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5737 r
= sd_bus_message_read(reply
, "s", &s
);
5739 return bus_log_parse_error(r
);
5741 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5752 static int is_system_running(sd_bus
*bus
, char **args
) {
5753 _cleanup_free_
char *state
= NULL
;
5756 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5759 return EXIT_FAILURE
;
5762 r
= sd_bus_get_property_string(
5764 "org.freedesktop.systemd1",
5765 "/org/freedesktop/systemd1",
5766 "org.freedesktop.systemd1.Manager",
5779 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5782 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5787 assert(original_path
);
5790 r
= tempfn_random(new_path
, NULL
, &t
);
5792 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5794 r
= mkdir_parents(new_path
, 0755);
5796 log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5801 r
= copy_file(original_path
, t
, 0, 0644, 0);
5805 log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5810 log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5820 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5821 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5823 switch (arg_scope
) {
5824 case UNIT_FILE_SYSTEM
:
5825 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5827 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5829 case UNIT_FILE_GLOBAL
:
5830 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5832 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5834 case UNIT_FILE_USER
:
5836 assert(user_runtime
);
5838 path
= path_join(arg_root
, user_home
, name
);
5840 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5843 run
= path_join(arg_root
, user_runtime
, name
);
5847 assert_not_reached("Invalid scope");
5849 if (!path
|| (arg_runtime
&& !run
))
5853 if (access(path
, F_OK
) >= 0)
5854 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5856 if (path2
&& access(path2
, F_OK
) >= 0)
5857 return log_error_errno(EEXIST
, "Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.",
5869 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
) {
5870 char *tmp_new_path
, *ending
;
5875 assert(ret_new_path
);
5876 assert(ret_tmp_path
);
5878 ending
= strjoina(unit_name
, ".d/override.conf");
5879 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5883 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5889 *ret_new_path
= tmp_new_path
;
5890 *ret_tmp_path
= tmp_tmp_path
;
5895 static int unit_file_create_copy(
5896 const char *unit_name
,
5897 const char *fragment_path
,
5898 const char *user_home
,
5899 const char *user_runtime
,
5900 char **ret_new_path
,
5901 char **ret_tmp_path
) {
5907 assert(fragment_path
);
5909 assert(ret_new_path
);
5910 assert(ret_tmp_path
);
5912 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5916 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5919 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5924 if (response
!= 'y') {
5925 log_warning("%s ignored", unit_name
);
5931 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5933 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5938 *ret_new_path
= tmp_new_path
;
5939 *ret_tmp_path
= tmp_tmp_path
;
5944 static int run_editor(char **paths
) {
5952 log_error_errno(errno
, "Failed to fork: %m");
5958 char *editor
, **editor_args
= NULL
;
5959 char **tmp_path
, **original_path
, *p
;
5960 unsigned n_editor_args
= 0, i
= 1;
5963 (void) reset_all_signal_handlers();
5964 (void) reset_signal_mask();
5966 argc
= strv_length(paths
)/2 + 1;
5968 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
5969 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
5970 * we try to execute well known editors
5972 editor
= getenv("SYSTEMD_EDITOR");
5974 editor
= getenv("EDITOR");
5976 editor
= getenv("VISUAL");
5978 if (!isempty(editor
)) {
5979 editor_args
= strv_split(editor
, WHITESPACE
);
5982 _exit(EXIT_FAILURE
);
5984 n_editor_args
= strv_length(editor_args
);
5985 argc
+= n_editor_args
- 1;
5987 args
= newa(const char*, argc
+ 1);
5989 if (n_editor_args
> 0) {
5990 args
[0] = editor_args
[0];
5991 for (; i
< n_editor_args
; i
++)
5992 args
[i
] = editor_args
[i
];
5995 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
5996 args
[i
] = *tmp_path
;
6001 if (n_editor_args
> 0)
6002 execvp(args
[0], (char* const*) args
);
6004 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6006 execvp(p
, (char* const*) args
);
6007 /* We do not fail if the editor doesn't exist
6008 * because we want to try each one of them before
6011 if (errno
!= ENOENT
) {
6012 log_error("Failed to execute %s: %m", editor
);
6013 _exit(EXIT_FAILURE
);
6017 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6018 _exit(EXIT_FAILURE
);
6021 r
= wait_for_terminate_and_warn("editor", pid
, true);
6023 return log_error_errno(r
, "Failed to wait for child: %m");
6028 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6029 _cleanup_free_
char *user_home
= NULL
;
6030 _cleanup_free_
char *user_runtime
= NULL
;
6031 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6032 bool avoid_bus_cache
;
6039 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6043 avoid_bus_cache
= !bus
|| avoid_bus();
6045 STRV_FOREACH(name
, names
) {
6046 _cleanup_free_
char *path
= NULL
;
6047 char *new_path
, *tmp_path
;
6049 r
= unit_find_paths(bus
, *name
, avoid_bus_cache
, &lp
, &path
, NULL
);
6055 // FIXME: support units with path==NULL (no FragmentPath)
6056 log_error("No fragment exists for %s.", *name
);
6061 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6063 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6067 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6075 static int edit(sd_bus
*bus
, char **args
) {
6076 _cleanup_strv_free_
char **names
= NULL
;
6077 _cleanup_strv_free_
char **paths
= NULL
;
6078 char **original
, **tmp
;
6084 log_error("Cannot edit units if not on a tty");
6088 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6089 log_error("Cannot remotely edit units");
6093 r
= expand_names(bus
, args
+ 1, NULL
, &names
);
6095 return log_error_errno(r
, "Failed to expand names: %m");
6097 r
= find_paths_to_edit(bus
, names
, &paths
);
6101 if (strv_isempty(paths
))
6104 r
= run_editor(paths
);
6108 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6109 /* If the temporary file is empty we ignore it.
6110 * It's useful if the user wants to cancel its modification
6112 if (null_or_empty_path(*tmp
)) {
6113 log_warning("Editing \"%s\" canceled: temporary file is empty", *original
);
6116 r
= rename(*tmp
, *original
);
6118 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6123 if (!arg_no_reload
&& bus
&& !avoid_bus())
6124 r
= daemon_reload(bus
, args
);
6127 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6128 unlink_noerrno(*tmp
);
6133 static void systemctl_help(void) {
6135 pager_open_if_enabled();
6137 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6138 "Query or send control commands to the systemd manager.\n\n"
6139 " -h --help Show this help\n"
6140 " --version Show package version\n"
6141 " --system Connect to system manager\n"
6142 " --user Connect to user service manager\n"
6143 " -H --host=[USER@]HOST\n"
6144 " Operate on remote host\n"
6145 " -M --machine=CONTAINER\n"
6146 " Operate on local container\n"
6147 " -t --type=TYPE List units of a particular type\n"
6148 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6149 " -p --property=NAME Show only properties by this name\n"
6150 " -a --all Show all loaded units/properties, including dead/empty\n"
6151 " ones. To list all units installed on the system, use\n"
6152 " the 'list-unit-files' command instead.\n"
6153 " -l --full Don't ellipsize unit names on output\n"
6154 " -r --recursive Show unit list of host and local containers\n"
6155 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6156 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6157 " queueing a new job\n"
6158 " --show-types When showing sockets, explicitly show their type\n"
6159 " -i --ignore-inhibitors\n"
6160 " When shutting down or sleeping, ignore inhibitors\n"
6161 " --kill-who=WHO Who to send signal to\n"
6162 " -s --signal=SIGNAL Which signal to send\n"
6163 " --now Start or stop unit in addition to enabling or disabling it\n"
6164 " -q --quiet Suppress output\n"
6165 " --no-block Do not wait until operation finished\n"
6166 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6167 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6168 " --no-legend Do not print a legend (column headers and hints)\n"
6169 " --no-pager Do not pipe output into a pager\n"
6170 " --no-ask-password\n"
6171 " Do not ask for system passwords\n"
6172 " --global Enable/disable unit files globally\n"
6173 " --runtime Enable unit files only temporarily until next reboot\n"
6174 " -f --force When enabling unit files, override existing symlinks\n"
6175 " When shutting down, execute action immediately\n"
6176 " --preset-mode= Apply only enable, only disable, or all presets\n"
6177 " --root=PATH Enable unit files in the specified root directory\n"
6178 " -n --lines=INTEGER Number of journal entries to show\n"
6179 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6180 " short-precise, short-monotonic, verbose,\n"
6181 " export, json, json-pretty, json-sse, cat)\n"
6182 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6183 " --plain Print unit dependencies as a list instead of a tree\n\n"
6185 " list-units [PATTERN...] List loaded units\n"
6186 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6187 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6188 " start NAME... Start (activate) one or more units\n"
6189 " stop NAME... Stop (deactivate) one or more units\n"
6190 " reload NAME... Reload one or more units\n"
6191 " restart NAME... Start or restart one or more units\n"
6192 " try-restart NAME... Restart one or more units if active\n"
6193 " reload-or-restart NAME... Reload one or more units if possible,\n"
6194 " otherwise start or restart\n"
6195 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6196 " otherwise restart if active\n"
6197 " isolate NAME Start one unit and stop all others\n"
6198 " kill NAME... Send signal to processes of a unit\n"
6199 " is-active PATTERN... Check whether units are active\n"
6200 " is-failed PATTERN... Check whether units are failed\n"
6201 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6202 " show [PATTERN...|JOB...] Show properties of one or more\n"
6203 " units/jobs or the manager\n"
6204 " cat PATTERN... Show files and drop-ins of one or more units\n"
6205 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6206 " help PATTERN...|PID... Show manual for one or more units\n"
6207 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6209 " list-dependencies [NAME] Recursively show units which are required\n"
6210 " or wanted by this unit or by which this\n"
6211 " unit is required or wanted\n\n"
6212 "Unit File Commands:\n"
6213 " list-unit-files [PATTERN...] List installed unit files\n"
6214 " enable NAME... Enable one or more unit files\n"
6215 " disable NAME... Disable one or more unit files\n"
6216 " reenable NAME... Reenable one or more unit files\n"
6217 " preset NAME... Enable/disable one or more unit files\n"
6218 " based on preset configuration\n"
6219 " preset-all Enable/disable all unit files based on\n"
6220 " preset configuration\n"
6221 " is-enabled NAME... Check whether unit files are enabled\n"
6222 " mask NAME... Mask one or more units\n"
6223 " unmask NAME... Unmask one or more units\n"
6224 " link PATH... Link one or more units files into\n"
6225 " the search path\n"
6226 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6227 " on specified one or more units\n"
6228 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6229 " on specified one or more units\n"
6230 " edit NAME... Edit one or more unit files\n"
6231 " get-default Get the name of the default target\n"
6232 " set-default NAME Set the default target\n\n"
6233 "Machine Commands:\n"
6234 " list-machines [PATTERN...] List local containers and host\n\n"
6236 " list-jobs [PATTERN...] List jobs\n"
6237 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6238 "Snapshot Commands:\n"
6239 " snapshot [NAME] Create a snapshot\n"
6240 " delete NAME... Remove one or more snapshots\n\n"
6241 "Environment Commands:\n"
6242 " show-environment Dump environment\n"
6243 " set-environment NAME=VALUE... Set one or more environment variables\n"
6244 " unset-environment NAME... Unset one or more environment variables\n"
6245 " import-environment [NAME...] Import all or some environment variables\n\n"
6246 "Manager Lifecycle Commands:\n"
6247 " daemon-reload Reload systemd manager configuration\n"
6248 " daemon-reexec Reexecute systemd manager\n\n"
6249 "System Commands:\n"
6250 " is-system-running Check whether system is fully running\n"
6251 " default Enter system default mode\n"
6252 " rescue Enter system rescue mode\n"
6253 " emergency Enter system emergency mode\n"
6254 " halt Shut down and halt the system\n"
6255 " poweroff Shut down and power-off the system\n"
6256 " reboot [ARG] Shut down and reboot the system\n"
6257 " kexec Shut down and reboot the system with kexec\n"
6258 " exit [EXIT_CODE] Request user instance or container exit\n"
6259 " switch-root ROOT [INIT] Change to a different root file system\n"
6260 " suspend Suspend the system\n"
6261 " hibernate Hibernate the system\n"
6262 " hybrid-sleep Hibernate and suspend the system\n",
6263 program_invocation_short_name
);
6266 static void halt_help(void) {
6267 printf("%s [OPTIONS...]%s\n\n"
6268 "%s the system.\n\n"
6269 " --help Show this help\n"
6270 " --halt Halt the machine\n"
6271 " -p --poweroff Switch off the machine\n"
6272 " --reboot Reboot the machine\n"
6273 " -f --force Force immediate halt/power-off/reboot\n"
6274 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6275 " -d --no-wtmp Don't write wtmp record\n"
6276 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6277 program_invocation_short_name
,
6278 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6279 arg_action
== ACTION_REBOOT
? "Reboot" :
6280 arg_action
== ACTION_POWEROFF
? "Power off" :
6284 static void shutdown_help(void) {
6285 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6286 "Shut down the system.\n\n"
6287 " --help Show this help\n"
6288 " -H --halt Halt the machine\n"
6289 " -P --poweroff Power-off the machine\n"
6290 " -r --reboot Reboot the machine\n"
6291 " -h Equivalent to --poweroff, overridden by --halt\n"
6292 " -k Don't halt/power-off/reboot, just send warnings\n"
6293 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6294 " -c Cancel a pending shutdown\n",
6295 program_invocation_short_name
);
6298 static void telinit_help(void) {
6299 printf("%s [OPTIONS...] {COMMAND}\n\n"
6300 "Send control commands to the init daemon.\n\n"
6301 " --help Show this help\n"
6302 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6304 " 0 Power-off the machine\n"
6305 " 6 Reboot the machine\n"
6306 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6307 " 1, s, S Enter rescue mode\n"
6308 " q, Q Reload init daemon configuration\n"
6309 " u, U Reexecute init daemon\n",
6310 program_invocation_short_name
);
6313 static void runlevel_help(void) {
6314 printf("%s [OPTIONS...]\n\n"
6315 "Prints the previous and current runlevel of the init system.\n\n"
6316 " --help Show this help\n",
6317 program_invocation_short_name
);
6320 static void help_types(void) {
6325 puts("Available unit types:");
6326 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++) {
6327 t
= unit_type_to_string(i
);
6333 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6342 ARG_IGNORE_DEPENDENCIES
,
6354 ARG_NO_ASK_PASSWORD
,
6367 static const struct option options
[] = {
6368 { "help", no_argument
, NULL
, 'h' },
6369 { "version", no_argument
, NULL
, ARG_VERSION
},
6370 { "type", required_argument
, NULL
, 't' },
6371 { "property", required_argument
, NULL
, 'p' },
6372 { "all", no_argument
, NULL
, 'a' },
6373 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6374 { "after", no_argument
, NULL
, ARG_AFTER
},
6375 { "before", no_argument
, NULL
, ARG_BEFORE
},
6376 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6377 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6378 { "full", no_argument
, NULL
, 'l' },
6379 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6380 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6381 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6382 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6383 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6384 { "user", no_argument
, NULL
, ARG_USER
},
6385 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6386 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6387 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6388 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6389 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6390 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6391 { "quiet", no_argument
, NULL
, 'q' },
6392 { "root", required_argument
, NULL
, ARG_ROOT
},
6393 { "force", no_argument
, NULL
, ARG_FORCE
},
6394 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6395 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6396 { "signal", required_argument
, NULL
, 's' },
6397 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6398 { "host", required_argument
, NULL
, 'H' },
6399 { "machine", required_argument
, NULL
, 'M' },
6400 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6401 { "lines", required_argument
, NULL
, 'n' },
6402 { "output", required_argument
, NULL
, 'o' },
6403 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6404 { "state", required_argument
, NULL
, ARG_STATE
},
6405 { "recursive", no_argument
, NULL
, 'r' },
6406 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6407 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6408 { "now", no_argument
, NULL
, ARG_NOW
},
6409 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6418 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6419 arg_ask_password
= true;
6421 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6433 const char *word
, *state
;
6436 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6437 _cleanup_free_
char *type
;
6439 type
= strndup(word
, size
);
6443 if (streq(type
, "help")) {
6448 if (unit_type_from_string(type
) >= 0) {
6449 if (strv_push(&arg_types
, type
))
6455 /* It's much nicer to use --state= for
6456 * load states, but let's support this
6457 * in --types= too for compatibility
6458 * with old versions */
6459 if (unit_load_state_from_string(optarg
) >= 0) {
6460 if (strv_push(&arg_states
, type
) < 0)
6466 log_error("Unknown unit type or load state '%s'.", type
);
6467 log_info("Use -t help to see a list of allowed values.");
6475 /* Make sure that if the empty property list
6476 was specified, we won't show any properties. */
6477 if (isempty(optarg
) && !arg_properties
) {
6478 arg_properties
= new0(char*, 1);
6479 if (!arg_properties
)
6482 const char *word
, *state
;
6485 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6488 prop
= strndup(word
, size
);
6492 if (strv_consume(&arg_properties
, prop
) < 0)
6497 /* If the user asked for a particular
6498 * property, show it to him, even if it is
6510 arg_dependency
= DEPENDENCY_REVERSE
;
6514 arg_dependency
= DEPENDENCY_AFTER
;
6518 arg_dependency
= DEPENDENCY_BEFORE
;
6521 case ARG_SHOW_TYPES
:
6522 arg_show_types
= true;
6526 arg_job_mode
= optarg
;
6530 arg_job_mode
= "fail";
6533 case ARG_IRREVERSIBLE
:
6534 arg_job_mode
= "replace-irreversibly";
6537 case ARG_IGNORE_DEPENDENCIES
:
6538 arg_job_mode
= "ignore-dependencies";
6542 arg_scope
= UNIT_FILE_USER
;
6546 arg_scope
= UNIT_FILE_SYSTEM
;
6550 arg_scope
= UNIT_FILE_GLOBAL
;
6554 arg_no_block
= true;
6558 arg_no_legend
= true;
6562 arg_no_pager
= true;
6578 if (strv_extend(&arg_states
, "failed") < 0)
6596 arg_no_reload
= true;
6600 arg_kill_who
= optarg
;
6604 if ((arg_signal
= signal_from_string_try_harder(optarg
)) < 0) {
6605 log_error("Failed to parse signal string %s.", optarg
);
6610 case ARG_NO_ASK_PASSWORD
:
6611 arg_ask_password
= false;
6615 arg_transport
= BUS_TRANSPORT_REMOTE
;
6620 arg_transport
= BUS_TRANSPORT_MACHINE
;
6629 if (safe_atou(optarg
, &arg_lines
) < 0) {
6630 log_error("Failed to parse lines '%s'", optarg
);
6636 arg_output
= output_mode_from_string(optarg
);
6637 if (arg_output
< 0) {
6638 log_error("Unknown output '%s'.", optarg
);
6644 arg_ignore_inhibitors
= true;
6651 case ARG_FIRMWARE_SETUP
:
6652 arg_firmware_setup
= true;
6656 const char *word
, *state
;
6659 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6662 s
= strndup(word
, size
);
6666 if (strv_consume(&arg_states
, s
) < 0)
6673 if (geteuid() != 0) {
6674 log_error("--recursive requires root privileges.");
6678 arg_recursive
= true;
6681 case ARG_PRESET_MODE
:
6683 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6684 if (arg_preset_mode
< 0) {
6685 log_error("Failed to parse preset mode: %s.", optarg
);
6696 if (strv_extend(&arg_wall
, optarg
) < 0)
6704 assert_not_reached("Unhandled option");
6707 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6708 log_error("Cannot access user instance remotely.");
6715 static int halt_parse_argv(int argc
, char *argv
[]) {
6724 static const struct option options
[] = {
6725 { "help", no_argument
, NULL
, ARG_HELP
},
6726 { "halt", no_argument
, NULL
, ARG_HALT
},
6727 { "poweroff", no_argument
, NULL
, 'p' },
6728 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6729 { "force", no_argument
, NULL
, 'f' },
6730 { "wtmp-only", no_argument
, NULL
, 'w' },
6731 { "no-wtmp", no_argument
, NULL
, 'd' },
6732 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6741 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6742 if (runlevel
== '0' || runlevel
== '6')
6745 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6753 arg_action
= ACTION_HALT
;
6757 if (arg_action
!= ACTION_REBOOT
)
6758 arg_action
= ACTION_POWEROFF
;
6762 arg_action
= ACTION_REBOOT
;
6784 /* Compatibility nops */
6791 assert_not_reached("Unhandled option");
6794 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6795 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6798 } else if (optind
< argc
) {
6799 log_error("Too many arguments.");
6806 static int parse_time_spec(const char *t
, usec_t
*_u
) {
6810 if (streq(t
, "now"))
6812 else if (!strchr(t
, ':')) {
6815 if (safe_atou64(t
, &u
) < 0)
6818 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6827 hour
= strtol(t
, &e
, 10);
6828 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6831 minute
= strtol(e
+1, &e
, 10);
6832 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6835 n
= now(CLOCK_REALTIME
);
6836 s
= (time_t) (n
/ USEC_PER_SEC
);
6838 assert_se(localtime_r(&s
, &tm
));
6840 tm
.tm_hour
= (int) hour
;
6841 tm
.tm_min
= (int) minute
;
6844 assert_se(s
= mktime(&tm
));
6846 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6849 *_u
+= USEC_PER_DAY
;
6855 static int shutdown_parse_argv(int argc
, char *argv
[]) {
6862 static const struct option options
[] = {
6863 { "help", no_argument
, NULL
, ARG_HELP
},
6864 { "halt", no_argument
, NULL
, 'H' },
6865 { "poweroff", no_argument
, NULL
, 'P' },
6866 { "reboot", no_argument
, NULL
, 'r' },
6867 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
6868 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6877 while ((c
= getopt_long(argc
, argv
, "HPrhkKt:afFc", options
, NULL
)) >= 0)
6885 arg_action
= ACTION_HALT
;
6889 arg_action
= ACTION_POWEROFF
;
6894 arg_action
= ACTION_KEXEC
;
6896 arg_action
= ACTION_REBOOT
;
6900 arg_action
= ACTION_KEXEC
;
6904 if (arg_action
!= ACTION_HALT
)
6905 arg_action
= ACTION_POWEROFF
;
6920 /* Compatibility nops */
6924 arg_action
= ACTION_CANCEL_SHUTDOWN
;
6931 assert_not_reached("Unhandled option");
6934 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
6935 r
= parse_time_spec(argv
[optind
], &arg_when
);
6937 log_error("Failed to parse time specification: %s", argv
[optind
]);
6941 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
6943 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
6944 /* No time argument for shutdown cancel */
6945 arg_wall
= argv
+ optind
;
6946 else if (argc
> optind
+ 1)
6947 /* We skip the time argument */
6948 arg_wall
= argv
+ optind
+ 1;
6955 static int telinit_parse_argv(int argc
, char *argv
[]) {
6962 static const struct option options
[] = {
6963 { "help", no_argument
, NULL
, ARG_HELP
},
6964 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6968 static const struct {
6972 { '0', ACTION_POWEROFF
},
6973 { '6', ACTION_REBOOT
},
6974 { '1', ACTION_RESCUE
},
6975 { '2', ACTION_RUNLEVEL2
},
6976 { '3', ACTION_RUNLEVEL3
},
6977 { '4', ACTION_RUNLEVEL4
},
6978 { '5', ACTION_RUNLEVEL5
},
6979 { 's', ACTION_RESCUE
},
6980 { 'S', ACTION_RESCUE
},
6981 { 'q', ACTION_RELOAD
},
6982 { 'Q', ACTION_RELOAD
},
6983 { 'u', ACTION_REEXEC
},
6984 { 'U', ACTION_REEXEC
}
6993 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7008 assert_not_reached("Unhandled option");
7011 if (optind
>= argc
) {
7012 log_error("%s: required argument missing.",
7013 program_invocation_short_name
);
7017 if (optind
+ 1 < argc
) {
7018 log_error("Too many arguments.");
7022 if (strlen(argv
[optind
]) != 1) {
7023 log_error("Expected single character argument.");
7027 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7028 if (table
[i
].from
== argv
[optind
][0])
7031 if (i
>= ELEMENTSOF(table
)) {
7032 log_error("Unknown command '%s'.", argv
[optind
]);
7036 arg_action
= table
[i
].to
;
7043 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7049 static const struct option options
[] = {
7050 { "help", no_argument
, NULL
, ARG_HELP
},
7059 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7070 assert_not_reached("Unhandled option");
7073 if (optind
< argc
) {
7074 log_error("Too many arguments.");
7081 static int parse_argv(int argc
, char *argv
[]) {
7085 if (program_invocation_short_name
) {
7087 if (strstr(program_invocation_short_name
, "halt")) {
7088 arg_action
= ACTION_HALT
;
7089 return halt_parse_argv(argc
, argv
);
7090 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7091 arg_action
= ACTION_POWEROFF
;
7092 return halt_parse_argv(argc
, argv
);
7093 } else if (strstr(program_invocation_short_name
, "reboot")) {
7095 arg_action
= ACTION_KEXEC
;
7097 arg_action
= ACTION_REBOOT
;
7098 return halt_parse_argv(argc
, argv
);
7099 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7100 arg_action
= ACTION_POWEROFF
;
7101 return shutdown_parse_argv(argc
, argv
);
7102 } else if (strstr(program_invocation_short_name
, "init")) {
7104 if (sd_booted() > 0) {
7105 arg_action
= _ACTION_INVALID
;
7106 return telinit_parse_argv(argc
, argv
);
7108 /* Hmm, so some other init system is
7109 * running, we need to forward this
7110 * request to it. For now we simply
7111 * guess that it is Upstart. */
7113 execv(TELINIT
, argv
);
7115 log_error("Couldn't find an alternative telinit implementation to spawn.");
7119 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7120 arg_action
= ACTION_RUNLEVEL
;
7121 return runlevel_parse_argv(argc
, argv
);
7125 arg_action
= ACTION_SYSTEMCTL
;
7126 return systemctl_parse_argv(argc
, argv
);
7129 _pure_
static int action_to_runlevel(void) {
7131 static const char table
[_ACTION_MAX
] = {
7132 [ACTION_HALT
] = '0',
7133 [ACTION_POWEROFF
] = '0',
7134 [ACTION_REBOOT
] = '6',
7135 [ACTION_RUNLEVEL2
] = '2',
7136 [ACTION_RUNLEVEL3
] = '3',
7137 [ACTION_RUNLEVEL4
] = '4',
7138 [ACTION_RUNLEVEL5
] = '5',
7139 [ACTION_RESCUE
] = '1'
7142 assert(arg_action
< _ACTION_MAX
);
7144 return table
[arg_action
];
7147 static int talk_initctl(void) {
7149 struct init_request request
= {
7150 .magic
= INIT_MAGIC
,
7152 .cmd
= INIT_CMD_RUNLVL
7155 _cleanup_close_
int fd
= -1;
7159 rl
= action_to_runlevel();
7163 request
.runlevel
= rl
;
7165 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7167 if (errno
== ENOENT
)
7170 log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7174 r
= loop_write(fd
, &request
, sizeof(request
), false);
7176 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7181 static int systemctl_main(sd_bus
*bus
, int argc
, char *argv
[], int bus_error
) {
7183 static const struct {
7191 int (* const dispatch
)(sd_bus
*bus
, char **args
);
7197 { "list-units", MORE
, 0, list_units
},
7198 { "list-unit-files", MORE
, 1, list_unit_files
, NOBUS
},
7199 { "list-sockets", MORE
, 1, list_sockets
},
7200 { "list-timers", MORE
, 1, list_timers
},
7201 { "list-jobs", MORE
, 1, list_jobs
},
7202 { "list-machines", MORE
, 1, list_machines
},
7203 { "clear-jobs", EQUAL
, 1, daemon_reload
},
7204 { "cancel", MORE
, 2, cancel_job
},
7205 { "start", MORE
, 2, start_unit
},
7206 { "stop", MORE
, 2, start_unit
},
7207 { "condstop", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7208 { "reload", MORE
, 2, start_unit
},
7209 { "restart", MORE
, 2, start_unit
},
7210 { "try-restart", MORE
, 2, start_unit
},
7211 { "reload-or-restart", MORE
, 2, start_unit
},
7212 { "reload-or-try-restart", MORE
, 2, start_unit
},
7213 { "force-reload", MORE
, 2, start_unit
}, /* For compatibility with SysV */
7214 { "condreload", MORE
, 2, start_unit
}, /* For compatibility with ALTLinux */
7215 { "condrestart", MORE
, 2, start_unit
}, /* For compatibility with RH */
7216 { "isolate", EQUAL
, 2, start_unit
},
7217 { "kill", MORE
, 2, kill_unit
},
7218 { "is-active", MORE
, 2, check_unit_active
},
7219 { "check", MORE
, 2, check_unit_active
},
7220 { "is-failed", MORE
, 2, check_unit_failed
},
7221 { "show", MORE
, 1, show
},
7222 { "cat", MORE
, 2, cat
, NOBUS
},
7223 { "status", MORE
, 1, show
},
7224 { "help", MORE
, 2, show
},
7225 { "snapshot", LESS
, 2, snapshot
},
7226 { "delete", MORE
, 2, delete_snapshot
},
7227 { "daemon-reload", EQUAL
, 1, daemon_reload
},
7228 { "daemon-reexec", EQUAL
, 1, daemon_reload
},
7229 { "show-environment", EQUAL
, 1, show_environment
},
7230 { "set-environment", MORE
, 2, set_environment
},
7231 { "unset-environment", MORE
, 2, set_environment
},
7232 { "import-environment", MORE
, 1, import_environment
},
7233 { "halt", EQUAL
, 1, start_special
, FORCE
},
7234 { "poweroff", EQUAL
, 1, start_special
, FORCE
},
7235 { "reboot", MORE
, 1, start_special
, FORCE
},
7236 { "kexec", EQUAL
, 1, start_special
},
7237 { "suspend", EQUAL
, 1, start_special
},
7238 { "hibernate", EQUAL
, 1, start_special
},
7239 { "hybrid-sleep", EQUAL
, 1, start_special
},
7240 { "default", EQUAL
, 1, start_special
},
7241 { "rescue", EQUAL
, 1, start_special
},
7242 { "emergency", EQUAL
, 1, start_special
},
7243 { "exit", LESS
, 2, start_special
},
7244 { "reset-failed", MORE
, 1, reset_failed
},
7245 { "enable", MORE
, 2, enable_unit
, NOBUS
},
7246 { "disable", MORE
, 2, enable_unit
, NOBUS
},
7247 { "is-enabled", MORE
, 2, unit_is_enabled
, NOBUS
},
7248 { "reenable", MORE
, 2, enable_unit
, NOBUS
},
7249 { "preset", MORE
, 2, enable_unit
, NOBUS
},
7250 { "preset-all", EQUAL
, 1, preset_all
, NOBUS
},
7251 { "mask", MORE
, 2, enable_unit
, NOBUS
},
7252 { "unmask", MORE
, 2, enable_unit
, NOBUS
},
7253 { "link", MORE
, 2, enable_unit
, NOBUS
},
7254 { "switch-root", MORE
, 2, switch_root
},
7255 { "list-dependencies", LESS
, 2, list_dependencies
},
7256 { "set-default", EQUAL
, 2, set_default
, NOBUS
},
7257 { "get-default", EQUAL
, 1, get_default
, NOBUS
},
7258 { "set-property", MORE
, 3, set_property
},
7259 { "is-system-running", EQUAL
, 1, is_system_running
},
7260 { "add-wants", MORE
, 3, add_dependency
, NOBUS
},
7261 { "add-requires", MORE
, 3, add_dependency
, NOBUS
},
7262 { "edit", MORE
, 2, edit
, NOBUS
},
7271 left
= argc
- optind
;
7273 /* Special rule: no arguments (left == 0) means "list-units" */
7275 if (streq(argv
[optind
], "help") && !argv
[optind
+1]) {
7276 log_error("This command expects one or more "
7277 "unit names. Did you mean --help?");
7281 for (; verb
->verb
; verb
++)
7282 if (streq(argv
[optind
], verb
->verb
))
7285 log_error("Unknown operation '%s'.", argv
[optind
]);
7290 switch (verb
->argc_cmp
) {
7293 if (left
!= verb
->argc
) {
7294 log_error("Invalid number of arguments.");
7301 if (left
< verb
->argc
) {
7302 log_error("Too few arguments.");
7309 if (left
> verb
->argc
) {
7310 log_error("Too many arguments.");
7317 assert_not_reached("Unknown comparison operator.");
7320 /* Require a bus connection for all operations but
7322 if (verb
->bus
== NOBUS
) {
7323 if (!bus
&& !avoid_bus()) {
7324 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7329 if (running_in_chroot() > 0) {
7330 log_info("Running in chroot, ignoring request.");
7334 if ((verb
->bus
!= FORCE
|| arg_force
<= 0) && !bus
) {
7335 log_error_errno(bus_error
, "Failed to get D-Bus connection: %m");
7340 return verb
->dispatch(bus
, argv
+ optind
);
7343 static int reload_with_fallback(sd_bus
*bus
) {
7346 /* First, try systemd via D-Bus. */
7347 if (daemon_reload(bus
, NULL
) >= 0)
7351 /* Nothing else worked, so let's try signals */
7352 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7354 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7355 return log_error_errno(errno
, "kill() failed: %m");
7360 static int start_with_fallback(sd_bus
*bus
) {
7363 /* First, try systemd via D-Bus. */
7364 if (start_unit(bus
, NULL
) >= 0)
7368 /* Nothing else worked, so let's try
7370 if (talk_initctl() > 0)
7373 log_error("Failed to talk to init daemon.");
7377 warn_wall(arg_action
);
7381 static int halt_now(enum action a
) {
7383 /* The kernel will automaticall flush ATA disks and suchlike
7384 * on reboot(), but the file systems need to be synce'd
7385 * explicitly in advance. */
7388 /* Make sure C-A-D is handled by the kernel from this point
7390 reboot(RB_ENABLE_CAD
);
7395 log_info("Halting.");
7396 reboot(RB_HALT_SYSTEM
);
7399 case ACTION_POWEROFF
:
7400 log_info("Powering off.");
7401 reboot(RB_POWER_OFF
);
7405 case ACTION_REBOOT
: {
7406 _cleanup_free_
char *param
= NULL
;
7408 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7409 log_info("Rebooting with argument '%s'.", param
);
7410 syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
,
7411 LINUX_REBOOT_CMD_RESTART2
, param
);
7414 log_info("Rebooting.");
7415 reboot(RB_AUTOBOOT
);
7420 assert_not_reached("Unknown action.");
7424 static int halt_main(sd_bus
*bus
) {
7427 r
= check_inhibitors(bus
, arg_action
);
7431 if (geteuid() != 0) {
7435 log_error("Must be root.");
7439 /* Try logind if we are a normal user and no special
7440 * mode applies. Maybe PolicyKit allows us to shutdown
7442 if (IN_SET(arg_action
,
7445 r
= reboot_with_logind(bus
, arg_action
);
7448 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7449 /* requested operation is not supported or already in progress */
7451 /* on all other errors, try low-level operation */
7456 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7457 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7458 _cleanup_free_
char *m
= NULL
;
7461 assert(geteuid() == 0);
7464 log_error("Unable to perform operation without bus connection.");
7468 r
= sd_bus_open_system(&b
);
7470 return log_error_errno(r
, "Unable to open system bus: %m");
7472 m
= strv_join(arg_wall
, " ");
7476 r
= sd_bus_call_method(
7478 "org.freedesktop.login1",
7479 "/org/freedesktop/login1",
7480 "org.freedesktop.login1.Manager",
7489 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7490 bus_error_message(&error
, r
));
7491 sd_bus_error_free(&error
);
7494 switch (arg_action
) {
7498 case ACTION_POWEROFF
:
7499 action
= "poweroff";
7510 action
= strjoina("dry-", action
);
7512 r
= sd_bus_call_method(
7514 "org.freedesktop.login1",
7515 "/org/freedesktop/login1",
7516 "org.freedesktop.login1.Manager",
7524 log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s",
7525 bus_error_message(&error
, r
));
7527 char date
[FORMAT_TIMESTAMP_MAX
];
7529 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.",
7530 format_timestamp(date
, sizeof(date
), arg_when
));
7535 if (!arg_dry
&& !arg_force
)
7536 return start_with_fallback(bus
);
7538 assert(geteuid() == 0);
7541 if (sd_booted() > 0)
7542 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7544 r
= utmp_put_shutdown();
7546 log_warning_errno(r
, "Failed to write utmp record: %m");
7553 r
= halt_now(arg_action
);
7554 log_error_errno(r
, "Failed to reboot: %m");
7559 static int runlevel_main(void) {
7560 int r
, runlevel
, previous
;
7562 r
= utmp_get_runlevel(&runlevel
, &previous
);
7569 previous
<= 0 ? 'N' : previous
,
7570 runlevel
<= 0 ? 'N' : runlevel
);
7575 int main(int argc
, char*argv
[]) {
7576 _cleanup_bus_flush_close_unref_ sd_bus
*bus
= NULL
;
7579 setlocale(LC_ALL
, "");
7580 log_parse_environment();
7583 /* Explicitly not on_tty() to avoid setting cached value.
7584 * This becomes relevant for piping output which might be
7586 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7588 r
= parse_argv(argc
, argv
);
7592 /* /sbin/runlevel doesn't need to communicate via D-Bus, so
7593 * let's shortcut this */
7594 if (arg_action
== ACTION_RUNLEVEL
) {
7595 r
= runlevel_main();
7599 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7600 log_info("Running in chroot, ignoring request.");
7606 r
= bus_open_transport_systemd(arg_transport
, arg_host
, arg_scope
!= UNIT_FILE_SYSTEM
, &bus
);
7609 sd_bus_set_allow_interactive_authorization(bus
, arg_ask_password
);
7611 /* systemctl_main() will print an error message for the bus
7612 * connection, but only if it needs to */
7614 switch (arg_action
) {
7616 case ACTION_SYSTEMCTL
:
7617 r
= systemctl_main(bus
, argc
, argv
, r
);
7621 case ACTION_POWEROFF
:
7627 case ACTION_RUNLEVEL2
:
7628 case ACTION_RUNLEVEL3
:
7629 case ACTION_RUNLEVEL4
:
7630 case ACTION_RUNLEVEL5
:
7632 case ACTION_EMERGENCY
:
7633 case ACTION_DEFAULT
:
7634 r
= start_with_fallback(bus
);
7639 r
= reload_with_fallback(bus
);
7642 case ACTION_CANCEL_SHUTDOWN
: {
7643 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7644 _cleanup_bus_flush_close_unref_ sd_bus
*b
= NULL
;
7645 _cleanup_free_
char *m
= NULL
;
7648 log_error("Unable to perform operation without bus connection.");
7652 r
= sd_bus_open_system(&b
);
7654 return log_error_errno(r
, "Unable to open system bus: %m");
7657 m
= strv_join(arg_wall
, " ");
7664 r
= sd_bus_call_method(
7666 "org.freedesktop.login1",
7667 "/org/freedesktop/login1",
7668 "org.freedesktop.login1.Manager",
7677 log_warning_errno(r
, "Failed to set wall message, ignoring: %s",
7678 bus_error_message(&error
, r
));
7679 sd_bus_error_free(&error
);
7682 r
= sd_bus_call_method(
7684 "org.freedesktop.login1",
7685 "/org/freedesktop/login1",
7686 "org.freedesktop.login1.Manager",
7687 "CancelScheduledShutdown",
7691 log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s",
7692 bus_error_message(&error
, r
));
7696 case ACTION_RUNLEVEL
:
7697 case _ACTION_INVALID
:
7699 assert_not_reached("Unknown action");
7704 ask_password_agent_close();
7705 polkit_agent_close();
7707 strv_free(arg_types
);
7708 strv_free(arg_states
);
7709 strv_free(arg_properties
);
7711 sd_bus_default_flush_close();
7713 return r
< 0 ? EXIT_FAILURE
: r
;