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 "alloc-util.h"
41 #include "bus-common-errors.h"
42 #include "bus-error.h"
43 #include "bus-message.h"
45 #include "cgroup-show.h"
46 #include "cgroup-util.h"
51 #include "exit-status.h"
54 #include "formats-util.h"
56 #include "glob-util.h"
57 #include "hostname-util.h"
62 #include "locale-util.h"
64 #include "logs-show.h"
68 #include "parse-util.h"
69 #include "path-lookup.h"
70 #include "path-util.h"
71 #include "process-util.h"
72 #include "rlimit-util.h"
74 #include "signal-util.h"
75 #include "socket-util.h"
76 #include "spawn-ask-password-agent.h"
77 #include "spawn-polkit-agent.h"
79 #include "stat-util.h"
81 #include "terminal-util.h"
82 #include "unit-name.h"
83 #include "user-util.h"
85 #include "utmp-wtmp.h"
89 static char **arg_types
= NULL
;
90 static char **arg_states
= NULL
;
91 static char **arg_properties
= NULL
;
92 static bool arg_all
= false;
93 static enum dependency
{
99 } arg_dependency
= DEPENDENCY_FORWARD
;
100 static const char *arg_job_mode
= "replace";
101 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
102 static bool arg_no_block
= false;
103 static bool arg_no_legend
= false;
104 static bool arg_no_pager
= false;
105 static bool arg_no_wtmp
= false;
106 static bool arg_no_wall
= false;
107 static bool arg_no_reload
= false;
108 static bool arg_show_types
= false;
109 static bool arg_ignore_inhibitors
= false;
110 static bool arg_dry
= false;
111 static bool arg_quiet
= false;
112 static bool arg_full
= false;
113 static bool arg_recursive
= false;
114 static int arg_force
= 0;
115 static bool arg_ask_password
= false;
116 static bool arg_runtime
= false;
117 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
118 static char **arg_wall
= NULL
;
119 static const char *arg_kill_who
= NULL
;
120 static int arg_signal
= SIGTERM
;
121 static char *arg_root
= NULL
;
122 static usec_t arg_when
= 0;
144 ACTION_CANCEL_SHUTDOWN
,
146 } arg_action
= ACTION_SYSTEMCTL
;
147 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
148 static const char *arg_host
= NULL
;
149 static unsigned arg_lines
= 10;
150 static OutputMode arg_output
= OUTPUT_SHORT
;
151 static bool arg_plain
= false;
152 static bool arg_firmware_setup
= false;
153 static bool arg_now
= false;
155 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
156 static int halt_now(enum action a
);
157 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
159 static bool original_stdout_is_tty
;
161 typedef enum BusFocus
{
162 BUS_FULL
, /* The full bus indicated via --system or --user */
163 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
167 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
169 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
172 assert(focus
< _BUS_FOCUS_MAX
);
175 /* We only go directly to the manager, if we are using a local transport */
176 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
179 if (!busses
[focus
]) {
182 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
184 if (focus
== BUS_MANAGER
)
185 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
187 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
189 return log_error_errno(r
, "Failed to connect to bus: %m");
191 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
194 *ret
= busses
[focus
];
198 static void release_busses(void) {
201 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
202 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
205 static void pager_open_if_enabled(void) {
213 static void ask_password_agent_open_if_enabled(void) {
215 /* Open the password agent as a child process if necessary */
217 if (!arg_ask_password
)
220 if (arg_scope
!= UNIT_FILE_SYSTEM
)
223 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
226 ask_password_agent_open();
229 static void polkit_agent_open_if_enabled(void) {
231 /* Open the polkit agent as a child process if necessary */
233 if (!arg_ask_password
)
236 if (arg_scope
!= UNIT_FILE_SYSTEM
)
239 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
245 static OutputFlags
get_output_flags(void) {
247 arg_all
* OUTPUT_SHOW_ALL
|
248 arg_full
* OUTPUT_FULL_WIDTH
|
249 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
250 on_tty() * OUTPUT_COLOR
|
251 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
254 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
257 if (!sd_bus_error_is_set(error
))
260 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
261 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
262 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
263 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
264 return EXIT_NOPERMISSION
;
266 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
267 return EXIT_NOTINSTALLED
;
269 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
270 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
271 return EXIT_NOTIMPLEMENTED
;
273 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
274 return EXIT_NOTCONFIGURED
;
282 static bool install_client_side(void) {
284 /* Decides when to execute enable/disable/... operations
285 * client-side rather than server-side. */
287 if (running_in_chroot() > 0)
290 if (sd_booted() <= 0)
293 if (!isempty(arg_root
))
296 if (arg_scope
== UNIT_FILE_GLOBAL
)
299 /* Unsupported environment variable, mostly for debugging purposes */
300 if (getenv_bool("SYSTEMCTL_INSTALL_CLIENT_SIDE") > 0)
306 static int compare_unit_info(const void *a
, const void *b
) {
307 const UnitInfo
*u
= a
, *v
= b
;
311 /* First, order by machine */
312 if (!u
->machine
&& v
->machine
)
314 if (u
->machine
&& !v
->machine
)
316 if (u
->machine
&& v
->machine
) {
317 r
= strcasecmp(u
->machine
, v
->machine
);
322 /* Second, order by unit type */
323 d1
= strrchr(u
->id
, '.');
324 d2
= strrchr(v
->id
, '.');
326 r
= strcasecmp(d1
, d2
);
331 /* Third, order by name */
332 return strcasecmp(u
->id
, v
->id
);
335 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
336 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
342 dot
= strrchr(u
->id
, '.');
346 if (!strv_find(arg_types
, dot
+1))
356 if (streq(u
->active_state
, "inactive") || u
->following
[0])
362 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
363 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
365 unsigned n_shown
= 0;
368 max_id_len
= strlen("UNIT");
369 load_len
= strlen("LOAD");
370 active_len
= strlen("ACTIVE");
371 sub_len
= strlen("SUB");
372 job_len
= strlen("JOB");
375 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
376 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
377 load_len
= MAX(load_len
, strlen(u
->load_state
));
378 active_len
= MAX(active_len
, strlen(u
->active_state
));
379 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
381 if (u
->job_id
!= 0) {
382 job_len
= MAX(job_len
, strlen(u
->job_type
));
386 if (!arg_no_legend
&&
387 (streq(u
->active_state
, "failed") ||
388 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
392 if (!arg_full
&& original_stdout_is_tty
) {
395 id_len
= MIN(max_id_len
, 25u);
396 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
399 basic_len
+= job_len
+ 1;
401 if (basic_len
< (unsigned) columns()) {
402 unsigned extra_len
, incr
;
403 extra_len
= columns() - basic_len
;
405 /* Either UNIT already got 25, or is fully satisfied.
406 * Grant up to 25 to DESC now. */
407 incr
= MIN(extra_len
, 25u);
411 /* split the remaining space between UNIT and DESC,
412 * but do not give UNIT more than it needs. */
414 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
416 desc_len
+= extra_len
- incr
;
422 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
423 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
424 const char *on_loaded
= "", *off_loaded
= "";
425 const char *on_active
= "", *off_active
= "";
426 const char *on_circle
= "", *off_circle
= "";
430 if (!n_shown
&& !arg_no_legend
) {
435 printf("%-*s %-*s %-*s %-*s ",
438 active_len
, "ACTIVE",
442 printf("%-*s ", job_len
, "JOB");
444 if (!arg_full
&& arg_no_pager
)
445 printf("%.*s\n", desc_len
, "DESCRIPTION");
447 printf("%s\n", "DESCRIPTION");
452 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
453 on_loaded
= ansi_highlight_red();
454 on_circle
= ansi_highlight_yellow();
455 off_loaded
= off_circle
= ansi_normal();
457 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
458 on_circle
= on_active
= ansi_highlight_red();
459 off_circle
= off_active
= ansi_normal();
464 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
473 e
= ellipsize(id
, id_len
, 33);
481 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
483 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
484 on_active
, id_len
, id
, off_active
,
485 on_loaded
, load_len
, u
->load_state
, off_loaded
,
486 on_active
, active_len
, u
->active_state
,
487 sub_len
, u
->sub_state
, off_active
,
488 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
491 printf("%.*s\n", desc_len
, u
->description
);
493 printf("%s\n", u
->description
);
496 if (!arg_no_legend
) {
497 const char *on
, *off
;
501 "LOAD = Reflects whether the unit definition was properly loaded.\n"
502 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
503 "SUB = The low-level unit activation state, values depend on unit type.");
504 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
505 on
= ansi_highlight();
508 on
= ansi_highlight_red();
513 printf("%s%u loaded units listed.%s\n"
514 "To show all installed unit files use 'systemctl list-unit-files'.\n",
517 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
518 "To show all installed unit files use 'systemctl list-unit-files'.\n",
525 static int get_unit_list(
529 UnitInfo
**unit_infos
,
531 sd_bus_message
**_reply
) {
533 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
534 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
535 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
544 r
= sd_bus_message_new_method_call(
547 "org.freedesktop.systemd1",
548 "/org/freedesktop/systemd1",
549 "org.freedesktop.systemd1.Manager",
550 "ListUnitsFiltered");
553 return bus_log_create_error(r
);
555 r
= sd_bus_message_append_strv(m
, arg_states
);
557 return bus_log_create_error(r
);
559 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
561 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
563 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
565 return bus_log_parse_error(r
);
567 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
570 if (!output_show_unit(&u
, patterns
))
573 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
576 (*unit_infos
)[c
++] = u
;
579 return bus_log_parse_error(r
);
581 r
= sd_bus_message_exit_container(reply
);
583 return bus_log_parse_error(r
);
591 static void message_set_freep(Set
**set
) {
594 while ((m
= set_steal_first(*set
)))
595 sd_bus_message_unref(m
);
600 static int get_unit_list_recursive(
603 UnitInfo
**_unit_infos
,
607 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
608 _cleanup_(message_set_freep
) Set
*replies
;
609 sd_bus_message
*reply
;
617 replies
= set_new(NULL
);
621 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
625 r
= set_put(replies
, reply
);
627 sd_bus_message_unref(reply
);
632 _cleanup_strv_free_
char **machines
= NULL
;
635 r
= sd_get_machine_names(&machines
);
637 return log_error_errno(r
, "Failed to get machine names: %m");
639 STRV_FOREACH(i
, machines
) {
640 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
643 r
= sd_bus_open_system_machine(&container
, *i
);
645 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
649 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
655 r
= set_put(replies
, reply
);
657 sd_bus_message_unref(reply
);
662 *_machines
= machines
;
667 *_unit_infos
= unit_infos
;
676 static int list_units(int argc
, char *argv
[], void *userdata
) {
677 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
678 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
679 _cleanup_strv_free_
char **machines
= NULL
;
683 pager_open_if_enabled();
685 r
= acquire_bus(BUS_MANAGER
, &bus
);
689 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
693 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
694 return output_units_list(unit_infos
, r
);
697 static int get_triggered_units(
702 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
709 r
= sd_bus_get_property_strv(
711 "org.freedesktop.systemd1",
713 "org.freedesktop.systemd1.Unit",
718 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
723 static int get_listening(
725 const char* unit_path
,
728 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
729 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
730 const char *type
, *path
;
733 r
= sd_bus_get_property(
735 "org.freedesktop.systemd1",
737 "org.freedesktop.systemd1.Socket",
743 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
745 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
747 return bus_log_parse_error(r
);
749 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
751 r
= strv_extend(listening
, type
);
755 r
= strv_extend(listening
, path
);
762 return bus_log_parse_error(r
);
764 r
= sd_bus_message_exit_container(reply
);
766 return bus_log_parse_error(r
);
778 /* Note: triggered is a list here, although it almost certainly
779 * will always be one unit. Nevertheless, dbus API allows for multiple
780 * values, so let's follow that. */
783 /* The strv above is shared. free is set only in the first one. */
787 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
793 if (!a
->machine
&& b
->machine
)
795 if (a
->machine
&& !b
->machine
)
797 if (a
->machine
&& b
->machine
) {
798 o
= strcasecmp(a
->machine
, b
->machine
);
803 o
= strcmp(a
->path
, b
->path
);
805 o
= strcmp(a
->type
, b
->type
);
810 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
811 struct socket_info
*s
;
812 unsigned pathlen
= strlen("LISTEN"),
813 typelen
= strlen("TYPE") * arg_show_types
,
814 socklen
= strlen("UNIT"),
815 servlen
= strlen("ACTIVATES");
816 const char *on
, *off
;
818 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
822 socklen
= MAX(socklen
, strlen(s
->id
));
824 typelen
= MAX(typelen
, strlen(s
->type
));
825 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
827 STRV_FOREACH(a
, s
->triggered
)
828 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
829 servlen
= MAX(servlen
, tmp
);
834 printf("%-*s %-*.*s%-*s %s\n",
836 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
840 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
841 _cleanup_free_
char *j
= NULL
;
846 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
854 printf("%-*s %-*s %-*s",
855 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
858 pathlen
, path
, socklen
, s
->id
);
859 STRV_FOREACH(a
, s
->triggered
)
861 a
== s
->triggered
? "" : ",", *a
);
865 on
= ansi_highlight();
870 on
= ansi_highlight_red();
874 if (!arg_no_legend
) {
875 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
877 printf("Pass --all to see loaded but inactive sockets, too.\n");
883 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
884 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
885 _cleanup_strv_free_
char **machines
= NULL
;
886 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
887 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
889 struct socket_info
*s
;
895 pager_open_if_enabled();
897 r
= acquire_bus(BUS_MANAGER
, &bus
);
901 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
905 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
906 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
909 if (!endswith(u
->id
, ".socket"))
912 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
916 c
= get_listening(bus
, u
->unit_path
, &listening
);
922 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
927 for (i
= 0; i
< c
; i
++)
928 socket_infos
[cs
+ i
] = (struct socket_info
) {
929 .machine
= u
->machine
,
931 .type
= listening
[i
*2],
932 .path
= listening
[i
*2 + 1],
933 .triggered
= triggered
,
934 .own_triggered
= i
==0,
937 /* from this point on we will cleanup those socket_infos */
940 listening
= triggered
= NULL
; /* avoid cleanup */
943 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
944 (__compar_fn_t
) socket_info_compare
);
946 output_sockets_list(socket_infos
, cs
);
949 assert(cs
== 0 || socket_infos
);
950 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
953 if (s
->own_triggered
)
954 strv_free(s
->triggered
);
960 static int get_next_elapse(
963 dual_timestamp
*next
) {
965 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
973 r
= sd_bus_get_property_trivial(
975 "org.freedesktop.systemd1",
977 "org.freedesktop.systemd1.Timer",
978 "NextElapseUSecMonotonic",
983 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
985 r
= sd_bus_get_property_trivial(
987 "org.freedesktop.systemd1",
989 "org.freedesktop.systemd1.Timer",
990 "NextElapseUSecRealtime",
995 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
1001 static int get_last_trigger(
1006 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1013 r
= sd_bus_get_property_trivial(
1015 "org.freedesktop.systemd1",
1017 "org.freedesktop.systemd1.Timer",
1023 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1029 const char* machine
;
1032 usec_t last_trigger
;
1036 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1042 if (!a
->machine
&& b
->machine
)
1044 if (a
->machine
&& !b
->machine
)
1046 if (a
->machine
&& b
->machine
) {
1047 o
= strcasecmp(a
->machine
, b
->machine
);
1052 if (a
->next_elapse
< b
->next_elapse
)
1054 if (a
->next_elapse
> b
->next_elapse
)
1057 return strcmp(a
->id
, b
->id
);
1060 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1061 struct timer_info
*t
;
1063 nextlen
= strlen("NEXT"),
1064 leftlen
= strlen("LEFT"),
1065 lastlen
= strlen("LAST"),
1066 passedlen
= strlen("PASSED"),
1067 unitlen
= strlen("UNIT"),
1068 activatelen
= strlen("ACTIVATES");
1070 const char *on
, *off
;
1072 assert(timer_infos
|| n
== 0);
1074 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1078 if (t
->next_elapse
> 0) {
1079 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1081 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1082 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1084 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1085 leftlen
= MAX(leftlen
, strlen(trel
));
1088 if (t
->last_trigger
> 0) {
1089 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1091 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1092 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1094 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1095 passedlen
= MAX(passedlen
, strlen(trel
));
1098 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1100 STRV_FOREACH(a
, t
->triggered
)
1101 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1103 activatelen
= MAX(activatelen
, ul
);
1108 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1112 passedlen
, "PASSED",
1116 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1117 _cleanup_free_
char *j
= NULL
;
1119 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1120 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1123 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1124 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1126 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1127 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1130 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1137 printf("%-*s %-*s %-*s %-*s %-*s",
1138 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1140 STRV_FOREACH(a
, t
->triggered
)
1142 a
== t
->triggered
? "" : ",", *a
);
1146 on
= ansi_highlight();
1147 off
= ansi_normal();
1151 on
= ansi_highlight_red();
1152 off
= ansi_normal();
1155 if (!arg_no_legend
) {
1156 printf("%s%u timers listed.%s\n", on
, n
, off
);
1158 printf("Pass --all to see loaded but inactive timers, too.\n");
1164 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1170 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1173 if (next
->monotonic
> nw
->monotonic
)
1174 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1176 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1178 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1179 next_elapse
= MIN(converted
, next
->realtime
);
1181 next_elapse
= converted
;
1184 next_elapse
= next
->realtime
;
1189 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1190 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1191 _cleanup_strv_free_
char **machines
= NULL
;
1192 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1193 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1194 struct timer_info
*t
;
1202 pager_open_if_enabled();
1204 r
= acquire_bus(BUS_MANAGER
, &bus
);
1208 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1212 dual_timestamp_get(&nw
);
1214 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1215 _cleanup_strv_free_
char **triggered
= NULL
;
1216 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1219 if (!endswith(u
->id
, ".timer"))
1222 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1226 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1230 get_last_trigger(bus
, u
->unit_path
, &last
);
1232 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1237 m
= calc_next_elapse(&nw
, &next
);
1239 timer_infos
[c
++] = (struct timer_info
) {
1240 .machine
= u
->machine
,
1243 .last_trigger
= last
,
1244 .triggered
= triggered
,
1247 triggered
= NULL
; /* avoid cleanup */
1250 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1251 (__compar_fn_t
) timer_info_compare
);
1253 output_timers_list(timer_infos
, c
);
1256 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1257 strv_free(t
->triggered
);
1262 static int compare_unit_file_list(const void *a
, const void *b
) {
1263 const char *d1
, *d2
;
1264 const UnitFileList
*u
= a
, *v
= b
;
1266 d1
= strrchr(u
->path
, '.');
1267 d2
= strrchr(v
->path
, '.');
1272 r
= strcasecmp(d1
, d2
);
1277 return strcasecmp(basename(u
->path
), basename(v
->path
));
1280 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1281 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1284 if (!strv_isempty(arg_types
)) {
1287 dot
= strrchr(u
->path
, '.');
1291 if (!strv_find(arg_types
, dot
+1))
1295 if (!strv_isempty(arg_states
) &&
1296 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1302 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1303 unsigned max_id_len
, id_cols
, state_cols
;
1304 const UnitFileList
*u
;
1306 max_id_len
= strlen("UNIT FILE");
1307 state_cols
= strlen("STATE");
1309 for (u
= units
; u
< units
+ c
; u
++) {
1310 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1311 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1315 unsigned basic_cols
;
1317 id_cols
= MIN(max_id_len
, 25u);
1318 basic_cols
= 1 + id_cols
+ state_cols
;
1319 if (basic_cols
< (unsigned) columns())
1320 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1322 id_cols
= max_id_len
;
1325 printf("%-*s %-*s\n",
1326 id_cols
, "UNIT FILE",
1327 state_cols
, "STATE");
1329 for (u
= units
; u
< units
+ c
; u
++) {
1330 _cleanup_free_
char *e
= NULL
;
1331 const char *on
, *off
;
1334 if (IN_SET(u
->state
,
1336 UNIT_FILE_MASKED_RUNTIME
,
1339 on
= ansi_highlight_red();
1340 off
= ansi_normal();
1341 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1342 on
= ansi_highlight_green();
1343 off
= ansi_normal();
1347 id
= basename(u
->path
);
1349 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1351 printf("%-*s %s%-*s%s\n",
1352 id_cols
, e
? e
: id
,
1353 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1357 printf("\n%u unit files listed.\n", c
);
1360 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1361 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1362 _cleanup_free_ UnitFileList
*units
= NULL
;
1370 pager_open_if_enabled();
1372 if (install_client_side()) {
1378 h
= hashmap_new(&string_hash_ops
);
1382 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1384 unit_file_list_free(h
);
1385 return log_error_errno(r
, "Failed to get unit file list: %m");
1388 n_units
= hashmap_size(h
);
1390 units
= new(UnitFileList
, n_units
);
1391 if (!units
&& n_units
> 0) {
1392 unit_file_list_free(h
);
1396 HASHMAP_FOREACH(u
, h
, i
) {
1397 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1404 assert(c
<= n_units
);
1407 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1410 r
= acquire_bus(BUS_MANAGER
, &bus
);
1414 r
= sd_bus_call_method(
1416 "org.freedesktop.systemd1",
1417 "/org/freedesktop/systemd1",
1418 "org.freedesktop.systemd1.Manager",
1424 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1426 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1428 return bus_log_parse_error(r
);
1430 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1432 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1435 units
[c
] = (struct UnitFileList
) {
1437 unit_file_state_from_string(state
)
1440 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1445 return bus_log_parse_error(r
);
1447 r
= sd_bus_message_exit_container(reply
);
1449 return bus_log_parse_error(r
);
1452 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1453 output_unit_file_list(units
, c
);
1455 if (install_client_side()) {
1456 for (unit
= units
; unit
< units
+ c
; unit
++)
1463 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1464 _cleanup_free_
char *n
= NULL
;
1465 size_t max_len
= MAX(columns(),20u);
1471 for (i
= level
- 1; i
>= 0; i
--) {
1473 if (len
> max_len
- 3 && !arg_full
) {
1474 printf("%s...\n",max_len
% 2 ? "" : " ");
1477 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1481 if (len
> max_len
- 3 && !arg_full
) {
1482 printf("%s...\n",max_len
% 2 ? "" : " ");
1486 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1490 printf("%s\n", name
);
1494 n
= ellipsize(name
, max_len
-len
, 100);
1502 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1504 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1505 [DEPENDENCY_FORWARD
] = "Requires\0"
1510 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1515 [DEPENDENCY_AFTER
] = "After\0",
1516 [DEPENDENCY_BEFORE
] = "Before\0",
1519 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1520 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1521 _cleanup_strv_free_
char **ret
= NULL
;
1522 _cleanup_free_
char *path
= NULL
;
1528 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1530 path
= unit_dbus_path_from_name(name
);
1534 r
= sd_bus_call_method(
1536 "org.freedesktop.systemd1",
1538 "org.freedesktop.DBus.Properties",
1542 "s", "org.freedesktop.systemd1.Unit");
1544 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1546 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1548 return bus_log_parse_error(r
);
1550 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1553 r
= sd_bus_message_read(reply
, "s", &prop
);
1555 return bus_log_parse_error(r
);
1557 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1558 r
= sd_bus_message_skip(reply
, "v");
1560 return bus_log_parse_error(r
);
1563 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1565 return bus_log_parse_error(r
);
1567 r
= bus_message_read_strv_extend(reply
, &ret
);
1569 return bus_log_parse_error(r
);
1571 r
= sd_bus_message_exit_container(reply
);
1573 return bus_log_parse_error(r
);
1576 r
= sd_bus_message_exit_container(reply
);
1578 return bus_log_parse_error(r
);
1582 return bus_log_parse_error(r
);
1584 r
= sd_bus_message_exit_container(reply
);
1586 return bus_log_parse_error(r
);
1594 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1595 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1597 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1599 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1602 return strcasecmp(*a
, *b
);
1605 static int list_dependencies_one(
1610 unsigned int branches
) {
1612 _cleanup_strv_free_
char **deps
= NULL
;
1620 r
= strv_extend(units
, name
);
1624 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1628 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1630 STRV_FOREACH(c
, deps
) {
1631 if (strv_contains(*units
, *c
)) {
1633 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1646 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1647 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1648 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1651 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1655 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1656 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1663 strv_remove(*units
, name
);
1668 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1669 _cleanup_strv_free_
char **units
= NULL
;
1670 _cleanup_free_
char *unit
= NULL
;
1676 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1678 return log_error_errno(r
, "Failed to mangle unit name: %m");
1682 u
= SPECIAL_DEFAULT_TARGET
;
1684 pager_open_if_enabled();
1686 r
= acquire_bus(BUS_MANAGER
, &bus
);
1692 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1695 struct machine_info
{
1699 char *control_group
;
1700 uint32_t n_failed_units
;
1705 static const struct bus_properties_map machine_info_property_map
[] = {
1706 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1707 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1708 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1709 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1710 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1714 static void machine_info_clear(struct machine_info
*info
) {
1718 free(info
->control_group
);
1723 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1729 for (i
= 0; i
< n
; i
++)
1730 machine_info_clear(&machine_infos
[i
]);
1732 free(machine_infos
);
1735 static int compare_machine_info(const void *a
, const void *b
) {
1736 const struct machine_info
*u
= a
, *v
= b
;
1738 if (u
->is_host
!= v
->is_host
)
1739 return u
->is_host
> v
->is_host
? -1 : 1;
1741 return strcasecmp(u
->name
, v
->name
);
1744 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1745 _cleanup_(sd_bus_flush_close_unrefp
) sd_bus
*container
= NULL
;
1751 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1758 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1765 static bool output_show_machine(const char *name
, char **patterns
) {
1766 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1769 static int get_machine_list(
1771 struct machine_info
**_machine_infos
,
1774 struct machine_info
*machine_infos
= NULL
;
1775 _cleanup_strv_free_
char **m
= NULL
;
1776 _cleanup_free_
char *hn
= NULL
;
1781 hn
= gethostname_malloc();
1785 if (output_show_machine(hn
, patterns
)) {
1786 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1789 machine_infos
[c
].is_host
= true;
1790 machine_infos
[c
].name
= hn
;
1793 get_machine_properties(bus
, &machine_infos
[c
]);
1797 r
= sd_get_machine_names(&m
);
1799 return log_error_errno(r
, "Failed to get machine list: %m");
1801 STRV_FOREACH(i
, m
) {
1802 _cleanup_free_
char *class = NULL
;
1804 if (!output_show_machine(*i
, patterns
))
1807 sd_machine_get_class(*i
, &class);
1808 if (!streq_ptr(class, "container"))
1811 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1812 free_machines_list(machine_infos
, c
);
1816 machine_infos
[c
].is_host
= false;
1817 machine_infos
[c
].name
= strdup(*i
);
1818 if (!machine_infos
[c
].name
) {
1819 free_machines_list(machine_infos
, c
);
1823 get_machine_properties(NULL
, &machine_infos
[c
]);
1827 *_machine_infos
= machine_infos
;
1831 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1832 struct machine_info
*m
;
1835 namelen
= sizeof("NAME") - 1,
1836 statelen
= sizeof("STATE") - 1,
1837 failedlen
= sizeof("FAILED") - 1,
1838 jobslen
= sizeof("JOBS") - 1;
1840 assert(machine_infos
|| n
== 0);
1842 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1843 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1844 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1845 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1846 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1848 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1852 if (!arg_no_legend
) {
1856 printf("%-*s %-*s %-*s %-*s\n",
1859 failedlen
, "FAILED",
1863 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1864 const char *on_state
= "", *off_state
= "";
1865 const char *on_failed
= "", *off_failed
= "";
1866 bool circle
= false;
1868 if (streq_ptr(m
->state
, "degraded")) {
1869 on_state
= ansi_highlight_red();
1870 off_state
= ansi_normal();
1872 } else if (!streq_ptr(m
->state
, "running")) {
1873 on_state
= ansi_highlight_yellow();
1874 off_state
= ansi_normal();
1878 if (m
->n_failed_units
> 0) {
1879 on_failed
= ansi_highlight_red();
1880 off_failed
= ansi_normal();
1882 on_failed
= off_failed
= "";
1885 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1888 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1889 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1890 on_state
, statelen
, strna(m
->state
), off_state
,
1891 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1892 jobslen
, m
->n_jobs
);
1894 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1895 namelen
, strna(m
->name
),
1896 on_state
, statelen
, strna(m
->state
), off_state
,
1897 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1898 jobslen
, m
->n_jobs
);
1902 printf("\n%u machines listed.\n", n
);
1905 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1906 struct machine_info
*machine_infos
= NULL
;
1910 if (geteuid() != 0) {
1911 log_error("Must be root.");
1915 pager_open_if_enabled();
1917 r
= acquire_bus(BUS_MANAGER
, &bus
);
1921 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1925 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1926 output_machines_list(machine_infos
, r
);
1927 free_machines_list(machine_infos
, r
);
1932 static int get_default(int argc
, char *argv
[], void *userdata
) {
1933 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
1934 _cleanup_free_
char *_path
= NULL
;
1938 if (install_client_side()) {
1939 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1941 return log_error_errno(r
, "Failed to get default target: %m");
1945 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
1948 r
= acquire_bus(BUS_MANAGER
, &bus
);
1952 r
= sd_bus_call_method(
1954 "org.freedesktop.systemd1",
1955 "/org/freedesktop/systemd1",
1956 "org.freedesktop.systemd1.Manager",
1962 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1964 r
= sd_bus_message_read(reply
, "s", &path
);
1966 return bus_log_parse_error(r
);
1970 printf("%s\n", path
);
1975 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1978 assert(changes
|| n_changes
== 0);
1980 for (i
= 0; i
< n_changes
; i
++) {
1981 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1982 log_info("Created symlink %s, pointing to %s.", changes
[i
].path
, changes
[i
].source
);
1984 log_info("Removed symlink %s.", changes
[i
].path
);
1988 static int set_default(int argc
, char *argv
[], void *userdata
) {
1989 _cleanup_free_
char *unit
= NULL
;
1995 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1997 return log_error_errno(r
, "Failed to mangle unit name: %m");
1999 if (install_client_side()) {
2000 UnitFileChange
*changes
= NULL
;
2001 unsigned n_changes
= 0;
2003 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2005 return log_error_errno(r
, "Failed to set default target: %m");
2008 dump_unit_file_changes(changes
, n_changes
);
2010 unit_file_changes_free(changes
, n_changes
);
2013 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2014 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2017 polkit_agent_open_if_enabled();
2019 r
= acquire_bus(BUS_MANAGER
, &bus
);
2023 r
= sd_bus_call_method(
2025 "org.freedesktop.systemd1",
2026 "/org/freedesktop/systemd1",
2027 "org.freedesktop.systemd1.Manager",
2033 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2035 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2039 /* Try to reload if enabled */
2041 r
= daemon_reload(argc
, argv
, userdata
);
2051 const char *name
, *type
, *state
;
2054 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2055 unsigned id_len
, unit_len
, type_len
, state_len
;
2056 const struct job_info
*j
;
2057 const char *on
, *off
;
2058 bool shorten
= false;
2060 assert(n
== 0 || jobs
);
2063 if (!arg_no_legend
) {
2064 on
= ansi_highlight_green();
2065 off
= ansi_normal();
2067 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2072 pager_open_if_enabled();
2074 id_len
= strlen("JOB");
2075 unit_len
= strlen("UNIT");
2076 type_len
= strlen("TYPE");
2077 state_len
= strlen("STATE");
2079 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2080 uint32_t id
= j
->id
;
2081 assert(j
->name
&& j
->type
&& j
->state
);
2083 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2084 unit_len
= MAX(unit_len
, strlen(j
->name
));
2085 type_len
= MAX(type_len
, strlen(j
->type
));
2086 state_len
= MAX(state_len
, strlen(j
->state
));
2089 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2090 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2095 printf("%*s %-*s %-*s %-*s\n",
2099 state_len
, "STATE");
2101 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2102 _cleanup_free_
char *e
= NULL
;
2104 if (streq(j
->state
, "running")) {
2105 on
= ansi_highlight();
2106 off
= ansi_normal();
2110 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2111 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2113 on
, unit_len
, e
? e
: j
->name
, off
,
2115 on
, state_len
, j
->state
, off
);
2118 if (!arg_no_legend
) {
2119 on
= ansi_highlight();
2120 off
= ansi_normal();
2122 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2126 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2127 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2130 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2131 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2132 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2133 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2134 _cleanup_free_
struct job_info
*jobs
= NULL
;
2140 bool skipped
= false;
2142 pager_open_if_enabled();
2144 r
= acquire_bus(BUS_MANAGER
, &bus
);
2148 r
= sd_bus_call_method(
2150 "org.freedesktop.systemd1",
2151 "/org/freedesktop/systemd1",
2152 "org.freedesktop.systemd1.Manager",
2158 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2160 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2162 return bus_log_parse_error(r
);
2164 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2165 struct job_info job
= { id
, name
, type
, state
};
2167 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2172 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2178 return bus_log_parse_error(r
);
2180 r
= sd_bus_message_exit_container(reply
);
2182 return bus_log_parse_error(r
);
2184 output_jobs_list(jobs
, c
, skipped
);
2188 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2194 return daemon_reload(argc
, argv
, userdata
);
2196 polkit_agent_open_if_enabled();
2198 r
= acquire_bus(BUS_MANAGER
, &bus
);
2202 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2203 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2207 q
= safe_atou32(*name
, &id
);
2209 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2211 q
= sd_bus_call_method(
2213 "org.freedesktop.systemd1",
2214 "/org/freedesktop/systemd1",
2215 "org.freedesktop.systemd1.Manager",
2221 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2230 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2231 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2235 /* We ignore all errors here, since this is used to show a
2238 /* We don't use unit_dbus_path_from_name() directly since we
2239 * don't want to load the unit if it isn't loaded. */
2241 r
= sd_bus_call_method(
2243 "org.freedesktop.systemd1",
2244 "/org/freedesktop/systemd1",
2245 "org.freedesktop.systemd1.Manager",
2253 r
= sd_bus_message_read(reply
, "o", &path
);
2257 r
= sd_bus_get_property_trivial(
2259 "org.freedesktop.systemd1",
2261 "org.freedesktop.systemd1.Unit",
2271 static void warn_unit_file_changed(const char *name
) {
2272 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2273 ansi_highlight_red(),
2276 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2279 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2286 STRV_FOREACH(p
, lp
->unit_path
) {
2287 _cleanup_free_
char *path
;
2289 path
= path_join(arg_root
, *p
, unit_name
);
2293 if (access(path
, F_OK
) == 0) {
2303 static int unit_find_paths(
2305 const char *unit_name
,
2307 char **fragment_path
,
2308 char ***dropin_paths
) {
2310 _cleanup_free_
char *path
= NULL
;
2311 _cleanup_strv_free_
char **dropins
= NULL
;
2315 * Finds where the unit is defined on disk. Returns 0 if the unit
2316 * is not found. Returns 1 if it is found, and sets
2317 * - the path to the unit in *path, if it exists on disk,
2318 * - and a strv of existing drop-ins in *dropins,
2319 * if the arg is not NULL and any dropins were found.
2323 assert(fragment_path
);
2326 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2327 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2328 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*unit_load_error
= NULL
;
2329 _cleanup_free_
char *unit
= NULL
;
2330 char *unit_load_error_name
, *unit_load_error_message
;
2332 unit
= unit_dbus_path_from_name(unit_name
);
2336 if (need_daemon_reload(bus
, unit_name
) > 0)
2337 warn_unit_file_changed(unit_name
);
2339 r
= sd_bus_get_property(
2341 "org.freedesktop.systemd1",
2343 "org.freedesktop.systemd1.Unit",
2349 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2351 r
= sd_bus_message_read(
2354 &unit_load_error_name
,
2355 &unit_load_error_message
);
2357 return bus_log_parse_error(r
);
2359 if (!isempty(unit_load_error_name
)) {
2360 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2364 r
= sd_bus_get_property_string(
2366 "org.freedesktop.systemd1",
2368 "org.freedesktop.systemd1.Unit",
2373 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2376 r
= sd_bus_get_property_strv(
2378 "org.freedesktop.systemd1",
2380 "org.freedesktop.systemd1.Unit",
2385 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2388 _cleanup_set_free_ Set
*names
;
2390 names
= set_new(NULL
);
2394 r
= set_put(names
, unit_name
);
2396 return log_error_errno(r
, "Failed to add unit name: %m");
2398 r
= unit_file_find_path(lp
, unit_name
, &path
);
2403 _cleanup_free_
char *template = NULL
;
2405 r
= unit_name_template(unit_name
, &template);
2406 if (r
< 0 && r
!= -EINVAL
)
2407 return log_error_errno(r
, "Failed to determine template name: %m");
2409 r
= unit_file_find_path(lp
, template, &path
);
2416 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2424 if (!isempty(path
)) {
2425 *fragment_path
= path
;
2430 if (dropin_paths
&& !strv_isempty(dropins
)) {
2431 *dropin_paths
= dropins
;
2437 log_error("No files found for %s.", unit_name
);
2442 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2443 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2444 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2450 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2452 return log_error_errno(r
, "Failed to mangle unit name: %m");
2454 /* We don't use unit_dbus_path_from_name() directly since we
2455 * don't want to load the unit if it isn't loaded. */
2457 r
= sd_bus_call_method(
2459 "org.freedesktop.systemd1",
2460 "/org/freedesktop/systemd1",
2461 "org.freedesktop.systemd1.Manager",
2472 r
= sd_bus_message_read(reply
, "o", &path
);
2474 return bus_log_parse_error(r
);
2476 r
= sd_bus_get_property_string(
2478 "org.freedesktop.systemd1",
2480 "org.freedesktop.systemd1.Unit",
2493 return nulstr_contains(good_states
, state
);
2496 static int check_triggering_units(
2500 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2501 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2502 _cleanup_strv_free_
char **triggered_by
= NULL
;
2503 bool print_warning_label
= true;
2507 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2509 return log_error_errno(r
, "Failed to mangle unit name: %m");
2511 path
= unit_dbus_path_from_name(n
);
2515 r
= sd_bus_get_property_string(
2517 "org.freedesktop.systemd1",
2519 "org.freedesktop.systemd1.Unit",
2524 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2526 if (streq(state
, "masked"))
2529 r
= sd_bus_get_property_strv(
2531 "org.freedesktop.systemd1",
2533 "org.freedesktop.systemd1.Unit",
2538 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2540 STRV_FOREACH(i
, triggered_by
) {
2541 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2543 return log_error_errno(r
, "Failed to check unit: %m");
2548 if (print_warning_label
) {
2549 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2550 print_warning_label
= false;
2553 log_warning(" %s", *i
);
2559 static const struct {
2562 } unit_actions
[] = {
2563 { "start", "StartUnit" },
2564 { "stop", "StopUnit" },
2565 { "condstop", "StopUnit" },
2566 { "reload", "ReloadUnit" },
2567 { "restart", "RestartUnit" },
2568 { "try-restart", "TryRestartUnit" },
2569 { "condrestart", "TryRestartUnit" },
2570 { "reload-or-restart", "ReloadOrRestartUnit" },
2571 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2572 { "condreload", "ReloadOrTryRestartUnit" },
2573 { "force-reload", "ReloadOrTryRestartUnit" }
2576 static const char *verb_to_method(const char *verb
) {
2579 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2580 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2581 return unit_actions
[i
].method
;
2586 static const char *method_to_verb(const char *method
) {
2589 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2590 if (streq_ptr(unit_actions
[i
].method
, method
))
2591 return unit_actions
[i
].verb
;
2596 static int start_unit_one(
2601 sd_bus_error
*error
,
2602 BusWaitForJobs
*w
) {
2604 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2613 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2615 r
= sd_bus_call_method(
2617 "org.freedesktop.systemd1",
2618 "/org/freedesktop/systemd1",
2619 "org.freedesktop.systemd1.Manager",
2627 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2628 /* There's always a fallback possible for
2629 * legacy actions. */
2630 return -EADDRNOTAVAIL
;
2632 verb
= method_to_verb(method
);
2634 return log_error_errno(r
, "Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2637 r
= sd_bus_message_read(reply
, "o", &path
);
2639 return bus_log_parse_error(r
);
2641 if (need_daemon_reload(bus
, name
) > 0)
2642 warn_unit_file_changed(name
);
2645 log_debug("Adding %s to the set", path
);
2646 r
= bus_wait_for_jobs_add(w
, path
);
2654 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2655 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2662 STRV_FOREACH(name
, names
) {
2666 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2668 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2670 return log_error_errno(r
, "Failed to mangle name: %m");
2672 if (string_is_glob(t
))
2673 r
= strv_consume(&globs
, t
);
2675 r
= strv_consume(&mangled
, t
);
2680 /* Query the manager only if any of the names are a glob, since
2681 * this is fairly expensive */
2682 if (!strv_isempty(globs
)) {
2683 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2684 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2686 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2690 for (i
= 0; i
< r
; i
++)
2691 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2696 mangled
= NULL
; /* do not free */
2701 static const struct {
2705 } action_table
[_ACTION_MAX
] = {
2706 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2707 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2708 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2709 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2710 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2711 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2712 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2713 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2714 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2715 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2716 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2717 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2718 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2719 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2720 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2723 static enum action
verb_to_action(const char *verb
) {
2726 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2727 if (streq_ptr(action_table
[i
].verb
, verb
))
2730 return _ACTION_INVALID
;
2733 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2734 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2735 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2736 _cleanup_strv_free_
char **names
= NULL
;
2741 ask_password_agent_open_if_enabled();
2742 polkit_agent_open_if_enabled();
2744 r
= acquire_bus(BUS_MANAGER
, &bus
);
2748 if (arg_action
== ACTION_SYSTEMCTL
) {
2751 method
= verb_to_method(argv
[0]);
2752 action
= verb_to_action(argv
[0]);
2754 if (streq(argv
[0], "isolate")) {
2758 mode
= action_table
[action
].mode
?: arg_job_mode
;
2760 one_name
= action_table
[action
].target
;
2762 assert(arg_action
< ELEMENTSOF(action_table
));
2763 assert(action_table
[arg_action
].target
);
2765 method
= "StartUnit";
2767 mode
= action_table
[arg_action
].mode
;
2768 one_name
= action_table
[arg_action
].target
;
2772 names
= strv_new(one_name
, NULL
);
2774 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2776 return log_error_errno(r
, "Failed to expand names: %m");
2779 if (!arg_no_block
) {
2780 r
= bus_wait_for_jobs_new(bus
, &w
);
2782 return log_error_errno(r
, "Could not watch jobs: %m");
2785 STRV_FOREACH(name
, names
) {
2786 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2789 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2790 if (r
>= 0 && q
< 0)
2791 r
= translate_bus_error_to_exit_status(q
, &error
);
2794 if (!arg_no_block
) {
2797 q
= bus_wait_for_jobs(w
, arg_quiet
, arg_scope
!= UNIT_FILE_SYSTEM
? "--user" : NULL
);
2801 /* When stopping units, warn if they can still be triggered by
2802 * another active unit (socket, path, timer) */
2803 if (!arg_quiet
&& streq(method
, "StopUnit"))
2804 STRV_FOREACH(name
, names
)
2805 check_triggering_units(bus
, *name
);
2811 static int logind_set_wall_message(void) {
2813 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2815 _cleanup_free_
char *m
= NULL
;
2818 r
= acquire_bus(BUS_FULL
, &bus
);
2822 m
= strv_join(arg_wall
, " ");
2826 r
= sd_bus_call_method(
2828 "org.freedesktop.login1",
2829 "/org/freedesktop/login1",
2830 "org.freedesktop.login1.Manager",
2839 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2845 /* Ask systemd-logind, which might grant access to unprivileged users
2846 * through PolicyKit */
2847 static int logind_reboot(enum action a
) {
2849 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
2850 const char *method
, *description
;
2854 polkit_agent_open_if_enabled();
2855 (void) logind_set_wall_message();
2857 r
= acquire_bus(BUS_FULL
, &bus
);
2865 description
= "reboot system";
2868 case ACTION_POWEROFF
:
2869 method
= "PowerOff";
2870 description
= "power off system";
2873 case ACTION_SUSPEND
:
2875 description
= "suspend system";
2878 case ACTION_HIBERNATE
:
2879 method
= "Hibernate";
2880 description
= "hibernate system";
2883 case ACTION_HYBRID_SLEEP
:
2884 method
= "HybridSleep";
2885 description
= "put system into hybrid sleep";
2892 r
= sd_bus_call_method(
2894 "org.freedesktop.login1",
2895 "/org/freedesktop/login1",
2896 "org.freedesktop.login1.Manager",
2900 "b", arg_ask_password
);
2902 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2910 static int logind_check_inhibitors(enum action a
) {
2912 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
2913 _cleanup_strv_free_
char **sessions
= NULL
;
2914 const char *what
, *who
, *why
, *mode
;
2921 if (arg_ignore_inhibitors
|| arg_force
> 0)
2933 r
= acquire_bus(BUS_FULL
, &bus
);
2937 r
= sd_bus_call_method(
2939 "org.freedesktop.login1",
2940 "/org/freedesktop/login1",
2941 "org.freedesktop.login1.Manager",
2947 /* If logind is not around, then there are no inhibitors... */
2950 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2952 return bus_log_parse_error(r
);
2954 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2955 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2956 _cleanup_strv_free_
char **sv
= NULL
;
2958 if (!streq(mode
, "block"))
2961 sv
= strv_split(what
, ":");
2965 if ((pid_t
) pid
< 0)
2966 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2968 if (!strv_contains(sv
,
2973 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2976 get_process_comm(pid
, &comm
);
2977 user
= uid_to_name(uid
);
2979 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2980 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2985 return bus_log_parse_error(r
);
2987 r
= sd_bus_message_exit_container(reply
);
2989 return bus_log_parse_error(r
);
2991 /* Check for current sessions */
2992 sd_get_sessions(&sessions
);
2993 STRV_FOREACH(s
, sessions
) {
2994 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2996 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2999 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
3002 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3005 sd_session_get_tty(*s
, &tty
);
3006 sd_session_get_seat(*s
, &seat
);
3007 sd_session_get_service(*s
, &service
);
3008 user
= uid_to_name(uid
);
3010 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3017 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3018 action_table
[a
].verb
);
3026 static int logind_prepare_firmware_setup(void) {
3028 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3032 r
= acquire_bus(BUS_FULL
, &bus
);
3036 r
= sd_bus_call_method(
3038 "org.freedesktop.login1",
3039 "/org/freedesktop/login1",
3040 "org.freedesktop.login1.Manager",
3041 "SetRebootToFirmwareSetup",
3046 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3050 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3055 static int prepare_firmware_setup(void) {
3058 if (!arg_firmware_setup
)
3061 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3063 r
= efi_set_reboot_to_firmware(true);
3065 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3070 return logind_prepare_firmware_setup();
3073 static int set_exit_code(uint8_t code
) {
3074 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3078 r
= acquire_bus(BUS_MANAGER
, &bus
);
3082 r
= sd_bus_call_method(
3084 "org.freedesktop.systemd1",
3085 "/org/freedesktop/systemd1",
3086 "org.freedesktop.systemd1.Manager",
3092 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3097 static int start_special(int argc
, char *argv
[], void *userdata
) {
3103 a
= verb_to_action(argv
[0]);
3105 r
= logind_check_inhibitors(a
);
3109 if (arg_force
>= 2 && geteuid() != 0) {
3110 log_error("Must be root.");
3114 r
= prepare_firmware_setup();
3118 if (a
== ACTION_REBOOT
&& argc
> 1) {
3119 r
= update_reboot_param_file(argv
[1]);
3123 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3126 /* If the exit code is not given on the command line,
3127 * don't reset it to zero: just keep it as it might
3128 * have been set previously. */
3130 r
= safe_atou8(argv
[1], &code
);
3132 return log_error_errno(r
, "Invalid exit code.");
3134 r
= set_exit_code(code
);
3139 if (arg_force
>= 2 &&
3146 if (arg_force
>= 1 &&
3153 return daemon_reload(argc
, argv
, userdata
);
3155 /* First try logind, to allow authentication with polkit */
3161 ACTION_HYBRID_SLEEP
)) {
3162 r
= logind_reboot(a
);
3165 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3166 /* requested operation is not supported or already in progress */
3169 /* On all other errors, try low-level operation */
3172 return start_unit(argc
, argv
, userdata
);
3175 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3176 _cleanup_strv_free_
char **names
= NULL
;
3181 r
= acquire_bus(BUS_MANAGER
, &bus
);
3185 r
= expand_names(bus
, args
, NULL
, &names
);
3187 return log_error_errno(r
, "Failed to expand names: %m");
3189 STRV_FOREACH(name
, names
) {
3192 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3202 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3203 /* According to LSB: 3, "program is not running" */
3204 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3207 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3208 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3211 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3212 _cleanup_strv_free_
char **names
= NULL
;
3213 char *kill_who
= NULL
, **name
;
3217 polkit_agent_open_if_enabled();
3219 r
= acquire_bus(BUS_MANAGER
, &bus
);
3224 arg_kill_who
= "all";
3226 /* --fail was specified */
3227 if (streq(arg_job_mode
, "fail"))
3228 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3230 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3232 return log_error_errno(r
, "Failed to expand names: %m");
3234 STRV_FOREACH(name
, names
) {
3235 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
3237 q
= sd_bus_call_method(
3239 "org.freedesktop.systemd1",
3240 "/org/freedesktop/systemd1",
3241 "org.freedesktop.systemd1.Manager",
3245 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3247 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3256 typedef struct ExecStatusInfo
{
3264 usec_t start_timestamp
;
3265 usec_t exit_timestamp
;
3270 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3273 static void exec_status_info_free(ExecStatusInfo
*i
) {
3282 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3283 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3286 int32_t code
, status
;
3292 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3294 return bus_log_parse_error(r
);
3298 r
= sd_bus_message_read(m
, "s", &path
);
3300 return bus_log_parse_error(r
);
3302 i
->path
= strdup(path
);
3306 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3308 return bus_log_parse_error(r
);
3310 r
= sd_bus_message_read(m
,
3313 &start_timestamp
, &start_timestamp_monotonic
,
3314 &exit_timestamp
, &exit_timestamp_monotonic
,
3318 return bus_log_parse_error(r
);
3321 i
->start_timestamp
= (usec_t
) start_timestamp
;
3322 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3323 i
->pid
= (pid_t
) pid
;
3327 r
= sd_bus_message_exit_container(m
);
3329 return bus_log_parse_error(r
);
3334 typedef struct UnitStatusInfo
{
3336 const char *load_state
;
3337 const char *active_state
;
3338 const char *sub_state
;
3339 const char *unit_file_state
;
3340 const char *unit_file_preset
;
3342 const char *description
;
3343 const char *following
;
3345 char **documentation
;
3347 const char *fragment_path
;
3348 const char *source_path
;
3349 const char *control_group
;
3351 char **dropin_paths
;
3353 const char *load_error
;
3356 usec_t inactive_exit_timestamp
;
3357 usec_t inactive_exit_timestamp_monotonic
;
3358 usec_t active_enter_timestamp
;
3359 usec_t active_exit_timestamp
;
3360 usec_t inactive_enter_timestamp
;
3362 bool need_daemon_reload
;
3368 const char *status_text
;
3369 const char *pid_file
;
3373 usec_t start_timestamp
;
3374 usec_t exit_timestamp
;
3376 int exit_code
, exit_status
;
3378 usec_t condition_timestamp
;
3379 bool condition_result
;
3380 bool failed_condition_trigger
;
3381 bool failed_condition_negate
;
3382 const char *failed_condition
;
3383 const char *failed_condition_parameter
;
3385 usec_t assert_timestamp
;
3387 bool failed_assert_trigger
;
3388 bool failed_assert_negate
;
3389 const char *failed_assert
;
3390 const char *failed_assert_parameter
;
3393 unsigned n_accepted
;
3394 unsigned n_connections
;
3397 /* Pairs of type, path */
3401 const char *sysfs_path
;
3403 /* Mount, Automount */
3410 uint64_t memory_current
;
3411 uint64_t memory_limit
;
3412 uint64_t cpu_usage_nsec
;
3413 uint64_t tasks_current
;
3416 LIST_HEAD(ExecStatusInfo
, exec
);
3419 static void print_status_info(
3424 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3426 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3427 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3433 /* This shows pretty information about a unit. See
3434 * print_property() for a low-level property printer */
3436 if (streq_ptr(i
->active_state
, "failed")) {
3437 active_on
= ansi_highlight_red();
3438 active_off
= ansi_normal();
3439 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3440 active_on
= ansi_highlight_green();
3441 active_off
= ansi_normal();
3443 active_on
= active_off
= "";
3445 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3447 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3448 printf(" - %s", i
->description
);
3453 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3455 if (streq_ptr(i
->load_state
, "error")) {
3456 on
= ansi_highlight_red();
3457 off
= ansi_normal();
3461 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3463 if (i
->load_error
!= 0)
3464 printf(" Loaded: %s%s%s (Reason: %s)\n",
3465 on
, strna(i
->load_state
), off
, i
->load_error
);
3466 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3467 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3468 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3469 else if (path
&& !isempty(i
->unit_file_state
))
3470 printf(" Loaded: %s%s%s (%s; %s)\n",
3471 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3473 printf(" Loaded: %s%s%s (%s)\n",
3474 on
, strna(i
->load_state
), off
, path
);
3476 printf(" Loaded: %s%s%s\n",
3477 on
, strna(i
->load_state
), off
);
3480 printf("Transient: yes\n");
3482 if (!strv_isempty(i
->dropin_paths
)) {
3483 _cleanup_free_
char *dir
= NULL
;
3487 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3488 if (! dir
|| last
) {
3489 printf(dir
? " " : " Drop-In: ");
3493 dir
= dirname_malloc(*dropin
);
3499 printf("%s\n %s", dir
,
3500 draw_special_char(DRAW_TREE_RIGHT
));
3503 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3505 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3509 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3511 printf(" Active: %s%s (%s)%s",
3512 active_on
, strna(i
->active_state
), ss
, active_off
);
3514 printf(" Active: %s%s%s",
3515 active_on
, strna(i
->active_state
), active_off
);
3517 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3518 printf(" (Result: %s)", i
->result
);
3520 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3521 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3522 (streq_ptr(i
->active_state
, "inactive") ||
3523 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3524 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3525 i
->active_exit_timestamp
;
3527 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3528 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3531 printf(" since %s; %s\n", s2
, s1
);
3533 printf(" since %s\n", s2
);
3537 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3538 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3539 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3541 printf("Condition: start %scondition failed%s at %s%s%s\n",
3542 ansi_highlight_yellow(), ansi_normal(),
3543 s2
, s1
? "; " : "", strempty(s1
));
3544 if (i
->failed_condition_trigger
)
3545 printf(" none of the trigger conditions were met\n");
3546 else if (i
->failed_condition
)
3547 printf(" %s=%s%s was not met\n",
3548 i
->failed_condition
,
3549 i
->failed_condition_negate
? "!" : "",
3550 i
->failed_condition_parameter
);
3553 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3554 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3555 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3557 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3558 ansi_highlight_red(), ansi_normal(),
3559 s2
, s1
? "; " : "", strempty(s1
));
3560 if (i
->failed_assert_trigger
)
3561 printf(" none of the trigger assertions were met\n");
3562 else if (i
->failed_assert
)
3563 printf(" %s=%s%s was not met\n",
3565 i
->failed_assert_negate
? "!" : "",
3566 i
->failed_assert_parameter
);
3570 printf(" Device: %s\n", i
->sysfs_path
);
3572 printf(" Where: %s\n", i
->where
);
3574 printf(" What: %s\n", i
->what
);
3576 STRV_FOREACH(t
, i
->documentation
)
3577 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3579 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3580 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3583 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3585 LIST_FOREACH(exec
, p
, i
->exec
) {
3586 _cleanup_free_
char *argv
= NULL
;
3589 /* Only show exited processes here */
3593 argv
= strv_join(p
->argv
, " ");
3594 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3596 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3598 on
= ansi_highlight_red();
3599 off
= ansi_normal();
3603 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3605 if (p
->code
== CLD_EXITED
) {
3608 printf("status=%i", p
->status
);
3610 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3615 printf("signal=%s", signal_to_string(p
->status
));
3617 printf(")%s\n", off
);
3619 if (i
->main_pid
== p
->pid
&&
3620 i
->start_timestamp
== p
->start_timestamp
&&
3621 i
->exit_timestamp
== p
->start_timestamp
)
3622 /* Let's not show this twice */
3625 if (p
->pid
== i
->control_pid
)
3629 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3630 if (i
->main_pid
> 0) {
3631 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3634 _cleanup_free_
char *comm
= NULL
;
3635 get_process_comm(i
->main_pid
, &comm
);
3637 printf(" (%s)", comm
);
3638 } else if (i
->exit_code
> 0) {
3639 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3641 if (i
->exit_code
== CLD_EXITED
) {
3644 printf("status=%i", i
->exit_status
);
3646 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3651 printf("signal=%s", signal_to_string(i
->exit_status
));
3655 if (i
->control_pid
> 0)
3659 if (i
->control_pid
> 0) {
3660 _cleanup_free_
char *c
= NULL
;
3662 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3664 get_process_comm(i
->control_pid
, &c
);
3673 printf(" Status: \"%s\"\n", i
->status_text
);
3674 if (i
->status_errno
> 0)
3675 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3677 if (i
->tasks_current
!= (uint64_t) -1) {
3678 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3680 if (i
->tasks_max
!= (uint64_t) -1)
3681 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3686 if (i
->memory_current
!= (uint64_t) -1) {
3687 char buf
[FORMAT_BYTES_MAX
];
3689 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3691 if (i
->memory_limit
!= (uint64_t) -1)
3692 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3697 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3698 char buf
[FORMAT_TIMESPAN_MAX
];
3699 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3702 if (i
->control_group
&&
3703 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3704 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3707 printf(" CGroup: %s\n", i
->control_group
);
3709 if (IN_SET(arg_transport
,
3710 BUS_TRANSPORT_LOCAL
,
3711 BUS_TRANSPORT_MACHINE
)) {
3714 static const char prefix
[] = " ";
3717 if (c
> sizeof(prefix
) - 1)
3718 c
-= sizeof(prefix
) - 1;
3722 if (i
->main_pid
> 0)
3723 extra
[k
++] = i
->main_pid
;
3725 if (i
->control_pid
> 0)
3726 extra
[k
++] = i
->control_pid
;
3728 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3732 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3733 show_journal_by_unit(
3738 i
->inactive_exit_timestamp_monotonic
,
3741 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3742 SD_JOURNAL_LOCAL_ONLY
,
3743 arg_scope
== UNIT_FILE_SYSTEM
,
3746 if (i
->need_daemon_reload
)
3747 warn_unit_file_changed(i
->id
);
3750 static void show_unit_help(UnitStatusInfo
*i
) {
3755 if (!i
->documentation
) {
3756 log_info("Documentation for %s not known.", i
->id
);
3760 STRV_FOREACH(p
, i
->documentation
)
3761 if (startswith(*p
, "man:"))
3762 show_man_page(*p
+ 4, false);
3764 log_info("Can't show: %s", *p
);
3767 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3774 switch (contents
[0]) {
3776 case SD_BUS_TYPE_STRING
: {
3779 r
= sd_bus_message_read(m
, "s", &s
);
3781 return bus_log_parse_error(r
);
3784 if (streq(name
, "Id"))
3786 else if (streq(name
, "LoadState"))
3788 else if (streq(name
, "ActiveState"))
3789 i
->active_state
= s
;
3790 else if (streq(name
, "SubState"))
3792 else if (streq(name
, "Description"))
3794 else if (streq(name
, "FragmentPath"))
3795 i
->fragment_path
= s
;
3796 else if (streq(name
, "SourcePath"))
3799 else if (streq(name
, "DefaultControlGroup")) {
3801 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3803 i
->control_group
= e
;
3806 else if (streq(name
, "ControlGroup"))
3807 i
->control_group
= s
;
3808 else if (streq(name
, "StatusText"))
3810 else if (streq(name
, "PIDFile"))
3812 else if (streq(name
, "SysFSPath"))
3814 else if (streq(name
, "Where"))
3816 else if (streq(name
, "What"))
3818 else if (streq(name
, "Following"))
3820 else if (streq(name
, "UnitFileState"))
3821 i
->unit_file_state
= s
;
3822 else if (streq(name
, "UnitFilePreset"))
3823 i
->unit_file_preset
= s
;
3824 else if (streq(name
, "Result"))
3831 case SD_BUS_TYPE_BOOLEAN
: {
3834 r
= sd_bus_message_read(m
, "b", &b
);
3836 return bus_log_parse_error(r
);
3838 if (streq(name
, "Accept"))
3840 else if (streq(name
, "NeedDaemonReload"))
3841 i
->need_daemon_reload
= b
;
3842 else if (streq(name
, "ConditionResult"))
3843 i
->condition_result
= b
;
3844 else if (streq(name
, "AssertResult"))
3845 i
->assert_result
= b
;
3846 else if (streq(name
, "Transient"))
3852 case SD_BUS_TYPE_UINT32
: {
3855 r
= sd_bus_message_read(m
, "u", &u
);
3857 return bus_log_parse_error(r
);
3859 if (streq(name
, "MainPID")) {
3861 i
->main_pid
= (pid_t
) u
;
3864 } else if (streq(name
, "ControlPID"))
3865 i
->control_pid
= (pid_t
) u
;
3866 else if (streq(name
, "ExecMainPID")) {
3868 i
->main_pid
= (pid_t
) u
;
3869 } else if (streq(name
, "NAccepted"))
3871 else if (streq(name
, "NConnections"))
3872 i
->n_connections
= u
;
3877 case SD_BUS_TYPE_INT32
: {
3880 r
= sd_bus_message_read(m
, "i", &j
);
3882 return bus_log_parse_error(r
);
3884 if (streq(name
, "ExecMainCode"))
3885 i
->exit_code
= (int) j
;
3886 else if (streq(name
, "ExecMainStatus"))
3887 i
->exit_status
= (int) j
;
3888 else if (streq(name
, "StatusErrno"))
3889 i
->status_errno
= (int) j
;
3894 case SD_BUS_TYPE_UINT64
: {
3897 r
= sd_bus_message_read(m
, "t", &u
);
3899 return bus_log_parse_error(r
);
3901 if (streq(name
, "ExecMainStartTimestamp"))
3902 i
->start_timestamp
= (usec_t
) u
;
3903 else if (streq(name
, "ExecMainExitTimestamp"))
3904 i
->exit_timestamp
= (usec_t
) u
;
3905 else if (streq(name
, "ActiveEnterTimestamp"))
3906 i
->active_enter_timestamp
= (usec_t
) u
;
3907 else if (streq(name
, "InactiveEnterTimestamp"))
3908 i
->inactive_enter_timestamp
= (usec_t
) u
;
3909 else if (streq(name
, "InactiveExitTimestamp"))
3910 i
->inactive_exit_timestamp
= (usec_t
) u
;
3911 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3912 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3913 else if (streq(name
, "ActiveExitTimestamp"))
3914 i
->active_exit_timestamp
= (usec_t
) u
;
3915 else if (streq(name
, "ConditionTimestamp"))
3916 i
->condition_timestamp
= (usec_t
) u
;
3917 else if (streq(name
, "AssertTimestamp"))
3918 i
->assert_timestamp
= (usec_t
) u
;
3919 else if (streq(name
, "MemoryCurrent"))
3920 i
->memory_current
= u
;
3921 else if (streq(name
, "MemoryLimit"))
3922 i
->memory_limit
= u
;
3923 else if (streq(name
, "TasksCurrent"))
3924 i
->tasks_current
= u
;
3925 else if (streq(name
, "TasksMax"))
3927 else if (streq(name
, "CPUUsageNSec"))
3928 i
->cpu_usage_nsec
= u
;
3933 case SD_BUS_TYPE_ARRAY
:
3935 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3936 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3938 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3940 return bus_log_parse_error(r
);
3942 info
= new0(ExecStatusInfo
, 1);
3946 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3948 info
->name
= strdup(name
);
3952 LIST_PREPEND(exec
, i
->exec
, info
);
3954 info
= new0(ExecStatusInfo
, 1);
3960 return bus_log_parse_error(r
);
3962 r
= sd_bus_message_exit_container(m
);
3964 return bus_log_parse_error(r
);
3968 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3969 const char *type
, *path
;
3971 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3973 return bus_log_parse_error(r
);
3975 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3977 r
= strv_extend(&i
->listen
, type
);
3981 r
= strv_extend(&i
->listen
, path
);
3986 return bus_log_parse_error(r
);
3988 r
= sd_bus_message_exit_container(m
);
3990 return bus_log_parse_error(r
);
3994 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3996 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3998 return bus_log_parse_error(r
);
4000 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
4002 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
4004 return bus_log_parse_error(r
);
4006 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
4007 const char *cond
, *param
;
4008 int trigger
, negate
;
4011 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4013 return bus_log_parse_error(r
);
4015 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4016 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4017 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4018 i
->failed_condition
= cond
;
4019 i
->failed_condition_trigger
= trigger
;
4020 i
->failed_condition_negate
= negate
;
4021 i
->failed_condition_parameter
= param
;
4025 return bus_log_parse_error(r
);
4027 r
= sd_bus_message_exit_container(m
);
4029 return bus_log_parse_error(r
);
4031 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4032 const char *cond
, *param
;
4033 int trigger
, negate
;
4036 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4038 return bus_log_parse_error(r
);
4040 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4041 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4042 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4043 i
->failed_assert
= cond
;
4044 i
->failed_assert_trigger
= trigger
;
4045 i
->failed_assert_negate
= negate
;
4046 i
->failed_assert_parameter
= param
;
4050 return bus_log_parse_error(r
);
4052 r
= sd_bus_message_exit_container(m
);
4054 return bus_log_parse_error(r
);
4061 case SD_BUS_TYPE_STRUCT_BEGIN
:
4063 if (streq(name
, "LoadError")) {
4064 const char *n
, *message
;
4066 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4068 return bus_log_parse_error(r
);
4070 if (!isempty(message
))
4071 i
->load_error
= message
;
4084 r
= sd_bus_message_skip(m
, contents
);
4086 return bus_log_parse_error(r
);
4091 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4097 /* This is a low-level property printer, see
4098 * print_status_info() for the nicer output */
4100 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4101 /* skip what we didn't read */
4102 r
= sd_bus_message_skip(m
, contents
);
4106 switch (contents
[0]) {
4108 case SD_BUS_TYPE_STRUCT_BEGIN
:
4110 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4113 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4115 return bus_log_parse_error(r
);
4118 printf("%s=%"PRIu32
"\n", name
, u
);
4120 printf("%s=\n", name
);
4124 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4127 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4129 return bus_log_parse_error(r
);
4131 if (arg_all
|| !isempty(s
))
4132 printf("%s=%s\n", name
, s
);
4136 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4137 const char *a
= NULL
, *b
= NULL
;
4139 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4141 return bus_log_parse_error(r
);
4143 if (arg_all
|| !isempty(a
) || !isempty(b
))
4144 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4147 } else if (streq_ptr(name
, "SystemCallFilter")) {
4148 _cleanup_strv_free_
char **l
= NULL
;
4151 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4153 return bus_log_parse_error(r
);
4155 r
= sd_bus_message_read(m
, "b", &whitelist
);
4157 return bus_log_parse_error(r
);
4159 r
= sd_bus_message_read_strv(m
, &l
);
4161 return bus_log_parse_error(r
);
4163 r
= sd_bus_message_exit_container(m
);
4165 return bus_log_parse_error(r
);
4167 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4171 fputs(name
, stdout
);
4177 STRV_FOREACH(i
, l
) {
4185 fputc('\n', stdout
);
4193 case SD_BUS_TYPE_ARRAY
:
4195 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4199 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4201 return bus_log_parse_error(r
);
4203 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4204 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4207 return bus_log_parse_error(r
);
4209 r
= sd_bus_message_exit_container(m
);
4211 return bus_log_parse_error(r
);
4215 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4216 const char *type
, *path
;
4218 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4220 return bus_log_parse_error(r
);
4222 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4223 printf("%s=%s\n", type
, path
);
4225 return bus_log_parse_error(r
);
4227 r
= sd_bus_message_exit_container(m
);
4229 return bus_log_parse_error(r
);
4233 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4234 const char *type
, *path
;
4236 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4238 return bus_log_parse_error(r
);
4240 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4241 printf("Listen%s=%s\n", type
, path
);
4243 return bus_log_parse_error(r
);
4245 r
= sd_bus_message_exit_container(m
);
4247 return bus_log_parse_error(r
);
4251 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4253 uint64_t value
, next_elapse
;
4255 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4257 return bus_log_parse_error(r
);
4259 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4260 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4262 printf("%s={ value=%s ; next_elapse=%s }\n",
4264 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4265 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4268 return bus_log_parse_error(r
);
4270 r
= sd_bus_message_exit_container(m
);
4272 return bus_log_parse_error(r
);
4276 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4277 ExecStatusInfo info
= {};
4279 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4281 return bus_log_parse_error(r
);
4283 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4284 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4285 _cleanup_free_
char *tt
;
4287 tt
= strv_join(info
.argv
, " ");
4289 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",
4293 yes_no(info
.ignore
),
4294 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4295 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4297 sigchld_code_to_string(info
.code
),
4299 info
.code
== CLD_EXITED
? "" : "/",
4300 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4303 strv_free(info
.argv
);
4307 r
= sd_bus_message_exit_container(m
);
4309 return bus_log_parse_error(r
);
4313 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4314 const char *path
, *rwm
;
4316 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4318 return bus_log_parse_error(r
);
4320 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4321 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4323 return bus_log_parse_error(r
);
4325 r
= sd_bus_message_exit_container(m
);
4327 return bus_log_parse_error(r
);
4331 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4335 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4337 return bus_log_parse_error(r
);
4339 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4340 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4342 return bus_log_parse_error(r
);
4344 r
= sd_bus_message_exit_container(m
);
4346 return bus_log_parse_error(r
);
4350 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4354 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4356 return bus_log_parse_error(r
);
4358 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4359 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4361 return bus_log_parse_error(r
);
4363 r
= sd_bus_message_exit_container(m
);
4365 return bus_log_parse_error(r
);
4373 r
= bus_print_property(name
, m
, arg_all
);
4375 return bus_log_parse_error(r
);
4378 r
= sd_bus_message_skip(m
, contents
);
4380 return bus_log_parse_error(r
);
4383 printf("%s=[unprintable]\n", name
);
4389 static int show_one(
4393 bool show_properties
,
4397 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4398 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4399 UnitStatusInfo info
= {
4400 .memory_current
= (uint64_t) -1,
4401 .memory_limit
= (uint64_t) -1,
4402 .cpu_usage_nsec
= (uint64_t) -1,
4403 .tasks_current
= (uint64_t) -1,
4404 .tasks_max
= (uint64_t) -1,
4412 log_debug("Showing one %s", path
);
4414 r
= sd_bus_call_method(
4416 "org.freedesktop.systemd1",
4418 "org.freedesktop.DBus.Properties",
4424 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4426 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4428 return bus_log_parse_error(r
);
4435 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4436 const char *name
, *contents
;
4438 r
= sd_bus_message_read(reply
, "s", &name
);
4440 return bus_log_parse_error(r
);
4442 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4444 return bus_log_parse_error(r
);
4446 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4448 return bus_log_parse_error(r
);
4450 if (show_properties
)
4451 r
= print_property(name
, reply
, contents
);
4453 r
= status_property(name
, reply
, &info
, contents
);
4457 r
= sd_bus_message_exit_container(reply
);
4459 return bus_log_parse_error(r
);
4461 r
= sd_bus_message_exit_container(reply
);
4463 return bus_log_parse_error(r
);
4466 return bus_log_parse_error(r
);
4468 r
= sd_bus_message_exit_container(reply
);
4470 return bus_log_parse_error(r
);
4474 if (!show_properties
) {
4475 if (streq(verb
, "help"))
4476 show_unit_help(&info
);
4478 print_status_info(&info
, ellipsized
);
4481 strv_free(info
.documentation
);
4482 strv_free(info
.dropin_paths
);
4483 strv_free(info
.listen
);
4485 if (!streq_ptr(info
.active_state
, "active") &&
4486 !streq_ptr(info
.active_state
, "reloading") &&
4487 streq(verb
, "status")) {
4488 /* According to LSB: "program not running" */
4489 /* 0: program is running or service is OK
4490 * 1: program is dead and /run PID file exists
4491 * 2: program is dead and /run/lock lock file exists
4492 * 3: program is not running
4493 * 4: program or service status is unknown
4495 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4501 while ((p
= info
.exec
)) {
4502 LIST_REMOVE(exec
, info
.exec
, p
);
4503 exec_status_info_free(p
);
4509 static int get_unit_dbus_path_by_pid(
4514 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4515 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4519 r
= sd_bus_call_method(
4521 "org.freedesktop.systemd1",
4522 "/org/freedesktop/systemd1",
4523 "org.freedesktop.systemd1.Manager",
4529 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4531 r
= sd_bus_message_read(reply
, "o", &u
);
4533 return bus_log_parse_error(r
);
4543 static int show_all(
4546 bool show_properties
,
4550 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
4551 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4556 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4560 pager_open_if_enabled();
4564 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4566 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4567 _cleanup_free_
char *p
= NULL
;
4569 p
= unit_dbus_path_from_name(u
->id
);
4573 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4576 else if (r
> 0 && ret
== 0)
4583 static int show_system_status(sd_bus
*bus
) {
4584 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4585 _cleanup_free_
char *hn
= NULL
;
4586 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4587 const char *on
, *off
;
4590 hn
= gethostname_malloc();
4594 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4596 return log_error_errno(r
, "Failed to read server status: %m");
4598 if (streq_ptr(mi
.state
, "degraded")) {
4599 on
= ansi_highlight_red();
4600 off
= ansi_normal();
4601 } else if (!streq_ptr(mi
.state
, "running")) {
4602 on
= ansi_highlight_yellow();
4603 off
= ansi_normal();
4607 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4609 printf(" State: %s%s%s\n",
4610 on
, strna(mi
.state
), off
);
4612 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4613 printf(" Failed: %u units\n", mi
.n_failed_units
);
4615 printf(" Since: %s; %s\n",
4616 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4617 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4619 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4620 if (IN_SET(arg_transport
,
4621 BUS_TRANSPORT_LOCAL
,
4622 BUS_TRANSPORT_MACHINE
)) {
4623 static const char prefix
[] = " ";
4627 if (c
> sizeof(prefix
) - 1)
4628 c
-= sizeof(prefix
) - 1;
4632 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4638 static int show(int argc
, char *argv
[], void *userdata
) {
4639 bool show_properties
, show_status
, show_help
, new_line
= false;
4640 bool ellipsized
= false;
4646 show_properties
= streq(argv
[0], "show");
4647 show_status
= streq(argv
[0], "status");
4648 show_help
= streq(argv
[0], "help");
4650 if (show_help
&& argc
<= 1) {
4651 log_error("This command expects one or more unit names. Did you mean --help?");
4655 pager_open_if_enabled();
4658 /* Increase max number of open files to 16K if we can, we
4659 * might needs this when browsing journal files, which might
4660 * be split up into many files. */
4661 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4663 r
= acquire_bus(BUS_MANAGER
, &bus
);
4667 /* If no argument is specified inspect the manager itself */
4668 if (show_properties
&& argc
<= 1)
4669 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4671 if (show_status
&& argc
<= 1) {
4673 pager_open_if_enabled();
4674 show_system_status(bus
);
4678 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4680 _cleanup_free_
char **patterns
= NULL
;
4683 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4684 _cleanup_free_
char *unit
= NULL
;
4687 if (safe_atou32(*name
, &id
) < 0) {
4688 if (strv_push(&patterns
, *name
) < 0)
4692 } else if (show_properties
) {
4693 /* Interpret as job id */
4694 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4698 /* Interpret as PID */
4699 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4706 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4709 else if (r
> 0 && ret
== 0)
4713 if (!strv_isempty(patterns
)) {
4714 _cleanup_strv_free_
char **names
= NULL
;
4716 r
= expand_names(bus
, patterns
, NULL
, &names
);
4718 return log_error_errno(r
, "Failed to expand names: %m");
4720 STRV_FOREACH(name
, names
) {
4721 _cleanup_free_
char *unit
;
4723 unit
= unit_dbus_path_from_name(*name
);
4727 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4730 else if (r
> 0 && ret
== 0)
4736 if (ellipsized
&& !arg_quiet
)
4737 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4742 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4746 assert(user_runtime
);
4749 if (arg_scope
== UNIT_FILE_USER
) {
4750 r
= user_config_home(user_home
);
4752 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4754 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4756 r
= user_runtime_dir(user_runtime
);
4758 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4760 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4763 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4765 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4770 static int cat_file(const char *filename
, bool newline
) {
4771 _cleanup_close_
int fd
;
4773 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4777 printf("%s%s# %s%s\n",
4778 newline
? "\n" : "",
4779 ansi_highlight_blue(),
4784 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4787 static int cat(int argc
, char *argv
[], void *userdata
) {
4788 _cleanup_free_
char *user_home
= NULL
;
4789 _cleanup_free_
char *user_runtime
= NULL
;
4790 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4791 _cleanup_strv_free_
char **names
= NULL
;
4797 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4798 log_error("Cannot remotely cat units.");
4802 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4806 r
= acquire_bus(BUS_MANAGER
, &bus
);
4810 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4812 return log_error_errno(r
, "Failed to expand names: %m");
4814 pager_open_if_enabled();
4816 STRV_FOREACH(name
, names
) {
4817 _cleanup_free_
char *fragment_path
= NULL
;
4818 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4821 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4832 if (fragment_path
) {
4833 r
= cat_file(fragment_path
, false);
4835 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4838 STRV_FOREACH(path
, dropin_paths
) {
4839 r
= cat_file(*path
, path
== dropin_paths
);
4841 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4848 static int set_property(int argc
, char *argv
[], void *userdata
) {
4849 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
4850 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4851 _cleanup_free_
char *n
= NULL
;
4856 polkit_agent_open_if_enabled();
4858 r
= acquire_bus(BUS_MANAGER
, &bus
);
4862 r
= sd_bus_message_new_method_call(
4865 "org.freedesktop.systemd1",
4866 "/org/freedesktop/systemd1",
4867 "org.freedesktop.systemd1.Manager",
4868 "SetUnitProperties");
4870 return bus_log_create_error(r
);
4872 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4874 return log_error_errno(r
, "Failed to mangle unit name: %m");
4876 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4878 return bus_log_create_error(r
);
4880 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4882 return bus_log_create_error(r
);
4884 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4885 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4887 return bus_log_create_error(r
);
4889 r
= bus_append_unit_property_assignment(m
, *i
);
4893 r
= sd_bus_message_close_container(m
);
4895 return bus_log_create_error(r
);
4898 r
= sd_bus_message_close_container(m
);
4900 return bus_log_create_error(r
);
4902 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4904 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4909 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4910 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4915 polkit_agent_open_if_enabled();
4917 r
= acquire_bus(BUS_MANAGER
, &bus
);
4921 if (arg_action
== ACTION_RELOAD
)
4923 else if (arg_action
== ACTION_REEXEC
)
4924 method
= "Reexecute";
4926 assert(arg_action
== ACTION_SYSTEMCTL
);
4929 streq(argv
[0], "clear-jobs") ||
4930 streq(argv
[0], "cancel") ? "ClearJobs" :
4931 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
4932 streq(argv
[0], "reset-failed") ? "ResetFailed" :
4933 streq(argv
[0], "halt") ? "Halt" :
4934 streq(argv
[0], "poweroff") ? "PowerOff" :
4935 streq(argv
[0], "reboot") ? "Reboot" :
4936 streq(argv
[0], "kexec") ? "KExec" :
4937 streq(argv
[0], "exit") ? "Exit" :
4938 /* "daemon-reload" */ "Reload";
4941 r
= sd_bus_call_method(
4943 "org.freedesktop.systemd1",
4944 "/org/freedesktop/systemd1",
4945 "org.freedesktop.systemd1.Manager",
4950 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
4951 /* There's always a fallback possible for
4952 * legacy actions. */
4954 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
4955 /* On reexecution, we expect a disconnect, not a
4959 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
4961 return r
< 0 ? r
: 0;
4964 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
4965 _cleanup_strv_free_
char **names
= NULL
;
4971 return daemon_reload(argc
, argv
, userdata
);
4973 polkit_agent_open_if_enabled();
4975 r
= acquire_bus(BUS_MANAGER
, &bus
);
4979 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4981 return log_error_errno(r
, "Failed to expand names: %m");
4983 STRV_FOREACH(name
, names
) {
4984 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
4986 q
= sd_bus_call_method(
4988 "org.freedesktop.systemd1",
4989 "/org/freedesktop/systemd1",
4990 "org.freedesktop.systemd1.Manager",
4996 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5005 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5006 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5007 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5012 pager_open_if_enabled();
5014 r
= acquire_bus(BUS_MANAGER
, &bus
);
5018 r
= sd_bus_get_property(
5020 "org.freedesktop.systemd1",
5021 "/org/freedesktop/systemd1",
5022 "org.freedesktop.systemd1.Manager",
5028 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5030 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5032 return bus_log_parse_error(r
);
5034 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5037 return bus_log_parse_error(r
);
5039 r
= sd_bus_message_exit_container(reply
);
5041 return bus_log_parse_error(r
);
5046 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5047 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5048 _cleanup_free_
char *cmdline_init
= NULL
;
5049 const char *root
, *init
;
5053 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5054 log_error("Cannot switch root remotely.");
5058 if (argc
< 2 || argc
> 3) {
5059 log_error("Wrong number of arguments.");
5068 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5069 "init", &cmdline_init
,
5072 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5074 init
= cmdline_init
;
5081 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5083 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5084 root_init_path
= strjoina(root
, "/", init
);
5086 /* If the passed init is actually the same as the
5087 * systemd binary, then let's suppress it. */
5088 if (files_same(root_init_path
, root_systemd_path
) > 0)
5092 r
= acquire_bus(BUS_MANAGER
, &bus
);
5096 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5098 r
= sd_bus_call_method(
5100 "org.freedesktop.systemd1",
5101 "/org/freedesktop/systemd1",
5102 "org.freedesktop.systemd1.Manager",
5108 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5113 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5114 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5115 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5123 polkit_agent_open_if_enabled();
5125 r
= acquire_bus(BUS_MANAGER
, &bus
);
5129 method
= streq(argv
[0], "set-environment")
5131 : "UnsetEnvironment";
5133 r
= sd_bus_message_new_method_call(
5136 "org.freedesktop.systemd1",
5137 "/org/freedesktop/systemd1",
5138 "org.freedesktop.systemd1.Manager",
5141 return bus_log_create_error(r
);
5143 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5145 return bus_log_create_error(r
);
5147 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5149 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5154 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5155 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5156 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
;
5160 polkit_agent_open_if_enabled();
5162 r
= acquire_bus(BUS_MANAGER
, &bus
);
5166 r
= sd_bus_message_new_method_call(
5169 "org.freedesktop.systemd1",
5170 "/org/freedesktop/systemd1",
5171 "org.freedesktop.systemd1.Manager",
5174 return bus_log_create_error(r
);
5177 r
= sd_bus_message_append_strv(m
, environ
);
5181 r
= sd_bus_message_open_container(m
, 'a', "s");
5183 return bus_log_create_error(r
);
5185 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5187 if (!env_name_is_valid(*a
)) {
5188 log_error("Not a valid environment variable name: %s", *a
);
5192 STRV_FOREACH(b
, environ
) {
5195 eq
= startswith(*b
, *a
);
5196 if (eq
&& *eq
== '=') {
5198 r
= sd_bus_message_append(m
, "s", *b
);
5200 return bus_log_create_error(r
);
5207 r
= sd_bus_message_close_container(m
);
5210 return bus_log_create_error(r
);
5212 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5214 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5219 static int enable_sysv_units(const char *verb
, char **args
) {
5222 #if defined(HAVE_SYSV_COMPAT)
5224 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5226 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5229 if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
5232 if (!STR_IN_SET(verb
,
5238 /* Processes all SysV units, and reshuffles the array so that
5239 * afterwards only the native units remain */
5241 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5248 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5249 bool found_native
= false, found_sysv
;
5251 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5259 if (!endswith(name
, ".service"))
5262 if (path_is_absolute(name
))
5265 STRV_FOREACH(k
, paths
.unit_path
) {
5266 _cleanup_free_
char *path
= NULL
;
5268 path
= path_join(arg_root
, *k
, name
);
5272 found_native
= access(path
, F_OK
) >= 0;
5277 /* If we have both a native unit and a SysV script,
5278 * enable/disable them both (below); for is-enabled, prefer the
5280 if (found_native
&& streq(verb
, "is-enabled"))
5283 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5287 p
[strlen(p
) - strlen(".service")] = 0;
5288 found_sysv
= access(p
, F_OK
) >= 0;
5293 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5295 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5297 if (!isempty(arg_root
))
5298 argv
[c
++] = q
= strappend("--root=", arg_root
);
5301 argv
[c
++] = basename(p
);
5304 l
= strv_join((char**)argv
, " ");
5308 log_info("Executing %s", l
);
5312 return log_error_errno(errno
, "Failed to fork: %m");
5313 else if (pid
== 0) {
5316 (void) reset_all_signal_handlers();
5317 (void) reset_signal_mask();
5319 execv(argv
[0], (char**) argv
);
5320 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5321 _exit(EXIT_FAILURE
);
5324 j
= wait_for_terminate(pid
, &status
);
5326 log_error_errno(j
, "Failed to wait for child: %m");
5330 if (status
.si_code
== CLD_EXITED
) {
5331 if (streq(verb
, "is-enabled")) {
5332 if (status
.si_status
== 0) {
5341 } else if (status
.si_status
!= 0)
5349 /* Remove this entry, so that we don't try enabling it as native unit */
5352 assert(args
[f
] == name
);
5353 strv_remove(args
, name
);
5360 static int mangle_names(char **original_names
, char ***mangled_names
) {
5361 char **i
, **l
, **name
;
5364 l
= i
= new(char*, strv_length(original_names
) + 1);
5368 STRV_FOREACH(name
, original_names
) {
5370 /* When enabling units qualified path names are OK,
5371 * too, hence allow them explicitly. */
5373 if (is_path(*name
)) {
5380 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5383 return log_error_errno(r
, "Failed to mangle unit name: %m");
5396 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5397 _cleanup_strv_free_
char **names
= NULL
;
5398 const char *verb
= argv
[0];
5399 UnitFileChange
*changes
= NULL
;
5400 unsigned n_changes
= 0;
5401 int carries_install_info
= -1;
5407 r
= mangle_names(strv_skip(argv
, 1), &names
);
5411 r
= enable_sysv_units(verb
, names
);
5415 /* If the operation was fully executed by the SysV compat,
5416 * let's finish early */
5417 if (strv_isempty(names
))
5420 if (install_client_side()) {
5421 if (streq(verb
, "enable")) {
5422 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5423 carries_install_info
= r
;
5424 } else if (streq(verb
, "disable"))
5425 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5426 else if (streq(verb
, "reenable")) {
5427 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5428 carries_install_info
= r
;
5429 } else if (streq(verb
, "link"))
5430 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5431 else if (streq(verb
, "preset")) {
5432 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5433 carries_install_info
= r
;
5434 } else if (streq(verb
, "mask"))
5435 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5436 else if (streq(verb
, "unmask"))
5437 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5439 assert_not_reached("Unknown verb");
5441 if (r
== -ESHUTDOWN
)
5442 return log_error_errno(r
, "Unit file is masked.");
5444 return log_error_errno(r
, "Operation failed: %m");
5447 dump_unit_file_changes(changes
, n_changes
);
5451 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5452 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5453 int expect_carries_install_info
= false;
5454 bool send_force
= true, send_preset_mode
= false;
5458 polkit_agent_open_if_enabled();
5460 r
= acquire_bus(BUS_MANAGER
, &bus
);
5464 if (streq(verb
, "enable")) {
5465 method
= "EnableUnitFiles";
5466 expect_carries_install_info
= true;
5467 } else if (streq(verb
, "disable")) {
5468 method
= "DisableUnitFiles";
5470 } else if (streq(verb
, "reenable")) {
5471 method
= "ReenableUnitFiles";
5472 expect_carries_install_info
= true;
5473 } else if (streq(verb
, "link"))
5474 method
= "LinkUnitFiles";
5475 else if (streq(verb
, "preset")) {
5477 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5478 method
= "PresetUnitFilesWithMode";
5479 send_preset_mode
= true;
5481 method
= "PresetUnitFiles";
5483 expect_carries_install_info
= true;
5484 } else if (streq(verb
, "mask"))
5485 method
= "MaskUnitFiles";
5486 else if (streq(verb
, "unmask")) {
5487 method
= "UnmaskUnitFiles";
5490 assert_not_reached("Unknown verb");
5492 r
= sd_bus_message_new_method_call(
5495 "org.freedesktop.systemd1",
5496 "/org/freedesktop/systemd1",
5497 "org.freedesktop.systemd1.Manager",
5500 return bus_log_create_error(r
);
5502 r
= sd_bus_message_append_strv(m
, names
);
5504 return bus_log_create_error(r
);
5506 if (send_preset_mode
) {
5507 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5509 return bus_log_create_error(r
);
5512 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5514 return bus_log_create_error(r
);
5517 r
= sd_bus_message_append(m
, "b", arg_force
);
5519 return bus_log_create_error(r
);
5522 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5524 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5526 if (expect_carries_install_info
) {
5527 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5529 return bus_log_parse_error(r
);
5532 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5536 /* Try to reload if enabled */
5538 r
= daemon_reload(argc
, argv
, userdata
);
5543 if (carries_install_info
== 0)
5544 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5545 "using systemctl.\n"
5546 "Possible reasons for having this kind of units are:\n"
5547 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5548 " .wants/ or .requires/ directory.\n"
5549 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5550 " a requirement dependency on it.\n"
5551 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5552 " D-Bus, udev, scripted systemctl call, ...).\n");
5554 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5555 char *new_args
[n_changes
+ 2];
5559 r
= acquire_bus(BUS_MANAGER
, &bus
);
5563 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5564 for (i
= 0; i
< n_changes
; i
++)
5565 new_args
[i
+ 1] = basename(changes
[i
].path
);
5566 new_args
[i
+ 1] = NULL
;
5568 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5572 unit_file_changes_free(changes
, n_changes
);
5577 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5578 _cleanup_strv_free_
char **names
= NULL
;
5579 _cleanup_free_
char *target
= NULL
;
5580 const char *verb
= argv
[0];
5587 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5589 return log_error_errno(r
, "Failed to mangle unit name: %m");
5591 r
= mangle_names(strv_skip(argv
, 2), &names
);
5595 if (streq(verb
, "add-wants"))
5597 else if (streq(verb
, "add-requires"))
5598 dep
= UNIT_REQUIRES
;
5600 assert_not_reached("Unknown verb");
5602 if (install_client_side()) {
5603 UnitFileChange
*changes
= NULL
;
5604 unsigned n_changes
= 0;
5606 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5607 if (r
== -ESHUTDOWN
)
5608 return log_error_errno(r
, "Unit file is masked.");
5610 return log_error_errno(r
, "Can't add dependency: %m");
5613 dump_unit_file_changes(changes
, n_changes
);
5615 unit_file_changes_free(changes
, n_changes
);
5618 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
, *m
= NULL
;
5619 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5622 polkit_agent_open_if_enabled();
5624 r
= acquire_bus(BUS_MANAGER
, &bus
);
5628 r
= sd_bus_message_new_method_call(
5631 "org.freedesktop.systemd1",
5632 "/org/freedesktop/systemd1",
5633 "org.freedesktop.systemd1.Manager",
5634 "AddDependencyUnitFiles");
5636 return bus_log_create_error(r
);
5638 r
= sd_bus_message_append_strv(m
, names
);
5640 return bus_log_create_error(r
);
5642 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5644 return bus_log_create_error(r
);
5646 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5648 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5650 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5655 r
= daemon_reload(argc
, argv
, userdata
);
5663 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5664 UnitFileChange
*changes
= NULL
;
5665 unsigned n_changes
= 0;
5668 if (install_client_side()) {
5670 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5672 log_error_errno(r
, "Operation failed: %m");
5677 dump_unit_file_changes(changes
, n_changes
);
5682 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5683 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5686 polkit_agent_open_if_enabled();
5688 r
= acquire_bus(BUS_MANAGER
, &bus
);
5692 r
= sd_bus_call_method(
5694 "org.freedesktop.systemd1",
5695 "/org/freedesktop/systemd1",
5696 "org.freedesktop.systemd1.Manager",
5697 "PresetAllUnitFiles",
5701 unit_file_preset_mode_to_string(arg_preset_mode
),
5705 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5707 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5712 r
= daemon_reload(argc
, argv
, userdata
);
5718 unit_file_changes_free(changes
, n_changes
);
5723 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5725 _cleanup_strv_free_
char **names
= NULL
;
5730 r
= mangle_names(strv_skip(argv
, 1), &names
);
5734 r
= enable_sysv_units(argv
[0], names
);
5740 if (install_client_side()) {
5742 STRV_FOREACH(name
, names
) {
5743 UnitFileState state
;
5745 r
= unit_file_get_state(arg_scope
, arg_root
, *name
, &state
);
5747 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5751 UNIT_FILE_ENABLED_RUNTIME
,
5753 UNIT_FILE_INDIRECT
))
5757 puts(unit_file_state_to_string(state
));
5761 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
5764 r
= acquire_bus(BUS_MANAGER
, &bus
);
5768 STRV_FOREACH(name
, names
) {
5769 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*reply
= NULL
;
5772 r
= sd_bus_call_method(
5774 "org.freedesktop.systemd1",
5775 "/org/freedesktop/systemd1",
5776 "org.freedesktop.systemd1.Manager",
5782 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5784 r
= sd_bus_message_read(reply
, "s", &s
);
5786 return bus_log_parse_error(r
);
5788 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5799 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5800 _cleanup_free_
char *state
= NULL
;
5804 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5807 return EXIT_FAILURE
;
5810 r
= acquire_bus(BUS_MANAGER
, &bus
);
5814 r
= sd_bus_get_property_string(
5816 "org.freedesktop.systemd1",
5817 "/org/freedesktop/systemd1",
5818 "org.freedesktop.systemd1.Manager",
5831 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5834 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5835 _cleanup_free_
char *t
= NULL
;
5839 assert(original_path
);
5842 r
= tempfn_random(new_path
, NULL
, &t
);
5844 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5846 r
= mkdir_parents(new_path
, 0755);
5848 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5850 r
= copy_file(original_path
, t
, 0, 0644, 0);
5855 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5858 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5866 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5867 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5872 switch (arg_scope
) {
5873 case UNIT_FILE_SYSTEM
:
5874 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5876 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5878 case UNIT_FILE_GLOBAL
:
5879 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5881 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5883 case UNIT_FILE_USER
:
5885 assert(user_runtime
);
5887 path
= path_join(arg_root
, user_home
, name
);
5889 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5892 run
= path_join(arg_root
, user_runtime
, name
);
5896 assert_not_reached("Invalid scope");
5898 if (!path
|| (arg_runtime
&& !run
))
5902 if (access(path
, F_OK
) >= 0) {
5903 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5907 if (path2
&& access(path2
, F_OK
) >= 0) {
5908 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5922 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
) {
5923 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
5927 assert(ret_new_path
);
5928 assert(ret_tmp_path
);
5930 ending
= strjoina(unit_name
, ".d/override.conf");
5931 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
5935 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
5941 *ret_new_path
= tmp_new_path
;
5942 *ret_tmp_path
= tmp_tmp_path
;
5947 static int unit_file_create_copy(
5948 const char *unit_name
,
5949 const char *fragment_path
,
5950 const char *user_home
,
5951 const char *user_runtime
,
5952 char **ret_new_path
,
5953 char **ret_tmp_path
) {
5955 char *tmp_new_path
, *tmp_tmp_path
;
5958 assert(fragment_path
);
5960 assert(ret_new_path
);
5961 assert(ret_tmp_path
);
5963 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
5967 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
5970 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
5975 if (response
!= 'y') {
5976 log_warning("%s ignored", unit_name
);
5982 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
5984 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
5989 *ret_new_path
= tmp_new_path
;
5990 *ret_tmp_path
= tmp_tmp_path
;
5995 static int run_editor(char **paths
) {
6003 return log_error_errno(errno
, "Failed to fork: %m");
6007 char *editor
, **editor_args
= NULL
;
6008 char **tmp_path
, **original_path
, *p
;
6009 unsigned n_editor_args
= 0, i
= 1;
6012 (void) reset_all_signal_handlers();
6013 (void) reset_signal_mask();
6015 argc
= strv_length(paths
)/2 + 1;
6017 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6018 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6019 * we try to execute well known editors
6021 editor
= getenv("SYSTEMD_EDITOR");
6023 editor
= getenv("EDITOR");
6025 editor
= getenv("VISUAL");
6027 if (!isempty(editor
)) {
6028 editor_args
= strv_split(editor
, WHITESPACE
);
6031 _exit(EXIT_FAILURE
);
6033 n_editor_args
= strv_length(editor_args
);
6034 argc
+= n_editor_args
- 1;
6036 args
= newa(const char*, argc
+ 1);
6038 if (n_editor_args
> 0) {
6039 args
[0] = editor_args
[0];
6040 for (; i
< n_editor_args
; i
++)
6041 args
[i
] = editor_args
[i
];
6044 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6045 args
[i
] = *tmp_path
;
6050 if (n_editor_args
> 0)
6051 execvp(args
[0], (char* const*) args
);
6053 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6055 execvp(p
, (char* const*) args
);
6056 /* We do not fail if the editor doesn't exist
6057 * because we want to try each one of them before
6060 if (errno
!= ENOENT
) {
6061 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6062 _exit(EXIT_FAILURE
);
6066 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6067 _exit(EXIT_FAILURE
);
6070 r
= wait_for_terminate_and_warn("editor", pid
, true);
6072 return log_error_errno(r
, "Failed to wait for child: %m");
6077 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6078 _cleanup_free_
char *user_home
= NULL
;
6079 _cleanup_free_
char *user_runtime
= NULL
;
6080 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6087 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6091 STRV_FOREACH(name
, names
) {
6092 _cleanup_free_
char *path
= NULL
;
6093 char *new_path
, *tmp_path
;
6095 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6101 // FIXME: support units with path==NULL (no FragmentPath)
6102 log_error("No fragment exists for %s.", *name
);
6107 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6109 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6113 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6121 static int edit(int argc
, char *argv
[], void *userdata
) {
6122 _cleanup_strv_free_
char **names
= NULL
;
6123 _cleanup_strv_free_
char **paths
= NULL
;
6124 char **original
, **tmp
;
6129 log_error("Cannot edit units if not on a tty.");
6133 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6134 log_error("Cannot edit units remotely.");
6138 r
= acquire_bus(BUS_MANAGER
, &bus
);
6142 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6144 return log_error_errno(r
, "Failed to expand names: %m");
6146 r
= find_paths_to_edit(bus
, names
, &paths
);
6150 if (strv_isempty(paths
))
6153 r
= run_editor(paths
);
6157 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6158 /* If the temporary file is empty we ignore it. It's
6159 * useful if the user wants to cancel its modification
6161 if (null_or_empty_path(*tmp
)) {
6162 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6166 r
= rename(*tmp
, *original
);
6168 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6175 if (!arg_no_reload
&& !install_client_side())
6176 r
= daemon_reload(argc
, argv
, userdata
);
6179 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6180 (void) unlink(*tmp
);
6185 static void systemctl_help(void) {
6187 pager_open_if_enabled();
6189 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6190 "Query or send control commands to the systemd manager.\n\n"
6191 " -h --help Show this help\n"
6192 " --version Show package version\n"
6193 " --system Connect to system manager\n"
6194 " --user Connect to user service manager\n"
6195 " -H --host=[USER@]HOST\n"
6196 " Operate on remote host\n"
6197 " -M --machine=CONTAINER\n"
6198 " Operate on local container\n"
6199 " -t --type=TYPE List units of a particular type\n"
6200 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6201 " -p --property=NAME Show only properties by this name\n"
6202 " -a --all Show all loaded units/properties, including dead/empty\n"
6203 " ones. To list all units installed on the system, use\n"
6204 " the 'list-unit-files' command instead.\n"
6205 " -l --full Don't ellipsize unit names on output\n"
6206 " -r --recursive Show unit list of host and local containers\n"
6207 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6208 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6209 " queueing a new job\n"
6210 " --show-types When showing sockets, explicitly show their type\n"
6211 " -i --ignore-inhibitors\n"
6212 " When shutting down or sleeping, ignore inhibitors\n"
6213 " --kill-who=WHO Who to send signal to\n"
6214 " -s --signal=SIGNAL Which signal to send\n"
6215 " --now Start or stop unit in addition to enabling or disabling it\n"
6216 " -q --quiet Suppress output\n"
6217 " --no-block Do not wait until operation finished\n"
6218 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6219 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6220 " --no-legend Do not print a legend (column headers and hints)\n"
6221 " --no-pager Do not pipe output into a pager\n"
6222 " --no-ask-password\n"
6223 " Do not ask for system passwords\n"
6224 " --global Enable/disable unit files globally\n"
6225 " --runtime Enable unit files only temporarily until next reboot\n"
6226 " -f --force When enabling unit files, override existing symlinks\n"
6227 " When shutting down, execute action immediately\n"
6228 " --preset-mode= Apply only enable, only disable, or all presets\n"
6229 " --root=PATH Enable unit files in the specified root directory\n"
6230 " -n --lines=INTEGER Number of journal entries to show\n"
6231 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6232 " short-precise, short-monotonic, verbose,\n"
6233 " export, json, json-pretty, json-sse, cat)\n"
6234 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6235 " --plain Print unit dependencies as a list instead of a tree\n\n"
6237 " list-units [PATTERN...] List loaded units\n"
6238 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6239 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6240 " start NAME... Start (activate) one or more units\n"
6241 " stop NAME... Stop (deactivate) one or more units\n"
6242 " reload NAME... Reload one or more units\n"
6243 " restart NAME... Start or restart one or more units\n"
6244 " try-restart NAME... Restart one or more units if active\n"
6245 " reload-or-restart NAME... Reload one or more units if possible,\n"
6246 " otherwise start or restart\n"
6247 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6248 " otherwise restart if active\n"
6249 " isolate NAME Start one unit and stop all others\n"
6250 " kill NAME... Send signal to processes of a unit\n"
6251 " is-active PATTERN... Check whether units are active\n"
6252 " is-failed PATTERN... Check whether units are failed\n"
6253 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6254 " show [PATTERN...|JOB...] Show properties of one or more\n"
6255 " units/jobs or the manager\n"
6256 " cat PATTERN... Show files and drop-ins of one or more units\n"
6257 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6258 " help PATTERN...|PID... Show manual for one or more units\n"
6259 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6261 " list-dependencies [NAME] Recursively show units which are required\n"
6262 " or wanted by this unit or by which this\n"
6263 " unit is required or wanted\n\n"
6264 "Unit File Commands:\n"
6265 " list-unit-files [PATTERN...] List installed unit files\n"
6266 " enable NAME... Enable one or more unit files\n"
6267 " disable NAME... Disable one or more unit files\n"
6268 " reenable NAME... Reenable one or more unit files\n"
6269 " preset NAME... Enable/disable one or more unit files\n"
6270 " based on preset configuration\n"
6271 " preset-all Enable/disable all unit files based on\n"
6272 " preset configuration\n"
6273 " is-enabled NAME... Check whether unit files are enabled\n"
6274 " mask NAME... Mask one or more units\n"
6275 " unmask NAME... Unmask one or more units\n"
6276 " link PATH... Link one or more units files into\n"
6277 " the search path\n"
6278 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6279 " on specified one or more units\n"
6280 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6281 " on specified one or more units\n"
6282 " edit NAME... Edit one or more unit files\n"
6283 " get-default Get the name of the default target\n"
6284 " set-default NAME Set the default target\n\n"
6285 "Machine Commands:\n"
6286 " list-machines [PATTERN...] List local containers and host\n\n"
6288 " list-jobs [PATTERN...] List jobs\n"
6289 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6290 "Environment Commands:\n"
6291 " show-environment Dump environment\n"
6292 " set-environment NAME=VALUE... Set one or more environment variables\n"
6293 " unset-environment NAME... Unset one or more environment variables\n"
6294 " import-environment [NAME...] Import all or some environment variables\n\n"
6295 "Manager Lifecycle Commands:\n"
6296 " daemon-reload Reload systemd manager configuration\n"
6297 " daemon-reexec Reexecute systemd manager\n\n"
6298 "System Commands:\n"
6299 " is-system-running Check whether system is fully running\n"
6300 " default Enter system default mode\n"
6301 " rescue Enter system rescue mode\n"
6302 " emergency Enter system emergency mode\n"
6303 " halt Shut down and halt the system\n"
6304 " poweroff Shut down and power-off the system\n"
6305 " reboot [ARG] Shut down and reboot the system\n"
6306 " kexec Shut down and reboot the system with kexec\n"
6307 " exit [EXIT_CODE] Request user instance or container exit\n"
6308 " switch-root ROOT [INIT] Change to a different root file system\n"
6309 " suspend Suspend the system\n"
6310 " hibernate Hibernate the system\n"
6311 " hybrid-sleep Hibernate and suspend the system\n",
6312 program_invocation_short_name
);
6315 static void halt_help(void) {
6316 printf("%s [OPTIONS...]%s\n\n"
6317 "%s the system.\n\n"
6318 " --help Show this help\n"
6319 " --halt Halt the machine\n"
6320 " -p --poweroff Switch off the machine\n"
6321 " --reboot Reboot the machine\n"
6322 " -f --force Force immediate halt/power-off/reboot\n"
6323 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6324 " -d --no-wtmp Don't write wtmp record\n"
6325 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6326 program_invocation_short_name
,
6327 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6328 arg_action
== ACTION_REBOOT
? "Reboot" :
6329 arg_action
== ACTION_POWEROFF
? "Power off" :
6333 static void shutdown_help(void) {
6334 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6335 "Shut down the system.\n\n"
6336 " --help Show this help\n"
6337 " -H --halt Halt the machine\n"
6338 " -P --poweroff Power-off the machine\n"
6339 " -r --reboot Reboot the machine\n"
6340 " -h Equivalent to --poweroff, overridden by --halt\n"
6341 " -k Don't halt/power-off/reboot, just send warnings\n"
6342 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6343 " -c Cancel a pending shutdown\n",
6344 program_invocation_short_name
);
6347 static void telinit_help(void) {
6348 printf("%s [OPTIONS...] {COMMAND}\n\n"
6349 "Send control commands to the init daemon.\n\n"
6350 " --help Show this help\n"
6351 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6353 " 0 Power-off the machine\n"
6354 " 6 Reboot the machine\n"
6355 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6356 " 1, s, S Enter rescue mode\n"
6357 " q, Q Reload init daemon configuration\n"
6358 " u, U Reexecute init daemon\n",
6359 program_invocation_short_name
);
6362 static void runlevel_help(void) {
6363 printf("%s [OPTIONS...]\n\n"
6364 "Prints the previous and current runlevel of the init system.\n\n"
6365 " --help Show this help\n",
6366 program_invocation_short_name
);
6369 static void help_types(void) {
6373 puts("Available unit types:");
6374 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6375 puts(unit_type_to_string(i
));
6378 static void help_states(void) {
6382 puts("Available unit load states:");
6383 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6384 puts(unit_load_state_to_string(i
));
6387 puts("\nAvailable unit active states:");
6388 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6389 puts(unit_active_state_to_string(i
));
6392 puts("\nAvailable automount unit substates:");
6393 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6394 puts(automount_state_to_string(i
));
6397 puts("\nAvailable busname unit substates:");
6398 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6399 puts(busname_state_to_string(i
));
6402 puts("\nAvailable device unit substates:");
6403 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6404 puts(device_state_to_string(i
));
6407 puts("\nAvailable mount unit substates:");
6408 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6409 puts(mount_state_to_string(i
));
6412 puts("\nAvailable path unit substates:");
6413 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6414 puts(path_state_to_string(i
));
6417 puts("\nAvailable scope unit substates:");
6418 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6419 puts(scope_state_to_string(i
));
6422 puts("\nAvailable service unit substates:");
6423 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6424 puts(service_state_to_string(i
));
6427 puts("\nAvailable slice unit substates:");
6428 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6429 puts(slice_state_to_string(i
));
6432 puts("\nAvailable socket unit substates:");
6433 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6434 puts(socket_state_to_string(i
));
6437 puts("\nAvailable swap unit substates:");
6438 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6439 puts(swap_state_to_string(i
));
6442 puts("\nAvailable target unit substates:");
6443 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6444 puts(target_state_to_string(i
));
6447 puts("\nAvailable timer unit substates:");
6448 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6449 puts(timer_state_to_string(i
));
6452 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6461 ARG_IGNORE_DEPENDENCIES
,
6473 ARG_NO_ASK_PASSWORD
,
6486 static const struct option options
[] = {
6487 { "help", no_argument
, NULL
, 'h' },
6488 { "version", no_argument
, NULL
, ARG_VERSION
},
6489 { "type", required_argument
, NULL
, 't' },
6490 { "property", required_argument
, NULL
, 'p' },
6491 { "all", no_argument
, NULL
, 'a' },
6492 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6493 { "after", no_argument
, NULL
, ARG_AFTER
},
6494 { "before", no_argument
, NULL
, ARG_BEFORE
},
6495 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6496 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6497 { "full", no_argument
, NULL
, 'l' },
6498 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6499 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6500 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6501 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6502 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6503 { "user", no_argument
, NULL
, ARG_USER
},
6504 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6505 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6506 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6507 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6508 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6509 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6510 { "quiet", no_argument
, NULL
, 'q' },
6511 { "root", required_argument
, NULL
, ARG_ROOT
},
6512 { "force", no_argument
, NULL
, ARG_FORCE
},
6513 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6514 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6515 { "signal", required_argument
, NULL
, 's' },
6516 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6517 { "host", required_argument
, NULL
, 'H' },
6518 { "machine", required_argument
, NULL
, 'M' },
6519 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6520 { "lines", required_argument
, NULL
, 'n' },
6521 { "output", required_argument
, NULL
, 'o' },
6522 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6523 { "state", required_argument
, NULL
, ARG_STATE
},
6524 { "recursive", no_argument
, NULL
, 'r' },
6525 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6526 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6527 { "now", no_argument
, NULL
, ARG_NOW
},
6528 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6538 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6539 arg_ask_password
= true;
6541 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6553 if (isempty(optarg
)) {
6554 log_error("--type requires arguments.");
6560 _cleanup_free_
char *type
= NULL
;
6562 r
= extract_first_word(&p
, &type
, ",", 0);
6564 return log_error_errno(r
, "Failed to parse type: %s", optarg
);
6569 if (streq(type
, "help")) {
6574 if (unit_type_from_string(type
) >= 0) {
6575 if (strv_push(&arg_types
, type
) < 0)
6581 /* It's much nicer to use --state= for
6582 * load states, but let's support this
6583 * in --types= too for compatibility
6584 * with old versions */
6585 if (unit_load_state_from_string(type
) >= 0) {
6586 if (strv_push(&arg_states
, type
) < 0)
6592 log_error("Unknown unit type or load state '%s'.", type
);
6593 log_info("Use -t help to see a list of allowed values.");
6601 /* Make sure that if the empty property list
6602 was specified, we won't show any properties. */
6603 if (isempty(optarg
) && !arg_properties
) {
6604 arg_properties
= new0(char*, 1);
6605 if (!arg_properties
)
6610 _cleanup_free_
char *prop
= NULL
;
6612 r
= extract_first_word(&p
, &prop
, ",", 0);
6614 return log_error_errno(r
, "Failed to parse property: %s", optarg
);
6619 if (strv_push(&arg_properties
, prop
) < 0)
6626 /* If the user asked for a particular
6627 * property, show it to him, even if it is
6639 arg_dependency
= DEPENDENCY_REVERSE
;
6643 arg_dependency
= DEPENDENCY_AFTER
;
6647 arg_dependency
= DEPENDENCY_BEFORE
;
6650 case ARG_SHOW_TYPES
:
6651 arg_show_types
= true;
6655 arg_job_mode
= optarg
;
6659 arg_job_mode
= "fail";
6662 case ARG_IRREVERSIBLE
:
6663 arg_job_mode
= "replace-irreversibly";
6666 case ARG_IGNORE_DEPENDENCIES
:
6667 arg_job_mode
= "ignore-dependencies";
6671 arg_scope
= UNIT_FILE_USER
;
6675 arg_scope
= UNIT_FILE_SYSTEM
;
6679 arg_scope
= UNIT_FILE_GLOBAL
;
6683 arg_no_block
= true;
6687 arg_no_legend
= true;
6691 arg_no_pager
= true;
6699 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6709 if (strv_extend(&arg_states
, "failed") < 0)
6727 arg_no_reload
= true;
6731 arg_kill_who
= optarg
;
6735 arg_signal
= signal_from_string_try_harder(optarg
);
6736 if (arg_signal
< 0) {
6737 log_error("Failed to parse signal string %s.", optarg
);
6742 case ARG_NO_ASK_PASSWORD
:
6743 arg_ask_password
= false;
6747 arg_transport
= BUS_TRANSPORT_REMOTE
;
6752 arg_transport
= BUS_TRANSPORT_MACHINE
;
6761 if (safe_atou(optarg
, &arg_lines
) < 0) {
6762 log_error("Failed to parse lines '%s'", optarg
);
6768 arg_output
= output_mode_from_string(optarg
);
6769 if (arg_output
< 0) {
6770 log_error("Unknown output '%s'.", optarg
);
6776 arg_ignore_inhibitors
= true;
6783 case ARG_FIRMWARE_SETUP
:
6784 arg_firmware_setup
= true;
6788 if (isempty(optarg
)) {
6789 log_error("--signal requires arguments.");
6795 _cleanup_free_
char *s
= NULL
;
6797 r
= extract_first_word(&p
, &s
, ",", 0);
6799 return log_error_errno(r
, "Failed to parse signal: %s", optarg
);
6804 if (streq(s
, "help")) {
6809 if (strv_push(&arg_states
, s
) < 0)
6818 if (geteuid() != 0) {
6819 log_error("--recursive requires root privileges.");
6823 arg_recursive
= true;
6826 case ARG_PRESET_MODE
:
6828 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6829 if (arg_preset_mode
< 0) {
6830 log_error("Failed to parse preset mode: %s.", optarg
);
6841 if (strv_extend(&arg_wall
, optarg
) < 0)
6849 assert_not_reached("Unhandled option");
6852 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6853 log_error("Cannot access user instance remotely.");
6860 static int halt_parse_argv(int argc
, char *argv
[]) {
6869 static const struct option options
[] = {
6870 { "help", no_argument
, NULL
, ARG_HELP
},
6871 { "halt", no_argument
, NULL
, ARG_HALT
},
6872 { "poweroff", no_argument
, NULL
, 'p' },
6873 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6874 { "force", no_argument
, NULL
, 'f' },
6875 { "wtmp-only", no_argument
, NULL
, 'w' },
6876 { "no-wtmp", no_argument
, NULL
, 'd' },
6877 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6886 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6887 if (runlevel
== '0' || runlevel
== '6')
6890 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6898 arg_action
= ACTION_HALT
;
6902 if (arg_action
!= ACTION_REBOOT
)
6903 arg_action
= ACTION_POWEROFF
;
6907 arg_action
= ACTION_REBOOT
;
6929 /* Compatibility nops */
6936 assert_not_reached("Unhandled option");
6939 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
6940 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
6943 } else if (optind
< argc
) {
6944 log_error("Too many arguments.");
6951 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
6955 if (streq(t
, "now"))
6957 else if (!strchr(t
, ':')) {
6960 if (safe_atou64(t
, &u
) < 0)
6963 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
6972 hour
= strtol(t
, &e
, 10);
6973 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
6976 minute
= strtol(e
+1, &e
, 10);
6977 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
6980 n
= now(CLOCK_REALTIME
);
6981 s
= (time_t) (n
/ USEC_PER_SEC
);
6983 assert_se(localtime_r(&s
, &tm
));
6985 tm
.tm_hour
= (int) hour
;
6986 tm
.tm_min
= (int) minute
;
6989 assert_se(s
= mktime(&tm
));
6991 *_u
= (usec_t
) s
* USEC_PER_SEC
;
6994 *_u
+= USEC_PER_DAY
;
7000 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7007 static const struct option options
[] = {
7008 { "help", no_argument
, NULL
, ARG_HELP
},
7009 { "halt", no_argument
, NULL
, 'H' },
7010 { "poweroff", no_argument
, NULL
, 'P' },
7011 { "reboot", no_argument
, NULL
, 'r' },
7012 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7013 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7023 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7031 arg_action
= ACTION_HALT
;
7035 arg_action
= ACTION_POWEROFF
;
7040 arg_action
= ACTION_KEXEC
;
7042 arg_action
= ACTION_REBOOT
;
7046 arg_action
= ACTION_KEXEC
;
7050 if (arg_action
!= ACTION_HALT
)
7051 arg_action
= ACTION_POWEROFF
;
7066 /* Compatibility nops */
7070 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7077 assert_not_reached("Unhandled option");
7080 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7081 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7083 log_error("Failed to parse time specification: %s", argv
[optind
]);
7087 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7089 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7090 /* No time argument for shutdown cancel */
7091 wall
= argv
+ optind
;
7092 else if (argc
> optind
+ 1)
7093 /* We skip the time argument */
7094 wall
= argv
+ optind
+ 1;
7097 arg_wall
= strv_copy(wall
);
7107 static int telinit_parse_argv(int argc
, char *argv
[]) {
7114 static const struct option options
[] = {
7115 { "help", no_argument
, NULL
, ARG_HELP
},
7116 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7120 static const struct {
7124 { '0', ACTION_POWEROFF
},
7125 { '6', ACTION_REBOOT
},
7126 { '1', ACTION_RESCUE
},
7127 { '2', ACTION_RUNLEVEL2
},
7128 { '3', ACTION_RUNLEVEL3
},
7129 { '4', ACTION_RUNLEVEL4
},
7130 { '5', ACTION_RUNLEVEL5
},
7131 { 's', ACTION_RESCUE
},
7132 { 'S', ACTION_RESCUE
},
7133 { 'q', ACTION_RELOAD
},
7134 { 'Q', ACTION_RELOAD
},
7135 { 'u', ACTION_REEXEC
},
7136 { 'U', ACTION_REEXEC
}
7145 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7160 assert_not_reached("Unhandled option");
7163 if (optind
>= argc
) {
7164 log_error("%s: required argument missing.", program_invocation_short_name
);
7168 if (optind
+ 1 < argc
) {
7169 log_error("Too many arguments.");
7173 if (strlen(argv
[optind
]) != 1) {
7174 log_error("Expected single character argument.");
7178 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7179 if (table
[i
].from
== argv
[optind
][0])
7182 if (i
>= ELEMENTSOF(table
)) {
7183 log_error("Unknown command '%s'.", argv
[optind
]);
7187 arg_action
= table
[i
].to
;
7194 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7200 static const struct option options
[] = {
7201 { "help", no_argument
, NULL
, ARG_HELP
},
7210 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7221 assert_not_reached("Unhandled option");
7224 if (optind
< argc
) {
7225 log_error("Too many arguments.");
7232 static int parse_argv(int argc
, char *argv
[]) {
7236 if (program_invocation_short_name
) {
7238 if (strstr(program_invocation_short_name
, "halt")) {
7239 arg_action
= ACTION_HALT
;
7240 return halt_parse_argv(argc
, argv
);
7241 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7242 arg_action
= ACTION_POWEROFF
;
7243 return halt_parse_argv(argc
, argv
);
7244 } else if (strstr(program_invocation_short_name
, "reboot")) {
7246 arg_action
= ACTION_KEXEC
;
7248 arg_action
= ACTION_REBOOT
;
7249 return halt_parse_argv(argc
, argv
);
7250 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7251 arg_action
= ACTION_POWEROFF
;
7252 return shutdown_parse_argv(argc
, argv
);
7253 } else if (strstr(program_invocation_short_name
, "init")) {
7255 if (sd_booted() > 0) {
7256 arg_action
= _ACTION_INVALID
;
7257 return telinit_parse_argv(argc
, argv
);
7259 /* Hmm, so some other init system is
7260 * running, we need to forward this
7261 * request to it. For now we simply
7262 * guess that it is Upstart. */
7264 execv(TELINIT
, argv
);
7266 log_error("Couldn't find an alternative telinit implementation to spawn.");
7270 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7271 arg_action
= ACTION_RUNLEVEL
;
7272 return runlevel_parse_argv(argc
, argv
);
7276 arg_action
= ACTION_SYSTEMCTL
;
7277 return systemctl_parse_argv(argc
, argv
);
7280 _pure_
static int action_to_runlevel(void) {
7282 static const char table
[_ACTION_MAX
] = {
7283 [ACTION_HALT
] = '0',
7284 [ACTION_POWEROFF
] = '0',
7285 [ACTION_REBOOT
] = '6',
7286 [ACTION_RUNLEVEL2
] = '2',
7287 [ACTION_RUNLEVEL3
] = '3',
7288 [ACTION_RUNLEVEL4
] = '4',
7289 [ACTION_RUNLEVEL5
] = '5',
7290 [ACTION_RESCUE
] = '1'
7293 assert(arg_action
< _ACTION_MAX
);
7295 return table
[arg_action
];
7298 static int talk_initctl(void) {
7299 #ifdef HAVE_SYSV_COMPAT
7300 struct init_request request
= {
7301 .magic
= INIT_MAGIC
,
7303 .cmd
= INIT_CMD_RUNLVL
7306 _cleanup_close_
int fd
= -1;
7310 rl
= action_to_runlevel();
7314 request
.runlevel
= rl
;
7316 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7318 if (errno
== ENOENT
)
7321 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7324 r
= loop_write(fd
, &request
, sizeof(request
), false);
7326 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7334 static int systemctl_main(int argc
, char *argv
[]) {
7336 static const Verb verbs
[] = {
7337 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
, list_units
},
7338 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7339 { "list-sockets", VERB_ANY
, VERB_ANY
, 0, list_sockets
},
7340 { "list-timers", VERB_ANY
, VERB_ANY
, 0, list_timers
},
7341 { "list-jobs", VERB_ANY
, VERB_ANY
, 0, list_jobs
},
7342 { "list-machines", VERB_ANY
, VERB_ANY
, 0, list_machines
},
7343 { "clear-jobs", VERB_ANY
, 1, 0, daemon_reload
},
7344 { "cancel", VERB_ANY
, VERB_ANY
, 0, cancel_job
},
7345 { "start", 2, VERB_ANY
, 0, start_unit
},
7346 { "stop", 2, VERB_ANY
, 0, start_unit
},
7347 { "condstop", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7348 { "reload", 2, VERB_ANY
, 0, start_unit
},
7349 { "restart", 2, VERB_ANY
, 0, start_unit
},
7350 { "try-restart", 2, VERB_ANY
, 0, start_unit
},
7351 { "reload-or-restart", 2, VERB_ANY
, 0, start_unit
},
7352 { "reload-or-try-restart", 2, VERB_ANY
, 0, start_unit
},
7353 { "force-reload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with SysV */
7354 { "condreload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7355 { "condrestart", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with RH */
7356 { "isolate", 2, 2, 0, start_unit
},
7357 { "kill", 2, VERB_ANY
, 0, kill_unit
},
7358 { "is-active", 2, VERB_ANY
, 0, check_unit_active
},
7359 { "check", 2, VERB_ANY
, 0, check_unit_active
},
7360 { "is-failed", 2, VERB_ANY
, 0, check_unit_failed
},
7361 { "show", VERB_ANY
, VERB_ANY
, 0, show
},
7362 { "cat", 2, VERB_ANY
, 0, cat
},
7363 { "status", VERB_ANY
, VERB_ANY
, 0, show
},
7364 { "help", VERB_ANY
, VERB_ANY
, 0, show
},
7365 { "daemon-reload", VERB_ANY
, 1, 0, daemon_reload
},
7366 { "daemon-reexec", VERB_ANY
, 1, 0, daemon_reload
},
7367 { "show-environment", VERB_ANY
, 1, 0, show_environment
},
7368 { "set-environment", 2, VERB_ANY
, 0, set_environment
},
7369 { "unset-environment", 2, VERB_ANY
, 0, set_environment
},
7370 { "import-environment", VERB_ANY
, VERB_ANY
, 0, import_environment
},
7371 { "halt", VERB_ANY
, 1, 0, start_special
},
7372 { "poweroff", VERB_ANY
, 1, 0, start_special
},
7373 { "reboot", VERB_ANY
, 2, 0, start_special
},
7374 { "kexec", VERB_ANY
, 1, 0, start_special
},
7375 { "suspend", VERB_ANY
, 1, 0, start_special
},
7376 { "hibernate", VERB_ANY
, 1, 0, start_special
},
7377 { "hybrid-sleep", VERB_ANY
, 1, 0, start_special
},
7378 { "default", VERB_ANY
, 1, 0, start_special
},
7379 { "rescue", VERB_ANY
, 1, 0, start_special
},
7380 { "emergency", VERB_ANY
, 1, 0, start_special
},
7381 { "exit", VERB_ANY
, 2, 0, start_special
},
7382 { "reset-failed", VERB_ANY
, VERB_ANY
, 0, reset_failed
},
7383 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7384 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7385 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7386 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7387 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7388 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7389 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7390 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7391 { "link", 2, VERB_ANY
, 0, enable_unit
},
7392 { "switch-root", 2, VERB_ANY
, 0, switch_root
},
7393 { "list-dependencies", VERB_ANY
, 2, 0, list_dependencies
},
7394 { "set-default", 2, 2, 0, set_default
},
7395 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7396 { "set-property", 3, VERB_ANY
, 0, set_property
},
7397 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7398 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7399 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7400 { "edit", 2, VERB_ANY
, 0, edit
},
7404 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7407 static int reload_with_fallback(void) {
7409 /* First, try systemd via D-Bus. */
7410 if (daemon_reload(0, NULL
, NULL
) >= 0)
7413 /* Nothing else worked, so let's try signals */
7414 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7416 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7417 return log_error_errno(errno
, "kill() failed: %m");
7422 static int start_with_fallback(void) {
7424 /* First, try systemd via D-Bus. */
7425 if (start_unit(0, NULL
, NULL
) >= 0)
7428 /* Nothing else worked, so let's try
7430 if (talk_initctl() > 0)
7433 log_error("Failed to talk to init daemon.");
7437 static int halt_now(enum action a
) {
7439 /* The kernel will automaticall flush ATA disks and suchlike
7440 * on reboot(), but the file systems need to be synce'd
7441 * explicitly in advance. */
7444 /* Make sure C-A-D is handled by the kernel from this point
7446 (void) reboot(RB_ENABLE_CAD
);
7451 log_info("Halting.");
7452 (void) reboot(RB_HALT_SYSTEM
);
7455 case ACTION_POWEROFF
:
7456 log_info("Powering off.");
7457 (void) reboot(RB_POWER_OFF
);
7461 case ACTION_REBOOT
: {
7462 _cleanup_free_
char *param
= NULL
;
7464 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7465 log_info("Rebooting with argument '%s'.", param
);
7466 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7469 log_info("Rebooting.");
7470 (void) reboot(RB_AUTOBOOT
);
7475 assert_not_reached("Unknown action.");
7479 static int logind_schedule_shutdown(void) {
7482 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7483 char date
[FORMAT_TIMESTAMP_MAX
];
7488 (void) logind_set_wall_message();
7490 r
= acquire_bus(BUS_FULL
, &bus
);
7494 switch (arg_action
) {
7498 case ACTION_POWEROFF
:
7499 action
= "poweroff";
7514 action
= strjoina("dry-", action
);
7516 r
= sd_bus_call_method(
7518 "org.freedesktop.login1",
7519 "/org/freedesktop/login1",
7520 "org.freedesktop.login1.Manager",
7528 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7530 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7533 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7538 static int halt_main(void) {
7541 r
= logind_check_inhibitors(arg_action
);
7546 return logind_schedule_shutdown();
7548 if (geteuid() != 0) {
7549 if (arg_dry
|| arg_force
> 0) {
7550 log_error("Must be root.");
7554 /* Try logind if we are a normal user and no special
7555 * mode applies. Maybe PolicyKit allows us to shutdown
7557 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7558 r
= logind_reboot(arg_action
);
7561 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7562 /* requested operation is not
7563 * supported on the local system or
7564 * already in progress */
7566 /* on all other errors, try low-level operation */
7570 if (!arg_dry
&& !arg_force
)
7571 return start_with_fallback();
7573 assert(geteuid() == 0);
7576 if (sd_booted() > 0)
7577 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7579 r
= utmp_put_shutdown();
7581 log_warning_errno(r
, "Failed to write utmp record: %m");
7588 r
= halt_now(arg_action
);
7589 return log_error_errno(r
, "Failed to reboot: %m");
7592 static int runlevel_main(void) {
7593 int r
, runlevel
, previous
;
7595 r
= utmp_get_runlevel(&runlevel
, &previous
);
7602 previous
<= 0 ? 'N' : previous
,
7603 runlevel
<= 0 ? 'N' : runlevel
);
7608 static int logind_cancel_shutdown(void) {
7610 _cleanup_(sd_bus_error_free
) sd_bus_error error
= SD_BUS_ERROR_NULL
;
7614 r
= acquire_bus(BUS_FULL
, &bus
);
7618 (void) logind_set_wall_message();
7620 r
= sd_bus_call_method(
7622 "org.freedesktop.login1",
7623 "/org/freedesktop/login1",
7624 "org.freedesktop.login1.Manager",
7625 "CancelScheduledShutdown",
7629 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7633 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7638 int main(int argc
, char*argv
[]) {
7641 setlocale(LC_ALL
, "");
7642 log_parse_environment();
7645 /* Explicitly not on_tty() to avoid setting cached value.
7646 * This becomes relevant for piping output which might be
7648 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7650 r
= parse_argv(argc
, argv
);
7654 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7655 log_info("Running in chroot, ignoring request.");
7660 /* systemctl_main() will print an error message for the bus
7661 * connection, but only if it needs to */
7663 switch (arg_action
) {
7665 case ACTION_SYSTEMCTL
:
7666 r
= systemctl_main(argc
, argv
);
7670 case ACTION_POWEROFF
:
7676 case ACTION_RUNLEVEL2
:
7677 case ACTION_RUNLEVEL3
:
7678 case ACTION_RUNLEVEL4
:
7679 case ACTION_RUNLEVEL5
:
7681 case ACTION_EMERGENCY
:
7682 case ACTION_DEFAULT
:
7683 r
= start_with_fallback();
7688 r
= reload_with_fallback();
7691 case ACTION_CANCEL_SHUTDOWN
:
7692 r
= logind_cancel_shutdown();
7695 case ACTION_RUNLEVEL
:
7696 r
= runlevel_main();
7699 case _ACTION_INVALID
:
7701 assert_not_reached("Unknown action");
7706 ask_password_agent_close();
7707 polkit_agent_close();
7709 strv_free(arg_types
);
7710 strv_free(arg_states
);
7711 strv_free(arg_properties
);
7713 strv_free(arg_wall
);
7718 /* Note that we return r here, not EXIT_SUCCESS, so that we can implement the LSB-like return codes */
7720 return r
< 0 ? EXIT_FAILURE
: r
;