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"
53 #include "formats-util.h"
54 #include "hostname-util.h"
60 #include "logs-show.h"
64 #include "path-lookup.h"
65 #include "path-util.h"
66 #include "process-util.h"
68 #include "signal-util.h"
69 #include "socket-util.h"
70 #include "spawn-ask-password-agent.h"
71 #include "spawn-polkit-agent.h"
74 #include "terminal-util.h"
75 #include "unit-name.h"
77 #include "utmp-wtmp.h"
80 static char **arg_types
= NULL
;
81 static char **arg_states
= NULL
;
82 static char **arg_properties
= NULL
;
83 static bool arg_all
= false;
84 static enum dependency
{
90 } arg_dependency
= DEPENDENCY_FORWARD
;
91 static const char *arg_job_mode
= "replace";
92 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
93 static bool arg_no_block
= false;
94 static bool arg_no_legend
= false;
95 static bool arg_no_pager
= false;
96 static bool arg_no_wtmp
= false;
97 static bool arg_no_wall
= false;
98 static bool arg_no_reload
= false;
99 static bool arg_show_types
= false;
100 static bool arg_ignore_inhibitors
= false;
101 static bool arg_dry
= false;
102 static bool arg_quiet
= false;
103 static bool arg_full
= false;
104 static bool arg_recursive
= false;
105 static int arg_force
= 0;
106 static bool arg_ask_password
= false;
107 static bool arg_runtime
= false;
108 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
109 static char **arg_wall
= NULL
;
110 static const char *arg_kill_who
= NULL
;
111 static int arg_signal
= SIGTERM
;
112 static char *arg_root
= NULL
;
113 static usec_t arg_when
= 0;
135 ACTION_CANCEL_SHUTDOWN
,
137 } arg_action
= ACTION_SYSTEMCTL
;
138 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
139 static const char *arg_host
= NULL
;
140 static unsigned arg_lines
= 10;
141 static OutputMode arg_output
= OUTPUT_SHORT
;
142 static bool arg_plain
= false;
143 static bool arg_firmware_setup
= false;
144 static bool arg_now
= false;
146 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
147 static int halt_now(enum action a
);
148 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
150 static bool original_stdout_is_tty
;
152 typedef enum BusFocus
{
153 BUS_FULL
, /* The full bus indicated via --system or --user */
154 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
158 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
160 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
163 assert(focus
< _BUS_FOCUS_MAX
);
166 /* We only go directly to the manager, if we are using a local transport */
167 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
170 if (!busses
[focus
]) {
173 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
175 if (focus
== BUS_MANAGER
)
176 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
178 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
180 return log_error_errno(r
, "Failed to connect to bus: %m");
182 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
185 *ret
= busses
[focus
];
189 static void release_busses(void) {
192 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
193 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
196 static void pager_open_if_enabled(void) {
204 static void ask_password_agent_open_if_enabled(void) {
206 /* Open the password agent as a child process if necessary */
208 if (!arg_ask_password
)
211 if (arg_scope
!= UNIT_FILE_SYSTEM
)
214 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
217 ask_password_agent_open();
220 static void polkit_agent_open_if_enabled(void) {
222 /* Open the polkit agent as a child process if necessary */
224 if (!arg_ask_password
)
227 if (arg_scope
!= UNIT_FILE_SYSTEM
)
230 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
236 static OutputFlags
get_output_flags(void) {
238 arg_all
* OUTPUT_SHOW_ALL
|
239 arg_full
* OUTPUT_FULL_WIDTH
|
240 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
241 on_tty() * OUTPUT_COLOR
|
242 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
245 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
248 if (!sd_bus_error_is_set(error
))
251 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
253 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
254 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
255 return EXIT_NOPERMISSION
;
257 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
258 return EXIT_NOTINSTALLED
;
260 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
261 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
262 return EXIT_NOTIMPLEMENTED
;
264 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
265 return EXIT_NOTCONFIGURED
;
273 static bool install_client_side(void) {
275 /* Decides when to execute enable/disable/... operations
276 * client-side rather than server-side. */
278 if (running_in_chroot() > 0)
281 if (sd_booted() <= 0)
284 if (!isempty(arg_root
))
287 if (arg_scope
== UNIT_FILE_GLOBAL
)
293 static int compare_unit_info(const void *a
, const void *b
) {
294 const UnitInfo
*u
= a
, *v
= b
;
298 /* First, order by machine */
299 if (!u
->machine
&& v
->machine
)
301 if (u
->machine
&& !v
->machine
)
303 if (u
->machine
&& v
->machine
) {
304 r
= strcasecmp(u
->machine
, v
->machine
);
309 /* Second, order by unit type */
310 d1
= strrchr(u
->id
, '.');
311 d2
= strrchr(v
->id
, '.');
313 r
= strcasecmp(d1
, d2
);
318 /* Third, order by name */
319 return strcasecmp(u
->id
, v
->id
);
322 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
323 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
329 dot
= strrchr(u
->id
, '.');
333 if (!strv_find(arg_types
, dot
+1))
343 if (streq(u
->active_state
, "inactive") || u
->following
[0])
349 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
350 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
352 unsigned n_shown
= 0;
355 max_id_len
= strlen("UNIT");
356 load_len
= strlen("LOAD");
357 active_len
= strlen("ACTIVE");
358 sub_len
= strlen("SUB");
359 job_len
= strlen("JOB");
362 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
363 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
364 load_len
= MAX(load_len
, strlen(u
->load_state
));
365 active_len
= MAX(active_len
, strlen(u
->active_state
));
366 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
368 if (u
->job_id
!= 0) {
369 job_len
= MAX(job_len
, strlen(u
->job_type
));
373 if (!arg_no_legend
&&
374 (streq(u
->active_state
, "failed") ||
375 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
379 if (!arg_full
&& original_stdout_is_tty
) {
382 id_len
= MIN(max_id_len
, 25u);
383 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
386 basic_len
+= job_len
+ 1;
388 if (basic_len
< (unsigned) columns()) {
389 unsigned extra_len
, incr
;
390 extra_len
= columns() - basic_len
;
392 /* Either UNIT already got 25, or is fully satisfied.
393 * Grant up to 25 to DESC now. */
394 incr
= MIN(extra_len
, 25u);
398 /* split the remaining space between UNIT and DESC,
399 * but do not give UNIT more than it needs. */
401 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
403 desc_len
+= extra_len
- incr
;
409 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
410 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
411 const char *on_loaded
= "", *off_loaded
= "";
412 const char *on_active
= "", *off_active
= "";
413 const char *on_circle
= "", *off_circle
= "";
417 if (!n_shown
&& !arg_no_legend
) {
422 printf("%-*s %-*s %-*s %-*s ",
425 active_len
, "ACTIVE",
429 printf("%-*s ", job_len
, "JOB");
431 if (!arg_full
&& arg_no_pager
)
432 printf("%.*s\n", desc_len
, "DESCRIPTION");
434 printf("%s\n", "DESCRIPTION");
439 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
440 on_loaded
= ansi_highlight_red();
441 on_circle
= ansi_highlight_yellow();
442 off_loaded
= off_circle
= ansi_normal();
444 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
445 on_circle
= on_active
= ansi_highlight_red();
446 off_circle
= off_active
= ansi_normal();
451 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
460 e
= ellipsize(id
, id_len
, 33);
468 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
470 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
471 on_active
, id_len
, id
, off_active
,
472 on_loaded
, load_len
, u
->load_state
, off_loaded
,
473 on_active
, active_len
, u
->active_state
,
474 sub_len
, u
->sub_state
, off_active
,
475 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
478 printf("%.*s\n", desc_len
, u
->description
);
480 printf("%s\n", u
->description
);
483 if (!arg_no_legend
) {
484 const char *on
, *off
;
488 "LOAD = Reflects whether the unit definition was properly loaded.\n"
489 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
490 "SUB = The low-level unit activation state, values depend on unit type.");
491 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
492 on
= ansi_highlight();
495 on
= ansi_highlight_red();
500 printf("%s%u loaded units listed.%s\n"
501 "To show all installed unit files use 'systemctl list-unit-files'.\n",
504 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
505 "To show all installed unit files use 'systemctl list-unit-files'.\n",
512 static int get_unit_list(
516 UnitInfo
**unit_infos
,
518 sd_bus_message
**_reply
) {
520 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
521 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
522 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
531 r
= sd_bus_message_new_method_call(
534 "org.freedesktop.systemd1",
535 "/org/freedesktop/systemd1",
536 "org.freedesktop.systemd1.Manager",
537 "ListUnitsFiltered");
540 return bus_log_create_error(r
);
542 r
= sd_bus_message_append_strv(m
, arg_states
);
544 return bus_log_create_error(r
);
546 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
548 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
550 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
552 return bus_log_parse_error(r
);
554 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
557 if (!output_show_unit(&u
, patterns
))
560 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
563 (*unit_infos
)[c
++] = u
;
566 return bus_log_parse_error(r
);
568 r
= sd_bus_message_exit_container(reply
);
570 return bus_log_parse_error(r
);
578 static void message_set_freep(Set
**set
) {
581 while ((m
= set_steal_first(*set
)))
582 sd_bus_message_unref(m
);
587 static int get_unit_list_recursive(
590 UnitInfo
**_unit_infos
,
594 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
595 _cleanup_(message_set_freep
) Set
*replies
;
596 sd_bus_message
*reply
;
604 replies
= set_new(NULL
);
608 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
612 r
= set_put(replies
, reply
);
614 sd_bus_message_unref(reply
);
619 _cleanup_strv_free_
char **machines
= NULL
;
622 r
= sd_get_machine_names(&machines
);
624 return log_error_errno(r
, "Failed to get machine names: %m");
626 STRV_FOREACH(i
, machines
) {
627 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
630 r
= sd_bus_open_system_machine(&container
, *i
);
632 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
636 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
642 r
= set_put(replies
, reply
);
644 sd_bus_message_unref(reply
);
649 *_machines
= machines
;
654 *_unit_infos
= unit_infos
;
663 static int list_units(int argc
, char *argv
[], void *userdata
) {
664 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
665 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
666 _cleanup_strv_free_
char **machines
= NULL
;
670 pager_open_if_enabled();
672 r
= acquire_bus(BUS_MANAGER
, &bus
);
676 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
680 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
681 return output_units_list(unit_infos
, r
);
684 static int get_triggered_units(
689 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
696 r
= sd_bus_get_property_strv(
698 "org.freedesktop.systemd1",
700 "org.freedesktop.systemd1.Unit",
705 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
710 static int get_listening(
712 const char* unit_path
,
715 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
716 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
717 const char *type
, *path
;
720 r
= sd_bus_get_property(
722 "org.freedesktop.systemd1",
724 "org.freedesktop.systemd1.Socket",
730 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
732 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
734 return bus_log_parse_error(r
);
736 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
738 r
= strv_extend(listening
, type
);
742 r
= strv_extend(listening
, path
);
749 return bus_log_parse_error(r
);
751 r
= sd_bus_message_exit_container(reply
);
753 return bus_log_parse_error(r
);
765 /* Note: triggered is a list here, although it almost certainly
766 * will always be one unit. Nevertheless, dbus API allows for multiple
767 * values, so let's follow that. */
770 /* The strv above is shared. free is set only in the first one. */
774 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
780 if (!a
->machine
&& b
->machine
)
782 if (a
->machine
&& !b
->machine
)
784 if (a
->machine
&& b
->machine
) {
785 o
= strcasecmp(a
->machine
, b
->machine
);
790 o
= strcmp(a
->path
, b
->path
);
792 o
= strcmp(a
->type
, b
->type
);
797 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
798 struct socket_info
*s
;
799 unsigned pathlen
= strlen("LISTEN"),
800 typelen
= strlen("TYPE") * arg_show_types
,
801 socklen
= strlen("UNIT"),
802 servlen
= strlen("ACTIVATES");
803 const char *on
, *off
;
805 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
809 socklen
= MAX(socklen
, strlen(s
->id
));
811 typelen
= MAX(typelen
, strlen(s
->type
));
812 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
814 STRV_FOREACH(a
, s
->triggered
)
815 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
816 servlen
= MAX(servlen
, tmp
);
821 printf("%-*s %-*.*s%-*s %s\n",
823 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
827 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
828 _cleanup_free_
char *j
= NULL
;
833 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
841 printf("%-*s %-*s %-*s",
842 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
845 pathlen
, path
, socklen
, s
->id
);
846 STRV_FOREACH(a
, s
->triggered
)
848 a
== s
->triggered
? "" : ",", *a
);
852 on
= ansi_highlight();
857 on
= ansi_highlight_red();
861 if (!arg_no_legend
) {
862 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
864 printf("Pass --all to see loaded but inactive sockets, too.\n");
870 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
871 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
872 _cleanup_strv_free_
char **machines
= NULL
;
873 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
874 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
876 struct socket_info
*s
;
882 pager_open_if_enabled();
884 r
= acquire_bus(BUS_MANAGER
, &bus
);
888 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
892 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
893 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
896 if (!endswith(u
->id
, ".socket"))
899 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
903 c
= get_listening(bus
, u
->unit_path
, &listening
);
909 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
914 for (i
= 0; i
< c
; i
++)
915 socket_infos
[cs
+ i
] = (struct socket_info
) {
916 .machine
= u
->machine
,
918 .type
= listening
[i
*2],
919 .path
= listening
[i
*2 + 1],
920 .triggered
= triggered
,
921 .own_triggered
= i
==0,
924 /* from this point on we will cleanup those socket_infos */
927 listening
= triggered
= NULL
; /* avoid cleanup */
930 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
931 (__compar_fn_t
) socket_info_compare
);
933 output_sockets_list(socket_infos
, cs
);
936 assert(cs
== 0 || socket_infos
);
937 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
940 if (s
->own_triggered
)
941 strv_free(s
->triggered
);
947 static int get_next_elapse(
950 dual_timestamp
*next
) {
952 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
960 r
= sd_bus_get_property_trivial(
962 "org.freedesktop.systemd1",
964 "org.freedesktop.systemd1.Timer",
965 "NextElapseUSecMonotonic",
970 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
972 r
= sd_bus_get_property_trivial(
974 "org.freedesktop.systemd1",
976 "org.freedesktop.systemd1.Timer",
977 "NextElapseUSecRealtime",
982 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
988 static int get_last_trigger(
993 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1000 r
= sd_bus_get_property_trivial(
1002 "org.freedesktop.systemd1",
1004 "org.freedesktop.systemd1.Timer",
1010 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1016 const char* machine
;
1019 usec_t last_trigger
;
1023 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1029 if (!a
->machine
&& b
->machine
)
1031 if (a
->machine
&& !b
->machine
)
1033 if (a
->machine
&& b
->machine
) {
1034 o
= strcasecmp(a
->machine
, b
->machine
);
1039 if (a
->next_elapse
< b
->next_elapse
)
1041 if (a
->next_elapse
> b
->next_elapse
)
1044 return strcmp(a
->id
, b
->id
);
1047 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1048 struct timer_info
*t
;
1050 nextlen
= strlen("NEXT"),
1051 leftlen
= strlen("LEFT"),
1052 lastlen
= strlen("LAST"),
1053 passedlen
= strlen("PASSED"),
1054 unitlen
= strlen("UNIT"),
1055 activatelen
= strlen("ACTIVATES");
1057 const char *on
, *off
;
1059 assert(timer_infos
|| n
== 0);
1061 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1065 if (t
->next_elapse
> 0) {
1066 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1068 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1069 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1071 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1072 leftlen
= MAX(leftlen
, strlen(trel
));
1075 if (t
->last_trigger
> 0) {
1076 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1078 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1079 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1081 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1082 passedlen
= MAX(passedlen
, strlen(trel
));
1085 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1087 STRV_FOREACH(a
, t
->triggered
)
1088 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1090 activatelen
= MAX(activatelen
, ul
);
1095 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1099 passedlen
, "PASSED",
1103 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1104 _cleanup_free_
char *j
= NULL
;
1106 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1107 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1110 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1111 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1113 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1114 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1117 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1124 printf("%-*s %-*s %-*s %-*s %-*s",
1125 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1127 STRV_FOREACH(a
, t
->triggered
)
1129 a
== t
->triggered
? "" : ",", *a
);
1133 on
= ansi_highlight();
1134 off
= ansi_normal();
1138 on
= ansi_highlight_red();
1139 off
= ansi_normal();
1142 if (!arg_no_legend
) {
1143 printf("%s%u timers listed.%s\n", on
, n
, off
);
1145 printf("Pass --all to see loaded but inactive timers, too.\n");
1151 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1157 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1160 if (next
->monotonic
> nw
->monotonic
)
1161 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1163 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1165 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1166 next_elapse
= MIN(converted
, next
->realtime
);
1168 next_elapse
= converted
;
1171 next_elapse
= next
->realtime
;
1176 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1177 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1178 _cleanup_strv_free_
char **machines
= NULL
;
1179 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1180 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1181 struct timer_info
*t
;
1189 pager_open_if_enabled();
1191 r
= acquire_bus(BUS_MANAGER
, &bus
);
1195 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1199 dual_timestamp_get(&nw
);
1201 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1202 _cleanup_strv_free_
char **triggered
= NULL
;
1203 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1206 if (!endswith(u
->id
, ".timer"))
1209 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1213 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1217 get_last_trigger(bus
, u
->unit_path
, &last
);
1219 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1224 m
= calc_next_elapse(&nw
, &next
);
1226 timer_infos
[c
++] = (struct timer_info
) {
1227 .machine
= u
->machine
,
1230 .last_trigger
= last
,
1231 .triggered
= triggered
,
1234 triggered
= NULL
; /* avoid cleanup */
1237 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1238 (__compar_fn_t
) timer_info_compare
);
1240 output_timers_list(timer_infos
, c
);
1243 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1244 strv_free(t
->triggered
);
1249 static int compare_unit_file_list(const void *a
, const void *b
) {
1250 const char *d1
, *d2
;
1251 const UnitFileList
*u
= a
, *v
= b
;
1253 d1
= strrchr(u
->path
, '.');
1254 d2
= strrchr(v
->path
, '.');
1259 r
= strcasecmp(d1
, d2
);
1264 return strcasecmp(basename(u
->path
), basename(v
->path
));
1267 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1268 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1271 if (!strv_isempty(arg_types
)) {
1274 dot
= strrchr(u
->path
, '.');
1278 if (!strv_find(arg_types
, dot
+1))
1282 if (!strv_isempty(arg_states
) &&
1283 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1289 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1290 unsigned max_id_len
, id_cols
, state_cols
;
1291 const UnitFileList
*u
;
1293 max_id_len
= strlen("UNIT FILE");
1294 state_cols
= strlen("STATE");
1296 for (u
= units
; u
< units
+ c
; u
++) {
1297 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1298 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1302 unsigned basic_cols
;
1304 id_cols
= MIN(max_id_len
, 25u);
1305 basic_cols
= 1 + id_cols
+ state_cols
;
1306 if (basic_cols
< (unsigned) columns())
1307 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1309 id_cols
= max_id_len
;
1312 printf("%-*s %-*s\n",
1313 id_cols
, "UNIT FILE",
1314 state_cols
, "STATE");
1316 for (u
= units
; u
< units
+ c
; u
++) {
1317 _cleanup_free_
char *e
= NULL
;
1318 const char *on
, *off
;
1321 if (IN_SET(u
->state
,
1323 UNIT_FILE_MASKED_RUNTIME
,
1325 UNIT_FILE_INVALID
)) {
1326 on
= ansi_highlight_red();
1327 off
= ansi_normal();
1328 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1329 on
= ansi_highlight_green();
1330 off
= ansi_normal();
1334 id
= basename(u
->path
);
1336 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1338 printf("%-*s %s%-*s%s\n",
1339 id_cols
, e
? e
: id
,
1340 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1344 printf("\n%u unit files listed.\n", c
);
1347 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1348 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1349 _cleanup_free_ UnitFileList
*units
= NULL
;
1357 pager_open_if_enabled();
1359 if (install_client_side()) {
1365 h
= hashmap_new(&string_hash_ops
);
1369 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1371 unit_file_list_free(h
);
1372 return log_error_errno(r
, "Failed to get unit file list: %m");
1375 n_units
= hashmap_size(h
);
1377 units
= new(UnitFileList
, n_units
);
1378 if (!units
&& n_units
> 0) {
1379 unit_file_list_free(h
);
1383 HASHMAP_FOREACH(u
, h
, i
) {
1384 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1391 assert(c
<= n_units
);
1394 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1397 r
= acquire_bus(BUS_MANAGER
, &bus
);
1401 r
= sd_bus_call_method(
1403 "org.freedesktop.systemd1",
1404 "/org/freedesktop/systemd1",
1405 "org.freedesktop.systemd1.Manager",
1411 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1413 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1415 return bus_log_parse_error(r
);
1417 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1419 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1422 units
[c
] = (struct UnitFileList
) {
1424 unit_file_state_from_string(state
)
1427 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1432 return bus_log_parse_error(r
);
1434 r
= sd_bus_message_exit_container(reply
);
1436 return bus_log_parse_error(r
);
1439 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1440 output_unit_file_list(units
, c
);
1442 if (install_client_side()) {
1443 for (unit
= units
; unit
< units
+ c
; unit
++)
1450 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1451 _cleanup_free_
char *n
= NULL
;
1452 size_t max_len
= MAX(columns(),20u);
1458 for (i
= level
- 1; i
>= 0; i
--) {
1460 if (len
> max_len
- 3 && !arg_full
) {
1461 printf("%s...\n",max_len
% 2 ? "" : " ");
1464 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1468 if (len
> max_len
- 3 && !arg_full
) {
1469 printf("%s...\n",max_len
% 2 ? "" : " ");
1473 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1477 printf("%s\n", name
);
1481 n
= ellipsize(name
, max_len
-len
, 100);
1489 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1491 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1492 [DEPENDENCY_FORWARD
] = "Requires\0"
1493 "RequiresOverridable\0"
1495 "RequisiteOverridable\0"
1499 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1500 "RequiredByOverridable\0"
1502 "RequisiteOfOverridable\0"
1506 [DEPENDENCY_AFTER
] = "After\0",
1507 [DEPENDENCY_BEFORE
] = "Before\0",
1510 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1511 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1512 _cleanup_strv_free_
char **ret
= NULL
;
1513 _cleanup_free_
char *path
= NULL
;
1519 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1521 path
= unit_dbus_path_from_name(name
);
1525 r
= sd_bus_call_method(
1527 "org.freedesktop.systemd1",
1529 "org.freedesktop.DBus.Properties",
1533 "s", "org.freedesktop.systemd1.Unit");
1535 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1537 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1539 return bus_log_parse_error(r
);
1541 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1544 r
= sd_bus_message_read(reply
, "s", &prop
);
1546 return bus_log_parse_error(r
);
1548 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1549 r
= sd_bus_message_skip(reply
, "v");
1551 return bus_log_parse_error(r
);
1554 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1556 return bus_log_parse_error(r
);
1558 r
= bus_message_read_strv_extend(reply
, &ret
);
1560 return bus_log_parse_error(r
);
1562 r
= sd_bus_message_exit_container(reply
);
1564 return bus_log_parse_error(r
);
1567 r
= sd_bus_message_exit_container(reply
);
1569 return bus_log_parse_error(r
);
1573 return bus_log_parse_error(r
);
1575 r
= sd_bus_message_exit_container(reply
);
1577 return bus_log_parse_error(r
);
1585 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1586 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1588 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1590 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1593 return strcasecmp(*a
, *b
);
1596 static int list_dependencies_one(
1601 unsigned int branches
) {
1603 _cleanup_strv_free_
char **deps
= NULL
;
1611 r
= strv_extend(units
, name
);
1615 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1619 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1621 STRV_FOREACH(c
, deps
) {
1622 if (strv_contains(*units
, *c
)) {
1624 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1637 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1638 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1639 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1642 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1646 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1647 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1654 strv_remove(*units
, name
);
1659 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1660 _cleanup_strv_free_
char **units
= NULL
;
1661 _cleanup_free_
char *unit
= NULL
;
1667 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1669 return log_error_errno(r
, "Failed to mangle unit name: %m");
1673 u
= SPECIAL_DEFAULT_TARGET
;
1675 pager_open_if_enabled();
1677 r
= acquire_bus(BUS_MANAGER
, &bus
);
1683 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1686 struct machine_info
{
1690 char *control_group
;
1691 uint32_t n_failed_units
;
1696 static const struct bus_properties_map machine_info_property_map
[] = {
1697 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1698 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1699 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1700 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1701 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1705 static void machine_info_clear(struct machine_info
*info
) {
1709 free(info
->control_group
);
1714 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1720 for (i
= 0; i
< n
; i
++)
1721 machine_info_clear(&machine_infos
[i
]);
1723 free(machine_infos
);
1726 static int compare_machine_info(const void *a
, const void *b
) {
1727 const struct machine_info
*u
= a
, *v
= b
;
1729 if (u
->is_host
!= v
->is_host
)
1730 return u
->is_host
> v
->is_host
? -1 : 1;
1732 return strcasecmp(u
->name
, v
->name
);
1735 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1736 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1742 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1749 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1756 static bool output_show_machine(const char *name
, char **patterns
) {
1757 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1760 static int get_machine_list(
1762 struct machine_info
**_machine_infos
,
1765 struct machine_info
*machine_infos
= NULL
;
1766 _cleanup_strv_free_
char **m
= NULL
;
1767 _cleanup_free_
char *hn
= NULL
;
1772 hn
= gethostname_malloc();
1776 if (output_show_machine(hn
, patterns
)) {
1777 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1780 machine_infos
[c
].is_host
= true;
1781 machine_infos
[c
].name
= hn
;
1784 get_machine_properties(bus
, &machine_infos
[c
]);
1788 r
= sd_get_machine_names(&m
);
1790 return log_error_errno(r
, "Failed to get machine list: %m");
1792 STRV_FOREACH(i
, m
) {
1793 _cleanup_free_
char *class = NULL
;
1795 if (!output_show_machine(*i
, patterns
))
1798 sd_machine_get_class(*i
, &class);
1799 if (!streq_ptr(class, "container"))
1802 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1803 free_machines_list(machine_infos
, c
);
1807 machine_infos
[c
].is_host
= false;
1808 machine_infos
[c
].name
= strdup(*i
);
1809 if (!machine_infos
[c
].name
) {
1810 free_machines_list(machine_infos
, c
);
1814 get_machine_properties(NULL
, &machine_infos
[c
]);
1818 *_machine_infos
= machine_infos
;
1822 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1823 struct machine_info
*m
;
1826 namelen
= sizeof("NAME") - 1,
1827 statelen
= sizeof("STATE") - 1,
1828 failedlen
= sizeof("FAILED") - 1,
1829 jobslen
= sizeof("JOBS") - 1;
1831 assert(machine_infos
|| n
== 0);
1833 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1834 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1835 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1836 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1837 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1839 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1843 if (!arg_no_legend
) {
1847 printf("%-*s %-*s %-*s %-*s\n",
1850 failedlen
, "FAILED",
1854 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1855 const char *on_state
= "", *off_state
= "";
1856 const char *on_failed
= "", *off_failed
= "";
1857 bool circle
= false;
1859 if (streq_ptr(m
->state
, "degraded")) {
1860 on_state
= ansi_highlight_red();
1861 off_state
= ansi_normal();
1863 } else if (!streq_ptr(m
->state
, "running")) {
1864 on_state
= ansi_highlight_yellow();
1865 off_state
= ansi_normal();
1869 if (m
->n_failed_units
> 0) {
1870 on_failed
= ansi_highlight_red();
1871 off_failed
= ansi_normal();
1873 on_failed
= off_failed
= "";
1876 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1879 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1880 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1881 on_state
, statelen
, strna(m
->state
), off_state
,
1882 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1883 jobslen
, m
->n_jobs
);
1885 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1886 namelen
, strna(m
->name
),
1887 on_state
, statelen
, strna(m
->state
), off_state
,
1888 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1889 jobslen
, m
->n_jobs
);
1893 printf("\n%u machines listed.\n", n
);
1896 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1897 struct machine_info
*machine_infos
= NULL
;
1901 if (geteuid() != 0) {
1902 log_error("Must be root.");
1906 pager_open_if_enabled();
1908 r
= acquire_bus(BUS_MANAGER
, &bus
);
1912 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1916 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1917 output_machines_list(machine_infos
, r
);
1918 free_machines_list(machine_infos
, r
);
1923 static int get_default(int argc
, char *argv
[], void *userdata
) {
1924 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1925 _cleanup_free_
char *_path
= NULL
;
1929 if (install_client_side()) {
1930 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1932 return log_error_errno(r
, "Failed to get default target: %m");
1936 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1939 r
= acquire_bus(BUS_MANAGER
, &bus
);
1943 r
= sd_bus_call_method(
1945 "org.freedesktop.systemd1",
1946 "/org/freedesktop/systemd1",
1947 "org.freedesktop.systemd1.Manager",
1953 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1955 r
= sd_bus_message_read(reply
, "s", &path
);
1957 return bus_log_parse_error(r
);
1961 printf("%s\n", path
);
1966 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1969 assert(changes
|| n_changes
== 0);
1971 for (i
= 0; i
< n_changes
; i
++) {
1972 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1973 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1975 log_info("Removed symlink %s.", changes
[i
].path
);
1979 static int set_default(int argc
, char *argv
[], void *userdata
) {
1980 _cleanup_free_
char *unit
= NULL
;
1986 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1988 return log_error_errno(r
, "Failed to mangle unit name: %m");
1990 if (install_client_side()) {
1991 UnitFileChange
*changes
= NULL
;
1992 unsigned n_changes
= 0;
1994 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1996 return log_error_errno(r
, "Failed to set default target: %m");
1999 dump_unit_file_changes(changes
, n_changes
);
2001 unit_file_changes_free(changes
, n_changes
);
2004 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2005 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2008 polkit_agent_open_if_enabled();
2010 r
= acquire_bus(BUS_MANAGER
, &bus
);
2014 r
= sd_bus_call_method(
2016 "org.freedesktop.systemd1",
2017 "/org/freedesktop/systemd1",
2018 "org.freedesktop.systemd1.Manager",
2024 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2026 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2030 /* Try to reload if enabled */
2032 r
= daemon_reload(argc
, argv
, userdata
);
2042 const char *name
, *type
, *state
;
2045 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2046 unsigned id_len
, unit_len
, type_len
, state_len
;
2047 const struct job_info
*j
;
2048 const char *on
, *off
;
2049 bool shorten
= false;
2051 assert(n
== 0 || jobs
);
2054 if (!arg_no_legend
) {
2055 on
= ansi_highlight_green();
2056 off
= ansi_normal();
2058 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2063 pager_open_if_enabled();
2065 id_len
= strlen("JOB");
2066 unit_len
= strlen("UNIT");
2067 type_len
= strlen("TYPE");
2068 state_len
= strlen("STATE");
2070 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2071 uint32_t id
= j
->id
;
2072 assert(j
->name
&& j
->type
&& j
->state
);
2074 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2075 unit_len
= MAX(unit_len
, strlen(j
->name
));
2076 type_len
= MAX(type_len
, strlen(j
->type
));
2077 state_len
= MAX(state_len
, strlen(j
->state
));
2080 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2081 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2086 printf("%*s %-*s %-*s %-*s\n",
2090 state_len
, "STATE");
2092 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2093 _cleanup_free_
char *e
= NULL
;
2095 if (streq(j
->state
, "running")) {
2096 on
= ansi_highlight();
2097 off
= ansi_normal();
2101 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2102 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2104 on
, unit_len
, e
? e
: j
->name
, off
,
2106 on
, state_len
, j
->state
, off
);
2109 if (!arg_no_legend
) {
2110 on
= ansi_highlight();
2111 off
= ansi_normal();
2113 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2117 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2118 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2121 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2122 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2123 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2124 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2125 _cleanup_free_
struct job_info
*jobs
= NULL
;
2131 bool skipped
= false;
2133 pager_open_if_enabled();
2135 r
= acquire_bus(BUS_MANAGER
, &bus
);
2139 r
= sd_bus_call_method(
2141 "org.freedesktop.systemd1",
2142 "/org/freedesktop/systemd1",
2143 "org.freedesktop.systemd1.Manager",
2149 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2151 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2153 return bus_log_parse_error(r
);
2155 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2156 struct job_info job
= { id
, name
, type
, state
};
2158 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2163 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2169 return bus_log_parse_error(r
);
2171 r
= sd_bus_message_exit_container(reply
);
2173 return bus_log_parse_error(r
);
2175 output_jobs_list(jobs
, c
, skipped
);
2179 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2185 return daemon_reload(argc
, argv
, userdata
);
2187 polkit_agent_open_if_enabled();
2189 r
= acquire_bus(BUS_MANAGER
, &bus
);
2193 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2194 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2198 q
= safe_atou32(*name
, &id
);
2200 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2202 q
= sd_bus_call_method(
2204 "org.freedesktop.systemd1",
2205 "/org/freedesktop/systemd1",
2206 "org.freedesktop.systemd1.Manager",
2212 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2221 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2222 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2226 /* We ignore all errors here, since this is used to show a
2229 /* We don't use unit_dbus_path_from_name() directly since we
2230 * don't want to load the unit if it isn't loaded. */
2232 r
= sd_bus_call_method(
2234 "org.freedesktop.systemd1",
2235 "/org/freedesktop/systemd1",
2236 "org.freedesktop.systemd1.Manager",
2244 r
= sd_bus_message_read(reply
, "o", &path
);
2248 r
= sd_bus_get_property_trivial(
2250 "org.freedesktop.systemd1",
2252 "org.freedesktop.systemd1.Unit",
2262 static void warn_unit_file_changed(const char *name
) {
2263 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2264 ansi_highlight_red(),
2267 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2270 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2277 STRV_FOREACH(p
, lp
->unit_path
) {
2278 _cleanup_free_
char *path
;
2280 path
= path_join(arg_root
, *p
, unit_name
);
2284 if (access(path
, F_OK
) == 0) {
2294 static int unit_find_paths(
2296 const char *unit_name
,
2298 char **fragment_path
,
2299 char ***dropin_paths
) {
2301 _cleanup_free_
char *path
= NULL
;
2302 _cleanup_strv_free_
char **dropins
= NULL
;
2306 * Finds where the unit is defined on disk. Returns 0 if the unit
2307 * is not found. Returns 1 if it is found, and sets
2308 * - the path to the unit in *path, if it exists on disk,
2309 * - and a strv of existing drop-ins in *dropins,
2310 * if the arg is not NULL and any dropins were found.
2314 assert(fragment_path
);
2317 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2318 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2319 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2320 _cleanup_free_
char *unit
= NULL
;
2321 char *unit_load_error_name
, *unit_load_error_message
;
2323 unit
= unit_dbus_path_from_name(unit_name
);
2327 if (need_daemon_reload(bus
, unit_name
) > 0)
2328 warn_unit_file_changed(unit_name
);
2330 r
= sd_bus_get_property(
2332 "org.freedesktop.systemd1",
2334 "org.freedesktop.systemd1.Unit",
2340 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2342 r
= sd_bus_message_read(
2345 &unit_load_error_name
,
2346 &unit_load_error_message
);
2348 return bus_log_parse_error(r
);
2350 if (!isempty(unit_load_error_name
)) {
2351 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2355 r
= sd_bus_get_property_string(
2357 "org.freedesktop.systemd1",
2359 "org.freedesktop.systemd1.Unit",
2364 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2367 r
= sd_bus_get_property_strv(
2369 "org.freedesktop.systemd1",
2371 "org.freedesktop.systemd1.Unit",
2376 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2379 _cleanup_set_free_ Set
*names
;
2381 names
= set_new(NULL
);
2385 r
= set_put(names
, unit_name
);
2387 return log_error_errno(r
, "Failed to add unit name: %m");
2389 r
= unit_file_find_path(lp
, unit_name
, &path
);
2394 _cleanup_free_
char *template = NULL
;
2396 r
= unit_name_template(unit_name
, &template);
2397 if (r
< 0 && r
!= -EINVAL
)
2398 return log_error_errno(r
, "Failed to determine template name: %m");
2400 r
= unit_file_find_path(lp
, template, &path
);
2407 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2415 if (!isempty(path
)) {
2416 *fragment_path
= path
;
2421 if (dropin_paths
&& !strv_isempty(dropins
)) {
2422 *dropin_paths
= dropins
;
2428 log_error("No files found for %s.", unit_name
);
2433 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2434 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2435 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2441 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2443 return log_error_errno(r
, "Failed to mangle unit name: %m");
2445 /* We don't use unit_dbus_path_from_name() directly since we
2446 * don't want to load the unit if it isn't loaded. */
2448 r
= sd_bus_call_method(
2450 "org.freedesktop.systemd1",
2451 "/org/freedesktop/systemd1",
2452 "org.freedesktop.systemd1.Manager",
2463 r
= sd_bus_message_read(reply
, "o", &path
);
2465 return bus_log_parse_error(r
);
2467 r
= sd_bus_get_property_string(
2469 "org.freedesktop.systemd1",
2471 "org.freedesktop.systemd1.Unit",
2484 return nulstr_contains(good_states
, state
);
2487 static int check_triggering_units(
2491 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2492 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2493 _cleanup_strv_free_
char **triggered_by
= NULL
;
2494 bool print_warning_label
= true;
2498 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2500 return log_error_errno(r
, "Failed to mangle unit name: %m");
2502 path
= unit_dbus_path_from_name(n
);
2506 r
= sd_bus_get_property_string(
2508 "org.freedesktop.systemd1",
2510 "org.freedesktop.systemd1.Unit",
2515 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2517 if (streq(state
, "masked"))
2520 r
= sd_bus_get_property_strv(
2522 "org.freedesktop.systemd1",
2524 "org.freedesktop.systemd1.Unit",
2529 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2531 STRV_FOREACH(i
, triggered_by
) {
2532 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2534 return log_error_errno(r
, "Failed to check unit: %m");
2539 if (print_warning_label
) {
2540 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2541 print_warning_label
= false;
2544 log_warning(" %s", *i
);
2550 static const struct {
2553 } unit_actions
[] = {
2554 { "start", "StartUnit" },
2555 { "stop", "StopUnit" },
2556 { "condstop", "StopUnit" },
2557 { "reload", "ReloadUnit" },
2558 { "restart", "RestartUnit" },
2559 { "try-restart", "TryRestartUnit" },
2560 { "condrestart", "TryRestartUnit" },
2561 { "reload-or-restart", "ReloadOrRestartUnit" },
2562 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2563 { "condreload", "ReloadOrTryRestartUnit" },
2564 { "force-reload", "ReloadOrTryRestartUnit" }
2567 static const char *verb_to_method(const char *verb
) {
2570 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2571 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2572 return unit_actions
[i
].method
;
2577 static const char *method_to_verb(const char *method
) {
2580 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2581 if (streq_ptr(unit_actions
[i
].method
, method
))
2582 return unit_actions
[i
].verb
;
2587 static int start_unit_one(
2592 sd_bus_error
*error
,
2593 BusWaitForJobs
*w
) {
2595 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2604 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2606 r
= sd_bus_call_method(
2608 "org.freedesktop.systemd1",
2609 "/org/freedesktop/systemd1",
2610 "org.freedesktop.systemd1.Manager",
2618 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2619 /* There's always a fallback possible for
2620 * legacy actions. */
2621 return -EADDRNOTAVAIL
;
2623 verb
= method_to_verb(method
);
2625 return log_error_errno(r
, "Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2628 r
= sd_bus_message_read(reply
, "o", &path
);
2630 return bus_log_parse_error(r
);
2632 if (need_daemon_reload(bus
, name
) > 0)
2633 warn_unit_file_changed(name
);
2636 log_debug("Adding %s to the set", path
);
2637 r
= bus_wait_for_jobs_add(w
, path
);
2645 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2646 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2653 STRV_FOREACH(name
, names
) {
2657 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2659 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2661 return log_error_errno(r
, "Failed to mangle name: %m");
2663 if (string_is_glob(t
))
2664 r
= strv_consume(&globs
, t
);
2666 r
= strv_consume(&mangled
, t
);
2671 /* Query the manager only if any of the names are a glob, since
2672 * this is fairly expensive */
2673 if (!strv_isempty(globs
)) {
2674 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2675 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2677 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2681 for (i
= 0; i
< r
; i
++)
2682 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2687 mangled
= NULL
; /* do not free */
2692 static const struct {
2696 } action_table
[_ACTION_MAX
] = {
2697 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2698 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2699 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2700 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2701 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2702 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2703 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2704 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2705 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2706 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2707 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2708 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2709 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2710 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2711 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2714 static enum action
verb_to_action(const char *verb
) {
2717 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2718 if (streq_ptr(action_table
[i
].verb
, verb
))
2721 return _ACTION_INVALID
;
2724 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2725 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2726 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2727 _cleanup_strv_free_
char **names
= NULL
;
2732 ask_password_agent_open_if_enabled();
2733 polkit_agent_open_if_enabled();
2735 r
= acquire_bus(BUS_MANAGER
, &bus
);
2739 if (arg_action
== ACTION_SYSTEMCTL
) {
2742 method
= verb_to_method(argv
[0]);
2743 action
= verb_to_action(argv
[0]);
2745 if (streq(argv
[0], "isolate")) {
2749 mode
= action_table
[action
].mode
?: arg_job_mode
;
2751 one_name
= action_table
[action
].target
;
2753 assert(arg_action
< ELEMENTSOF(action_table
));
2754 assert(action_table
[arg_action
].target
);
2756 method
= "StartUnit";
2758 mode
= action_table
[arg_action
].mode
;
2759 one_name
= action_table
[arg_action
].target
;
2763 names
= strv_new(one_name
, NULL
);
2765 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2767 return log_error_errno(r
, "Failed to expand names: %m");
2770 if (!arg_no_block
) {
2771 r
= bus_wait_for_jobs_new(bus
, &w
);
2773 return log_error_errno(r
, "Could not watch jobs: %m");
2776 STRV_FOREACH(name
, names
) {
2777 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2780 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2781 if (r
>= 0 && q
< 0)
2782 r
= translate_bus_error_to_exit_status(q
, &error
);
2785 if (!arg_no_block
) {
2788 q
= bus_wait_for_jobs(w
, arg_quiet
);
2792 /* When stopping units, warn if they can still be triggered by
2793 * another active unit (socket, path, timer) */
2794 if (!arg_quiet
&& streq(method
, "StopUnit"))
2795 STRV_FOREACH(name
, names
)
2796 check_triggering_units(bus
, *name
);
2802 static int logind_set_wall_message(void) {
2804 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2806 _cleanup_free_
char *m
= NULL
;
2809 r
= acquire_bus(BUS_FULL
, &bus
);
2813 m
= strv_join(arg_wall
, " ");
2817 r
= sd_bus_call_method(
2819 "org.freedesktop.login1",
2820 "/org/freedesktop/login1",
2821 "org.freedesktop.login1.Manager",
2830 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2836 /* Ask systemd-logind, which might grant access to unprivileged users
2837 * through PolicyKit */
2838 static int logind_reboot(enum action a
) {
2840 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2841 const char *method
, *description
;
2845 polkit_agent_open_if_enabled();
2846 (void) logind_set_wall_message();
2848 r
= acquire_bus(BUS_FULL
, &bus
);
2856 description
= "reboot system";
2859 case ACTION_POWEROFF
:
2860 method
= "PowerOff";
2861 description
= "power off system";
2864 case ACTION_SUSPEND
:
2866 description
= "suspend system";
2869 case ACTION_HIBERNATE
:
2870 method
= "Hibernate";
2871 description
= "hibernate system";
2874 case ACTION_HYBRID_SLEEP
:
2875 method
= "HybridSleep";
2876 description
= "put system into hybrid sleep";
2883 r
= sd_bus_call_method(
2885 "org.freedesktop.login1",
2886 "/org/freedesktop/login1",
2887 "org.freedesktop.login1.Manager",
2891 "b", arg_ask_password
);
2893 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2901 static int logind_check_inhibitors(enum action a
) {
2903 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2904 _cleanup_strv_free_
char **sessions
= NULL
;
2905 const char *what
, *who
, *why
, *mode
;
2912 if (arg_ignore_inhibitors
|| arg_force
> 0)
2924 r
= acquire_bus(BUS_FULL
, &bus
);
2928 r
= sd_bus_call_method(
2930 "org.freedesktop.login1",
2931 "/org/freedesktop/login1",
2932 "org.freedesktop.login1.Manager",
2938 /* If logind is not around, then there are no inhibitors... */
2941 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2943 return bus_log_parse_error(r
);
2945 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2946 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2947 _cleanup_strv_free_
char **sv
= NULL
;
2949 if (!streq(mode
, "block"))
2952 sv
= strv_split(what
, ":");
2956 if ((pid_t
) pid
< 0)
2957 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2959 if (!strv_contains(sv
,
2964 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2967 get_process_comm(pid
, &comm
);
2968 user
= uid_to_name(uid
);
2970 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2971 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2976 return bus_log_parse_error(r
);
2978 r
= sd_bus_message_exit_container(reply
);
2980 return bus_log_parse_error(r
);
2982 /* Check for current sessions */
2983 sd_get_sessions(&sessions
);
2984 STRV_FOREACH(s
, sessions
) {
2985 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2987 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2990 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2993 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2996 sd_session_get_tty(*s
, &tty
);
2997 sd_session_get_seat(*s
, &seat
);
2998 sd_session_get_service(*s
, &service
);
2999 user
= uid_to_name(uid
);
3001 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3008 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3009 action_table
[a
].verb
);
3017 static int logind_prepare_firmware_setup(void) {
3019 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3023 r
= acquire_bus(BUS_FULL
, &bus
);
3027 r
= sd_bus_call_method(
3029 "org.freedesktop.login1",
3030 "/org/freedesktop/login1",
3031 "org.freedesktop.login1.Manager",
3032 "SetRebootToFirmwareSetup",
3037 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3041 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3046 static int prepare_firmware_setup(void) {
3049 if (!arg_firmware_setup
)
3052 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3054 r
= efi_set_reboot_to_firmware(true);
3056 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3061 return logind_prepare_firmware_setup();
3064 static int set_exit_code(uint8_t code
) {
3065 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3069 r
= acquire_bus(BUS_MANAGER
, &bus
);
3073 r
= sd_bus_call_method(
3075 "org.freedesktop.systemd1",
3076 "/org/freedesktop/systemd1",
3077 "org.freedesktop.systemd1.Manager",
3083 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3088 static int start_special(int argc
, char *argv
[], void *userdata
) {
3094 a
= verb_to_action(argv
[0]);
3096 r
= logind_check_inhibitors(a
);
3100 if (arg_force
>= 2 && geteuid() != 0) {
3101 log_error("Must be root.");
3105 r
= prepare_firmware_setup();
3109 if (a
== ACTION_REBOOT
&& argc
> 1) {
3110 r
= update_reboot_param_file(argv
[1]);
3114 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3117 /* If the exit code is not given on the command line,
3118 * don't reset it to zero: just keep it as it might
3119 * have been set previously. */
3121 r
= safe_atou8(argv
[1], &code
);
3123 return log_error_errno(r
, "Invalid exit code.");
3125 r
= set_exit_code(code
);
3130 if (arg_force
>= 2 &&
3137 if (arg_force
>= 1 &&
3144 return daemon_reload(argc
, argv
, userdata
);
3146 /* First try logind, to allow authentication with polkit */
3152 ACTION_HYBRID_SLEEP
)) {
3153 r
= logind_reboot(a
);
3156 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3157 /* requested operation is not supported or already in progress */
3160 /* On all other errors, try low-level operation */
3163 return start_unit(argc
, argv
, userdata
);
3166 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3167 _cleanup_strv_free_
char **names
= NULL
;
3172 r
= acquire_bus(BUS_MANAGER
, &bus
);
3176 r
= expand_names(bus
, args
, NULL
, &names
);
3178 return log_error_errno(r
, "Failed to expand names: %m");
3180 STRV_FOREACH(name
, names
) {
3183 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3193 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3194 /* According to LSB: 3, "program is not running" */
3195 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3198 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3199 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3202 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3203 _cleanup_strv_free_
char **names
= NULL
;
3204 char *kill_who
= NULL
, **name
;
3208 polkit_agent_open_if_enabled();
3210 r
= acquire_bus(BUS_MANAGER
, &bus
);
3215 arg_kill_who
= "all";
3217 /* --fail was specified */
3218 if (streq(arg_job_mode
, "fail"))
3219 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3221 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3223 return log_error_errno(r
, "Failed to expand names: %m");
3225 STRV_FOREACH(name
, names
) {
3226 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3228 q
= sd_bus_call_method(
3230 "org.freedesktop.systemd1",
3231 "/org/freedesktop/systemd1",
3232 "org.freedesktop.systemd1.Manager",
3236 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3238 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3247 typedef struct ExecStatusInfo
{
3255 usec_t start_timestamp
;
3256 usec_t exit_timestamp
;
3261 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3264 static void exec_status_info_free(ExecStatusInfo
*i
) {
3273 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3274 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3277 int32_t code
, status
;
3283 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3285 return bus_log_parse_error(r
);
3289 r
= sd_bus_message_read(m
, "s", &path
);
3291 return bus_log_parse_error(r
);
3293 i
->path
= strdup(path
);
3297 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3299 return bus_log_parse_error(r
);
3301 r
= sd_bus_message_read(m
,
3304 &start_timestamp
, &start_timestamp_monotonic
,
3305 &exit_timestamp
, &exit_timestamp_monotonic
,
3309 return bus_log_parse_error(r
);
3312 i
->start_timestamp
= (usec_t
) start_timestamp
;
3313 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3314 i
->pid
= (pid_t
) pid
;
3318 r
= sd_bus_message_exit_container(m
);
3320 return bus_log_parse_error(r
);
3325 typedef struct UnitStatusInfo
{
3327 const char *load_state
;
3328 const char *active_state
;
3329 const char *sub_state
;
3330 const char *unit_file_state
;
3331 const char *unit_file_preset
;
3333 const char *description
;
3334 const char *following
;
3336 char **documentation
;
3338 const char *fragment_path
;
3339 const char *source_path
;
3340 const char *control_group
;
3342 char **dropin_paths
;
3344 const char *load_error
;
3347 usec_t inactive_exit_timestamp
;
3348 usec_t inactive_exit_timestamp_monotonic
;
3349 usec_t active_enter_timestamp
;
3350 usec_t active_exit_timestamp
;
3351 usec_t inactive_enter_timestamp
;
3353 bool need_daemon_reload
;
3358 const char *status_text
;
3359 const char *pid_file
;
3363 usec_t start_timestamp
;
3364 usec_t exit_timestamp
;
3366 int exit_code
, exit_status
;
3368 usec_t condition_timestamp
;
3369 bool condition_result
;
3370 bool failed_condition_trigger
;
3371 bool failed_condition_negate
;
3372 const char *failed_condition
;
3373 const char *failed_condition_parameter
;
3375 usec_t assert_timestamp
;
3377 bool failed_assert_trigger
;
3378 bool failed_assert_negate
;
3379 const char *failed_assert
;
3380 const char *failed_assert_parameter
;
3383 unsigned n_accepted
;
3384 unsigned n_connections
;
3387 /* Pairs of type, path */
3391 const char *sysfs_path
;
3393 /* Mount, Automount */
3400 uint64_t memory_current
;
3401 uint64_t memory_limit
;
3402 uint64_t cpu_usage_nsec
;
3403 uint64_t tasks_current
;
3406 LIST_HEAD(ExecStatusInfo
, exec
);
3409 static void print_status_info(
3414 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3416 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3417 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3423 /* This shows pretty information about a unit. See
3424 * print_property() for a low-level property printer */
3426 if (streq_ptr(i
->active_state
, "failed")) {
3427 active_on
= ansi_highlight_red();
3428 active_off
= ansi_normal();
3429 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3430 active_on
= ansi_highlight_green();
3431 active_off
= ansi_normal();
3433 active_on
= active_off
= "";
3435 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3437 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3438 printf(" - %s", i
->description
);
3443 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3445 if (streq_ptr(i
->load_state
, "error")) {
3446 on
= ansi_highlight_red();
3447 off
= ansi_normal();
3451 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3454 printf(" Loaded: %s%s%s (Reason: %s)\n",
3455 on
, strna(i
->load_state
), off
, i
->load_error
);
3456 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3457 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3458 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3459 else if (path
&& !isempty(i
->unit_file_state
))
3460 printf(" Loaded: %s%s%s (%s; %s)\n",
3461 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3463 printf(" Loaded: %s%s%s (%s)\n",
3464 on
, strna(i
->load_state
), off
, path
);
3466 printf(" Loaded: %s%s%s\n",
3467 on
, strna(i
->load_state
), off
);
3469 if (!strv_isempty(i
->dropin_paths
)) {
3470 _cleanup_free_
char *dir
= NULL
;
3474 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3475 if (! dir
|| last
) {
3476 printf(dir
? " " : " Drop-In: ");
3480 if (path_get_parent(*dropin
, &dir
) < 0) {
3485 printf("%s\n %s", dir
,
3486 draw_special_char(DRAW_TREE_RIGHT
));
3489 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3491 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3495 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3497 printf(" Active: %s%s (%s)%s",
3498 active_on
, strna(i
->active_state
), ss
, active_off
);
3500 printf(" Active: %s%s%s",
3501 active_on
, strna(i
->active_state
), active_off
);
3503 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3504 printf(" (Result: %s)", i
->result
);
3506 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3507 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3508 (streq_ptr(i
->active_state
, "inactive") ||
3509 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3510 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3511 i
->active_exit_timestamp
;
3513 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3514 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3517 printf(" since %s; %s\n", s2
, s1
);
3519 printf(" since %s\n", s2
);
3523 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3524 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3525 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3527 printf("Condition: start %scondition failed%s at %s%s%s\n",
3528 ansi_highlight_yellow(), ansi_normal(),
3529 s2
, s1
? "; " : "", strempty(s1
));
3530 if (i
->failed_condition_trigger
)
3531 printf(" none of the trigger conditions were met\n");
3532 else if (i
->failed_condition
)
3533 printf(" %s=%s%s was not met\n",
3534 i
->failed_condition
,
3535 i
->failed_condition_negate
? "!" : "",
3536 i
->failed_condition_parameter
);
3539 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3540 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3541 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3543 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3544 ansi_highlight_red(), ansi_normal(),
3545 s2
, s1
? "; " : "", strempty(s1
));
3546 if (i
->failed_assert_trigger
)
3547 printf(" none of the trigger assertions were met\n");
3548 else if (i
->failed_assert
)
3549 printf(" %s=%s%s was not met\n",
3551 i
->failed_assert_negate
? "!" : "",
3552 i
->failed_assert_parameter
);
3556 printf(" Device: %s\n", i
->sysfs_path
);
3558 printf(" Where: %s\n", i
->where
);
3560 printf(" What: %s\n", i
->what
);
3562 STRV_FOREACH(t
, i
->documentation
)
3563 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3565 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3566 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3569 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3571 LIST_FOREACH(exec
, p
, i
->exec
) {
3572 _cleanup_free_
char *argv
= NULL
;
3575 /* Only show exited processes here */
3579 argv
= strv_join(p
->argv
, " ");
3580 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3582 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3584 on
= ansi_highlight_red();
3585 off
= ansi_normal();
3589 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3591 if (p
->code
== CLD_EXITED
) {
3594 printf("status=%i", p
->status
);
3596 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3601 printf("signal=%s", signal_to_string(p
->status
));
3603 printf(")%s\n", off
);
3605 if (i
->main_pid
== p
->pid
&&
3606 i
->start_timestamp
== p
->start_timestamp
&&
3607 i
->exit_timestamp
== p
->start_timestamp
)
3608 /* Let's not show this twice */
3611 if (p
->pid
== i
->control_pid
)
3615 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3616 if (i
->main_pid
> 0) {
3617 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3620 _cleanup_free_
char *comm
= NULL
;
3621 get_process_comm(i
->main_pid
, &comm
);
3623 printf(" (%s)", comm
);
3624 } else if (i
->exit_code
> 0) {
3625 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3627 if (i
->exit_code
== CLD_EXITED
) {
3630 printf("status=%i", i
->exit_status
);
3632 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3637 printf("signal=%s", signal_to_string(i
->exit_status
));
3641 if (i
->control_pid
> 0)
3645 if (i
->control_pid
> 0) {
3646 _cleanup_free_
char *c
= NULL
;
3648 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3650 get_process_comm(i
->control_pid
, &c
);
3659 printf(" Status: \"%s\"\n", i
->status_text
);
3660 if (i
->status_errno
> 0)
3661 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3663 if (i
->tasks_current
!= (uint64_t) -1) {
3664 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3666 if (i
->tasks_max
!= (uint64_t) -1)
3667 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3672 if (i
->memory_current
!= (uint64_t) -1) {
3673 char buf
[FORMAT_BYTES_MAX
];
3675 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3677 if (i
->memory_limit
!= (uint64_t) -1)
3678 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3683 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3684 char buf
[FORMAT_TIMESPAN_MAX
];
3685 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3688 if (i
->control_group
&&
3689 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3690 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3693 printf(" CGroup: %s\n", i
->control_group
);
3695 if (IN_SET(arg_transport
,
3696 BUS_TRANSPORT_LOCAL
,
3697 BUS_TRANSPORT_MACHINE
)) {
3700 static const char prefix
[] = " ";
3703 if (c
> sizeof(prefix
) - 1)
3704 c
-= sizeof(prefix
) - 1;
3708 if (i
->main_pid
> 0)
3709 extra
[k
++] = i
->main_pid
;
3711 if (i
->control_pid
> 0)
3712 extra
[k
++] = i
->control_pid
;
3714 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3718 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3719 show_journal_by_unit(
3724 i
->inactive_exit_timestamp_monotonic
,
3727 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3728 SD_JOURNAL_LOCAL_ONLY
,
3729 arg_scope
== UNIT_FILE_SYSTEM
,
3732 if (i
->need_daemon_reload
)
3733 warn_unit_file_changed(i
->id
);
3736 static void show_unit_help(UnitStatusInfo
*i
) {
3741 if (!i
->documentation
) {
3742 log_info("Documentation for %s not known.", i
->id
);
3746 STRV_FOREACH(p
, i
->documentation
)
3747 if (startswith(*p
, "man:"))
3748 show_man_page(*p
+ 4, false);
3750 log_info("Can't show: %s", *p
);
3753 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3760 switch (contents
[0]) {
3762 case SD_BUS_TYPE_STRING
: {
3765 r
= sd_bus_message_read(m
, "s", &s
);
3767 return bus_log_parse_error(r
);
3770 if (streq(name
, "Id"))
3772 else if (streq(name
, "LoadState"))
3774 else if (streq(name
, "ActiveState"))
3775 i
->active_state
= s
;
3776 else if (streq(name
, "SubState"))
3778 else if (streq(name
, "Description"))
3780 else if (streq(name
, "FragmentPath"))
3781 i
->fragment_path
= s
;
3782 else if (streq(name
, "SourcePath"))
3785 else if (streq(name
, "DefaultControlGroup")) {
3787 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3789 i
->control_group
= e
;
3792 else if (streq(name
, "ControlGroup"))
3793 i
->control_group
= s
;
3794 else if (streq(name
, "StatusText"))
3796 else if (streq(name
, "PIDFile"))
3798 else if (streq(name
, "SysFSPath"))
3800 else if (streq(name
, "Where"))
3802 else if (streq(name
, "What"))
3804 else if (streq(name
, "Following"))
3806 else if (streq(name
, "UnitFileState"))
3807 i
->unit_file_state
= s
;
3808 else if (streq(name
, "UnitFilePreset"))
3809 i
->unit_file_preset
= s
;
3810 else if (streq(name
, "Result"))
3817 case SD_BUS_TYPE_BOOLEAN
: {
3820 r
= sd_bus_message_read(m
, "b", &b
);
3822 return bus_log_parse_error(r
);
3824 if (streq(name
, "Accept"))
3826 else if (streq(name
, "NeedDaemonReload"))
3827 i
->need_daemon_reload
= b
;
3828 else if (streq(name
, "ConditionResult"))
3829 i
->condition_result
= b
;
3830 else if (streq(name
, "AssertResult"))
3831 i
->assert_result
= b
;
3836 case SD_BUS_TYPE_UINT32
: {
3839 r
= sd_bus_message_read(m
, "u", &u
);
3841 return bus_log_parse_error(r
);
3843 if (streq(name
, "MainPID")) {
3845 i
->main_pid
= (pid_t
) u
;
3848 } else if (streq(name
, "ControlPID"))
3849 i
->control_pid
= (pid_t
) u
;
3850 else if (streq(name
, "ExecMainPID")) {
3852 i
->main_pid
= (pid_t
) u
;
3853 } else if (streq(name
, "NAccepted"))
3855 else if (streq(name
, "NConnections"))
3856 i
->n_connections
= u
;
3861 case SD_BUS_TYPE_INT32
: {
3864 r
= sd_bus_message_read(m
, "i", &j
);
3866 return bus_log_parse_error(r
);
3868 if (streq(name
, "ExecMainCode"))
3869 i
->exit_code
= (int) j
;
3870 else if (streq(name
, "ExecMainStatus"))
3871 i
->exit_status
= (int) j
;
3872 else if (streq(name
, "StatusErrno"))
3873 i
->status_errno
= (int) j
;
3878 case SD_BUS_TYPE_UINT64
: {
3881 r
= sd_bus_message_read(m
, "t", &u
);
3883 return bus_log_parse_error(r
);
3885 if (streq(name
, "ExecMainStartTimestamp"))
3886 i
->start_timestamp
= (usec_t
) u
;
3887 else if (streq(name
, "ExecMainExitTimestamp"))
3888 i
->exit_timestamp
= (usec_t
) u
;
3889 else if (streq(name
, "ActiveEnterTimestamp"))
3890 i
->active_enter_timestamp
= (usec_t
) u
;
3891 else if (streq(name
, "InactiveEnterTimestamp"))
3892 i
->inactive_enter_timestamp
= (usec_t
) u
;
3893 else if (streq(name
, "InactiveExitTimestamp"))
3894 i
->inactive_exit_timestamp
= (usec_t
) u
;
3895 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3896 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3897 else if (streq(name
, "ActiveExitTimestamp"))
3898 i
->active_exit_timestamp
= (usec_t
) u
;
3899 else if (streq(name
, "ConditionTimestamp"))
3900 i
->condition_timestamp
= (usec_t
) u
;
3901 else if (streq(name
, "AssertTimestamp"))
3902 i
->assert_timestamp
= (usec_t
) u
;
3903 else if (streq(name
, "MemoryCurrent"))
3904 i
->memory_current
= u
;
3905 else if (streq(name
, "MemoryLimit"))
3906 i
->memory_limit
= u
;
3907 else if (streq(name
, "TasksCurrent"))
3908 i
->tasks_current
= u
;
3909 else if (streq(name
, "TasksMax"))
3911 else if (streq(name
, "CPUUsageNSec"))
3912 i
->cpu_usage_nsec
= u
;
3917 case SD_BUS_TYPE_ARRAY
:
3919 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3920 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3922 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3924 return bus_log_parse_error(r
);
3926 info
= new0(ExecStatusInfo
, 1);
3930 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3932 info
->name
= strdup(name
);
3936 LIST_PREPEND(exec
, i
->exec
, info
);
3938 info
= new0(ExecStatusInfo
, 1);
3944 return bus_log_parse_error(r
);
3946 r
= sd_bus_message_exit_container(m
);
3948 return bus_log_parse_error(r
);
3952 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3953 const char *type
, *path
;
3955 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3957 return bus_log_parse_error(r
);
3959 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3961 r
= strv_extend(&i
->listen
, type
);
3965 r
= strv_extend(&i
->listen
, path
);
3970 return bus_log_parse_error(r
);
3972 r
= sd_bus_message_exit_container(m
);
3974 return bus_log_parse_error(r
);
3978 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3980 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3982 return bus_log_parse_error(r
);
3984 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3986 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3988 return bus_log_parse_error(r
);
3990 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3991 const char *cond
, *param
;
3992 int trigger
, negate
;
3995 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3997 return bus_log_parse_error(r
);
3999 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4000 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4001 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4002 i
->failed_condition
= cond
;
4003 i
->failed_condition_trigger
= trigger
;
4004 i
->failed_condition_negate
= negate
;
4005 i
->failed_condition_parameter
= param
;
4009 return bus_log_parse_error(r
);
4011 r
= sd_bus_message_exit_container(m
);
4013 return bus_log_parse_error(r
);
4015 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4016 const char *cond
, *param
;
4017 int trigger
, negate
;
4020 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4022 return bus_log_parse_error(r
);
4024 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4025 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4026 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4027 i
->failed_assert
= cond
;
4028 i
->failed_assert_trigger
= trigger
;
4029 i
->failed_assert_negate
= negate
;
4030 i
->failed_assert_parameter
= param
;
4034 return bus_log_parse_error(r
);
4036 r
= sd_bus_message_exit_container(m
);
4038 return bus_log_parse_error(r
);
4045 case SD_BUS_TYPE_STRUCT_BEGIN
:
4047 if (streq(name
, "LoadError")) {
4048 const char *n
, *message
;
4050 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4052 return bus_log_parse_error(r
);
4054 if (!isempty(message
))
4055 i
->load_error
= message
;
4068 r
= sd_bus_message_skip(m
, contents
);
4070 return bus_log_parse_error(r
);
4075 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4081 /* This is a low-level property printer, see
4082 * print_status_info() for the nicer output */
4084 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4085 /* skip what we didn't read */
4086 r
= sd_bus_message_skip(m
, contents
);
4090 switch (contents
[0]) {
4092 case SD_BUS_TYPE_STRUCT_BEGIN
:
4094 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4097 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4099 return bus_log_parse_error(r
);
4102 printf("%s=%"PRIu32
"\n", name
, u
);
4104 printf("%s=\n", name
);
4108 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4111 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4113 return bus_log_parse_error(r
);
4115 if (arg_all
|| !isempty(s
))
4116 printf("%s=%s\n", name
, s
);
4120 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4121 const char *a
= NULL
, *b
= NULL
;
4123 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4125 return bus_log_parse_error(r
);
4127 if (arg_all
|| !isempty(a
) || !isempty(b
))
4128 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4131 } else if (streq_ptr(name
, "SystemCallFilter")) {
4132 _cleanup_strv_free_
char **l
= NULL
;
4135 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4137 return bus_log_parse_error(r
);
4139 r
= sd_bus_message_read(m
, "b", &whitelist
);
4141 return bus_log_parse_error(r
);
4143 r
= sd_bus_message_read_strv(m
, &l
);
4145 return bus_log_parse_error(r
);
4147 r
= sd_bus_message_exit_container(m
);
4149 return bus_log_parse_error(r
);
4151 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4155 fputs(name
, stdout
);
4161 STRV_FOREACH(i
, l
) {
4169 fputc('\n', stdout
);
4177 case SD_BUS_TYPE_ARRAY
:
4179 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4183 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4185 return bus_log_parse_error(r
);
4187 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4188 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4191 return bus_log_parse_error(r
);
4193 r
= sd_bus_message_exit_container(m
);
4195 return bus_log_parse_error(r
);
4199 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4200 const char *type
, *path
;
4202 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4204 return bus_log_parse_error(r
);
4206 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4207 printf("%s=%s\n", type
, path
);
4209 return bus_log_parse_error(r
);
4211 r
= sd_bus_message_exit_container(m
);
4213 return bus_log_parse_error(r
);
4217 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4218 const char *type
, *path
;
4220 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4222 return bus_log_parse_error(r
);
4224 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4225 printf("Listen%s=%s\n", type
, path
);
4227 return bus_log_parse_error(r
);
4229 r
= sd_bus_message_exit_container(m
);
4231 return bus_log_parse_error(r
);
4235 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4237 uint64_t value
, next_elapse
;
4239 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4241 return bus_log_parse_error(r
);
4243 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4244 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4246 printf("%s={ value=%s ; next_elapse=%s }\n",
4248 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4249 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4252 return bus_log_parse_error(r
);
4254 r
= sd_bus_message_exit_container(m
);
4256 return bus_log_parse_error(r
);
4260 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4261 ExecStatusInfo info
= {};
4263 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4265 return bus_log_parse_error(r
);
4267 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4268 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4269 _cleanup_free_
char *tt
;
4271 tt
= strv_join(info
.argv
, " ");
4273 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",
4277 yes_no(info
.ignore
),
4278 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4279 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4281 sigchld_code_to_string(info
.code
),
4283 info
.code
== CLD_EXITED
? "" : "/",
4284 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4287 strv_free(info
.argv
);
4291 r
= sd_bus_message_exit_container(m
);
4293 return bus_log_parse_error(r
);
4297 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4298 const char *path
, *rwm
;
4300 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4302 return bus_log_parse_error(r
);
4304 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4305 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4307 return bus_log_parse_error(r
);
4309 r
= sd_bus_message_exit_container(m
);
4311 return bus_log_parse_error(r
);
4315 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4319 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4321 return bus_log_parse_error(r
);
4323 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4324 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4326 return bus_log_parse_error(r
);
4328 r
= sd_bus_message_exit_container(m
);
4330 return bus_log_parse_error(r
);
4334 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4338 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4340 return bus_log_parse_error(r
);
4342 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4343 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4345 return bus_log_parse_error(r
);
4347 r
= sd_bus_message_exit_container(m
);
4349 return bus_log_parse_error(r
);
4357 r
= bus_print_property(name
, m
, arg_all
);
4359 return bus_log_parse_error(r
);
4362 r
= sd_bus_message_skip(m
, contents
);
4364 return bus_log_parse_error(r
);
4367 printf("%s=[unprintable]\n", name
);
4373 static int show_one(
4377 bool show_properties
,
4381 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4382 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4383 UnitStatusInfo info
= {
4384 .memory_current
= (uint64_t) -1,
4385 .memory_limit
= (uint64_t) -1,
4386 .cpu_usage_nsec
= (uint64_t) -1,
4387 .tasks_current
= (uint64_t) -1,
4388 .tasks_max
= (uint64_t) -1,
4396 log_debug("Showing one %s", path
);
4398 r
= sd_bus_call_method(
4400 "org.freedesktop.systemd1",
4402 "org.freedesktop.DBus.Properties",
4408 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4410 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4412 return bus_log_parse_error(r
);
4419 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4420 const char *name
, *contents
;
4422 r
= sd_bus_message_read(reply
, "s", &name
);
4424 return bus_log_parse_error(r
);
4426 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4428 return bus_log_parse_error(r
);
4430 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4432 return bus_log_parse_error(r
);
4434 if (show_properties
)
4435 r
= print_property(name
, reply
, contents
);
4437 r
= status_property(name
, reply
, &info
, contents
);
4441 r
= sd_bus_message_exit_container(reply
);
4443 return bus_log_parse_error(r
);
4445 r
= sd_bus_message_exit_container(reply
);
4447 return bus_log_parse_error(r
);
4450 return bus_log_parse_error(r
);
4452 r
= sd_bus_message_exit_container(reply
);
4454 return bus_log_parse_error(r
);
4458 if (!show_properties
) {
4459 if (streq(verb
, "help"))
4460 show_unit_help(&info
);
4462 print_status_info(&info
, ellipsized
);
4465 strv_free(info
.documentation
);
4466 strv_free(info
.dropin_paths
);
4467 strv_free(info
.listen
);
4469 if (!streq_ptr(info
.active_state
, "active") &&
4470 !streq_ptr(info
.active_state
, "reloading") &&
4471 streq(verb
, "status")) {
4472 /* According to LSB: "program not running" */
4473 /* 0: program is running or service is OK
4474 * 1: program is dead and /run PID file exists
4475 * 2: program is dead and /run/lock lock file exists
4476 * 3: program is not running
4477 * 4: program or service status is unknown
4479 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4485 while ((p
= info
.exec
)) {
4486 LIST_REMOVE(exec
, info
.exec
, p
);
4487 exec_status_info_free(p
);
4493 static int get_unit_dbus_path_by_pid(
4498 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4499 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4503 r
= sd_bus_call_method(
4505 "org.freedesktop.systemd1",
4506 "/org/freedesktop/systemd1",
4507 "org.freedesktop.systemd1.Manager",
4513 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4515 r
= sd_bus_message_read(reply
, "o", &u
);
4517 return bus_log_parse_error(r
);
4527 static int show_all(
4530 bool show_properties
,
4534 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4535 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4540 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4544 pager_open_if_enabled();
4548 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4550 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4551 _cleanup_free_
char *p
= NULL
;
4553 p
= unit_dbus_path_from_name(u
->id
);
4557 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4560 else if (r
> 0 && ret
== 0)
4567 static int show_system_status(sd_bus
*bus
) {
4568 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4569 _cleanup_free_
char *hn
= NULL
;
4570 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4571 const char *on
, *off
;
4574 hn
= gethostname_malloc();
4578 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4580 return log_error_errno(r
, "Failed to read server status: %m");
4582 if (streq_ptr(mi
.state
, "degraded")) {
4583 on
= ansi_highlight_red();
4584 off
= ansi_normal();
4585 } else if (!streq_ptr(mi
.state
, "running")) {
4586 on
= ansi_highlight_yellow();
4587 off
= ansi_normal();
4591 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4593 printf(" State: %s%s%s\n",
4594 on
, strna(mi
.state
), off
);
4596 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4597 printf(" Failed: %u units\n", mi
.n_failed_units
);
4599 printf(" Since: %s; %s\n",
4600 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4601 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4603 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4604 if (IN_SET(arg_transport
,
4605 BUS_TRANSPORT_LOCAL
,
4606 BUS_TRANSPORT_MACHINE
)) {
4607 static const char prefix
[] = " ";
4611 if (c
> sizeof(prefix
) - 1)
4612 c
-= sizeof(prefix
) - 1;
4616 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4622 static int show(int argc
, char *argv
[], void *userdata
) {
4623 bool show_properties
, show_status
, show_help
, new_line
= false;
4624 bool ellipsized
= false;
4630 show_properties
= streq(argv
[0], "show");
4631 show_status
= streq(argv
[0], "status");
4632 show_help
= streq(argv
[0], "help");
4634 if (show_help
&& argc
<= 1) {
4635 log_error("This command expects one or more unit names. Did you mean --help?");
4639 if (show_properties
)
4640 pager_open_if_enabled();
4643 /* Increase max number of open files to 16K if we can, we
4644 * might needs this when browsing journal files, which might
4645 * be split up into many files. */
4646 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4648 r
= acquire_bus(BUS_MANAGER
, &bus
);
4652 /* If no argument is specified inspect the manager itself */
4653 if (show_properties
&& argc
<= 1)
4654 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4656 if (show_status
&& argc
<= 1) {
4658 pager_open_if_enabled();
4659 show_system_status(bus
);
4663 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4665 _cleanup_free_
char **patterns
= NULL
;
4668 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4669 _cleanup_free_
char *unit
= NULL
;
4672 if (safe_atou32(*name
, &id
) < 0) {
4673 if (strv_push(&patterns
, *name
) < 0)
4677 } else if (show_properties
) {
4678 /* Interpret as job id */
4679 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4683 /* Interpret as PID */
4684 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4691 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4694 else if (r
> 0 && ret
== 0)
4698 if (!strv_isempty(patterns
)) {
4699 _cleanup_strv_free_
char **names
= NULL
;
4701 r
= expand_names(bus
, patterns
, NULL
, &names
);
4703 return log_error_errno(r
, "Failed to expand names: %m");
4705 STRV_FOREACH(name
, names
) {
4706 _cleanup_free_
char *unit
;
4708 unit
= unit_dbus_path_from_name(*name
);
4712 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4715 else if (r
> 0 && ret
== 0)
4721 if (ellipsized
&& !arg_quiet
)
4722 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4727 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4731 assert(user_runtime
);
4734 if (arg_scope
== UNIT_FILE_USER
) {
4735 r
= user_config_home(user_home
);
4737 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4739 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4741 r
= user_runtime_dir(user_runtime
);
4743 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4745 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4748 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4750 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4755 static int cat_file(const char *filename
, bool newline
) {
4756 _cleanup_close_
int fd
;
4758 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4762 printf("%s%s# %s%s\n",
4763 newline
? "\n" : "",
4764 ansi_highlight_blue(),
4769 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4772 static int cat(int argc
, char *argv
[], void *userdata
) {
4773 _cleanup_free_
char *user_home
= NULL
;
4774 _cleanup_free_
char *user_runtime
= NULL
;
4775 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4776 _cleanup_strv_free_
char **names
= NULL
;
4782 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4783 log_error("Cannot remotely cat units.");
4787 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4791 r
= acquire_bus(BUS_MANAGER
, &bus
);
4795 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4797 return log_error_errno(r
, "Failed to expand names: %m");
4799 pager_open_if_enabled();
4801 STRV_FOREACH(name
, names
) {
4802 _cleanup_free_
char *fragment_path
= NULL
;
4803 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4806 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4817 if (fragment_path
) {
4818 r
= cat_file(fragment_path
, false);
4820 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4823 STRV_FOREACH(path
, dropin_paths
) {
4824 r
= cat_file(*path
, path
== dropin_paths
);
4826 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4833 static int set_property(int argc
, char *argv
[], void *userdata
) {
4834 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4835 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4836 _cleanup_free_
char *n
= NULL
;
4841 polkit_agent_open_if_enabled();
4843 r
= acquire_bus(BUS_MANAGER
, &bus
);
4847 r
= sd_bus_message_new_method_call(
4850 "org.freedesktop.systemd1",
4851 "/org/freedesktop/systemd1",
4852 "org.freedesktop.systemd1.Manager",
4853 "SetUnitProperties");
4855 return bus_log_create_error(r
);
4857 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4859 return log_error_errno(r
, "Failed to mangle unit name: %m");
4861 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4863 return bus_log_create_error(r
);
4865 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4867 return bus_log_create_error(r
);
4869 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4870 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4872 return bus_log_create_error(r
);
4874 r
= bus_append_unit_property_assignment(m
, *i
);
4878 r
= sd_bus_message_close_container(m
);
4880 return bus_log_create_error(r
);
4883 r
= sd_bus_message_close_container(m
);
4885 return bus_log_create_error(r
);
4887 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4889 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4894 static int snapshot(int argc
, char *argv
[], void *userdata
) {
4895 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4896 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4897 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4902 polkit_agent_open_if_enabled();
4905 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4907 return log_error_errno(r
, "Failed to generate unit name: %m");
4914 r
= acquire_bus(BUS_MANAGER
, &bus
);
4918 r
= sd_bus_call_method(
4920 "org.freedesktop.systemd1",
4921 "/org/freedesktop/systemd1",
4922 "org.freedesktop.systemd1.Manager",
4928 return log_error_errno(r
, "Failed to create snapshot: %s", bus_error_message(&error
, r
));
4930 r
= sd_bus_message_read(reply
, "o", &path
);
4932 return bus_log_parse_error(r
);
4934 r
= sd_bus_get_property_string(
4936 "org.freedesktop.systemd1",
4938 "org.freedesktop.systemd1.Unit",
4943 return log_error_errno(r
, "Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4951 static int delete_snapshot(int argc
, char *argv
[], void *userdata
) {
4952 _cleanup_strv_free_
char **names
= NULL
;
4957 polkit_agent_open_if_enabled();
4959 r
= acquire_bus(BUS_MANAGER
, &bus
);
4963 r
= expand_names(bus
, strv_skip(argv
, 1), ".snapshot", &names
);
4965 return log_error_errno(r
, "Failed to expand names: %m");
4967 STRV_FOREACH(name
, names
) {
4968 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4971 q
= sd_bus_call_method(
4973 "org.freedesktop.systemd1",
4974 "/org/freedesktop/systemd1",
4975 "org.freedesktop.systemd1.Manager",
4981 log_error_errno(q
, "Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4990 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4991 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4996 polkit_agent_open_if_enabled();
4998 r
= acquire_bus(BUS_MANAGER
, &bus
);
5002 if (arg_action
== ACTION_RELOAD
)
5004 else if (arg_action
== ACTION_REEXEC
)
5005 method
= "Reexecute";
5007 assert(arg_action
== ACTION_SYSTEMCTL
);
5010 streq(argv
[0], "clear-jobs") ||
5011 streq(argv
[0], "cancel") ? "ClearJobs" :
5012 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5013 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5014 streq(argv
[0], "halt") ? "Halt" :
5015 streq(argv
[0], "poweroff") ? "PowerOff" :
5016 streq(argv
[0], "reboot") ? "Reboot" :
5017 streq(argv
[0], "kexec") ? "KExec" :
5018 streq(argv
[0], "exit") ? "Exit" :
5019 /* "daemon-reload" */ "Reload";
5022 r
= sd_bus_call_method(
5024 "org.freedesktop.systemd1",
5025 "/org/freedesktop/systemd1",
5026 "org.freedesktop.systemd1.Manager",
5031 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
5032 /* There's always a fallback possible for
5033 * legacy actions. */
5035 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
5036 /* On reexecution, we expect a disconnect, not a
5040 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5042 return r
< 0 ? r
: 0;
5045 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5046 _cleanup_strv_free_
char **names
= NULL
;
5052 return daemon_reload(argc
, argv
, userdata
);
5054 polkit_agent_open_if_enabled();
5056 r
= acquire_bus(BUS_MANAGER
, &bus
);
5060 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5062 return log_error_errno(r
, "Failed to expand names: %m");
5064 STRV_FOREACH(name
, names
) {
5065 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5067 q
= sd_bus_call_method(
5069 "org.freedesktop.systemd1",
5070 "/org/freedesktop/systemd1",
5071 "org.freedesktop.systemd1.Manager",
5077 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5086 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5087 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5088 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5093 pager_open_if_enabled();
5095 r
= acquire_bus(BUS_MANAGER
, &bus
);
5099 r
= sd_bus_get_property(
5101 "org.freedesktop.systemd1",
5102 "/org/freedesktop/systemd1",
5103 "org.freedesktop.systemd1.Manager",
5109 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5111 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5113 return bus_log_parse_error(r
);
5115 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5118 return bus_log_parse_error(r
);
5120 r
= sd_bus_message_exit_container(reply
);
5122 return bus_log_parse_error(r
);
5127 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5128 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5129 _cleanup_free_
char *cmdline_init
= NULL
;
5130 const char *root
, *init
;
5134 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5135 log_error("Cannot switch root remotely.");
5139 if (argc
< 2 || argc
> 3) {
5140 log_error("Wrong number of arguments.");
5149 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5150 "init", &cmdline_init
,
5153 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5155 init
= cmdline_init
;
5162 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5164 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5165 root_init_path
= strjoina(root
, "/", init
);
5167 /* If the passed init is actually the same as the
5168 * systemd binary, then let's suppress it. */
5169 if (files_same(root_init_path
, root_systemd_path
) > 0)
5173 r
= acquire_bus(BUS_MANAGER
, &bus
);
5177 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5179 r
= sd_bus_call_method(
5181 "org.freedesktop.systemd1",
5182 "/org/freedesktop/systemd1",
5183 "org.freedesktop.systemd1.Manager",
5189 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5194 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5195 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5196 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5204 polkit_agent_open_if_enabled();
5206 r
= acquire_bus(BUS_MANAGER
, &bus
);
5210 method
= streq(argv
[0], "set-environment")
5212 : "UnsetEnvironment";
5214 r
= sd_bus_message_new_method_call(
5217 "org.freedesktop.systemd1",
5218 "/org/freedesktop/systemd1",
5219 "org.freedesktop.systemd1.Manager",
5222 return bus_log_create_error(r
);
5224 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5226 return bus_log_create_error(r
);
5228 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5230 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5235 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5236 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5237 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5241 polkit_agent_open_if_enabled();
5243 r
= acquire_bus(BUS_MANAGER
, &bus
);
5247 r
= sd_bus_message_new_method_call(
5250 "org.freedesktop.systemd1",
5251 "/org/freedesktop/systemd1",
5252 "org.freedesktop.systemd1.Manager",
5255 return bus_log_create_error(r
);
5258 r
= sd_bus_message_append_strv(m
, environ
);
5262 r
= sd_bus_message_open_container(m
, 'a', "s");
5264 return bus_log_create_error(r
);
5266 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5268 if (!env_name_is_valid(*a
)) {
5269 log_error("Not a valid environment variable name: %s", *a
);
5273 STRV_FOREACH(b
, environ
) {
5276 eq
= startswith(*b
, *a
);
5277 if (eq
&& *eq
== '=') {
5279 r
= sd_bus_message_append(m
, "s", *b
);
5281 return bus_log_create_error(r
);
5288 r
= sd_bus_message_close_container(m
);
5291 return bus_log_create_error(r
);
5293 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5295 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5300 static int enable_sysv_units(const char *verb
, char **args
) {
5303 #if defined(HAVE_SYSV_COMPAT)
5305 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5307 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5310 if (!STR_IN_SET(verb
,
5316 /* Processes all SysV units, and reshuffles the array so that
5317 * afterwards only the native units remain */
5319 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5326 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5327 bool found_native
= false, found_sysv
;
5329 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5337 if (!endswith(name
, ".service"))
5340 if (path_is_absolute(name
))
5343 STRV_FOREACH(k
, paths
.unit_path
) {
5344 _cleanup_free_
char *path
= NULL
;
5346 path
= path_join(arg_root
, *k
, name
);
5350 found_native
= access(path
, F_OK
) >= 0;
5355 /* If we have both a native unit and a SysV script,
5356 * enable/disable them both (below); for is-enabled, prefer the
5358 if (found_native
&& streq(verb
, "is-enabled"))
5361 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5365 p
[strlen(p
) - strlen(".service")] = 0;
5366 found_sysv
= access(p
, F_OK
) >= 0;
5371 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5373 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5375 if (!isempty(arg_root
))
5376 argv
[c
++] = q
= strappend("--root=", arg_root
);
5379 argv
[c
++] = basename(p
);
5382 l
= strv_join((char**)argv
, " ");
5386 log_info("Executing %s", l
);
5390 return log_error_errno(errno
, "Failed to fork: %m");
5391 else if (pid
== 0) {
5394 (void) reset_all_signal_handlers();
5395 (void) reset_signal_mask();
5397 execv(argv
[0], (char**) argv
);
5398 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5399 _exit(EXIT_FAILURE
);
5402 j
= wait_for_terminate(pid
, &status
);
5404 log_error_errno(j
, "Failed to wait for child: %m");
5408 if (status
.si_code
== CLD_EXITED
) {
5409 if (streq(verb
, "is-enabled")) {
5410 if (status
.si_status
== 0) {
5419 } else if (status
.si_status
!= 0)
5427 /* Remove this entry, so that we don't try enabling it as native unit */
5430 assert(args
[f
] == name
);
5431 strv_remove(args
, name
);
5438 static int mangle_names(char **original_names
, char ***mangled_names
) {
5439 char **i
, **l
, **name
;
5442 l
= i
= new(char*, strv_length(original_names
) + 1);
5446 STRV_FOREACH(name
, original_names
) {
5448 /* When enabling units qualified path names are OK,
5449 * too, hence allow them explicitly. */
5451 if (is_path(*name
)) {
5458 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5461 return log_error_errno(r
, "Failed to mangle unit name: %m");
5474 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5475 _cleanup_strv_free_
char **names
= NULL
;
5476 const char *verb
= argv
[0];
5477 UnitFileChange
*changes
= NULL
;
5478 unsigned n_changes
= 0;
5479 int carries_install_info
= -1;
5485 r
= mangle_names(strv_skip(argv
, 1), &names
);
5489 r
= enable_sysv_units(verb
, names
);
5493 /* If the operation was fully executed by the SysV compat,
5494 * let's finish early */
5495 if (strv_isempty(names
))
5498 if (install_client_side()) {
5499 if (streq(verb
, "enable")) {
5500 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5501 carries_install_info
= r
;
5502 } else if (streq(verb
, "disable"))
5503 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5504 else if (streq(verb
, "reenable")) {
5505 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5506 carries_install_info
= r
;
5507 } else if (streq(verb
, "link"))
5508 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5509 else if (streq(verb
, "preset")) {
5510 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5511 carries_install_info
= r
;
5512 } else if (streq(verb
, "mask"))
5513 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5514 else if (streq(verb
, "unmask"))
5515 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5517 assert_not_reached("Unknown verb");
5520 log_error_errno(r
, "Operation failed: %m");
5525 dump_unit_file_changes(changes
, n_changes
);
5529 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5530 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5531 int expect_carries_install_info
= false;
5532 bool send_force
= true, send_preset_mode
= false;
5536 polkit_agent_open_if_enabled();
5538 r
= acquire_bus(BUS_MANAGER
, &bus
);
5542 if (streq(verb
, "enable")) {
5543 method
= "EnableUnitFiles";
5544 expect_carries_install_info
= true;
5545 } else if (streq(verb
, "disable")) {
5546 method
= "DisableUnitFiles";
5548 } else if (streq(verb
, "reenable")) {
5549 method
= "ReenableUnitFiles";
5550 expect_carries_install_info
= true;
5551 } else if (streq(verb
, "link"))
5552 method
= "LinkUnitFiles";
5553 else if (streq(verb
, "preset")) {
5555 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5556 method
= "PresetUnitFilesWithMode";
5557 send_preset_mode
= true;
5559 method
= "PresetUnitFiles";
5561 expect_carries_install_info
= true;
5562 } else if (streq(verb
, "mask"))
5563 method
= "MaskUnitFiles";
5564 else if (streq(verb
, "unmask")) {
5565 method
= "UnmaskUnitFiles";
5568 assert_not_reached("Unknown verb");
5570 r
= sd_bus_message_new_method_call(
5573 "org.freedesktop.systemd1",
5574 "/org/freedesktop/systemd1",
5575 "org.freedesktop.systemd1.Manager",
5578 return bus_log_create_error(r
);
5580 r
= sd_bus_message_append_strv(m
, names
);
5582 return bus_log_create_error(r
);
5584 if (send_preset_mode
) {
5585 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5587 return bus_log_create_error(r
);
5590 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5592 return bus_log_create_error(r
);
5595 r
= sd_bus_message_append(m
, "b", arg_force
);
5597 return bus_log_create_error(r
);
5600 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5602 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5604 if (expect_carries_install_info
) {
5605 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5607 return bus_log_parse_error(r
);
5610 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5614 /* Try to reload if enabled */
5616 r
= daemon_reload(argc
, argv
, userdata
);
5621 if (carries_install_info
== 0)
5622 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5623 "using systemctl.\n"
5624 "Possible reasons for having this kind of units are:\n"
5625 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5626 " .wants/ or .requires/ directory.\n"
5627 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5628 " a requirement dependency on it.\n"
5629 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5630 " D-Bus, udev, scripted systemctl call, ...).\n");
5632 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5633 char *new_args
[n_changes
+ 2];
5637 r
= acquire_bus(BUS_MANAGER
, &bus
);
5641 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5642 for (i
= 0; i
< n_changes
; i
++)
5643 new_args
[i
+ 1] = basename(changes
[i
].path
);
5644 new_args
[i
+ 1] = NULL
;
5646 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5650 unit_file_changes_free(changes
, n_changes
);
5655 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5656 _cleanup_strv_free_
char **names
= NULL
;
5657 _cleanup_free_
char *target
= NULL
;
5658 const char *verb
= argv
[0];
5665 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5667 return log_error_errno(r
, "Failed to mangle unit name: %m");
5669 r
= mangle_names(strv_skip(argv
, 2), &names
);
5673 if (streq(verb
, "add-wants"))
5675 else if (streq(verb
, "add-requires"))
5676 dep
= UNIT_REQUIRES
;
5678 assert_not_reached("Unknown verb");
5680 if (install_client_side()) {
5681 UnitFileChange
*changes
= NULL
;
5682 unsigned n_changes
= 0;
5684 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5687 return log_error_errno(r
, "Can't add dependency: %m");
5690 dump_unit_file_changes(changes
, n_changes
);
5692 unit_file_changes_free(changes
, n_changes
);
5695 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5696 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5699 polkit_agent_open_if_enabled();
5701 r
= acquire_bus(BUS_MANAGER
, &bus
);
5705 r
= sd_bus_message_new_method_call(
5708 "org.freedesktop.systemd1",
5709 "/org/freedesktop/systemd1",
5710 "org.freedesktop.systemd1.Manager",
5711 "AddDependencyUnitFiles");
5713 return bus_log_create_error(r
);
5715 r
= sd_bus_message_append_strv(m
, names
);
5717 return bus_log_create_error(r
);
5719 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5721 return bus_log_create_error(r
);
5723 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5725 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5727 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5732 r
= daemon_reload(argc
, argv
, userdata
);
5740 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5741 UnitFileChange
*changes
= NULL
;
5742 unsigned n_changes
= 0;
5745 if (install_client_side()) {
5747 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5749 log_error_errno(r
, "Operation failed: %m");
5754 dump_unit_file_changes(changes
, n_changes
);
5759 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5760 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5763 polkit_agent_open_if_enabled();
5765 r
= acquire_bus(BUS_MANAGER
, &bus
);
5769 r
= sd_bus_call_method(
5771 "org.freedesktop.systemd1",
5772 "/org/freedesktop/systemd1",
5773 "org.freedesktop.systemd1.Manager",
5774 "PresetAllUnitFiles",
5778 unit_file_preset_mode_to_string(arg_preset_mode
),
5782 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5784 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5789 r
= daemon_reload(argc
, argv
, userdata
);
5795 unit_file_changes_free(changes
, n_changes
);
5800 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5802 _cleanup_strv_free_
char **names
= NULL
;
5807 r
= mangle_names(strv_skip(argv
, 1), &names
);
5811 r
= enable_sysv_units(argv
[0], names
);
5817 if (install_client_side()) {
5819 STRV_FOREACH(name
, names
) {
5820 UnitFileState state
;
5822 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5824 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5828 UNIT_FILE_ENABLED_RUNTIME
,
5830 UNIT_FILE_INDIRECT
))
5834 puts(unit_file_state_to_string(state
));
5838 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5841 r
= acquire_bus(BUS_MANAGER
, &bus
);
5845 STRV_FOREACH(name
, names
) {
5846 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5849 r
= sd_bus_call_method(
5851 "org.freedesktop.systemd1",
5852 "/org/freedesktop/systemd1",
5853 "org.freedesktop.systemd1.Manager",
5859 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5861 r
= sd_bus_message_read(reply
, "s", &s
);
5863 return bus_log_parse_error(r
);
5865 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5876 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5877 _cleanup_free_
char *state
= NULL
;
5881 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5884 return EXIT_FAILURE
;
5887 r
= acquire_bus(BUS_MANAGER
, &bus
);
5891 r
= sd_bus_get_property_string(
5893 "org.freedesktop.systemd1",
5894 "/org/freedesktop/systemd1",
5895 "org.freedesktop.systemd1.Manager",
5908 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5911 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5912 _cleanup_free_
char *t
= NULL
;
5916 assert(original_path
);
5919 r
= tempfn_random(new_path
, NULL
, &t
);
5921 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5923 r
= mkdir_parents(new_path
, 0755);
5925 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5927 r
= copy_file(original_path
, t
, 0, 0644, 0);
5932 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5935 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5943 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5944 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5949 switch (arg_scope
) {
5950 case UNIT_FILE_SYSTEM
:
5951 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5953 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5955 case UNIT_FILE_GLOBAL
:
5956 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5958 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5960 case UNIT_FILE_USER
:
5962 assert(user_runtime
);
5964 path
= path_join(arg_root
, user_home
, name
);
5966 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5969 run
= path_join(arg_root
, user_runtime
, name
);
5973 assert_not_reached("Invalid scope");
5975 if (!path
|| (arg_runtime
&& !run
))
5979 if (access(path
, F_OK
) >= 0) {
5980 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5984 if (path2
&& access(path2
, F_OK
) >= 0) {
5985 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5999 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
) {
6000 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6004 assert(ret_new_path
);
6005 assert(ret_tmp_path
);
6007 ending
= strjoina(unit_name
, ".d/override.conf");
6008 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
6012 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6018 *ret_new_path
= tmp_new_path
;
6019 *ret_tmp_path
= tmp_tmp_path
;
6024 static int unit_file_create_copy(
6025 const char *unit_name
,
6026 const char *fragment_path
,
6027 const char *user_home
,
6028 const char *user_runtime
,
6029 char **ret_new_path
,
6030 char **ret_tmp_path
) {
6032 char *tmp_new_path
, *tmp_tmp_path
;
6035 assert(fragment_path
);
6037 assert(ret_new_path
);
6038 assert(ret_tmp_path
);
6040 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
6044 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6047 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6052 if (response
!= 'y') {
6053 log_warning("%s ignored", unit_name
);
6059 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6061 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6066 *ret_new_path
= tmp_new_path
;
6067 *ret_tmp_path
= tmp_tmp_path
;
6072 static int run_editor(char **paths
) {
6080 return log_error_errno(errno
, "Failed to fork: %m");
6084 char *editor
, **editor_args
= NULL
;
6085 char **tmp_path
, **original_path
, *p
;
6086 unsigned n_editor_args
= 0, i
= 1;
6089 (void) reset_all_signal_handlers();
6090 (void) reset_signal_mask();
6092 argc
= strv_length(paths
)/2 + 1;
6094 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6095 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6096 * we try to execute well known editors
6098 editor
= getenv("SYSTEMD_EDITOR");
6100 editor
= getenv("EDITOR");
6102 editor
= getenv("VISUAL");
6104 if (!isempty(editor
)) {
6105 editor_args
= strv_split(editor
, WHITESPACE
);
6108 _exit(EXIT_FAILURE
);
6110 n_editor_args
= strv_length(editor_args
);
6111 argc
+= n_editor_args
- 1;
6113 args
= newa(const char*, argc
+ 1);
6115 if (n_editor_args
> 0) {
6116 args
[0] = editor_args
[0];
6117 for (; i
< n_editor_args
; i
++)
6118 args
[i
] = editor_args
[i
];
6121 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6122 args
[i
] = *tmp_path
;
6127 if (n_editor_args
> 0)
6128 execvp(args
[0], (char* const*) args
);
6130 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6132 execvp(p
, (char* const*) args
);
6133 /* We do not fail if the editor doesn't exist
6134 * because we want to try each one of them before
6137 if (errno
!= ENOENT
) {
6138 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6139 _exit(EXIT_FAILURE
);
6143 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6144 _exit(EXIT_FAILURE
);
6147 r
= wait_for_terminate_and_warn("editor", pid
, true);
6149 return log_error_errno(r
, "Failed to wait for child: %m");
6154 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6155 _cleanup_free_
char *user_home
= NULL
;
6156 _cleanup_free_
char *user_runtime
= NULL
;
6157 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6164 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6168 STRV_FOREACH(name
, names
) {
6169 _cleanup_free_
char *path
= NULL
;
6170 char *new_path
, *tmp_path
;
6172 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6178 // FIXME: support units with path==NULL (no FragmentPath)
6179 log_error("No fragment exists for %s.", *name
);
6184 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6186 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6190 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6198 static int edit(int argc
, char *argv
[], void *userdata
) {
6199 _cleanup_strv_free_
char **names
= NULL
;
6200 _cleanup_strv_free_
char **paths
= NULL
;
6201 char **original
, **tmp
;
6206 log_error("Cannot edit units if not on a tty.");
6210 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6211 log_error("Cannot edit units remotely.");
6215 r
= acquire_bus(BUS_MANAGER
, &bus
);
6219 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6221 return log_error_errno(r
, "Failed to expand names: %m");
6223 r
= find_paths_to_edit(bus
, names
, &paths
);
6227 if (strv_isempty(paths
))
6230 r
= run_editor(paths
);
6234 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6235 /* If the temporary file is empty we ignore it. It's
6236 * useful if the user wants to cancel its modification
6238 if (null_or_empty_path(*tmp
)) {
6239 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6243 r
= rename(*tmp
, *original
);
6245 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6252 if (!arg_no_reload
&& !install_client_side())
6253 r
= daemon_reload(argc
, argv
, userdata
);
6256 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6257 (void) unlink(*tmp
);
6262 static void systemctl_help(void) {
6264 pager_open_if_enabled();
6266 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6267 "Query or send control commands to the systemd manager.\n\n"
6268 " -h --help Show this help\n"
6269 " --version Show package version\n"
6270 " --system Connect to system manager\n"
6271 " --user Connect to user service manager\n"
6272 " -H --host=[USER@]HOST\n"
6273 " Operate on remote host\n"
6274 " -M --machine=CONTAINER\n"
6275 " Operate on local container\n"
6276 " -t --type=TYPE List units of a particular type\n"
6277 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6278 " -p --property=NAME Show only properties by this name\n"
6279 " -a --all Show all loaded units/properties, including dead/empty\n"
6280 " ones. To list all units installed on the system, use\n"
6281 " the 'list-unit-files' command instead.\n"
6282 " -l --full Don't ellipsize unit names on output\n"
6283 " -r --recursive Show unit list of host and local containers\n"
6284 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6285 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6286 " queueing a new job\n"
6287 " --show-types When showing sockets, explicitly show their type\n"
6288 " -i --ignore-inhibitors\n"
6289 " When shutting down or sleeping, ignore inhibitors\n"
6290 " --kill-who=WHO Who to send signal to\n"
6291 " -s --signal=SIGNAL Which signal to send\n"
6292 " --now Start or stop unit in addition to enabling or disabling it\n"
6293 " -q --quiet Suppress output\n"
6294 " --no-block Do not wait until operation finished\n"
6295 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6296 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6297 " --no-legend Do not print a legend (column headers and hints)\n"
6298 " --no-pager Do not pipe output into a pager\n"
6299 " --no-ask-password\n"
6300 " Do not ask for system passwords\n"
6301 " --global Enable/disable unit files globally\n"
6302 " --runtime Enable unit files only temporarily until next reboot\n"
6303 " -f --force When enabling unit files, override existing symlinks\n"
6304 " When shutting down, execute action immediately\n"
6305 " --preset-mode= Apply only enable, only disable, or all presets\n"
6306 " --root=PATH Enable unit files in the specified root directory\n"
6307 " -n --lines=INTEGER Number of journal entries to show\n"
6308 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6309 " short-precise, short-monotonic, verbose,\n"
6310 " export, json, json-pretty, json-sse, cat)\n"
6311 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6312 " --plain Print unit dependencies as a list instead of a tree\n\n"
6314 " list-units [PATTERN...] List loaded units\n"
6315 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6316 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6317 " start NAME... Start (activate) one or more units\n"
6318 " stop NAME... Stop (deactivate) one or more units\n"
6319 " reload NAME... Reload one or more units\n"
6320 " restart NAME... Start or restart one or more units\n"
6321 " try-restart NAME... Restart one or more units if active\n"
6322 " reload-or-restart NAME... Reload one or more units if possible,\n"
6323 " otherwise start or restart\n"
6324 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6325 " otherwise restart if active\n"
6326 " isolate NAME Start one unit and stop all others\n"
6327 " kill NAME... Send signal to processes of a unit\n"
6328 " is-active PATTERN... Check whether units are active\n"
6329 " is-failed PATTERN... Check whether units are failed\n"
6330 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6331 " show [PATTERN...|JOB...] Show properties of one or more\n"
6332 " units/jobs or the manager\n"
6333 " cat PATTERN... Show files and drop-ins of one or more units\n"
6334 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6335 " help PATTERN...|PID... Show manual for one or more units\n"
6336 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6338 " list-dependencies [NAME] Recursively show units which are required\n"
6339 " or wanted by this unit or by which this\n"
6340 " unit is required or wanted\n\n"
6341 "Unit File Commands:\n"
6342 " list-unit-files [PATTERN...] List installed unit files\n"
6343 " enable NAME... Enable one or more unit files\n"
6344 " disable NAME... Disable one or more unit files\n"
6345 " reenable NAME... Reenable one or more unit files\n"
6346 " preset NAME... Enable/disable one or more unit files\n"
6347 " based on preset configuration\n"
6348 " preset-all Enable/disable all unit files based on\n"
6349 " preset configuration\n"
6350 " is-enabled NAME... Check whether unit files are enabled\n"
6351 " mask NAME... Mask one or more units\n"
6352 " unmask NAME... Unmask one or more units\n"
6353 " link PATH... Link one or more units files into\n"
6354 " the search path\n"
6355 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6356 " on specified one or more units\n"
6357 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6358 " on specified one or more units\n"
6359 " edit NAME... Edit one or more unit files\n"
6360 " get-default Get the name of the default target\n"
6361 " set-default NAME Set the default target\n\n"
6362 "Machine Commands:\n"
6363 " list-machines [PATTERN...] List local containers and host\n\n"
6365 " list-jobs [PATTERN...] List jobs\n"
6366 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6367 "Snapshot Commands:\n"
6368 " snapshot [NAME] Create a snapshot\n"
6369 " delete NAME... Remove one or more snapshots\n\n"
6370 "Environment Commands:\n"
6371 " show-environment Dump environment\n"
6372 " set-environment NAME=VALUE... Set one or more environment variables\n"
6373 " unset-environment NAME... Unset one or more environment variables\n"
6374 " import-environment [NAME...] Import all or some environment variables\n\n"
6375 "Manager Lifecycle Commands:\n"
6376 " daemon-reload Reload systemd manager configuration\n"
6377 " daemon-reexec Reexecute systemd manager\n\n"
6378 "System Commands:\n"
6379 " is-system-running Check whether system is fully running\n"
6380 " default Enter system default mode\n"
6381 " rescue Enter system rescue mode\n"
6382 " emergency Enter system emergency mode\n"
6383 " halt Shut down and halt the system\n"
6384 " poweroff Shut down and power-off the system\n"
6385 " reboot [ARG] Shut down and reboot the system\n"
6386 " kexec Shut down and reboot the system with kexec\n"
6387 " exit [EXIT_CODE] Request user instance or container exit\n"
6388 " switch-root ROOT [INIT] Change to a different root file system\n"
6389 " suspend Suspend the system\n"
6390 " hibernate Hibernate the system\n"
6391 " hybrid-sleep Hibernate and suspend the system\n",
6392 program_invocation_short_name
);
6395 static void halt_help(void) {
6396 printf("%s [OPTIONS...]%s\n\n"
6397 "%s the system.\n\n"
6398 " --help Show this help\n"
6399 " --halt Halt the machine\n"
6400 " -p --poweroff Switch off the machine\n"
6401 " --reboot Reboot the machine\n"
6402 " -f --force Force immediate halt/power-off/reboot\n"
6403 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6404 " -d --no-wtmp Don't write wtmp record\n"
6405 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6406 program_invocation_short_name
,
6407 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6408 arg_action
== ACTION_REBOOT
? "Reboot" :
6409 arg_action
== ACTION_POWEROFF
? "Power off" :
6413 static void shutdown_help(void) {
6414 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6415 "Shut down the system.\n\n"
6416 " --help Show this help\n"
6417 " -H --halt Halt the machine\n"
6418 " -P --poweroff Power-off the machine\n"
6419 " -r --reboot Reboot the machine\n"
6420 " -h Equivalent to --poweroff, overridden by --halt\n"
6421 " -k Don't halt/power-off/reboot, just send warnings\n"
6422 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6423 " -c Cancel a pending shutdown\n",
6424 program_invocation_short_name
);
6427 static void telinit_help(void) {
6428 printf("%s [OPTIONS...] {COMMAND}\n\n"
6429 "Send control commands to the init daemon.\n\n"
6430 " --help Show this help\n"
6431 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6433 " 0 Power-off the machine\n"
6434 " 6 Reboot the machine\n"
6435 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6436 " 1, s, S Enter rescue mode\n"
6437 " q, Q Reload init daemon configuration\n"
6438 " u, U Reexecute init daemon\n",
6439 program_invocation_short_name
);
6442 static void runlevel_help(void) {
6443 printf("%s [OPTIONS...]\n\n"
6444 "Prints the previous and current runlevel of the init system.\n\n"
6445 " --help Show this help\n",
6446 program_invocation_short_name
);
6449 static void help_types(void) {
6453 puts("Available unit types:");
6454 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6455 puts(unit_type_to_string(i
));
6458 static void help_states(void) {
6462 puts("Available unit load states:");
6463 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6464 puts(unit_load_state_to_string(i
));
6467 puts("\nAvailable unit active states:");
6468 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6469 puts(unit_active_state_to_string(i
));
6472 puts("\nAvailable automount unit substates:");
6473 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6474 puts(automount_state_to_string(i
));
6477 puts("\nAvailable busname unit substates:");
6478 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6479 puts(busname_state_to_string(i
));
6482 puts("\nAvailable device unit substates:");
6483 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6484 puts(device_state_to_string(i
));
6487 puts("\nAvailable mount unit substates:");
6488 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6489 puts(mount_state_to_string(i
));
6492 puts("\nAvailable path unit substates:");
6493 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6494 puts(path_state_to_string(i
));
6497 puts("\nAvailable scope unit substates:");
6498 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6499 puts(scope_state_to_string(i
));
6502 puts("\nAvailable service unit substates:");
6503 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6504 puts(service_state_to_string(i
));
6507 puts("\nAvailable slice unit substates:");
6508 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6509 puts(slice_state_to_string(i
));
6512 puts("\nAvailable snapshot unit substates:");
6513 for (i
= 0; i
< _SNAPSHOT_STATE_MAX
; i
++)
6514 puts(snapshot_state_to_string(i
));
6517 puts("\nAvailable socket unit substates:");
6518 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6519 puts(socket_state_to_string(i
));
6522 puts("\nAvailable swap unit substates:");
6523 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6524 puts(swap_state_to_string(i
));
6527 puts("\nAvailable target unit substates:");
6528 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6529 puts(target_state_to_string(i
));
6532 puts("\nAvailable timer unit substates:");
6533 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6534 puts(timer_state_to_string(i
));
6537 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6546 ARG_IGNORE_DEPENDENCIES
,
6558 ARG_NO_ASK_PASSWORD
,
6571 static const struct option options
[] = {
6572 { "help", no_argument
, NULL
, 'h' },
6573 { "version", no_argument
, NULL
, ARG_VERSION
},
6574 { "type", required_argument
, NULL
, 't' },
6575 { "property", required_argument
, NULL
, 'p' },
6576 { "all", no_argument
, NULL
, 'a' },
6577 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6578 { "after", no_argument
, NULL
, ARG_AFTER
},
6579 { "before", no_argument
, NULL
, ARG_BEFORE
},
6580 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6581 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6582 { "full", no_argument
, NULL
, 'l' },
6583 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6584 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6585 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6586 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6587 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6588 { "user", no_argument
, NULL
, ARG_USER
},
6589 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6590 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6591 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6592 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6593 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6594 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6595 { "quiet", no_argument
, NULL
, 'q' },
6596 { "root", required_argument
, NULL
, ARG_ROOT
},
6597 { "force", no_argument
, NULL
, ARG_FORCE
},
6598 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6599 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6600 { "signal", required_argument
, NULL
, 's' },
6601 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6602 { "host", required_argument
, NULL
, 'H' },
6603 { "machine", required_argument
, NULL
, 'M' },
6604 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6605 { "lines", required_argument
, NULL
, 'n' },
6606 { "output", required_argument
, NULL
, 'o' },
6607 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6608 { "state", required_argument
, NULL
, ARG_STATE
},
6609 { "recursive", no_argument
, NULL
, 'r' },
6610 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6611 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6612 { "now", no_argument
, NULL
, ARG_NOW
},
6613 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6622 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6623 arg_ask_password
= true;
6625 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6637 const char *word
, *state
;
6640 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6641 _cleanup_free_
char *type
;
6643 type
= strndup(word
, size
);
6647 if (streq(type
, "help")) {
6652 if (unit_type_from_string(type
) >= 0) {
6653 if (strv_push(&arg_types
, type
) < 0)
6659 /* It's much nicer to use --state= for
6660 * load states, but let's support this
6661 * in --types= too for compatibility
6662 * with old versions */
6663 if (unit_load_state_from_string(type
) >= 0) {
6664 if (strv_push(&arg_states
, type
) < 0)
6670 log_error("Unknown unit type or load state '%s'.", type
);
6671 log_info("Use -t help to see a list of allowed values.");
6679 /* Make sure that if the empty property list
6680 was specified, we won't show any properties. */
6681 if (isempty(optarg
) && !arg_properties
) {
6682 arg_properties
= new0(char*, 1);
6683 if (!arg_properties
)
6686 const char *word
, *state
;
6689 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6692 prop
= strndup(word
, size
);
6696 if (strv_consume(&arg_properties
, prop
) < 0)
6701 /* If the user asked for a particular
6702 * property, show it to him, even if it is
6714 arg_dependency
= DEPENDENCY_REVERSE
;
6718 arg_dependency
= DEPENDENCY_AFTER
;
6722 arg_dependency
= DEPENDENCY_BEFORE
;
6725 case ARG_SHOW_TYPES
:
6726 arg_show_types
= true;
6730 arg_job_mode
= optarg
;
6734 arg_job_mode
= "fail";
6737 case ARG_IRREVERSIBLE
:
6738 arg_job_mode
= "replace-irreversibly";
6741 case ARG_IGNORE_DEPENDENCIES
:
6742 arg_job_mode
= "ignore-dependencies";
6746 arg_scope
= UNIT_FILE_USER
;
6750 arg_scope
= UNIT_FILE_SYSTEM
;
6754 arg_scope
= UNIT_FILE_GLOBAL
;
6758 arg_no_block
= true;
6762 arg_no_legend
= true;
6766 arg_no_pager
= true;
6774 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6784 if (strv_extend(&arg_states
, "failed") < 0)
6802 arg_no_reload
= true;
6806 arg_kill_who
= optarg
;
6810 arg_signal
= signal_from_string_try_harder(optarg
);
6811 if (arg_signal
< 0) {
6812 log_error("Failed to parse signal string %s.", optarg
);
6817 case ARG_NO_ASK_PASSWORD
:
6818 arg_ask_password
= false;
6822 arg_transport
= BUS_TRANSPORT_REMOTE
;
6827 arg_transport
= BUS_TRANSPORT_MACHINE
;
6836 if (safe_atou(optarg
, &arg_lines
) < 0) {
6837 log_error("Failed to parse lines '%s'", optarg
);
6843 arg_output
= output_mode_from_string(optarg
);
6844 if (arg_output
< 0) {
6845 log_error("Unknown output '%s'.", optarg
);
6851 arg_ignore_inhibitors
= true;
6858 case ARG_FIRMWARE_SETUP
:
6859 arg_firmware_setup
= true;
6863 const char *word
, *state
;
6866 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6867 _cleanup_free_
char *s
= NULL
;
6869 s
= strndup(word
, size
);
6873 if (streq(s
, "help")) {
6878 if (strv_push(&arg_states
, s
) < 0)
6887 if (geteuid() != 0) {
6888 log_error("--recursive requires root privileges.");
6892 arg_recursive
= true;
6895 case ARG_PRESET_MODE
:
6897 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6898 if (arg_preset_mode
< 0) {
6899 log_error("Failed to parse preset mode: %s.", optarg
);
6910 if (strv_extend(&arg_wall
, optarg
) < 0)
6918 assert_not_reached("Unhandled option");
6921 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6922 log_error("Cannot access user instance remotely.");
6929 static int halt_parse_argv(int argc
, char *argv
[]) {
6938 static const struct option options
[] = {
6939 { "help", no_argument
, NULL
, ARG_HELP
},
6940 { "halt", no_argument
, NULL
, ARG_HALT
},
6941 { "poweroff", no_argument
, NULL
, 'p' },
6942 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6943 { "force", no_argument
, NULL
, 'f' },
6944 { "wtmp-only", no_argument
, NULL
, 'w' },
6945 { "no-wtmp", no_argument
, NULL
, 'd' },
6946 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6955 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6956 if (runlevel
== '0' || runlevel
== '6')
6959 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6967 arg_action
= ACTION_HALT
;
6971 if (arg_action
!= ACTION_REBOOT
)
6972 arg_action
= ACTION_POWEROFF
;
6976 arg_action
= ACTION_REBOOT
;
6998 /* Compatibility nops */
7005 assert_not_reached("Unhandled option");
7008 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7009 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7012 } else if (optind
< argc
) {
7013 log_error("Too many arguments.");
7020 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7024 if (streq(t
, "now"))
7026 else if (!strchr(t
, ':')) {
7029 if (safe_atou64(t
, &u
) < 0)
7032 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7041 hour
= strtol(t
, &e
, 10);
7042 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7045 minute
= strtol(e
+1, &e
, 10);
7046 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7049 n
= now(CLOCK_REALTIME
);
7050 s
= (time_t) (n
/ USEC_PER_SEC
);
7052 assert_se(localtime_r(&s
, &tm
));
7054 tm
.tm_hour
= (int) hour
;
7055 tm
.tm_min
= (int) minute
;
7058 assert_se(s
= mktime(&tm
));
7060 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7063 *_u
+= USEC_PER_DAY
;
7069 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7076 static const struct option options
[] = {
7077 { "help", no_argument
, NULL
, ARG_HELP
},
7078 { "halt", no_argument
, NULL
, 'H' },
7079 { "poweroff", no_argument
, NULL
, 'P' },
7080 { "reboot", no_argument
, NULL
, 'r' },
7081 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7082 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7092 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7100 arg_action
= ACTION_HALT
;
7104 arg_action
= ACTION_POWEROFF
;
7109 arg_action
= ACTION_KEXEC
;
7111 arg_action
= ACTION_REBOOT
;
7115 arg_action
= ACTION_KEXEC
;
7119 if (arg_action
!= ACTION_HALT
)
7120 arg_action
= ACTION_POWEROFF
;
7135 /* Compatibility nops */
7139 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7146 assert_not_reached("Unhandled option");
7149 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7150 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7152 log_error("Failed to parse time specification: %s", argv
[optind
]);
7156 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7158 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7159 /* No time argument for shutdown cancel */
7160 wall
= argv
+ optind
;
7161 else if (argc
> optind
+ 1)
7162 /* We skip the time argument */
7163 wall
= argv
+ optind
+ 1;
7166 arg_wall
= strv_copy(wall
);
7176 static int telinit_parse_argv(int argc
, char *argv
[]) {
7183 static const struct option options
[] = {
7184 { "help", no_argument
, NULL
, ARG_HELP
},
7185 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7189 static const struct {
7193 { '0', ACTION_POWEROFF
},
7194 { '6', ACTION_REBOOT
},
7195 { '1', ACTION_RESCUE
},
7196 { '2', ACTION_RUNLEVEL2
},
7197 { '3', ACTION_RUNLEVEL3
},
7198 { '4', ACTION_RUNLEVEL4
},
7199 { '5', ACTION_RUNLEVEL5
},
7200 { 's', ACTION_RESCUE
},
7201 { 'S', ACTION_RESCUE
},
7202 { 'q', ACTION_RELOAD
},
7203 { 'Q', ACTION_RELOAD
},
7204 { 'u', ACTION_REEXEC
},
7205 { 'U', ACTION_REEXEC
}
7214 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7229 assert_not_reached("Unhandled option");
7232 if (optind
>= argc
) {
7233 log_error("%s: required argument missing.", program_invocation_short_name
);
7237 if (optind
+ 1 < argc
) {
7238 log_error("Too many arguments.");
7242 if (strlen(argv
[optind
]) != 1) {
7243 log_error("Expected single character argument.");
7247 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7248 if (table
[i
].from
== argv
[optind
][0])
7251 if (i
>= ELEMENTSOF(table
)) {
7252 log_error("Unknown command '%s'.", argv
[optind
]);
7256 arg_action
= table
[i
].to
;
7263 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7269 static const struct option options
[] = {
7270 { "help", no_argument
, NULL
, ARG_HELP
},
7279 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7290 assert_not_reached("Unhandled option");
7293 if (optind
< argc
) {
7294 log_error("Too many arguments.");
7301 static int parse_argv(int argc
, char *argv
[]) {
7305 if (program_invocation_short_name
) {
7307 if (strstr(program_invocation_short_name
, "halt")) {
7308 arg_action
= ACTION_HALT
;
7309 return halt_parse_argv(argc
, argv
);
7310 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7311 arg_action
= ACTION_POWEROFF
;
7312 return halt_parse_argv(argc
, argv
);
7313 } else if (strstr(program_invocation_short_name
, "reboot")) {
7315 arg_action
= ACTION_KEXEC
;
7317 arg_action
= ACTION_REBOOT
;
7318 return halt_parse_argv(argc
, argv
);
7319 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7320 arg_action
= ACTION_POWEROFF
;
7321 return shutdown_parse_argv(argc
, argv
);
7322 } else if (strstr(program_invocation_short_name
, "init")) {
7324 if (sd_booted() > 0) {
7325 arg_action
= _ACTION_INVALID
;
7326 return telinit_parse_argv(argc
, argv
);
7328 /* Hmm, so some other init system is
7329 * running, we need to forward this
7330 * request to it. For now we simply
7331 * guess that it is Upstart. */
7333 execv(TELINIT
, argv
);
7335 log_error("Couldn't find an alternative telinit implementation to spawn.");
7339 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7340 arg_action
= ACTION_RUNLEVEL
;
7341 return runlevel_parse_argv(argc
, argv
);
7345 arg_action
= ACTION_SYSTEMCTL
;
7346 return systemctl_parse_argv(argc
, argv
);
7349 _pure_
static int action_to_runlevel(void) {
7351 static const char table
[_ACTION_MAX
] = {
7352 [ACTION_HALT
] = '0',
7353 [ACTION_POWEROFF
] = '0',
7354 [ACTION_REBOOT
] = '6',
7355 [ACTION_RUNLEVEL2
] = '2',
7356 [ACTION_RUNLEVEL3
] = '3',
7357 [ACTION_RUNLEVEL4
] = '4',
7358 [ACTION_RUNLEVEL5
] = '5',
7359 [ACTION_RESCUE
] = '1'
7362 assert(arg_action
< _ACTION_MAX
);
7364 return table
[arg_action
];
7367 static int talk_initctl(void) {
7368 #ifdef HAVE_SYSV_COMPAT
7369 struct init_request request
= {
7370 .magic
= INIT_MAGIC
,
7372 .cmd
= INIT_CMD_RUNLVL
7375 _cleanup_close_
int fd
= -1;
7379 rl
= action_to_runlevel();
7383 request
.runlevel
= rl
;
7385 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7387 if (errno
== ENOENT
)
7390 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7393 r
= loop_write(fd
, &request
, sizeof(request
), false);
7395 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7403 static int systemctl_main(int argc
, char *argv
[]) {
7405 static const Verb verbs
[] = {
7406 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
, list_units
},
7407 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7408 { "list-sockets", VERB_ANY
, VERB_ANY
, 0, list_sockets
},
7409 { "list-timers", VERB_ANY
, VERB_ANY
, 0, list_timers
},
7410 { "list-jobs", VERB_ANY
, VERB_ANY
, 0, list_jobs
},
7411 { "list-machines", VERB_ANY
, VERB_ANY
, 0, list_machines
},
7412 { "clear-jobs", VERB_ANY
, 1, 0, daemon_reload
},
7413 { "cancel", 2, VERB_ANY
, 0, cancel_job
},
7414 { "start", 2, VERB_ANY
, 0, start_unit
},
7415 { "stop", 2, VERB_ANY
, 0, start_unit
},
7416 { "condstop", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7417 { "reload", 2, VERB_ANY
, 0, start_unit
},
7418 { "restart", 2, VERB_ANY
, 0, start_unit
},
7419 { "try-restart", 2, VERB_ANY
, 0, start_unit
},
7420 { "reload-or-restart", 2, VERB_ANY
, 0, start_unit
},
7421 { "reload-or-try-restart", 2, VERB_ANY
, 0, start_unit
},
7422 { "force-reload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with SysV */
7423 { "condreload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7424 { "condrestart", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with RH */
7425 { "isolate", 2, 2, 0, start_unit
},
7426 { "kill", 2, VERB_ANY
, 0, kill_unit
},
7427 { "is-active", 2, VERB_ANY
, 0, check_unit_active
},
7428 { "check", 2, VERB_ANY
, 0, check_unit_active
},
7429 { "is-failed", 2, VERB_ANY
, 0, check_unit_failed
},
7430 { "show", VERB_ANY
, VERB_ANY
, 0, show
},
7431 { "cat", 2, VERB_ANY
, 0, cat
},
7432 { "status", VERB_ANY
, VERB_ANY
, 0, show
},
7433 { "help", VERB_ANY
, VERB_ANY
, 0, show
},
7434 { "snapshot", VERB_ANY
, 2, 0, snapshot
},
7435 { "delete", 2, VERB_ANY
, 0, delete_snapshot
},
7436 { "daemon-reload", VERB_ANY
, 1, 0, daemon_reload
},
7437 { "daemon-reexec", VERB_ANY
, 1, 0, daemon_reload
},
7438 { "show-environment", VERB_ANY
, 1, 0, show_environment
},
7439 { "set-environment", 2, VERB_ANY
, 0, set_environment
},
7440 { "unset-environment", 2, VERB_ANY
, 0, set_environment
},
7441 { "import-environment", VERB_ANY
, VERB_ANY
, 0, import_environment
},
7442 { "halt", VERB_ANY
, 1, 0, start_special
},
7443 { "poweroff", VERB_ANY
, 1, 0, start_special
},
7444 { "reboot", VERB_ANY
, 2, 0, start_special
},
7445 { "kexec", VERB_ANY
, 1, 0, start_special
},
7446 { "suspend", VERB_ANY
, 1, 0, start_special
},
7447 { "hibernate", VERB_ANY
, 1, 0, start_special
},
7448 { "hybrid-sleep", VERB_ANY
, 1, 0, start_special
},
7449 { "default", VERB_ANY
, 1, 0, start_special
},
7450 { "rescue", VERB_ANY
, 1, 0, start_special
},
7451 { "emergency", VERB_ANY
, 1, 0, start_special
},
7452 { "exit", VERB_ANY
, 2, 0, start_special
},
7453 { "reset-failed", VERB_ANY
, VERB_ANY
, 0, reset_failed
},
7454 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7455 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7456 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7457 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7458 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7459 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7460 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7461 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7462 { "link", 2, VERB_ANY
, 0, enable_unit
},
7463 { "switch-root", 2, VERB_ANY
, 0, switch_root
},
7464 { "list-dependencies", VERB_ANY
, 2, 0, list_dependencies
},
7465 { "set-default", 2, 2, 0, set_default
},
7466 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7467 { "set-property", 3, VERB_ANY
, 0, set_property
},
7468 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7469 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7470 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7471 { "edit", 2, VERB_ANY
, 0, edit
},
7475 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7478 static int reload_with_fallback(void) {
7480 /* First, try systemd via D-Bus. */
7481 if (daemon_reload(0, NULL
, NULL
) >= 0)
7484 /* Nothing else worked, so let's try signals */
7485 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7487 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7488 return log_error_errno(errno
, "kill() failed: %m");
7493 static int start_with_fallback(void) {
7495 /* First, try systemd via D-Bus. */
7496 if (start_unit(0, NULL
, NULL
) >= 0)
7499 /* Nothing else worked, so let's try
7501 if (talk_initctl() > 0)
7504 log_error("Failed to talk to init daemon.");
7508 static int halt_now(enum action a
) {
7510 /* The kernel will automaticall flush ATA disks and suchlike
7511 * on reboot(), but the file systems need to be synce'd
7512 * explicitly in advance. */
7515 /* Make sure C-A-D is handled by the kernel from this point
7517 (void) reboot(RB_ENABLE_CAD
);
7522 log_info("Halting.");
7523 (void) reboot(RB_HALT_SYSTEM
);
7526 case ACTION_POWEROFF
:
7527 log_info("Powering off.");
7528 (void) reboot(RB_POWER_OFF
);
7532 case ACTION_REBOOT
: {
7533 _cleanup_free_
char *param
= NULL
;
7535 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7536 log_info("Rebooting with argument '%s'.", param
);
7537 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7540 log_info("Rebooting.");
7541 (void) reboot(RB_AUTOBOOT
);
7546 assert_not_reached("Unknown action.");
7550 static int logind_schedule_shutdown(void) {
7553 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7554 char date
[FORMAT_TIMESTAMP_MAX
];
7559 (void) logind_set_wall_message();
7561 r
= acquire_bus(BUS_FULL
, &bus
);
7565 switch (arg_action
) {
7569 case ACTION_POWEROFF
:
7570 action
= "poweroff";
7585 action
= strjoina("dry-", action
);
7587 r
= sd_bus_call_method(
7589 "org.freedesktop.login1",
7590 "/org/freedesktop/login1",
7591 "org.freedesktop.login1.Manager",
7599 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7601 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7604 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7609 static int halt_main(void) {
7612 r
= logind_check_inhibitors(arg_action
);
7617 return logind_schedule_shutdown();
7619 if (geteuid() != 0) {
7620 if (arg_dry
|| arg_force
> 0) {
7621 log_error("Must be root.");
7625 /* Try logind if we are a normal user and no special
7626 * mode applies. Maybe PolicyKit allows us to shutdown
7628 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7629 r
= logind_reboot(arg_action
);
7632 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7633 /* requested operation is not
7634 * supported on the local system or
7635 * already in progress */
7637 /* on all other errors, try low-level operation */
7641 if (!arg_dry
&& !arg_force
)
7642 return start_with_fallback();
7644 assert(geteuid() == 0);
7647 if (sd_booted() > 0)
7648 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7650 r
= utmp_put_shutdown();
7652 log_warning_errno(r
, "Failed to write utmp record: %m");
7659 r
= halt_now(arg_action
);
7660 return log_error_errno(r
, "Failed to reboot: %m");
7663 static int runlevel_main(void) {
7664 int r
, runlevel
, previous
;
7666 r
= utmp_get_runlevel(&runlevel
, &previous
);
7673 previous
<= 0 ? 'N' : previous
,
7674 runlevel
<= 0 ? 'N' : runlevel
);
7679 static int logind_cancel_shutdown(void) {
7681 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7685 r
= acquire_bus(BUS_FULL
, &bus
);
7689 (void) logind_set_wall_message();
7691 r
= sd_bus_call_method(
7693 "org.freedesktop.login1",
7694 "/org/freedesktop/login1",
7695 "org.freedesktop.login1.Manager",
7696 "CancelScheduledShutdown",
7700 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7704 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7709 int main(int argc
, char*argv
[]) {
7712 setlocale(LC_ALL
, "");
7713 log_parse_environment();
7716 /* Explicitly not on_tty() to avoid setting cached value.
7717 * This becomes relevant for piping output which might be
7719 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7721 r
= parse_argv(argc
, argv
);
7725 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7726 log_info("Running in chroot, ignoring request.");
7731 /* systemctl_main() will print an error message for the bus
7732 * connection, but only if it needs to */
7734 switch (arg_action
) {
7736 case ACTION_SYSTEMCTL
:
7737 r
= systemctl_main(argc
, argv
);
7741 case ACTION_POWEROFF
:
7747 case ACTION_RUNLEVEL2
:
7748 case ACTION_RUNLEVEL3
:
7749 case ACTION_RUNLEVEL4
:
7750 case ACTION_RUNLEVEL5
:
7752 case ACTION_EMERGENCY
:
7753 case ACTION_DEFAULT
:
7754 r
= start_with_fallback();
7759 r
= reload_with_fallback();
7762 case ACTION_CANCEL_SHUTDOWN
:
7763 r
= logind_cancel_shutdown();
7766 case ACTION_RUNLEVEL
:
7767 r
= runlevel_main();
7770 case _ACTION_INVALID
:
7772 assert_not_reached("Unknown action");
7777 ask_password_agent_close();
7778 polkit_agent_close();
7780 strv_free(arg_types
);
7781 strv_free(arg_states
);
7782 strv_free(arg_properties
);
7784 strv_free(arg_wall
);
7789 return r
< 0 ? EXIT_FAILURE
: r
;