1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
7 Copyright 2013 Marc-Antoine Perennou
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
26 #include <linux/reboot.h>
32 #include <sys/reboot.h>
33 #include <sys/socket.h>
37 #include "sd-daemon.h"
40 #include "bus-common-errors.h"
41 #include "bus-error.h"
42 #include "bus-message.h"
44 #include "cgroup-show.h"
45 #include "cgroup-util.h"
50 #include "exit-status.h"
53 #include "formats-util.h"
54 #include "hostname-util.h"
60 #include "logs-show.h"
64 #include "parse-util.h"
65 #include "path-lookup.h"
66 #include "path-util.h"
67 #include "process-util.h"
69 #include "signal-util.h"
70 #include "socket-util.h"
71 #include "spawn-ask-password-agent.h"
72 #include "spawn-polkit-agent.h"
75 #include "terminal-util.h"
76 #include "unit-name.h"
77 #include "user-util.h"
79 #include "utmp-wtmp.h"
82 static char **arg_types
= NULL
;
83 static char **arg_states
= NULL
;
84 static char **arg_properties
= NULL
;
85 static bool arg_all
= false;
86 static enum dependency
{
92 } arg_dependency
= DEPENDENCY_FORWARD
;
93 static const char *arg_job_mode
= "replace";
94 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
95 static bool arg_no_block
= false;
96 static bool arg_no_legend
= false;
97 static bool arg_no_pager
= false;
98 static bool arg_no_wtmp
= false;
99 static bool arg_no_wall
= false;
100 static bool arg_no_reload
= false;
101 static bool arg_show_types
= false;
102 static bool arg_ignore_inhibitors
= false;
103 static bool arg_dry
= false;
104 static bool arg_quiet
= false;
105 static bool arg_full
= false;
106 static bool arg_recursive
= false;
107 static int arg_force
= 0;
108 static bool arg_ask_password
= false;
109 static bool arg_runtime
= false;
110 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
111 static char **arg_wall
= NULL
;
112 static const char *arg_kill_who
= NULL
;
113 static int arg_signal
= SIGTERM
;
114 static char *arg_root
= NULL
;
115 static usec_t arg_when
= 0;
137 ACTION_CANCEL_SHUTDOWN
,
139 } arg_action
= ACTION_SYSTEMCTL
;
140 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
141 static const char *arg_host
= NULL
;
142 static unsigned arg_lines
= 10;
143 static OutputMode arg_output
= OUTPUT_SHORT
;
144 static bool arg_plain
= false;
145 static bool arg_firmware_setup
= false;
146 static bool arg_now
= false;
148 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
149 static int halt_now(enum action a
);
150 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
152 static bool original_stdout_is_tty
;
154 typedef enum BusFocus
{
155 BUS_FULL
, /* The full bus indicated via --system or --user */
156 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
160 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
162 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
165 assert(focus
< _BUS_FOCUS_MAX
);
168 /* We only go directly to the manager, if we are using a local transport */
169 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
172 if (!busses
[focus
]) {
175 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
177 if (focus
== BUS_MANAGER
)
178 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
180 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
182 return log_error_errno(r
, "Failed to connect to bus: %m");
184 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
187 *ret
= busses
[focus
];
191 static void release_busses(void) {
194 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
195 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
198 static void pager_open_if_enabled(void) {
206 static void ask_password_agent_open_if_enabled(void) {
208 /* Open the password agent as a child process if necessary */
210 if (!arg_ask_password
)
213 if (arg_scope
!= UNIT_FILE_SYSTEM
)
216 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
219 ask_password_agent_open();
222 static void polkit_agent_open_if_enabled(void) {
224 /* Open the polkit agent as a child process if necessary */
226 if (!arg_ask_password
)
229 if (arg_scope
!= UNIT_FILE_SYSTEM
)
232 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
238 static OutputFlags
get_output_flags(void) {
240 arg_all
* OUTPUT_SHOW_ALL
|
241 arg_full
* OUTPUT_FULL_WIDTH
|
242 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
243 on_tty() * OUTPUT_COLOR
|
244 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
247 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
250 if (!sd_bus_error_is_set(error
))
253 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
254 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
255 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
256 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
257 return EXIT_NOPERMISSION
;
259 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
260 return EXIT_NOTINSTALLED
;
262 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
263 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
264 return EXIT_NOTIMPLEMENTED
;
266 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
267 return EXIT_NOTCONFIGURED
;
275 static bool install_client_side(void) {
277 /* Decides when to execute enable/disable/... operations
278 * client-side rather than server-side. */
280 if (running_in_chroot() > 0)
283 if (sd_booted() <= 0)
286 if (!isempty(arg_root
))
289 if (arg_scope
== UNIT_FILE_GLOBAL
)
295 static int compare_unit_info(const void *a
, const void *b
) {
296 const UnitInfo
*u
= a
, *v
= b
;
300 /* First, order by machine */
301 if (!u
->machine
&& v
->machine
)
303 if (u
->machine
&& !v
->machine
)
305 if (u
->machine
&& v
->machine
) {
306 r
= strcasecmp(u
->machine
, v
->machine
);
311 /* Second, order by unit type */
312 d1
= strrchr(u
->id
, '.');
313 d2
= strrchr(v
->id
, '.');
315 r
= strcasecmp(d1
, d2
);
320 /* Third, order by name */
321 return strcasecmp(u
->id
, v
->id
);
324 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
325 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
331 dot
= strrchr(u
->id
, '.');
335 if (!strv_find(arg_types
, dot
+1))
345 if (streq(u
->active_state
, "inactive") || u
->following
[0])
351 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
352 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
354 unsigned n_shown
= 0;
357 max_id_len
= strlen("UNIT");
358 load_len
= strlen("LOAD");
359 active_len
= strlen("ACTIVE");
360 sub_len
= strlen("SUB");
361 job_len
= strlen("JOB");
364 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
365 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
366 load_len
= MAX(load_len
, strlen(u
->load_state
));
367 active_len
= MAX(active_len
, strlen(u
->active_state
));
368 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
370 if (u
->job_id
!= 0) {
371 job_len
= MAX(job_len
, strlen(u
->job_type
));
375 if (!arg_no_legend
&&
376 (streq(u
->active_state
, "failed") ||
377 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
381 if (!arg_full
&& original_stdout_is_tty
) {
384 id_len
= MIN(max_id_len
, 25u);
385 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
388 basic_len
+= job_len
+ 1;
390 if (basic_len
< (unsigned) columns()) {
391 unsigned extra_len
, incr
;
392 extra_len
= columns() - basic_len
;
394 /* Either UNIT already got 25, or is fully satisfied.
395 * Grant up to 25 to DESC now. */
396 incr
= MIN(extra_len
, 25u);
400 /* split the remaining space between UNIT and DESC,
401 * but do not give UNIT more than it needs. */
403 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
405 desc_len
+= extra_len
- incr
;
411 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
412 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
413 const char *on_loaded
= "", *off_loaded
= "";
414 const char *on_active
= "", *off_active
= "";
415 const char *on_circle
= "", *off_circle
= "";
419 if (!n_shown
&& !arg_no_legend
) {
424 printf("%-*s %-*s %-*s %-*s ",
427 active_len
, "ACTIVE",
431 printf("%-*s ", job_len
, "JOB");
433 if (!arg_full
&& arg_no_pager
)
434 printf("%.*s\n", desc_len
, "DESCRIPTION");
436 printf("%s\n", "DESCRIPTION");
441 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
442 on_loaded
= ansi_highlight_red();
443 on_circle
= ansi_highlight_yellow();
444 off_loaded
= off_circle
= ansi_normal();
446 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
447 on_circle
= on_active
= ansi_highlight_red();
448 off_circle
= off_active
= ansi_normal();
453 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
462 e
= ellipsize(id
, id_len
, 33);
470 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
472 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
473 on_active
, id_len
, id
, off_active
,
474 on_loaded
, load_len
, u
->load_state
, off_loaded
,
475 on_active
, active_len
, u
->active_state
,
476 sub_len
, u
->sub_state
, off_active
,
477 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
480 printf("%.*s\n", desc_len
, u
->description
);
482 printf("%s\n", u
->description
);
485 if (!arg_no_legend
) {
486 const char *on
, *off
;
490 "LOAD = Reflects whether the unit definition was properly loaded.\n"
491 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
492 "SUB = The low-level unit activation state, values depend on unit type.");
493 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
494 on
= ansi_highlight();
497 on
= ansi_highlight_red();
502 printf("%s%u loaded units listed.%s\n"
503 "To show all installed unit files use 'systemctl list-unit-files'.\n",
506 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
507 "To show all installed unit files use 'systemctl list-unit-files'.\n",
514 static int get_unit_list(
518 UnitInfo
**unit_infos
,
520 sd_bus_message
**_reply
) {
522 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
523 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
524 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
533 r
= sd_bus_message_new_method_call(
536 "org.freedesktop.systemd1",
537 "/org/freedesktop/systemd1",
538 "org.freedesktop.systemd1.Manager",
539 "ListUnitsFiltered");
542 return bus_log_create_error(r
);
544 r
= sd_bus_message_append_strv(m
, arg_states
);
546 return bus_log_create_error(r
);
548 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
550 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
552 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
554 return bus_log_parse_error(r
);
556 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
559 if (!output_show_unit(&u
, patterns
))
562 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
565 (*unit_infos
)[c
++] = u
;
568 return bus_log_parse_error(r
);
570 r
= sd_bus_message_exit_container(reply
);
572 return bus_log_parse_error(r
);
580 static void message_set_freep(Set
**set
) {
583 while ((m
= set_steal_first(*set
)))
584 sd_bus_message_unref(m
);
589 static int get_unit_list_recursive(
592 UnitInfo
**_unit_infos
,
596 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
597 _cleanup_(message_set_freep
) Set
*replies
;
598 sd_bus_message
*reply
;
606 replies
= set_new(NULL
);
610 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
614 r
= set_put(replies
, reply
);
616 sd_bus_message_unref(reply
);
621 _cleanup_strv_free_
char **machines
= NULL
;
624 r
= sd_get_machine_names(&machines
);
626 return log_error_errno(r
, "Failed to get machine names: %m");
628 STRV_FOREACH(i
, machines
) {
629 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
632 r
= sd_bus_open_system_machine(&container
, *i
);
634 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
638 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
644 r
= set_put(replies
, reply
);
646 sd_bus_message_unref(reply
);
651 *_machines
= machines
;
656 *_unit_infos
= unit_infos
;
665 static int list_units(int argc
, char *argv
[], void *userdata
) {
666 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
667 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
668 _cleanup_strv_free_
char **machines
= NULL
;
672 pager_open_if_enabled();
674 r
= acquire_bus(BUS_MANAGER
, &bus
);
678 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
682 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
683 return output_units_list(unit_infos
, r
);
686 static int get_triggered_units(
691 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
698 r
= sd_bus_get_property_strv(
700 "org.freedesktop.systemd1",
702 "org.freedesktop.systemd1.Unit",
707 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
712 static int get_listening(
714 const char* unit_path
,
717 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
718 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
719 const char *type
, *path
;
722 r
= sd_bus_get_property(
724 "org.freedesktop.systemd1",
726 "org.freedesktop.systemd1.Socket",
732 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
734 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
736 return bus_log_parse_error(r
);
738 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
740 r
= strv_extend(listening
, type
);
744 r
= strv_extend(listening
, path
);
751 return bus_log_parse_error(r
);
753 r
= sd_bus_message_exit_container(reply
);
755 return bus_log_parse_error(r
);
767 /* Note: triggered is a list here, although it almost certainly
768 * will always be one unit. Nevertheless, dbus API allows for multiple
769 * values, so let's follow that. */
772 /* The strv above is shared. free is set only in the first one. */
776 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
782 if (!a
->machine
&& b
->machine
)
784 if (a
->machine
&& !b
->machine
)
786 if (a
->machine
&& b
->machine
) {
787 o
= strcasecmp(a
->machine
, b
->machine
);
792 o
= strcmp(a
->path
, b
->path
);
794 o
= strcmp(a
->type
, b
->type
);
799 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
800 struct socket_info
*s
;
801 unsigned pathlen
= strlen("LISTEN"),
802 typelen
= strlen("TYPE") * arg_show_types
,
803 socklen
= strlen("UNIT"),
804 servlen
= strlen("ACTIVATES");
805 const char *on
, *off
;
807 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
811 socklen
= MAX(socklen
, strlen(s
->id
));
813 typelen
= MAX(typelen
, strlen(s
->type
));
814 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
816 STRV_FOREACH(a
, s
->triggered
)
817 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
818 servlen
= MAX(servlen
, tmp
);
823 printf("%-*s %-*.*s%-*s %s\n",
825 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
829 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
830 _cleanup_free_
char *j
= NULL
;
835 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
843 printf("%-*s %-*s %-*s",
844 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
847 pathlen
, path
, socklen
, s
->id
);
848 STRV_FOREACH(a
, s
->triggered
)
850 a
== s
->triggered
? "" : ",", *a
);
854 on
= ansi_highlight();
859 on
= ansi_highlight_red();
863 if (!arg_no_legend
) {
864 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
866 printf("Pass --all to see loaded but inactive sockets, too.\n");
872 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
873 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
874 _cleanup_strv_free_
char **machines
= NULL
;
875 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
876 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
878 struct socket_info
*s
;
884 pager_open_if_enabled();
886 r
= acquire_bus(BUS_MANAGER
, &bus
);
890 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
894 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
895 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
898 if (!endswith(u
->id
, ".socket"))
901 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
905 c
= get_listening(bus
, u
->unit_path
, &listening
);
911 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
916 for (i
= 0; i
< c
; i
++)
917 socket_infos
[cs
+ i
] = (struct socket_info
) {
918 .machine
= u
->machine
,
920 .type
= listening
[i
*2],
921 .path
= listening
[i
*2 + 1],
922 .triggered
= triggered
,
923 .own_triggered
= i
==0,
926 /* from this point on we will cleanup those socket_infos */
929 listening
= triggered
= NULL
; /* avoid cleanup */
932 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
933 (__compar_fn_t
) socket_info_compare
);
935 output_sockets_list(socket_infos
, cs
);
938 assert(cs
== 0 || socket_infos
);
939 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
942 if (s
->own_triggered
)
943 strv_free(s
->triggered
);
949 static int get_next_elapse(
952 dual_timestamp
*next
) {
954 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
962 r
= sd_bus_get_property_trivial(
964 "org.freedesktop.systemd1",
966 "org.freedesktop.systemd1.Timer",
967 "NextElapseUSecMonotonic",
972 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
974 r
= sd_bus_get_property_trivial(
976 "org.freedesktop.systemd1",
978 "org.freedesktop.systemd1.Timer",
979 "NextElapseUSecRealtime",
984 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
990 static int get_last_trigger(
995 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1002 r
= sd_bus_get_property_trivial(
1004 "org.freedesktop.systemd1",
1006 "org.freedesktop.systemd1.Timer",
1012 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1018 const char* machine
;
1021 usec_t last_trigger
;
1025 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1031 if (!a
->machine
&& b
->machine
)
1033 if (a
->machine
&& !b
->machine
)
1035 if (a
->machine
&& b
->machine
) {
1036 o
= strcasecmp(a
->machine
, b
->machine
);
1041 if (a
->next_elapse
< b
->next_elapse
)
1043 if (a
->next_elapse
> b
->next_elapse
)
1046 return strcmp(a
->id
, b
->id
);
1049 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1050 struct timer_info
*t
;
1052 nextlen
= strlen("NEXT"),
1053 leftlen
= strlen("LEFT"),
1054 lastlen
= strlen("LAST"),
1055 passedlen
= strlen("PASSED"),
1056 unitlen
= strlen("UNIT"),
1057 activatelen
= strlen("ACTIVATES");
1059 const char *on
, *off
;
1061 assert(timer_infos
|| n
== 0);
1063 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1067 if (t
->next_elapse
> 0) {
1068 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1070 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1071 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1073 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1074 leftlen
= MAX(leftlen
, strlen(trel
));
1077 if (t
->last_trigger
> 0) {
1078 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1080 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1081 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1083 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1084 passedlen
= MAX(passedlen
, strlen(trel
));
1087 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1089 STRV_FOREACH(a
, t
->triggered
)
1090 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1092 activatelen
= MAX(activatelen
, ul
);
1097 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1101 passedlen
, "PASSED",
1105 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1106 _cleanup_free_
char *j
= NULL
;
1108 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1109 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1112 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1113 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1115 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1116 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1119 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1126 printf("%-*s %-*s %-*s %-*s %-*s",
1127 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1129 STRV_FOREACH(a
, t
->triggered
)
1131 a
== t
->triggered
? "" : ",", *a
);
1135 on
= ansi_highlight();
1136 off
= ansi_normal();
1140 on
= ansi_highlight_red();
1141 off
= ansi_normal();
1144 if (!arg_no_legend
) {
1145 printf("%s%u timers listed.%s\n", on
, n
, off
);
1147 printf("Pass --all to see loaded but inactive timers, too.\n");
1153 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1159 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1162 if (next
->monotonic
> nw
->monotonic
)
1163 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1165 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1167 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1168 next_elapse
= MIN(converted
, next
->realtime
);
1170 next_elapse
= converted
;
1173 next_elapse
= next
->realtime
;
1178 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1179 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1180 _cleanup_strv_free_
char **machines
= NULL
;
1181 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1182 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1183 struct timer_info
*t
;
1191 pager_open_if_enabled();
1193 r
= acquire_bus(BUS_MANAGER
, &bus
);
1197 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1201 dual_timestamp_get(&nw
);
1203 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1204 _cleanup_strv_free_
char **triggered
= NULL
;
1205 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1208 if (!endswith(u
->id
, ".timer"))
1211 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1215 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1219 get_last_trigger(bus
, u
->unit_path
, &last
);
1221 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1226 m
= calc_next_elapse(&nw
, &next
);
1228 timer_infos
[c
++] = (struct timer_info
) {
1229 .machine
= u
->machine
,
1232 .last_trigger
= last
,
1233 .triggered
= triggered
,
1236 triggered
= NULL
; /* avoid cleanup */
1239 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1240 (__compar_fn_t
) timer_info_compare
);
1242 output_timers_list(timer_infos
, c
);
1245 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1246 strv_free(t
->triggered
);
1251 static int compare_unit_file_list(const void *a
, const void *b
) {
1252 const char *d1
, *d2
;
1253 const UnitFileList
*u
= a
, *v
= b
;
1255 d1
= strrchr(u
->path
, '.');
1256 d2
= strrchr(v
->path
, '.');
1261 r
= strcasecmp(d1
, d2
);
1266 return strcasecmp(basename(u
->path
), basename(v
->path
));
1269 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1270 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1273 if (!strv_isempty(arg_types
)) {
1276 dot
= strrchr(u
->path
, '.');
1280 if (!strv_find(arg_types
, dot
+1))
1284 if (!strv_isempty(arg_states
) &&
1285 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1291 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1292 unsigned max_id_len
, id_cols
, state_cols
;
1293 const UnitFileList
*u
;
1295 max_id_len
= strlen("UNIT FILE");
1296 state_cols
= strlen("STATE");
1298 for (u
= units
; u
< units
+ c
; u
++) {
1299 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1300 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1304 unsigned basic_cols
;
1306 id_cols
= MIN(max_id_len
, 25u);
1307 basic_cols
= 1 + id_cols
+ state_cols
;
1308 if (basic_cols
< (unsigned) columns())
1309 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1311 id_cols
= max_id_len
;
1314 printf("%-*s %-*s\n",
1315 id_cols
, "UNIT FILE",
1316 state_cols
, "STATE");
1318 for (u
= units
; u
< units
+ c
; u
++) {
1319 _cleanup_free_
char *e
= NULL
;
1320 const char *on
, *off
;
1323 if (IN_SET(u
->state
,
1325 UNIT_FILE_MASKED_RUNTIME
,
1327 UNIT_FILE_INVALID
)) {
1328 on
= ansi_highlight_red();
1329 off
= ansi_normal();
1330 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1331 on
= ansi_highlight_green();
1332 off
= ansi_normal();
1336 id
= basename(u
->path
);
1338 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1340 printf("%-*s %s%-*s%s\n",
1341 id_cols
, e
? e
: id
,
1342 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1346 printf("\n%u unit files listed.\n", c
);
1349 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1350 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1351 _cleanup_free_ UnitFileList
*units
= NULL
;
1359 pager_open_if_enabled();
1361 if (install_client_side()) {
1367 h
= hashmap_new(&string_hash_ops
);
1371 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1373 unit_file_list_free(h
);
1374 return log_error_errno(r
, "Failed to get unit file list: %m");
1377 n_units
= hashmap_size(h
);
1379 units
= new(UnitFileList
, n_units
);
1380 if (!units
&& n_units
> 0) {
1381 unit_file_list_free(h
);
1385 HASHMAP_FOREACH(u
, h
, i
) {
1386 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1393 assert(c
<= n_units
);
1396 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1399 r
= acquire_bus(BUS_MANAGER
, &bus
);
1403 r
= sd_bus_call_method(
1405 "org.freedesktop.systemd1",
1406 "/org/freedesktop/systemd1",
1407 "org.freedesktop.systemd1.Manager",
1413 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1415 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1417 return bus_log_parse_error(r
);
1419 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1421 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1424 units
[c
] = (struct UnitFileList
) {
1426 unit_file_state_from_string(state
)
1429 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1434 return bus_log_parse_error(r
);
1436 r
= sd_bus_message_exit_container(reply
);
1438 return bus_log_parse_error(r
);
1441 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1442 output_unit_file_list(units
, c
);
1444 if (install_client_side()) {
1445 for (unit
= units
; unit
< units
+ c
; unit
++)
1452 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1453 _cleanup_free_
char *n
= NULL
;
1454 size_t max_len
= MAX(columns(),20u);
1460 for (i
= level
- 1; i
>= 0; i
--) {
1462 if (len
> max_len
- 3 && !arg_full
) {
1463 printf("%s...\n",max_len
% 2 ? "" : " ");
1466 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1470 if (len
> max_len
- 3 && !arg_full
) {
1471 printf("%s...\n",max_len
% 2 ? "" : " ");
1475 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1479 printf("%s\n", name
);
1483 n
= ellipsize(name
, max_len
-len
, 100);
1491 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1493 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1494 [DEPENDENCY_FORWARD
] = "Requires\0"
1495 "RequiresOverridable\0"
1497 "RequisiteOverridable\0"
1501 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1502 "RequiredByOverridable\0"
1504 "RequisiteOfOverridable\0"
1508 [DEPENDENCY_AFTER
] = "After\0",
1509 [DEPENDENCY_BEFORE
] = "Before\0",
1512 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1513 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1514 _cleanup_strv_free_
char **ret
= NULL
;
1515 _cleanup_free_
char *path
= NULL
;
1521 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1523 path
= unit_dbus_path_from_name(name
);
1527 r
= sd_bus_call_method(
1529 "org.freedesktop.systemd1",
1531 "org.freedesktop.DBus.Properties",
1535 "s", "org.freedesktop.systemd1.Unit");
1537 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1539 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1541 return bus_log_parse_error(r
);
1543 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1546 r
= sd_bus_message_read(reply
, "s", &prop
);
1548 return bus_log_parse_error(r
);
1550 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1551 r
= sd_bus_message_skip(reply
, "v");
1553 return bus_log_parse_error(r
);
1556 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1558 return bus_log_parse_error(r
);
1560 r
= bus_message_read_strv_extend(reply
, &ret
);
1562 return bus_log_parse_error(r
);
1564 r
= sd_bus_message_exit_container(reply
);
1566 return bus_log_parse_error(r
);
1569 r
= sd_bus_message_exit_container(reply
);
1571 return bus_log_parse_error(r
);
1575 return bus_log_parse_error(r
);
1577 r
= sd_bus_message_exit_container(reply
);
1579 return bus_log_parse_error(r
);
1587 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1588 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1590 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1592 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1595 return strcasecmp(*a
, *b
);
1598 static int list_dependencies_one(
1603 unsigned int branches
) {
1605 _cleanup_strv_free_
char **deps
= NULL
;
1613 r
= strv_extend(units
, name
);
1617 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1621 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1623 STRV_FOREACH(c
, deps
) {
1624 if (strv_contains(*units
, *c
)) {
1626 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1639 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1640 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1641 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1644 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1648 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1649 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1656 strv_remove(*units
, name
);
1661 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1662 _cleanup_strv_free_
char **units
= NULL
;
1663 _cleanup_free_
char *unit
= NULL
;
1669 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1671 return log_error_errno(r
, "Failed to mangle unit name: %m");
1675 u
= SPECIAL_DEFAULT_TARGET
;
1677 pager_open_if_enabled();
1679 r
= acquire_bus(BUS_MANAGER
, &bus
);
1685 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1688 struct machine_info
{
1692 char *control_group
;
1693 uint32_t n_failed_units
;
1698 static const struct bus_properties_map machine_info_property_map
[] = {
1699 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1700 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1701 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1702 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1703 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1707 static void machine_info_clear(struct machine_info
*info
) {
1711 free(info
->control_group
);
1716 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1722 for (i
= 0; i
< n
; i
++)
1723 machine_info_clear(&machine_infos
[i
]);
1725 free(machine_infos
);
1728 static int compare_machine_info(const void *a
, const void *b
) {
1729 const struct machine_info
*u
= a
, *v
= b
;
1731 if (u
->is_host
!= v
->is_host
)
1732 return u
->is_host
> v
->is_host
? -1 : 1;
1734 return strcasecmp(u
->name
, v
->name
);
1737 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1738 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1744 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1751 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1758 static bool output_show_machine(const char *name
, char **patterns
) {
1759 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1762 static int get_machine_list(
1764 struct machine_info
**_machine_infos
,
1767 struct machine_info
*machine_infos
= NULL
;
1768 _cleanup_strv_free_
char **m
= NULL
;
1769 _cleanup_free_
char *hn
= NULL
;
1774 hn
= gethostname_malloc();
1778 if (output_show_machine(hn
, patterns
)) {
1779 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1782 machine_infos
[c
].is_host
= true;
1783 machine_infos
[c
].name
= hn
;
1786 get_machine_properties(bus
, &machine_infos
[c
]);
1790 r
= sd_get_machine_names(&m
);
1792 return log_error_errno(r
, "Failed to get machine list: %m");
1794 STRV_FOREACH(i
, m
) {
1795 _cleanup_free_
char *class = NULL
;
1797 if (!output_show_machine(*i
, patterns
))
1800 sd_machine_get_class(*i
, &class);
1801 if (!streq_ptr(class, "container"))
1804 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1805 free_machines_list(machine_infos
, c
);
1809 machine_infos
[c
].is_host
= false;
1810 machine_infos
[c
].name
= strdup(*i
);
1811 if (!machine_infos
[c
].name
) {
1812 free_machines_list(machine_infos
, c
);
1816 get_machine_properties(NULL
, &machine_infos
[c
]);
1820 *_machine_infos
= machine_infos
;
1824 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1825 struct machine_info
*m
;
1828 namelen
= sizeof("NAME") - 1,
1829 statelen
= sizeof("STATE") - 1,
1830 failedlen
= sizeof("FAILED") - 1,
1831 jobslen
= sizeof("JOBS") - 1;
1833 assert(machine_infos
|| n
== 0);
1835 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1836 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1837 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1838 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1839 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1841 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1845 if (!arg_no_legend
) {
1849 printf("%-*s %-*s %-*s %-*s\n",
1852 failedlen
, "FAILED",
1856 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1857 const char *on_state
= "", *off_state
= "";
1858 const char *on_failed
= "", *off_failed
= "";
1859 bool circle
= false;
1861 if (streq_ptr(m
->state
, "degraded")) {
1862 on_state
= ansi_highlight_red();
1863 off_state
= ansi_normal();
1865 } else if (!streq_ptr(m
->state
, "running")) {
1866 on_state
= ansi_highlight_yellow();
1867 off_state
= ansi_normal();
1871 if (m
->n_failed_units
> 0) {
1872 on_failed
= ansi_highlight_red();
1873 off_failed
= ansi_normal();
1875 on_failed
= off_failed
= "";
1878 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1881 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1882 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1883 on_state
, statelen
, strna(m
->state
), off_state
,
1884 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1885 jobslen
, m
->n_jobs
);
1887 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1888 namelen
, strna(m
->name
),
1889 on_state
, statelen
, strna(m
->state
), off_state
,
1890 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1891 jobslen
, m
->n_jobs
);
1895 printf("\n%u machines listed.\n", n
);
1898 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1899 struct machine_info
*machine_infos
= NULL
;
1903 if (geteuid() != 0) {
1904 log_error("Must be root.");
1908 pager_open_if_enabled();
1910 r
= acquire_bus(BUS_MANAGER
, &bus
);
1914 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1918 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1919 output_machines_list(machine_infos
, r
);
1920 free_machines_list(machine_infos
, r
);
1925 static int get_default(int argc
, char *argv
[], void *userdata
) {
1926 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1927 _cleanup_free_
char *_path
= NULL
;
1931 if (install_client_side()) {
1932 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1934 return log_error_errno(r
, "Failed to get default target: %m");
1938 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1941 r
= acquire_bus(BUS_MANAGER
, &bus
);
1945 r
= sd_bus_call_method(
1947 "org.freedesktop.systemd1",
1948 "/org/freedesktop/systemd1",
1949 "org.freedesktop.systemd1.Manager",
1955 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1957 r
= sd_bus_message_read(reply
, "s", &path
);
1959 return bus_log_parse_error(r
);
1963 printf("%s\n", path
);
1968 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1971 assert(changes
|| n_changes
== 0);
1973 for (i
= 0; i
< n_changes
; i
++) {
1974 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1975 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1977 log_info("Removed symlink %s.", changes
[i
].path
);
1981 static int set_default(int argc
, char *argv
[], void *userdata
) {
1982 _cleanup_free_
char *unit
= NULL
;
1988 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1990 return log_error_errno(r
, "Failed to mangle unit name: %m");
1992 if (install_client_side()) {
1993 UnitFileChange
*changes
= NULL
;
1994 unsigned n_changes
= 0;
1996 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1998 return log_error_errno(r
, "Failed to set default target: %m");
2001 dump_unit_file_changes(changes
, n_changes
);
2003 unit_file_changes_free(changes
, n_changes
);
2006 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2007 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2010 polkit_agent_open_if_enabled();
2012 r
= acquire_bus(BUS_MANAGER
, &bus
);
2016 r
= sd_bus_call_method(
2018 "org.freedesktop.systemd1",
2019 "/org/freedesktop/systemd1",
2020 "org.freedesktop.systemd1.Manager",
2026 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2028 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2032 /* Try to reload if enabled */
2034 r
= daemon_reload(argc
, argv
, userdata
);
2044 const char *name
, *type
, *state
;
2047 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2048 unsigned id_len
, unit_len
, type_len
, state_len
;
2049 const struct job_info
*j
;
2050 const char *on
, *off
;
2051 bool shorten
= false;
2053 assert(n
== 0 || jobs
);
2056 if (!arg_no_legend
) {
2057 on
= ansi_highlight_green();
2058 off
= ansi_normal();
2060 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2065 pager_open_if_enabled();
2067 id_len
= strlen("JOB");
2068 unit_len
= strlen("UNIT");
2069 type_len
= strlen("TYPE");
2070 state_len
= strlen("STATE");
2072 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2073 uint32_t id
= j
->id
;
2074 assert(j
->name
&& j
->type
&& j
->state
);
2076 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2077 unit_len
= MAX(unit_len
, strlen(j
->name
));
2078 type_len
= MAX(type_len
, strlen(j
->type
));
2079 state_len
= MAX(state_len
, strlen(j
->state
));
2082 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2083 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2088 printf("%*s %-*s %-*s %-*s\n",
2092 state_len
, "STATE");
2094 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2095 _cleanup_free_
char *e
= NULL
;
2097 if (streq(j
->state
, "running")) {
2098 on
= ansi_highlight();
2099 off
= ansi_normal();
2103 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2104 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2106 on
, unit_len
, e
? e
: j
->name
, off
,
2108 on
, state_len
, j
->state
, off
);
2111 if (!arg_no_legend
) {
2112 on
= ansi_highlight();
2113 off
= ansi_normal();
2115 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2119 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2120 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2123 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2124 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2125 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2126 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2127 _cleanup_free_
struct job_info
*jobs
= NULL
;
2133 bool skipped
= false;
2135 pager_open_if_enabled();
2137 r
= acquire_bus(BUS_MANAGER
, &bus
);
2141 r
= sd_bus_call_method(
2143 "org.freedesktop.systemd1",
2144 "/org/freedesktop/systemd1",
2145 "org.freedesktop.systemd1.Manager",
2151 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2153 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2155 return bus_log_parse_error(r
);
2157 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2158 struct job_info job
= { id
, name
, type
, state
};
2160 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2165 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2171 return bus_log_parse_error(r
);
2173 r
= sd_bus_message_exit_container(reply
);
2175 return bus_log_parse_error(r
);
2177 output_jobs_list(jobs
, c
, skipped
);
2181 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2187 return daemon_reload(argc
, argv
, userdata
);
2189 polkit_agent_open_if_enabled();
2191 r
= acquire_bus(BUS_MANAGER
, &bus
);
2195 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2196 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2200 q
= safe_atou32(*name
, &id
);
2202 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2204 q
= sd_bus_call_method(
2206 "org.freedesktop.systemd1",
2207 "/org/freedesktop/systemd1",
2208 "org.freedesktop.systemd1.Manager",
2214 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2223 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2224 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2228 /* We ignore all errors here, since this is used to show a
2231 /* We don't use unit_dbus_path_from_name() directly since we
2232 * don't want to load the unit if it isn't loaded. */
2234 r
= sd_bus_call_method(
2236 "org.freedesktop.systemd1",
2237 "/org/freedesktop/systemd1",
2238 "org.freedesktop.systemd1.Manager",
2246 r
= sd_bus_message_read(reply
, "o", &path
);
2250 r
= sd_bus_get_property_trivial(
2252 "org.freedesktop.systemd1",
2254 "org.freedesktop.systemd1.Unit",
2264 static void warn_unit_file_changed(const char *name
) {
2265 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2266 ansi_highlight_red(),
2269 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2272 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2279 STRV_FOREACH(p
, lp
->unit_path
) {
2280 _cleanup_free_
char *path
;
2282 path
= path_join(arg_root
, *p
, unit_name
);
2286 if (access(path
, F_OK
) == 0) {
2296 static int unit_find_paths(
2298 const char *unit_name
,
2300 char **fragment_path
,
2301 char ***dropin_paths
) {
2303 _cleanup_free_
char *path
= NULL
;
2304 _cleanup_strv_free_
char **dropins
= NULL
;
2308 * Finds where the unit is defined on disk. Returns 0 if the unit
2309 * is not found. Returns 1 if it is found, and sets
2310 * - the path to the unit in *path, if it exists on disk,
2311 * - and a strv of existing drop-ins in *dropins,
2312 * if the arg is not NULL and any dropins were found.
2316 assert(fragment_path
);
2319 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2320 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2321 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2322 _cleanup_free_
char *unit
= NULL
;
2323 char *unit_load_error_name
, *unit_load_error_message
;
2325 unit
= unit_dbus_path_from_name(unit_name
);
2329 if (need_daemon_reload(bus
, unit_name
) > 0)
2330 warn_unit_file_changed(unit_name
);
2332 r
= sd_bus_get_property(
2334 "org.freedesktop.systemd1",
2336 "org.freedesktop.systemd1.Unit",
2342 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2344 r
= sd_bus_message_read(
2347 &unit_load_error_name
,
2348 &unit_load_error_message
);
2350 return bus_log_parse_error(r
);
2352 if (!isempty(unit_load_error_name
)) {
2353 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2357 r
= sd_bus_get_property_string(
2359 "org.freedesktop.systemd1",
2361 "org.freedesktop.systemd1.Unit",
2366 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2369 r
= sd_bus_get_property_strv(
2371 "org.freedesktop.systemd1",
2373 "org.freedesktop.systemd1.Unit",
2378 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2381 _cleanup_set_free_ Set
*names
;
2383 names
= set_new(NULL
);
2387 r
= set_put(names
, unit_name
);
2389 return log_error_errno(r
, "Failed to add unit name: %m");
2391 r
= unit_file_find_path(lp
, unit_name
, &path
);
2396 _cleanup_free_
char *template = NULL
;
2398 r
= unit_name_template(unit_name
, &template);
2399 if (r
< 0 && r
!= -EINVAL
)
2400 return log_error_errno(r
, "Failed to determine template name: %m");
2402 r
= unit_file_find_path(lp
, template, &path
);
2409 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2417 if (!isempty(path
)) {
2418 *fragment_path
= path
;
2423 if (dropin_paths
&& !strv_isempty(dropins
)) {
2424 *dropin_paths
= dropins
;
2430 log_error("No files found for %s.", unit_name
);
2435 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2436 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2437 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2443 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2445 return log_error_errno(r
, "Failed to mangle unit name: %m");
2447 /* We don't use unit_dbus_path_from_name() directly since we
2448 * don't want to load the unit if it isn't loaded. */
2450 r
= sd_bus_call_method(
2452 "org.freedesktop.systemd1",
2453 "/org/freedesktop/systemd1",
2454 "org.freedesktop.systemd1.Manager",
2465 r
= sd_bus_message_read(reply
, "o", &path
);
2467 return bus_log_parse_error(r
);
2469 r
= sd_bus_get_property_string(
2471 "org.freedesktop.systemd1",
2473 "org.freedesktop.systemd1.Unit",
2486 return nulstr_contains(good_states
, state
);
2489 static int check_triggering_units(
2493 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2494 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2495 _cleanup_strv_free_
char **triggered_by
= NULL
;
2496 bool print_warning_label
= true;
2500 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2502 return log_error_errno(r
, "Failed to mangle unit name: %m");
2504 path
= unit_dbus_path_from_name(n
);
2508 r
= sd_bus_get_property_string(
2510 "org.freedesktop.systemd1",
2512 "org.freedesktop.systemd1.Unit",
2517 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2519 if (streq(state
, "masked"))
2522 r
= sd_bus_get_property_strv(
2524 "org.freedesktop.systemd1",
2526 "org.freedesktop.systemd1.Unit",
2531 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2533 STRV_FOREACH(i
, triggered_by
) {
2534 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2536 return log_error_errno(r
, "Failed to check unit: %m");
2541 if (print_warning_label
) {
2542 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2543 print_warning_label
= false;
2546 log_warning(" %s", *i
);
2552 static const struct {
2555 } unit_actions
[] = {
2556 { "start", "StartUnit" },
2557 { "stop", "StopUnit" },
2558 { "condstop", "StopUnit" },
2559 { "reload", "ReloadUnit" },
2560 { "restart", "RestartUnit" },
2561 { "try-restart", "TryRestartUnit" },
2562 { "condrestart", "TryRestartUnit" },
2563 { "reload-or-restart", "ReloadOrRestartUnit" },
2564 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2565 { "condreload", "ReloadOrTryRestartUnit" },
2566 { "force-reload", "ReloadOrTryRestartUnit" }
2569 static const char *verb_to_method(const char *verb
) {
2572 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2573 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2574 return unit_actions
[i
].method
;
2579 static const char *method_to_verb(const char *method
) {
2582 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2583 if (streq_ptr(unit_actions
[i
].method
, method
))
2584 return unit_actions
[i
].verb
;
2589 static int start_unit_one(
2594 sd_bus_error
*error
,
2595 BusWaitForJobs
*w
) {
2597 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2606 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2608 r
= sd_bus_call_method(
2610 "org.freedesktop.systemd1",
2611 "/org/freedesktop/systemd1",
2612 "org.freedesktop.systemd1.Manager",
2620 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2621 /* There's always a fallback possible for
2622 * legacy actions. */
2623 return -EADDRNOTAVAIL
;
2625 verb
= method_to_verb(method
);
2627 return log_error_errno(r
, "Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2630 r
= sd_bus_message_read(reply
, "o", &path
);
2632 return bus_log_parse_error(r
);
2634 if (need_daemon_reload(bus
, name
) > 0)
2635 warn_unit_file_changed(name
);
2638 log_debug("Adding %s to the set", path
);
2639 r
= bus_wait_for_jobs_add(w
, path
);
2647 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2648 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2655 STRV_FOREACH(name
, names
) {
2659 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2661 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2663 return log_error_errno(r
, "Failed to mangle name: %m");
2665 if (string_is_glob(t
))
2666 r
= strv_consume(&globs
, t
);
2668 r
= strv_consume(&mangled
, t
);
2673 /* Query the manager only if any of the names are a glob, since
2674 * this is fairly expensive */
2675 if (!strv_isempty(globs
)) {
2676 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2677 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2679 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2683 for (i
= 0; i
< r
; i
++)
2684 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2689 mangled
= NULL
; /* do not free */
2694 static const struct {
2698 } action_table
[_ACTION_MAX
] = {
2699 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2700 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2701 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2702 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2703 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2704 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2705 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2706 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2707 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2708 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2709 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2710 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2711 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2712 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2713 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2716 static enum action
verb_to_action(const char *verb
) {
2719 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2720 if (streq_ptr(action_table
[i
].verb
, verb
))
2723 return _ACTION_INVALID
;
2726 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2727 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2728 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2729 _cleanup_strv_free_
char **names
= NULL
;
2734 ask_password_agent_open_if_enabled();
2735 polkit_agent_open_if_enabled();
2737 r
= acquire_bus(BUS_MANAGER
, &bus
);
2741 if (arg_action
== ACTION_SYSTEMCTL
) {
2744 method
= verb_to_method(argv
[0]);
2745 action
= verb_to_action(argv
[0]);
2747 if (streq(argv
[0], "isolate")) {
2751 mode
= action_table
[action
].mode
?: arg_job_mode
;
2753 one_name
= action_table
[action
].target
;
2755 assert(arg_action
< ELEMENTSOF(action_table
));
2756 assert(action_table
[arg_action
].target
);
2758 method
= "StartUnit";
2760 mode
= action_table
[arg_action
].mode
;
2761 one_name
= action_table
[arg_action
].target
;
2765 names
= strv_new(one_name
, NULL
);
2767 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2769 return log_error_errno(r
, "Failed to expand names: %m");
2772 if (!arg_no_block
) {
2773 r
= bus_wait_for_jobs_new(bus
, &w
);
2775 return log_error_errno(r
, "Could not watch jobs: %m");
2778 STRV_FOREACH(name
, names
) {
2779 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2782 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2783 if (r
>= 0 && q
< 0)
2784 r
= translate_bus_error_to_exit_status(q
, &error
);
2787 if (!arg_no_block
) {
2790 q
= bus_wait_for_jobs(w
, arg_quiet
);
2794 /* When stopping units, warn if they can still be triggered by
2795 * another active unit (socket, path, timer) */
2796 if (!arg_quiet
&& streq(method
, "StopUnit"))
2797 STRV_FOREACH(name
, names
)
2798 check_triggering_units(bus
, *name
);
2804 static int logind_set_wall_message(void) {
2806 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2808 _cleanup_free_
char *m
= NULL
;
2811 r
= acquire_bus(BUS_FULL
, &bus
);
2815 m
= strv_join(arg_wall
, " ");
2819 r
= sd_bus_call_method(
2821 "org.freedesktop.login1",
2822 "/org/freedesktop/login1",
2823 "org.freedesktop.login1.Manager",
2832 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2838 /* Ask systemd-logind, which might grant access to unprivileged users
2839 * through PolicyKit */
2840 static int logind_reboot(enum action a
) {
2842 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2843 const char *method
, *description
;
2847 polkit_agent_open_if_enabled();
2848 (void) logind_set_wall_message();
2850 r
= acquire_bus(BUS_FULL
, &bus
);
2858 description
= "reboot system";
2861 case ACTION_POWEROFF
:
2862 method
= "PowerOff";
2863 description
= "power off system";
2866 case ACTION_SUSPEND
:
2868 description
= "suspend system";
2871 case ACTION_HIBERNATE
:
2872 method
= "Hibernate";
2873 description
= "hibernate system";
2876 case ACTION_HYBRID_SLEEP
:
2877 method
= "HybridSleep";
2878 description
= "put system into hybrid sleep";
2885 r
= sd_bus_call_method(
2887 "org.freedesktop.login1",
2888 "/org/freedesktop/login1",
2889 "org.freedesktop.login1.Manager",
2893 "b", arg_ask_password
);
2895 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2903 static int logind_check_inhibitors(enum action a
) {
2905 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2906 _cleanup_strv_free_
char **sessions
= NULL
;
2907 const char *what
, *who
, *why
, *mode
;
2914 if (arg_ignore_inhibitors
|| arg_force
> 0)
2926 r
= acquire_bus(BUS_FULL
, &bus
);
2930 r
= sd_bus_call_method(
2932 "org.freedesktop.login1",
2933 "/org/freedesktop/login1",
2934 "org.freedesktop.login1.Manager",
2940 /* If logind is not around, then there are no inhibitors... */
2943 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2945 return bus_log_parse_error(r
);
2947 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2948 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2949 _cleanup_strv_free_
char **sv
= NULL
;
2951 if (!streq(mode
, "block"))
2954 sv
= strv_split(what
, ":");
2958 if ((pid_t
) pid
< 0)
2959 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2961 if (!strv_contains(sv
,
2966 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2969 get_process_comm(pid
, &comm
);
2970 user
= uid_to_name(uid
);
2972 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2973 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2978 return bus_log_parse_error(r
);
2980 r
= sd_bus_message_exit_container(reply
);
2982 return bus_log_parse_error(r
);
2984 /* Check for current sessions */
2985 sd_get_sessions(&sessions
);
2986 STRV_FOREACH(s
, sessions
) {
2987 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2989 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2992 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2995 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2998 sd_session_get_tty(*s
, &tty
);
2999 sd_session_get_seat(*s
, &seat
);
3000 sd_session_get_service(*s
, &service
);
3001 user
= uid_to_name(uid
);
3003 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3010 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3011 action_table
[a
].verb
);
3019 static int logind_prepare_firmware_setup(void) {
3021 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3025 r
= acquire_bus(BUS_FULL
, &bus
);
3029 r
= sd_bus_call_method(
3031 "org.freedesktop.login1",
3032 "/org/freedesktop/login1",
3033 "org.freedesktop.login1.Manager",
3034 "SetRebootToFirmwareSetup",
3039 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3043 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3048 static int prepare_firmware_setup(void) {
3051 if (!arg_firmware_setup
)
3054 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3056 r
= efi_set_reboot_to_firmware(true);
3058 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3063 return logind_prepare_firmware_setup();
3066 static int set_exit_code(uint8_t code
) {
3067 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3071 r
= acquire_bus(BUS_MANAGER
, &bus
);
3075 r
= sd_bus_call_method(
3077 "org.freedesktop.systemd1",
3078 "/org/freedesktop/systemd1",
3079 "org.freedesktop.systemd1.Manager",
3085 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3090 static int start_special(int argc
, char *argv
[], void *userdata
) {
3096 a
= verb_to_action(argv
[0]);
3098 r
= logind_check_inhibitors(a
);
3102 if (arg_force
>= 2 && geteuid() != 0) {
3103 log_error("Must be root.");
3107 r
= prepare_firmware_setup();
3111 if (a
== ACTION_REBOOT
&& argc
> 1) {
3112 r
= update_reboot_param_file(argv
[1]);
3116 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3119 /* If the exit code is not given on the command line,
3120 * don't reset it to zero: just keep it as it might
3121 * have been set previously. */
3123 r
= safe_atou8(argv
[1], &code
);
3125 return log_error_errno(r
, "Invalid exit code.");
3127 r
= set_exit_code(code
);
3132 if (arg_force
>= 2 &&
3139 if (arg_force
>= 1 &&
3146 return daemon_reload(argc
, argv
, userdata
);
3148 /* First try logind, to allow authentication with polkit */
3154 ACTION_HYBRID_SLEEP
)) {
3155 r
= logind_reboot(a
);
3158 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3159 /* requested operation is not supported or already in progress */
3162 /* On all other errors, try low-level operation */
3165 return start_unit(argc
, argv
, userdata
);
3168 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3169 _cleanup_strv_free_
char **names
= NULL
;
3174 r
= acquire_bus(BUS_MANAGER
, &bus
);
3178 r
= expand_names(bus
, args
, NULL
, &names
);
3180 return log_error_errno(r
, "Failed to expand names: %m");
3182 STRV_FOREACH(name
, names
) {
3185 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3195 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3196 /* According to LSB: 3, "program is not running" */
3197 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3200 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3201 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3204 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3205 _cleanup_strv_free_
char **names
= NULL
;
3206 char *kill_who
= NULL
, **name
;
3210 polkit_agent_open_if_enabled();
3212 r
= acquire_bus(BUS_MANAGER
, &bus
);
3217 arg_kill_who
= "all";
3219 /* --fail was specified */
3220 if (streq(arg_job_mode
, "fail"))
3221 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3223 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3225 return log_error_errno(r
, "Failed to expand names: %m");
3227 STRV_FOREACH(name
, names
) {
3228 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3230 q
= sd_bus_call_method(
3232 "org.freedesktop.systemd1",
3233 "/org/freedesktop/systemd1",
3234 "org.freedesktop.systemd1.Manager",
3238 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3240 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3249 typedef struct ExecStatusInfo
{
3257 usec_t start_timestamp
;
3258 usec_t exit_timestamp
;
3263 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3266 static void exec_status_info_free(ExecStatusInfo
*i
) {
3275 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3276 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3279 int32_t code
, status
;
3285 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3287 return bus_log_parse_error(r
);
3291 r
= sd_bus_message_read(m
, "s", &path
);
3293 return bus_log_parse_error(r
);
3295 i
->path
= strdup(path
);
3299 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3301 return bus_log_parse_error(r
);
3303 r
= sd_bus_message_read(m
,
3306 &start_timestamp
, &start_timestamp_monotonic
,
3307 &exit_timestamp
, &exit_timestamp_monotonic
,
3311 return bus_log_parse_error(r
);
3314 i
->start_timestamp
= (usec_t
) start_timestamp
;
3315 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3316 i
->pid
= (pid_t
) pid
;
3320 r
= sd_bus_message_exit_container(m
);
3322 return bus_log_parse_error(r
);
3327 typedef struct UnitStatusInfo
{
3329 const char *load_state
;
3330 const char *active_state
;
3331 const char *sub_state
;
3332 const char *unit_file_state
;
3333 const char *unit_file_preset
;
3335 const char *description
;
3336 const char *following
;
3338 char **documentation
;
3340 const char *fragment_path
;
3341 const char *source_path
;
3342 const char *control_group
;
3344 char **dropin_paths
;
3346 const char *load_error
;
3349 usec_t inactive_exit_timestamp
;
3350 usec_t inactive_exit_timestamp_monotonic
;
3351 usec_t active_enter_timestamp
;
3352 usec_t active_exit_timestamp
;
3353 usec_t inactive_enter_timestamp
;
3355 bool need_daemon_reload
;
3360 const char *status_text
;
3361 const char *pid_file
;
3365 usec_t start_timestamp
;
3366 usec_t exit_timestamp
;
3368 int exit_code
, exit_status
;
3370 usec_t condition_timestamp
;
3371 bool condition_result
;
3372 bool failed_condition_trigger
;
3373 bool failed_condition_negate
;
3374 const char *failed_condition
;
3375 const char *failed_condition_parameter
;
3377 usec_t assert_timestamp
;
3379 bool failed_assert_trigger
;
3380 bool failed_assert_negate
;
3381 const char *failed_assert
;
3382 const char *failed_assert_parameter
;
3385 unsigned n_accepted
;
3386 unsigned n_connections
;
3389 /* Pairs of type, path */
3393 const char *sysfs_path
;
3395 /* Mount, Automount */
3402 uint64_t memory_current
;
3403 uint64_t memory_limit
;
3404 uint64_t cpu_usage_nsec
;
3405 uint64_t tasks_current
;
3408 LIST_HEAD(ExecStatusInfo
, exec
);
3411 static void print_status_info(
3416 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3418 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3419 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3425 /* This shows pretty information about a unit. See
3426 * print_property() for a low-level property printer */
3428 if (streq_ptr(i
->active_state
, "failed")) {
3429 active_on
= ansi_highlight_red();
3430 active_off
= ansi_normal();
3431 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3432 active_on
= ansi_highlight_green();
3433 active_off
= ansi_normal();
3435 active_on
= active_off
= "";
3437 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3439 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3440 printf(" - %s", i
->description
);
3445 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3447 if (streq_ptr(i
->load_state
, "error")) {
3448 on
= ansi_highlight_red();
3449 off
= ansi_normal();
3453 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3456 printf(" Loaded: %s%s%s (Reason: %s)\n",
3457 on
, strna(i
->load_state
), off
, i
->load_error
);
3458 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3459 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3460 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3461 else if (path
&& !isempty(i
->unit_file_state
))
3462 printf(" Loaded: %s%s%s (%s; %s)\n",
3463 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3465 printf(" Loaded: %s%s%s (%s)\n",
3466 on
, strna(i
->load_state
), off
, path
);
3468 printf(" Loaded: %s%s%s\n",
3469 on
, strna(i
->load_state
), off
);
3471 if (!strv_isempty(i
->dropin_paths
)) {
3472 _cleanup_free_
char *dir
= NULL
;
3476 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3477 if (! dir
|| last
) {
3478 printf(dir
? " " : " Drop-In: ");
3482 if (path_get_parent(*dropin
, &dir
) < 0) {
3487 printf("%s\n %s", dir
,
3488 draw_special_char(DRAW_TREE_RIGHT
));
3491 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3493 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3497 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3499 printf(" Active: %s%s (%s)%s",
3500 active_on
, strna(i
->active_state
), ss
, active_off
);
3502 printf(" Active: %s%s%s",
3503 active_on
, strna(i
->active_state
), active_off
);
3505 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3506 printf(" (Result: %s)", i
->result
);
3508 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3509 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3510 (streq_ptr(i
->active_state
, "inactive") ||
3511 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3512 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3513 i
->active_exit_timestamp
;
3515 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3516 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3519 printf(" since %s; %s\n", s2
, s1
);
3521 printf(" since %s\n", s2
);
3525 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3526 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3527 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3529 printf("Condition: start %scondition failed%s at %s%s%s\n",
3530 ansi_highlight_yellow(), ansi_normal(),
3531 s2
, s1
? "; " : "", strempty(s1
));
3532 if (i
->failed_condition_trigger
)
3533 printf(" none of the trigger conditions were met\n");
3534 else if (i
->failed_condition
)
3535 printf(" %s=%s%s was not met\n",
3536 i
->failed_condition
,
3537 i
->failed_condition_negate
? "!" : "",
3538 i
->failed_condition_parameter
);
3541 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3542 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3543 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3545 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3546 ansi_highlight_red(), ansi_normal(),
3547 s2
, s1
? "; " : "", strempty(s1
));
3548 if (i
->failed_assert_trigger
)
3549 printf(" none of the trigger assertions were met\n");
3550 else if (i
->failed_assert
)
3551 printf(" %s=%s%s was not met\n",
3553 i
->failed_assert_negate
? "!" : "",
3554 i
->failed_assert_parameter
);
3558 printf(" Device: %s\n", i
->sysfs_path
);
3560 printf(" Where: %s\n", i
->where
);
3562 printf(" What: %s\n", i
->what
);
3564 STRV_FOREACH(t
, i
->documentation
)
3565 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3567 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3568 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3571 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3573 LIST_FOREACH(exec
, p
, i
->exec
) {
3574 _cleanup_free_
char *argv
= NULL
;
3577 /* Only show exited processes here */
3581 argv
= strv_join(p
->argv
, " ");
3582 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3584 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3586 on
= ansi_highlight_red();
3587 off
= ansi_normal();
3591 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3593 if (p
->code
== CLD_EXITED
) {
3596 printf("status=%i", p
->status
);
3598 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3603 printf("signal=%s", signal_to_string(p
->status
));
3605 printf(")%s\n", off
);
3607 if (i
->main_pid
== p
->pid
&&
3608 i
->start_timestamp
== p
->start_timestamp
&&
3609 i
->exit_timestamp
== p
->start_timestamp
)
3610 /* Let's not show this twice */
3613 if (p
->pid
== i
->control_pid
)
3617 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3618 if (i
->main_pid
> 0) {
3619 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3622 _cleanup_free_
char *comm
= NULL
;
3623 get_process_comm(i
->main_pid
, &comm
);
3625 printf(" (%s)", comm
);
3626 } else if (i
->exit_code
> 0) {
3627 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3629 if (i
->exit_code
== CLD_EXITED
) {
3632 printf("status=%i", i
->exit_status
);
3634 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3639 printf("signal=%s", signal_to_string(i
->exit_status
));
3643 if (i
->control_pid
> 0)
3647 if (i
->control_pid
> 0) {
3648 _cleanup_free_
char *c
= NULL
;
3650 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3652 get_process_comm(i
->control_pid
, &c
);
3661 printf(" Status: \"%s\"\n", i
->status_text
);
3662 if (i
->status_errno
> 0)
3663 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3665 if (i
->tasks_current
!= (uint64_t) -1) {
3666 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3668 if (i
->tasks_max
!= (uint64_t) -1)
3669 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3674 if (i
->memory_current
!= (uint64_t) -1) {
3675 char buf
[FORMAT_BYTES_MAX
];
3677 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3679 if (i
->memory_limit
!= (uint64_t) -1)
3680 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3685 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3686 char buf
[FORMAT_TIMESPAN_MAX
];
3687 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3690 if (i
->control_group
&&
3691 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3692 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3695 printf(" CGroup: %s\n", i
->control_group
);
3697 if (IN_SET(arg_transport
,
3698 BUS_TRANSPORT_LOCAL
,
3699 BUS_TRANSPORT_MACHINE
)) {
3702 static const char prefix
[] = " ";
3705 if (c
> sizeof(prefix
) - 1)
3706 c
-= sizeof(prefix
) - 1;
3710 if (i
->main_pid
> 0)
3711 extra
[k
++] = i
->main_pid
;
3713 if (i
->control_pid
> 0)
3714 extra
[k
++] = i
->control_pid
;
3716 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3720 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3721 show_journal_by_unit(
3726 i
->inactive_exit_timestamp_monotonic
,
3729 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3730 SD_JOURNAL_LOCAL_ONLY
,
3731 arg_scope
== UNIT_FILE_SYSTEM
,
3734 if (i
->need_daemon_reload
)
3735 warn_unit_file_changed(i
->id
);
3738 static void show_unit_help(UnitStatusInfo
*i
) {
3743 if (!i
->documentation
) {
3744 log_info("Documentation for %s not known.", i
->id
);
3748 STRV_FOREACH(p
, i
->documentation
)
3749 if (startswith(*p
, "man:"))
3750 show_man_page(*p
+ 4, false);
3752 log_info("Can't show: %s", *p
);
3755 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3762 switch (contents
[0]) {
3764 case SD_BUS_TYPE_STRING
: {
3767 r
= sd_bus_message_read(m
, "s", &s
);
3769 return bus_log_parse_error(r
);
3772 if (streq(name
, "Id"))
3774 else if (streq(name
, "LoadState"))
3776 else if (streq(name
, "ActiveState"))
3777 i
->active_state
= s
;
3778 else if (streq(name
, "SubState"))
3780 else if (streq(name
, "Description"))
3782 else if (streq(name
, "FragmentPath"))
3783 i
->fragment_path
= s
;
3784 else if (streq(name
, "SourcePath"))
3787 else if (streq(name
, "DefaultControlGroup")) {
3789 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3791 i
->control_group
= e
;
3794 else if (streq(name
, "ControlGroup"))
3795 i
->control_group
= s
;
3796 else if (streq(name
, "StatusText"))
3798 else if (streq(name
, "PIDFile"))
3800 else if (streq(name
, "SysFSPath"))
3802 else if (streq(name
, "Where"))
3804 else if (streq(name
, "What"))
3806 else if (streq(name
, "Following"))
3808 else if (streq(name
, "UnitFileState"))
3809 i
->unit_file_state
= s
;
3810 else if (streq(name
, "UnitFilePreset"))
3811 i
->unit_file_preset
= s
;
3812 else if (streq(name
, "Result"))
3819 case SD_BUS_TYPE_BOOLEAN
: {
3822 r
= sd_bus_message_read(m
, "b", &b
);
3824 return bus_log_parse_error(r
);
3826 if (streq(name
, "Accept"))
3828 else if (streq(name
, "NeedDaemonReload"))
3829 i
->need_daemon_reload
= b
;
3830 else if (streq(name
, "ConditionResult"))
3831 i
->condition_result
= b
;
3832 else if (streq(name
, "AssertResult"))
3833 i
->assert_result
= b
;
3838 case SD_BUS_TYPE_UINT32
: {
3841 r
= sd_bus_message_read(m
, "u", &u
);
3843 return bus_log_parse_error(r
);
3845 if (streq(name
, "MainPID")) {
3847 i
->main_pid
= (pid_t
) u
;
3850 } else if (streq(name
, "ControlPID"))
3851 i
->control_pid
= (pid_t
) u
;
3852 else if (streq(name
, "ExecMainPID")) {
3854 i
->main_pid
= (pid_t
) u
;
3855 } else if (streq(name
, "NAccepted"))
3857 else if (streq(name
, "NConnections"))
3858 i
->n_connections
= u
;
3863 case SD_BUS_TYPE_INT32
: {
3866 r
= sd_bus_message_read(m
, "i", &j
);
3868 return bus_log_parse_error(r
);
3870 if (streq(name
, "ExecMainCode"))
3871 i
->exit_code
= (int) j
;
3872 else if (streq(name
, "ExecMainStatus"))
3873 i
->exit_status
= (int) j
;
3874 else if (streq(name
, "StatusErrno"))
3875 i
->status_errno
= (int) j
;
3880 case SD_BUS_TYPE_UINT64
: {
3883 r
= sd_bus_message_read(m
, "t", &u
);
3885 return bus_log_parse_error(r
);
3887 if (streq(name
, "ExecMainStartTimestamp"))
3888 i
->start_timestamp
= (usec_t
) u
;
3889 else if (streq(name
, "ExecMainExitTimestamp"))
3890 i
->exit_timestamp
= (usec_t
) u
;
3891 else if (streq(name
, "ActiveEnterTimestamp"))
3892 i
->active_enter_timestamp
= (usec_t
) u
;
3893 else if (streq(name
, "InactiveEnterTimestamp"))
3894 i
->inactive_enter_timestamp
= (usec_t
) u
;
3895 else if (streq(name
, "InactiveExitTimestamp"))
3896 i
->inactive_exit_timestamp
= (usec_t
) u
;
3897 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3898 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3899 else if (streq(name
, "ActiveExitTimestamp"))
3900 i
->active_exit_timestamp
= (usec_t
) u
;
3901 else if (streq(name
, "ConditionTimestamp"))
3902 i
->condition_timestamp
= (usec_t
) u
;
3903 else if (streq(name
, "AssertTimestamp"))
3904 i
->assert_timestamp
= (usec_t
) u
;
3905 else if (streq(name
, "MemoryCurrent"))
3906 i
->memory_current
= u
;
3907 else if (streq(name
, "MemoryLimit"))
3908 i
->memory_limit
= u
;
3909 else if (streq(name
, "TasksCurrent"))
3910 i
->tasks_current
= u
;
3911 else if (streq(name
, "TasksMax"))
3913 else if (streq(name
, "CPUUsageNSec"))
3914 i
->cpu_usage_nsec
= u
;
3919 case SD_BUS_TYPE_ARRAY
:
3921 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3922 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3924 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3926 return bus_log_parse_error(r
);
3928 info
= new0(ExecStatusInfo
, 1);
3932 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3934 info
->name
= strdup(name
);
3938 LIST_PREPEND(exec
, i
->exec
, info
);
3940 info
= new0(ExecStatusInfo
, 1);
3946 return bus_log_parse_error(r
);
3948 r
= sd_bus_message_exit_container(m
);
3950 return bus_log_parse_error(r
);
3954 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3955 const char *type
, *path
;
3957 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3959 return bus_log_parse_error(r
);
3961 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3963 r
= strv_extend(&i
->listen
, type
);
3967 r
= strv_extend(&i
->listen
, path
);
3972 return bus_log_parse_error(r
);
3974 r
= sd_bus_message_exit_container(m
);
3976 return bus_log_parse_error(r
);
3980 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3982 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3984 return bus_log_parse_error(r
);
3986 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3988 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3990 return bus_log_parse_error(r
);
3992 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3993 const char *cond
, *param
;
3994 int trigger
, negate
;
3997 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3999 return bus_log_parse_error(r
);
4001 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4002 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4003 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4004 i
->failed_condition
= cond
;
4005 i
->failed_condition_trigger
= trigger
;
4006 i
->failed_condition_negate
= negate
;
4007 i
->failed_condition_parameter
= param
;
4011 return bus_log_parse_error(r
);
4013 r
= sd_bus_message_exit_container(m
);
4015 return bus_log_parse_error(r
);
4017 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4018 const char *cond
, *param
;
4019 int trigger
, negate
;
4022 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4024 return bus_log_parse_error(r
);
4026 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4027 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4028 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4029 i
->failed_assert
= cond
;
4030 i
->failed_assert_trigger
= trigger
;
4031 i
->failed_assert_negate
= negate
;
4032 i
->failed_assert_parameter
= param
;
4036 return bus_log_parse_error(r
);
4038 r
= sd_bus_message_exit_container(m
);
4040 return bus_log_parse_error(r
);
4047 case SD_BUS_TYPE_STRUCT_BEGIN
:
4049 if (streq(name
, "LoadError")) {
4050 const char *n
, *message
;
4052 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4054 return bus_log_parse_error(r
);
4056 if (!isempty(message
))
4057 i
->load_error
= message
;
4070 r
= sd_bus_message_skip(m
, contents
);
4072 return bus_log_parse_error(r
);
4077 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4083 /* This is a low-level property printer, see
4084 * print_status_info() for the nicer output */
4086 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4087 /* skip what we didn't read */
4088 r
= sd_bus_message_skip(m
, contents
);
4092 switch (contents
[0]) {
4094 case SD_BUS_TYPE_STRUCT_BEGIN
:
4096 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4099 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4101 return bus_log_parse_error(r
);
4104 printf("%s=%"PRIu32
"\n", name
, u
);
4106 printf("%s=\n", name
);
4110 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4113 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4115 return bus_log_parse_error(r
);
4117 if (arg_all
|| !isempty(s
))
4118 printf("%s=%s\n", name
, s
);
4122 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4123 const char *a
= NULL
, *b
= NULL
;
4125 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4127 return bus_log_parse_error(r
);
4129 if (arg_all
|| !isempty(a
) || !isempty(b
))
4130 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4133 } else if (streq_ptr(name
, "SystemCallFilter")) {
4134 _cleanup_strv_free_
char **l
= NULL
;
4137 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4139 return bus_log_parse_error(r
);
4141 r
= sd_bus_message_read(m
, "b", &whitelist
);
4143 return bus_log_parse_error(r
);
4145 r
= sd_bus_message_read_strv(m
, &l
);
4147 return bus_log_parse_error(r
);
4149 r
= sd_bus_message_exit_container(m
);
4151 return bus_log_parse_error(r
);
4153 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4157 fputs(name
, stdout
);
4163 STRV_FOREACH(i
, l
) {
4171 fputc('\n', stdout
);
4179 case SD_BUS_TYPE_ARRAY
:
4181 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4185 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4187 return bus_log_parse_error(r
);
4189 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4190 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4193 return bus_log_parse_error(r
);
4195 r
= sd_bus_message_exit_container(m
);
4197 return bus_log_parse_error(r
);
4201 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4202 const char *type
, *path
;
4204 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4206 return bus_log_parse_error(r
);
4208 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4209 printf("%s=%s\n", type
, path
);
4211 return bus_log_parse_error(r
);
4213 r
= sd_bus_message_exit_container(m
);
4215 return bus_log_parse_error(r
);
4219 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4220 const char *type
, *path
;
4222 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4224 return bus_log_parse_error(r
);
4226 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4227 printf("Listen%s=%s\n", type
, path
);
4229 return bus_log_parse_error(r
);
4231 r
= sd_bus_message_exit_container(m
);
4233 return bus_log_parse_error(r
);
4237 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4239 uint64_t value
, next_elapse
;
4241 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4243 return bus_log_parse_error(r
);
4245 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4246 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4248 printf("%s={ value=%s ; next_elapse=%s }\n",
4250 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4251 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4254 return bus_log_parse_error(r
);
4256 r
= sd_bus_message_exit_container(m
);
4258 return bus_log_parse_error(r
);
4262 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4263 ExecStatusInfo info
= {};
4265 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4267 return bus_log_parse_error(r
);
4269 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4270 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4271 _cleanup_free_
char *tt
;
4273 tt
= strv_join(info
.argv
, " ");
4275 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",
4279 yes_no(info
.ignore
),
4280 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4281 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4283 sigchld_code_to_string(info
.code
),
4285 info
.code
== CLD_EXITED
? "" : "/",
4286 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4289 strv_free(info
.argv
);
4293 r
= sd_bus_message_exit_container(m
);
4295 return bus_log_parse_error(r
);
4299 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4300 const char *path
, *rwm
;
4302 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4304 return bus_log_parse_error(r
);
4306 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4307 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4309 return bus_log_parse_error(r
);
4311 r
= sd_bus_message_exit_container(m
);
4313 return bus_log_parse_error(r
);
4317 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4321 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4323 return bus_log_parse_error(r
);
4325 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4326 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4328 return bus_log_parse_error(r
);
4330 r
= sd_bus_message_exit_container(m
);
4332 return bus_log_parse_error(r
);
4336 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4340 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4342 return bus_log_parse_error(r
);
4344 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4345 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4347 return bus_log_parse_error(r
);
4349 r
= sd_bus_message_exit_container(m
);
4351 return bus_log_parse_error(r
);
4359 r
= bus_print_property(name
, m
, arg_all
);
4361 return bus_log_parse_error(r
);
4364 r
= sd_bus_message_skip(m
, contents
);
4366 return bus_log_parse_error(r
);
4369 printf("%s=[unprintable]\n", name
);
4375 static int show_one(
4379 bool show_properties
,
4383 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4384 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4385 UnitStatusInfo info
= {
4386 .memory_current
= (uint64_t) -1,
4387 .memory_limit
= (uint64_t) -1,
4388 .cpu_usage_nsec
= (uint64_t) -1,
4389 .tasks_current
= (uint64_t) -1,
4390 .tasks_max
= (uint64_t) -1,
4398 log_debug("Showing one %s", path
);
4400 r
= sd_bus_call_method(
4402 "org.freedesktop.systemd1",
4404 "org.freedesktop.DBus.Properties",
4410 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4412 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4414 return bus_log_parse_error(r
);
4421 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4422 const char *name
, *contents
;
4424 r
= sd_bus_message_read(reply
, "s", &name
);
4426 return bus_log_parse_error(r
);
4428 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4430 return bus_log_parse_error(r
);
4432 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4434 return bus_log_parse_error(r
);
4436 if (show_properties
)
4437 r
= print_property(name
, reply
, contents
);
4439 r
= status_property(name
, reply
, &info
, contents
);
4443 r
= sd_bus_message_exit_container(reply
);
4445 return bus_log_parse_error(r
);
4447 r
= sd_bus_message_exit_container(reply
);
4449 return bus_log_parse_error(r
);
4452 return bus_log_parse_error(r
);
4454 r
= sd_bus_message_exit_container(reply
);
4456 return bus_log_parse_error(r
);
4460 if (!show_properties
) {
4461 if (streq(verb
, "help"))
4462 show_unit_help(&info
);
4464 print_status_info(&info
, ellipsized
);
4467 strv_free(info
.documentation
);
4468 strv_free(info
.dropin_paths
);
4469 strv_free(info
.listen
);
4471 if (!streq_ptr(info
.active_state
, "active") &&
4472 !streq_ptr(info
.active_state
, "reloading") &&
4473 streq(verb
, "status")) {
4474 /* According to LSB: "program not running" */
4475 /* 0: program is running or service is OK
4476 * 1: program is dead and /run PID file exists
4477 * 2: program is dead and /run/lock lock file exists
4478 * 3: program is not running
4479 * 4: program or service status is unknown
4481 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4487 while ((p
= info
.exec
)) {
4488 LIST_REMOVE(exec
, info
.exec
, p
);
4489 exec_status_info_free(p
);
4495 static int get_unit_dbus_path_by_pid(
4500 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4501 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4505 r
= sd_bus_call_method(
4507 "org.freedesktop.systemd1",
4508 "/org/freedesktop/systemd1",
4509 "org.freedesktop.systemd1.Manager",
4515 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4517 r
= sd_bus_message_read(reply
, "o", &u
);
4519 return bus_log_parse_error(r
);
4529 static int show_all(
4532 bool show_properties
,
4536 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4537 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4542 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4546 pager_open_if_enabled();
4550 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4552 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4553 _cleanup_free_
char *p
= NULL
;
4555 p
= unit_dbus_path_from_name(u
->id
);
4559 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4562 else if (r
> 0 && ret
== 0)
4569 static int show_system_status(sd_bus
*bus
) {
4570 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4571 _cleanup_free_
char *hn
= NULL
;
4572 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4573 const char *on
, *off
;
4576 hn
= gethostname_malloc();
4580 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4582 return log_error_errno(r
, "Failed to read server status: %m");
4584 if (streq_ptr(mi
.state
, "degraded")) {
4585 on
= ansi_highlight_red();
4586 off
= ansi_normal();
4587 } else if (!streq_ptr(mi
.state
, "running")) {
4588 on
= ansi_highlight_yellow();
4589 off
= ansi_normal();
4593 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4595 printf(" State: %s%s%s\n",
4596 on
, strna(mi
.state
), off
);
4598 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4599 printf(" Failed: %u units\n", mi
.n_failed_units
);
4601 printf(" Since: %s; %s\n",
4602 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4603 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4605 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4606 if (IN_SET(arg_transport
,
4607 BUS_TRANSPORT_LOCAL
,
4608 BUS_TRANSPORT_MACHINE
)) {
4609 static const char prefix
[] = " ";
4613 if (c
> sizeof(prefix
) - 1)
4614 c
-= sizeof(prefix
) - 1;
4618 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4624 static int show(int argc
, char *argv
[], void *userdata
) {
4625 bool show_properties
, show_status
, show_help
, new_line
= false;
4626 bool ellipsized
= false;
4632 show_properties
= streq(argv
[0], "show");
4633 show_status
= streq(argv
[0], "status");
4634 show_help
= streq(argv
[0], "help");
4636 if (show_help
&& argc
<= 1) {
4637 log_error("This command expects one or more unit names. Did you mean --help?");
4641 if (show_properties
)
4642 pager_open_if_enabled();
4645 /* Increase max number of open files to 16K if we can, we
4646 * might needs this when browsing journal files, which might
4647 * be split up into many files. */
4648 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4650 r
= acquire_bus(BUS_MANAGER
, &bus
);
4654 /* If no argument is specified inspect the manager itself */
4655 if (show_properties
&& argc
<= 1)
4656 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4658 if (show_status
&& argc
<= 1) {
4660 pager_open_if_enabled();
4661 show_system_status(bus
);
4665 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4667 _cleanup_free_
char **patterns
= NULL
;
4670 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4671 _cleanup_free_
char *unit
= NULL
;
4674 if (safe_atou32(*name
, &id
) < 0) {
4675 if (strv_push(&patterns
, *name
) < 0)
4679 } else if (show_properties
) {
4680 /* Interpret as job id */
4681 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4685 /* Interpret as PID */
4686 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4693 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4696 else if (r
> 0 && ret
== 0)
4700 if (!strv_isempty(patterns
)) {
4701 _cleanup_strv_free_
char **names
= NULL
;
4703 r
= expand_names(bus
, patterns
, NULL
, &names
);
4705 return log_error_errno(r
, "Failed to expand names: %m");
4707 STRV_FOREACH(name
, names
) {
4708 _cleanup_free_
char *unit
;
4710 unit
= unit_dbus_path_from_name(*name
);
4714 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4717 else if (r
> 0 && ret
== 0)
4723 if (ellipsized
&& !arg_quiet
)
4724 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4729 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4733 assert(user_runtime
);
4736 if (arg_scope
== UNIT_FILE_USER
) {
4737 r
= user_config_home(user_home
);
4739 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4741 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4743 r
= user_runtime_dir(user_runtime
);
4745 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4747 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4750 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4752 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4757 static int cat_file(const char *filename
, bool newline
) {
4758 _cleanup_close_
int fd
;
4760 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4764 printf("%s%s# %s%s\n",
4765 newline
? "\n" : "",
4766 ansi_highlight_blue(),
4771 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4774 static int cat(int argc
, char *argv
[], void *userdata
) {
4775 _cleanup_free_
char *user_home
= NULL
;
4776 _cleanup_free_
char *user_runtime
= NULL
;
4777 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4778 _cleanup_strv_free_
char **names
= NULL
;
4784 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4785 log_error("Cannot remotely cat units.");
4789 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4793 r
= acquire_bus(BUS_MANAGER
, &bus
);
4797 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4799 return log_error_errno(r
, "Failed to expand names: %m");
4801 pager_open_if_enabled();
4803 STRV_FOREACH(name
, names
) {
4804 _cleanup_free_
char *fragment_path
= NULL
;
4805 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4808 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4819 if (fragment_path
) {
4820 r
= cat_file(fragment_path
, false);
4822 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4825 STRV_FOREACH(path
, dropin_paths
) {
4826 r
= cat_file(*path
, path
== dropin_paths
);
4828 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4835 static int set_property(int argc
, char *argv
[], void *userdata
) {
4836 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4837 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4838 _cleanup_free_
char *n
= NULL
;
4843 polkit_agent_open_if_enabled();
4845 r
= acquire_bus(BUS_MANAGER
, &bus
);
4849 r
= sd_bus_message_new_method_call(
4852 "org.freedesktop.systemd1",
4853 "/org/freedesktop/systemd1",
4854 "org.freedesktop.systemd1.Manager",
4855 "SetUnitProperties");
4857 return bus_log_create_error(r
);
4859 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4861 return log_error_errno(r
, "Failed to mangle unit name: %m");
4863 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4865 return bus_log_create_error(r
);
4867 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4869 return bus_log_create_error(r
);
4871 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4872 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4874 return bus_log_create_error(r
);
4876 r
= bus_append_unit_property_assignment(m
, *i
);
4880 r
= sd_bus_message_close_container(m
);
4882 return bus_log_create_error(r
);
4885 r
= sd_bus_message_close_container(m
);
4887 return bus_log_create_error(r
);
4889 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4891 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4896 static int snapshot(int argc
, char *argv
[], void *userdata
) {
4897 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4898 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4899 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4904 polkit_agent_open_if_enabled();
4907 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4909 return log_error_errno(r
, "Failed to generate unit name: %m");
4916 r
= acquire_bus(BUS_MANAGER
, &bus
);
4920 r
= sd_bus_call_method(
4922 "org.freedesktop.systemd1",
4923 "/org/freedesktop/systemd1",
4924 "org.freedesktop.systemd1.Manager",
4930 return log_error_errno(r
, "Failed to create snapshot: %s", bus_error_message(&error
, r
));
4932 r
= sd_bus_message_read(reply
, "o", &path
);
4934 return bus_log_parse_error(r
);
4936 r
= sd_bus_get_property_string(
4938 "org.freedesktop.systemd1",
4940 "org.freedesktop.systemd1.Unit",
4945 return log_error_errno(r
, "Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4953 static int delete_snapshot(int argc
, char *argv
[], void *userdata
) {
4954 _cleanup_strv_free_
char **names
= NULL
;
4959 polkit_agent_open_if_enabled();
4961 r
= acquire_bus(BUS_MANAGER
, &bus
);
4965 r
= expand_names(bus
, strv_skip(argv
, 1), ".snapshot", &names
);
4967 return log_error_errno(r
, "Failed to expand names: %m");
4969 STRV_FOREACH(name
, names
) {
4970 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4973 q
= sd_bus_call_method(
4975 "org.freedesktop.systemd1",
4976 "/org/freedesktop/systemd1",
4977 "org.freedesktop.systemd1.Manager",
4983 log_error_errno(q
, "Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4992 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4993 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4998 polkit_agent_open_if_enabled();
5000 r
= acquire_bus(BUS_MANAGER
, &bus
);
5004 if (arg_action
== ACTION_RELOAD
)
5006 else if (arg_action
== ACTION_REEXEC
)
5007 method
= "Reexecute";
5009 assert(arg_action
== ACTION_SYSTEMCTL
);
5012 streq(argv
[0], "clear-jobs") ||
5013 streq(argv
[0], "cancel") ? "ClearJobs" :
5014 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5015 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5016 streq(argv
[0], "halt") ? "Halt" :
5017 streq(argv
[0], "poweroff") ? "PowerOff" :
5018 streq(argv
[0], "reboot") ? "Reboot" :
5019 streq(argv
[0], "kexec") ? "KExec" :
5020 streq(argv
[0], "exit") ? "Exit" :
5021 /* "daemon-reload" */ "Reload";
5024 r
= sd_bus_call_method(
5026 "org.freedesktop.systemd1",
5027 "/org/freedesktop/systemd1",
5028 "org.freedesktop.systemd1.Manager",
5033 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
5034 /* There's always a fallback possible for
5035 * legacy actions. */
5037 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
5038 /* On reexecution, we expect a disconnect, not a
5042 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5044 return r
< 0 ? r
: 0;
5047 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5048 _cleanup_strv_free_
char **names
= NULL
;
5054 return daemon_reload(argc
, argv
, userdata
);
5056 polkit_agent_open_if_enabled();
5058 r
= acquire_bus(BUS_MANAGER
, &bus
);
5062 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5064 return log_error_errno(r
, "Failed to expand names: %m");
5066 STRV_FOREACH(name
, names
) {
5067 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5069 q
= sd_bus_call_method(
5071 "org.freedesktop.systemd1",
5072 "/org/freedesktop/systemd1",
5073 "org.freedesktop.systemd1.Manager",
5079 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5088 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5089 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5090 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5095 pager_open_if_enabled();
5097 r
= acquire_bus(BUS_MANAGER
, &bus
);
5101 r
= sd_bus_get_property(
5103 "org.freedesktop.systemd1",
5104 "/org/freedesktop/systemd1",
5105 "org.freedesktop.systemd1.Manager",
5111 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5113 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5115 return bus_log_parse_error(r
);
5117 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5120 return bus_log_parse_error(r
);
5122 r
= sd_bus_message_exit_container(reply
);
5124 return bus_log_parse_error(r
);
5129 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5130 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5131 _cleanup_free_
char *cmdline_init
= NULL
;
5132 const char *root
, *init
;
5136 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5137 log_error("Cannot switch root remotely.");
5141 if (argc
< 2 || argc
> 3) {
5142 log_error("Wrong number of arguments.");
5151 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5152 "init", &cmdline_init
,
5155 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5157 init
= cmdline_init
;
5164 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5166 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5167 root_init_path
= strjoina(root
, "/", init
);
5169 /* If the passed init is actually the same as the
5170 * systemd binary, then let's suppress it. */
5171 if (files_same(root_init_path
, root_systemd_path
) > 0)
5175 r
= acquire_bus(BUS_MANAGER
, &bus
);
5179 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5181 r
= sd_bus_call_method(
5183 "org.freedesktop.systemd1",
5184 "/org/freedesktop/systemd1",
5185 "org.freedesktop.systemd1.Manager",
5191 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5196 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5197 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5198 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5206 polkit_agent_open_if_enabled();
5208 r
= acquire_bus(BUS_MANAGER
, &bus
);
5212 method
= streq(argv
[0], "set-environment")
5214 : "UnsetEnvironment";
5216 r
= sd_bus_message_new_method_call(
5219 "org.freedesktop.systemd1",
5220 "/org/freedesktop/systemd1",
5221 "org.freedesktop.systemd1.Manager",
5224 return bus_log_create_error(r
);
5226 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5228 return bus_log_create_error(r
);
5230 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5232 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5237 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5238 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5239 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5243 polkit_agent_open_if_enabled();
5245 r
= acquire_bus(BUS_MANAGER
, &bus
);
5249 r
= sd_bus_message_new_method_call(
5252 "org.freedesktop.systemd1",
5253 "/org/freedesktop/systemd1",
5254 "org.freedesktop.systemd1.Manager",
5257 return bus_log_create_error(r
);
5260 r
= sd_bus_message_append_strv(m
, environ
);
5264 r
= sd_bus_message_open_container(m
, 'a', "s");
5266 return bus_log_create_error(r
);
5268 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5270 if (!env_name_is_valid(*a
)) {
5271 log_error("Not a valid environment variable name: %s", *a
);
5275 STRV_FOREACH(b
, environ
) {
5278 eq
= startswith(*b
, *a
);
5279 if (eq
&& *eq
== '=') {
5281 r
= sd_bus_message_append(m
, "s", *b
);
5283 return bus_log_create_error(r
);
5290 r
= sd_bus_message_close_container(m
);
5293 return bus_log_create_error(r
);
5295 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5297 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5302 static int enable_sysv_units(const char *verb
, char **args
) {
5305 #if defined(HAVE_SYSV_COMPAT)
5307 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5309 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5312 if (!STR_IN_SET(verb
,
5318 /* Processes all SysV units, and reshuffles the array so that
5319 * afterwards only the native units remain */
5321 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5328 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5329 bool found_native
= false, found_sysv
;
5331 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5339 if (!endswith(name
, ".service"))
5342 if (path_is_absolute(name
))
5345 STRV_FOREACH(k
, paths
.unit_path
) {
5346 _cleanup_free_
char *path
= NULL
;
5348 path
= path_join(arg_root
, *k
, name
);
5352 found_native
= access(path
, F_OK
) >= 0;
5357 /* If we have both a native unit and a SysV script,
5358 * enable/disable them both (below); for is-enabled, prefer the
5360 if (found_native
&& streq(verb
, "is-enabled"))
5363 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5367 p
[strlen(p
) - strlen(".service")] = 0;
5368 found_sysv
= access(p
, F_OK
) >= 0;
5373 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5375 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5377 if (!isempty(arg_root
))
5378 argv
[c
++] = q
= strappend("--root=", arg_root
);
5381 argv
[c
++] = basename(p
);
5384 l
= strv_join((char**)argv
, " ");
5388 log_info("Executing %s", l
);
5392 return log_error_errno(errno
, "Failed to fork: %m");
5393 else if (pid
== 0) {
5396 (void) reset_all_signal_handlers();
5397 (void) reset_signal_mask();
5399 execv(argv
[0], (char**) argv
);
5400 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5401 _exit(EXIT_FAILURE
);
5404 j
= wait_for_terminate(pid
, &status
);
5406 log_error_errno(j
, "Failed to wait for child: %m");
5410 if (status
.si_code
== CLD_EXITED
) {
5411 if (streq(verb
, "is-enabled")) {
5412 if (status
.si_status
== 0) {
5421 } else if (status
.si_status
!= 0)
5429 /* Remove this entry, so that we don't try enabling it as native unit */
5432 assert(args
[f
] == name
);
5433 strv_remove(args
, name
);
5440 static int mangle_names(char **original_names
, char ***mangled_names
) {
5441 char **i
, **l
, **name
;
5444 l
= i
= new(char*, strv_length(original_names
) + 1);
5448 STRV_FOREACH(name
, original_names
) {
5450 /* When enabling units qualified path names are OK,
5451 * too, hence allow them explicitly. */
5453 if (is_path(*name
)) {
5460 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5463 return log_error_errno(r
, "Failed to mangle unit name: %m");
5476 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5477 _cleanup_strv_free_
char **names
= NULL
;
5478 const char *verb
= argv
[0];
5479 UnitFileChange
*changes
= NULL
;
5480 unsigned n_changes
= 0;
5481 int carries_install_info
= -1;
5487 r
= mangle_names(strv_skip(argv
, 1), &names
);
5491 r
= enable_sysv_units(verb
, names
);
5495 /* If the operation was fully executed by the SysV compat,
5496 * let's finish early */
5497 if (strv_isempty(names
))
5500 if (install_client_side()) {
5501 if (streq(verb
, "enable")) {
5502 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5503 carries_install_info
= r
;
5504 } else if (streq(verb
, "disable"))
5505 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5506 else if (streq(verb
, "reenable")) {
5507 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5508 carries_install_info
= r
;
5509 } else if (streq(verb
, "link"))
5510 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5511 else if (streq(verb
, "preset")) {
5512 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5513 carries_install_info
= r
;
5514 } else if (streq(verb
, "mask"))
5515 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5516 else if (streq(verb
, "unmask"))
5517 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5519 assert_not_reached("Unknown verb");
5522 log_error_errno(r
, "Operation failed: %m");
5527 dump_unit_file_changes(changes
, n_changes
);
5531 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5532 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5533 int expect_carries_install_info
= false;
5534 bool send_force
= true, send_preset_mode
= false;
5538 polkit_agent_open_if_enabled();
5540 r
= acquire_bus(BUS_MANAGER
, &bus
);
5544 if (streq(verb
, "enable")) {
5545 method
= "EnableUnitFiles";
5546 expect_carries_install_info
= true;
5547 } else if (streq(verb
, "disable")) {
5548 method
= "DisableUnitFiles";
5550 } else if (streq(verb
, "reenable")) {
5551 method
= "ReenableUnitFiles";
5552 expect_carries_install_info
= true;
5553 } else if (streq(verb
, "link"))
5554 method
= "LinkUnitFiles";
5555 else if (streq(verb
, "preset")) {
5557 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5558 method
= "PresetUnitFilesWithMode";
5559 send_preset_mode
= true;
5561 method
= "PresetUnitFiles";
5563 expect_carries_install_info
= true;
5564 } else if (streq(verb
, "mask"))
5565 method
= "MaskUnitFiles";
5566 else if (streq(verb
, "unmask")) {
5567 method
= "UnmaskUnitFiles";
5570 assert_not_reached("Unknown verb");
5572 r
= sd_bus_message_new_method_call(
5575 "org.freedesktop.systemd1",
5576 "/org/freedesktop/systemd1",
5577 "org.freedesktop.systemd1.Manager",
5580 return bus_log_create_error(r
);
5582 r
= sd_bus_message_append_strv(m
, names
);
5584 return bus_log_create_error(r
);
5586 if (send_preset_mode
) {
5587 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5589 return bus_log_create_error(r
);
5592 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5594 return bus_log_create_error(r
);
5597 r
= sd_bus_message_append(m
, "b", arg_force
);
5599 return bus_log_create_error(r
);
5602 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5604 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5606 if (expect_carries_install_info
) {
5607 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5609 return bus_log_parse_error(r
);
5612 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5616 /* Try to reload if enabled */
5618 r
= daemon_reload(argc
, argv
, userdata
);
5623 if (carries_install_info
== 0)
5624 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5625 "using systemctl.\n"
5626 "Possible reasons for having this kind of units are:\n"
5627 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5628 " .wants/ or .requires/ directory.\n"
5629 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5630 " a requirement dependency on it.\n"
5631 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5632 " D-Bus, udev, scripted systemctl call, ...).\n");
5634 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5635 char *new_args
[n_changes
+ 2];
5639 r
= acquire_bus(BUS_MANAGER
, &bus
);
5643 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5644 for (i
= 0; i
< n_changes
; i
++)
5645 new_args
[i
+ 1] = basename(changes
[i
].path
);
5646 new_args
[i
+ 1] = NULL
;
5648 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5652 unit_file_changes_free(changes
, n_changes
);
5657 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5658 _cleanup_strv_free_
char **names
= NULL
;
5659 _cleanup_free_
char *target
= NULL
;
5660 const char *verb
= argv
[0];
5667 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5669 return log_error_errno(r
, "Failed to mangle unit name: %m");
5671 r
= mangle_names(strv_skip(argv
, 2), &names
);
5675 if (streq(verb
, "add-wants"))
5677 else if (streq(verb
, "add-requires"))
5678 dep
= UNIT_REQUIRES
;
5680 assert_not_reached("Unknown verb");
5682 if (install_client_side()) {
5683 UnitFileChange
*changes
= NULL
;
5684 unsigned n_changes
= 0;
5686 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5689 return log_error_errno(r
, "Can't add dependency: %m");
5692 dump_unit_file_changes(changes
, n_changes
);
5694 unit_file_changes_free(changes
, n_changes
);
5697 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5698 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5701 polkit_agent_open_if_enabled();
5703 r
= acquire_bus(BUS_MANAGER
, &bus
);
5707 r
= sd_bus_message_new_method_call(
5710 "org.freedesktop.systemd1",
5711 "/org/freedesktop/systemd1",
5712 "org.freedesktop.systemd1.Manager",
5713 "AddDependencyUnitFiles");
5715 return bus_log_create_error(r
);
5717 r
= sd_bus_message_append_strv(m
, names
);
5719 return bus_log_create_error(r
);
5721 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5723 return bus_log_create_error(r
);
5725 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5727 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5729 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5734 r
= daemon_reload(argc
, argv
, userdata
);
5742 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5743 UnitFileChange
*changes
= NULL
;
5744 unsigned n_changes
= 0;
5747 if (install_client_side()) {
5749 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5751 log_error_errno(r
, "Operation failed: %m");
5756 dump_unit_file_changes(changes
, n_changes
);
5761 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5762 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5765 polkit_agent_open_if_enabled();
5767 r
= acquire_bus(BUS_MANAGER
, &bus
);
5771 r
= sd_bus_call_method(
5773 "org.freedesktop.systemd1",
5774 "/org/freedesktop/systemd1",
5775 "org.freedesktop.systemd1.Manager",
5776 "PresetAllUnitFiles",
5780 unit_file_preset_mode_to_string(arg_preset_mode
),
5784 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5786 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5791 r
= daemon_reload(argc
, argv
, userdata
);
5797 unit_file_changes_free(changes
, n_changes
);
5802 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5804 _cleanup_strv_free_
char **names
= NULL
;
5809 r
= mangle_names(strv_skip(argv
, 1), &names
);
5813 r
= enable_sysv_units(argv
[0], names
);
5819 if (install_client_side()) {
5821 STRV_FOREACH(name
, names
) {
5822 UnitFileState state
;
5824 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5826 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5830 UNIT_FILE_ENABLED_RUNTIME
,
5832 UNIT_FILE_INDIRECT
))
5836 puts(unit_file_state_to_string(state
));
5840 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5843 r
= acquire_bus(BUS_MANAGER
, &bus
);
5847 STRV_FOREACH(name
, names
) {
5848 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5851 r
= sd_bus_call_method(
5853 "org.freedesktop.systemd1",
5854 "/org/freedesktop/systemd1",
5855 "org.freedesktop.systemd1.Manager",
5861 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5863 r
= sd_bus_message_read(reply
, "s", &s
);
5865 return bus_log_parse_error(r
);
5867 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5878 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5879 _cleanup_free_
char *state
= NULL
;
5883 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5886 return EXIT_FAILURE
;
5889 r
= acquire_bus(BUS_MANAGER
, &bus
);
5893 r
= sd_bus_get_property_string(
5895 "org.freedesktop.systemd1",
5896 "/org/freedesktop/systemd1",
5897 "org.freedesktop.systemd1.Manager",
5910 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5913 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5914 _cleanup_free_
char *t
= NULL
;
5918 assert(original_path
);
5921 r
= tempfn_random(new_path
, NULL
, &t
);
5923 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5925 r
= mkdir_parents(new_path
, 0755);
5927 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5929 r
= copy_file(original_path
, t
, 0, 0644, 0);
5934 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5937 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5945 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5946 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5951 switch (arg_scope
) {
5952 case UNIT_FILE_SYSTEM
:
5953 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5955 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5957 case UNIT_FILE_GLOBAL
:
5958 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5960 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5962 case UNIT_FILE_USER
:
5964 assert(user_runtime
);
5966 path
= path_join(arg_root
, user_home
, name
);
5968 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5971 run
= path_join(arg_root
, user_runtime
, name
);
5975 assert_not_reached("Invalid scope");
5977 if (!path
|| (arg_runtime
&& !run
))
5981 if (access(path
, F_OK
) >= 0) {
5982 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5986 if (path2
&& access(path2
, F_OK
) >= 0) {
5987 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
6001 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
) {
6002 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6006 assert(ret_new_path
);
6007 assert(ret_tmp_path
);
6009 ending
= strjoina(unit_name
, ".d/override.conf");
6010 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
6014 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6020 *ret_new_path
= tmp_new_path
;
6021 *ret_tmp_path
= tmp_tmp_path
;
6026 static int unit_file_create_copy(
6027 const char *unit_name
,
6028 const char *fragment_path
,
6029 const char *user_home
,
6030 const char *user_runtime
,
6031 char **ret_new_path
,
6032 char **ret_tmp_path
) {
6034 char *tmp_new_path
, *tmp_tmp_path
;
6037 assert(fragment_path
);
6039 assert(ret_new_path
);
6040 assert(ret_tmp_path
);
6042 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
6046 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6049 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6054 if (response
!= 'y') {
6055 log_warning("%s ignored", unit_name
);
6061 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6063 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6068 *ret_new_path
= tmp_new_path
;
6069 *ret_tmp_path
= tmp_tmp_path
;
6074 static int run_editor(char **paths
) {
6082 return log_error_errno(errno
, "Failed to fork: %m");
6086 char *editor
, **editor_args
= NULL
;
6087 char **tmp_path
, **original_path
, *p
;
6088 unsigned n_editor_args
= 0, i
= 1;
6091 (void) reset_all_signal_handlers();
6092 (void) reset_signal_mask();
6094 argc
= strv_length(paths
)/2 + 1;
6096 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6097 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6098 * we try to execute well known editors
6100 editor
= getenv("SYSTEMD_EDITOR");
6102 editor
= getenv("EDITOR");
6104 editor
= getenv("VISUAL");
6106 if (!isempty(editor
)) {
6107 editor_args
= strv_split(editor
, WHITESPACE
);
6110 _exit(EXIT_FAILURE
);
6112 n_editor_args
= strv_length(editor_args
);
6113 argc
+= n_editor_args
- 1;
6115 args
= newa(const char*, argc
+ 1);
6117 if (n_editor_args
> 0) {
6118 args
[0] = editor_args
[0];
6119 for (; i
< n_editor_args
; i
++)
6120 args
[i
] = editor_args
[i
];
6123 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6124 args
[i
] = *tmp_path
;
6129 if (n_editor_args
> 0)
6130 execvp(args
[0], (char* const*) args
);
6132 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6134 execvp(p
, (char* const*) args
);
6135 /* We do not fail if the editor doesn't exist
6136 * because we want to try each one of them before
6139 if (errno
!= ENOENT
) {
6140 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6141 _exit(EXIT_FAILURE
);
6145 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6146 _exit(EXIT_FAILURE
);
6149 r
= wait_for_terminate_and_warn("editor", pid
, true);
6151 return log_error_errno(r
, "Failed to wait for child: %m");
6156 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6157 _cleanup_free_
char *user_home
= NULL
;
6158 _cleanup_free_
char *user_runtime
= NULL
;
6159 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6166 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6170 STRV_FOREACH(name
, names
) {
6171 _cleanup_free_
char *path
= NULL
;
6172 char *new_path
, *tmp_path
;
6174 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6180 // FIXME: support units with path==NULL (no FragmentPath)
6181 log_error("No fragment exists for %s.", *name
);
6186 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6188 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6192 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6200 static int edit(int argc
, char *argv
[], void *userdata
) {
6201 _cleanup_strv_free_
char **names
= NULL
;
6202 _cleanup_strv_free_
char **paths
= NULL
;
6203 char **original
, **tmp
;
6208 log_error("Cannot edit units if not on a tty.");
6212 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6213 log_error("Cannot edit units remotely.");
6217 r
= acquire_bus(BUS_MANAGER
, &bus
);
6221 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6223 return log_error_errno(r
, "Failed to expand names: %m");
6225 r
= find_paths_to_edit(bus
, names
, &paths
);
6229 if (strv_isempty(paths
))
6232 r
= run_editor(paths
);
6236 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6237 /* If the temporary file is empty we ignore it. It's
6238 * useful if the user wants to cancel its modification
6240 if (null_or_empty_path(*tmp
)) {
6241 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6245 r
= rename(*tmp
, *original
);
6247 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6254 if (!arg_no_reload
&& !install_client_side())
6255 r
= daemon_reload(argc
, argv
, userdata
);
6258 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6259 (void) unlink(*tmp
);
6264 static void systemctl_help(void) {
6266 pager_open_if_enabled();
6268 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6269 "Query or send control commands to the systemd manager.\n\n"
6270 " -h --help Show this help\n"
6271 " --version Show package version\n"
6272 " --system Connect to system manager\n"
6273 " --user Connect to user service manager\n"
6274 " -H --host=[USER@]HOST\n"
6275 " Operate on remote host\n"
6276 " -M --machine=CONTAINER\n"
6277 " Operate on local container\n"
6278 " -t --type=TYPE List units of a particular type\n"
6279 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6280 " -p --property=NAME Show only properties by this name\n"
6281 " -a --all Show all loaded units/properties, including dead/empty\n"
6282 " ones. To list all units installed on the system, use\n"
6283 " the 'list-unit-files' command instead.\n"
6284 " -l --full Don't ellipsize unit names on output\n"
6285 " -r --recursive Show unit list of host and local containers\n"
6286 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6287 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6288 " queueing a new job\n"
6289 " --show-types When showing sockets, explicitly show their type\n"
6290 " -i --ignore-inhibitors\n"
6291 " When shutting down or sleeping, ignore inhibitors\n"
6292 " --kill-who=WHO Who to send signal to\n"
6293 " -s --signal=SIGNAL Which signal to send\n"
6294 " --now Start or stop unit in addition to enabling or disabling it\n"
6295 " -q --quiet Suppress output\n"
6296 " --no-block Do not wait until operation finished\n"
6297 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6298 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6299 " --no-legend Do not print a legend (column headers and hints)\n"
6300 " --no-pager Do not pipe output into a pager\n"
6301 " --no-ask-password\n"
6302 " Do not ask for system passwords\n"
6303 " --global Enable/disable unit files globally\n"
6304 " --runtime Enable unit files only temporarily until next reboot\n"
6305 " -f --force When enabling unit files, override existing symlinks\n"
6306 " When shutting down, execute action immediately\n"
6307 " --preset-mode= Apply only enable, only disable, or all presets\n"
6308 " --root=PATH Enable unit files in the specified root directory\n"
6309 " -n --lines=INTEGER Number of journal entries to show\n"
6310 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6311 " short-precise, short-monotonic, verbose,\n"
6312 " export, json, json-pretty, json-sse, cat)\n"
6313 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6314 " --plain Print unit dependencies as a list instead of a tree\n\n"
6316 " list-units [PATTERN...] List loaded units\n"
6317 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6318 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6319 " start NAME... Start (activate) one or more units\n"
6320 " stop NAME... Stop (deactivate) one or more units\n"
6321 " reload NAME... Reload one or more units\n"
6322 " restart NAME... Start or restart one or more units\n"
6323 " try-restart NAME... Restart one or more units if active\n"
6324 " reload-or-restart NAME... Reload one or more units if possible,\n"
6325 " otherwise start or restart\n"
6326 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6327 " otherwise restart if active\n"
6328 " isolate NAME Start one unit and stop all others\n"
6329 " kill NAME... Send signal to processes of a unit\n"
6330 " is-active PATTERN... Check whether units are active\n"
6331 " is-failed PATTERN... Check whether units are failed\n"
6332 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6333 " show [PATTERN...|JOB...] Show properties of one or more\n"
6334 " units/jobs or the manager\n"
6335 " cat PATTERN... Show files and drop-ins of one or more units\n"
6336 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6337 " help PATTERN...|PID... Show manual for one or more units\n"
6338 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6340 " list-dependencies [NAME] Recursively show units which are required\n"
6341 " or wanted by this unit or by which this\n"
6342 " unit is required or wanted\n\n"
6343 "Unit File Commands:\n"
6344 " list-unit-files [PATTERN...] List installed unit files\n"
6345 " enable NAME... Enable one or more unit files\n"
6346 " disable NAME... Disable one or more unit files\n"
6347 " reenable NAME... Reenable one or more unit files\n"
6348 " preset NAME... Enable/disable one or more unit files\n"
6349 " based on preset configuration\n"
6350 " preset-all Enable/disable all unit files based on\n"
6351 " preset configuration\n"
6352 " is-enabled NAME... Check whether unit files are enabled\n"
6353 " mask NAME... Mask one or more units\n"
6354 " unmask NAME... Unmask one or more units\n"
6355 " link PATH... Link one or more units files into\n"
6356 " the search path\n"
6357 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6358 " on specified one or more units\n"
6359 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6360 " on specified one or more units\n"
6361 " edit NAME... Edit one or more unit files\n"
6362 " get-default Get the name of the default target\n"
6363 " set-default NAME Set the default target\n\n"
6364 "Machine Commands:\n"
6365 " list-machines [PATTERN...] List local containers and host\n\n"
6367 " list-jobs [PATTERN...] List jobs\n"
6368 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6369 "Snapshot Commands:\n"
6370 " snapshot [NAME] Create a snapshot\n"
6371 " delete NAME... Remove one or more snapshots\n\n"
6372 "Environment Commands:\n"
6373 " show-environment Dump environment\n"
6374 " set-environment NAME=VALUE... Set one or more environment variables\n"
6375 " unset-environment NAME... Unset one or more environment variables\n"
6376 " import-environment [NAME...] Import all or some environment variables\n\n"
6377 "Manager Lifecycle Commands:\n"
6378 " daemon-reload Reload systemd manager configuration\n"
6379 " daemon-reexec Reexecute systemd manager\n\n"
6380 "System Commands:\n"
6381 " is-system-running Check whether system is fully running\n"
6382 " default Enter system default mode\n"
6383 " rescue Enter system rescue mode\n"
6384 " emergency Enter system emergency mode\n"
6385 " halt Shut down and halt the system\n"
6386 " poweroff Shut down and power-off the system\n"
6387 " reboot [ARG] Shut down and reboot the system\n"
6388 " kexec Shut down and reboot the system with kexec\n"
6389 " exit [EXIT_CODE] Request user instance or container exit\n"
6390 " switch-root ROOT [INIT] Change to a different root file system\n"
6391 " suspend Suspend the system\n"
6392 " hibernate Hibernate the system\n"
6393 " hybrid-sleep Hibernate and suspend the system\n",
6394 program_invocation_short_name
);
6397 static void halt_help(void) {
6398 printf("%s [OPTIONS...]%s\n\n"
6399 "%s the system.\n\n"
6400 " --help Show this help\n"
6401 " --halt Halt the machine\n"
6402 " -p --poweroff Switch off the machine\n"
6403 " --reboot Reboot the machine\n"
6404 " -f --force Force immediate halt/power-off/reboot\n"
6405 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6406 " -d --no-wtmp Don't write wtmp record\n"
6407 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6408 program_invocation_short_name
,
6409 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6410 arg_action
== ACTION_REBOOT
? "Reboot" :
6411 arg_action
== ACTION_POWEROFF
? "Power off" :
6415 static void shutdown_help(void) {
6416 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6417 "Shut down the system.\n\n"
6418 " --help Show this help\n"
6419 " -H --halt Halt the machine\n"
6420 " -P --poweroff Power-off the machine\n"
6421 " -r --reboot Reboot the machine\n"
6422 " -h Equivalent to --poweroff, overridden by --halt\n"
6423 " -k Don't halt/power-off/reboot, just send warnings\n"
6424 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6425 " -c Cancel a pending shutdown\n",
6426 program_invocation_short_name
);
6429 static void telinit_help(void) {
6430 printf("%s [OPTIONS...] {COMMAND}\n\n"
6431 "Send control commands to the init daemon.\n\n"
6432 " --help Show this help\n"
6433 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6435 " 0 Power-off the machine\n"
6436 " 6 Reboot the machine\n"
6437 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6438 " 1, s, S Enter rescue mode\n"
6439 " q, Q Reload init daemon configuration\n"
6440 " u, U Reexecute init daemon\n",
6441 program_invocation_short_name
);
6444 static void runlevel_help(void) {
6445 printf("%s [OPTIONS...]\n\n"
6446 "Prints the previous and current runlevel of the init system.\n\n"
6447 " --help Show this help\n",
6448 program_invocation_short_name
);
6451 static void help_types(void) {
6455 puts("Available unit types:");
6456 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6457 puts(unit_type_to_string(i
));
6460 static void help_states(void) {
6464 puts("Available unit load states:");
6465 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6466 puts(unit_load_state_to_string(i
));
6469 puts("\nAvailable unit active states:");
6470 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6471 puts(unit_active_state_to_string(i
));
6474 puts("\nAvailable automount unit substates:");
6475 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6476 puts(automount_state_to_string(i
));
6479 puts("\nAvailable busname unit substates:");
6480 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6481 puts(busname_state_to_string(i
));
6484 puts("\nAvailable device unit substates:");
6485 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6486 puts(device_state_to_string(i
));
6489 puts("\nAvailable mount unit substates:");
6490 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6491 puts(mount_state_to_string(i
));
6494 puts("\nAvailable path unit substates:");
6495 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6496 puts(path_state_to_string(i
));
6499 puts("\nAvailable scope unit substates:");
6500 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6501 puts(scope_state_to_string(i
));
6504 puts("\nAvailable service unit substates:");
6505 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6506 puts(service_state_to_string(i
));
6509 puts("\nAvailable slice unit substates:");
6510 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6511 puts(slice_state_to_string(i
));
6514 puts("\nAvailable snapshot unit substates:");
6515 for (i
= 0; i
< _SNAPSHOT_STATE_MAX
; i
++)
6516 puts(snapshot_state_to_string(i
));
6519 puts("\nAvailable socket unit substates:");
6520 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6521 puts(socket_state_to_string(i
));
6524 puts("\nAvailable swap unit substates:");
6525 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6526 puts(swap_state_to_string(i
));
6529 puts("\nAvailable target unit substates:");
6530 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6531 puts(target_state_to_string(i
));
6534 puts("\nAvailable timer unit substates:");
6535 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6536 puts(timer_state_to_string(i
));
6539 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6548 ARG_IGNORE_DEPENDENCIES
,
6560 ARG_NO_ASK_PASSWORD
,
6573 static const struct option options
[] = {
6574 { "help", no_argument
, NULL
, 'h' },
6575 { "version", no_argument
, NULL
, ARG_VERSION
},
6576 { "type", required_argument
, NULL
, 't' },
6577 { "property", required_argument
, NULL
, 'p' },
6578 { "all", no_argument
, NULL
, 'a' },
6579 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6580 { "after", no_argument
, NULL
, ARG_AFTER
},
6581 { "before", no_argument
, NULL
, ARG_BEFORE
},
6582 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6583 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6584 { "full", no_argument
, NULL
, 'l' },
6585 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6586 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6587 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6588 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6589 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6590 { "user", no_argument
, NULL
, ARG_USER
},
6591 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6592 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6593 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6594 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6595 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6596 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6597 { "quiet", no_argument
, NULL
, 'q' },
6598 { "root", required_argument
, NULL
, ARG_ROOT
},
6599 { "force", no_argument
, NULL
, ARG_FORCE
},
6600 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6601 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6602 { "signal", required_argument
, NULL
, 's' },
6603 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6604 { "host", required_argument
, NULL
, 'H' },
6605 { "machine", required_argument
, NULL
, 'M' },
6606 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6607 { "lines", required_argument
, NULL
, 'n' },
6608 { "output", required_argument
, NULL
, 'o' },
6609 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6610 { "state", required_argument
, NULL
, ARG_STATE
},
6611 { "recursive", no_argument
, NULL
, 'r' },
6612 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6613 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6614 { "now", no_argument
, NULL
, ARG_NOW
},
6615 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6624 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6625 arg_ask_password
= true;
6627 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6639 const char *word
, *state
;
6642 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6643 _cleanup_free_
char *type
;
6645 type
= strndup(word
, size
);
6649 if (streq(type
, "help")) {
6654 if (unit_type_from_string(type
) >= 0) {
6655 if (strv_push(&arg_types
, type
) < 0)
6661 /* It's much nicer to use --state= for
6662 * load states, but let's support this
6663 * in --types= too for compatibility
6664 * with old versions */
6665 if (unit_load_state_from_string(type
) >= 0) {
6666 if (strv_push(&arg_states
, type
) < 0)
6672 log_error("Unknown unit type or load state '%s'.", type
);
6673 log_info("Use -t help to see a list of allowed values.");
6681 /* Make sure that if the empty property list
6682 was specified, we won't show any properties. */
6683 if (isempty(optarg
) && !arg_properties
) {
6684 arg_properties
= new0(char*, 1);
6685 if (!arg_properties
)
6688 const char *word
, *state
;
6691 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6694 prop
= strndup(word
, size
);
6698 if (strv_consume(&arg_properties
, prop
) < 0)
6703 /* If the user asked for a particular
6704 * property, show it to him, even if it is
6716 arg_dependency
= DEPENDENCY_REVERSE
;
6720 arg_dependency
= DEPENDENCY_AFTER
;
6724 arg_dependency
= DEPENDENCY_BEFORE
;
6727 case ARG_SHOW_TYPES
:
6728 arg_show_types
= true;
6732 arg_job_mode
= optarg
;
6736 arg_job_mode
= "fail";
6739 case ARG_IRREVERSIBLE
:
6740 arg_job_mode
= "replace-irreversibly";
6743 case ARG_IGNORE_DEPENDENCIES
:
6744 arg_job_mode
= "ignore-dependencies";
6748 arg_scope
= UNIT_FILE_USER
;
6752 arg_scope
= UNIT_FILE_SYSTEM
;
6756 arg_scope
= UNIT_FILE_GLOBAL
;
6760 arg_no_block
= true;
6764 arg_no_legend
= true;
6768 arg_no_pager
= true;
6776 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6786 if (strv_extend(&arg_states
, "failed") < 0)
6804 arg_no_reload
= true;
6808 arg_kill_who
= optarg
;
6812 arg_signal
= signal_from_string_try_harder(optarg
);
6813 if (arg_signal
< 0) {
6814 log_error("Failed to parse signal string %s.", optarg
);
6819 case ARG_NO_ASK_PASSWORD
:
6820 arg_ask_password
= false;
6824 arg_transport
= BUS_TRANSPORT_REMOTE
;
6829 arg_transport
= BUS_TRANSPORT_MACHINE
;
6838 if (safe_atou(optarg
, &arg_lines
) < 0) {
6839 log_error("Failed to parse lines '%s'", optarg
);
6845 arg_output
= output_mode_from_string(optarg
);
6846 if (arg_output
< 0) {
6847 log_error("Unknown output '%s'.", optarg
);
6853 arg_ignore_inhibitors
= true;
6860 case ARG_FIRMWARE_SETUP
:
6861 arg_firmware_setup
= true;
6865 const char *word
, *state
;
6868 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6869 _cleanup_free_
char *s
= NULL
;
6871 s
= strndup(word
, size
);
6875 if (streq(s
, "help")) {
6880 if (strv_push(&arg_states
, s
) < 0)
6889 if (geteuid() != 0) {
6890 log_error("--recursive requires root privileges.");
6894 arg_recursive
= true;
6897 case ARG_PRESET_MODE
:
6899 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6900 if (arg_preset_mode
< 0) {
6901 log_error("Failed to parse preset mode: %s.", optarg
);
6912 if (strv_extend(&arg_wall
, optarg
) < 0)
6920 assert_not_reached("Unhandled option");
6923 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6924 log_error("Cannot access user instance remotely.");
6931 static int halt_parse_argv(int argc
, char *argv
[]) {
6940 static const struct option options
[] = {
6941 { "help", no_argument
, NULL
, ARG_HELP
},
6942 { "halt", no_argument
, NULL
, ARG_HALT
},
6943 { "poweroff", no_argument
, NULL
, 'p' },
6944 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6945 { "force", no_argument
, NULL
, 'f' },
6946 { "wtmp-only", no_argument
, NULL
, 'w' },
6947 { "no-wtmp", no_argument
, NULL
, 'd' },
6948 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6957 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6958 if (runlevel
== '0' || runlevel
== '6')
6961 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6969 arg_action
= ACTION_HALT
;
6973 if (arg_action
!= ACTION_REBOOT
)
6974 arg_action
= ACTION_POWEROFF
;
6978 arg_action
= ACTION_REBOOT
;
7000 /* Compatibility nops */
7007 assert_not_reached("Unhandled option");
7010 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7011 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7014 } else if (optind
< argc
) {
7015 log_error("Too many arguments.");
7022 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7026 if (streq(t
, "now"))
7028 else if (!strchr(t
, ':')) {
7031 if (safe_atou64(t
, &u
) < 0)
7034 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7043 hour
= strtol(t
, &e
, 10);
7044 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7047 minute
= strtol(e
+1, &e
, 10);
7048 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7051 n
= now(CLOCK_REALTIME
);
7052 s
= (time_t) (n
/ USEC_PER_SEC
);
7054 assert_se(localtime_r(&s
, &tm
));
7056 tm
.tm_hour
= (int) hour
;
7057 tm
.tm_min
= (int) minute
;
7060 assert_se(s
= mktime(&tm
));
7062 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7065 *_u
+= USEC_PER_DAY
;
7071 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7078 static const struct option options
[] = {
7079 { "help", no_argument
, NULL
, ARG_HELP
},
7080 { "halt", no_argument
, NULL
, 'H' },
7081 { "poweroff", no_argument
, NULL
, 'P' },
7082 { "reboot", no_argument
, NULL
, 'r' },
7083 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7084 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7094 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7102 arg_action
= ACTION_HALT
;
7106 arg_action
= ACTION_POWEROFF
;
7111 arg_action
= ACTION_KEXEC
;
7113 arg_action
= ACTION_REBOOT
;
7117 arg_action
= ACTION_KEXEC
;
7121 if (arg_action
!= ACTION_HALT
)
7122 arg_action
= ACTION_POWEROFF
;
7137 /* Compatibility nops */
7141 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7148 assert_not_reached("Unhandled option");
7151 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7152 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7154 log_error("Failed to parse time specification: %s", argv
[optind
]);
7158 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7160 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7161 /* No time argument for shutdown cancel */
7162 wall
= argv
+ optind
;
7163 else if (argc
> optind
+ 1)
7164 /* We skip the time argument */
7165 wall
= argv
+ optind
+ 1;
7168 arg_wall
= strv_copy(wall
);
7178 static int telinit_parse_argv(int argc
, char *argv
[]) {
7185 static const struct option options
[] = {
7186 { "help", no_argument
, NULL
, ARG_HELP
},
7187 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7191 static const struct {
7195 { '0', ACTION_POWEROFF
},
7196 { '6', ACTION_REBOOT
},
7197 { '1', ACTION_RESCUE
},
7198 { '2', ACTION_RUNLEVEL2
},
7199 { '3', ACTION_RUNLEVEL3
},
7200 { '4', ACTION_RUNLEVEL4
},
7201 { '5', ACTION_RUNLEVEL5
},
7202 { 's', ACTION_RESCUE
},
7203 { 'S', ACTION_RESCUE
},
7204 { 'q', ACTION_RELOAD
},
7205 { 'Q', ACTION_RELOAD
},
7206 { 'u', ACTION_REEXEC
},
7207 { 'U', ACTION_REEXEC
}
7216 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7231 assert_not_reached("Unhandled option");
7234 if (optind
>= argc
) {
7235 log_error("%s: required argument missing.", program_invocation_short_name
);
7239 if (optind
+ 1 < argc
) {
7240 log_error("Too many arguments.");
7244 if (strlen(argv
[optind
]) != 1) {
7245 log_error("Expected single character argument.");
7249 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7250 if (table
[i
].from
== argv
[optind
][0])
7253 if (i
>= ELEMENTSOF(table
)) {
7254 log_error("Unknown command '%s'.", argv
[optind
]);
7258 arg_action
= table
[i
].to
;
7265 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7271 static const struct option options
[] = {
7272 { "help", no_argument
, NULL
, ARG_HELP
},
7281 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7292 assert_not_reached("Unhandled option");
7295 if (optind
< argc
) {
7296 log_error("Too many arguments.");
7303 static int parse_argv(int argc
, char *argv
[]) {
7307 if (program_invocation_short_name
) {
7309 if (strstr(program_invocation_short_name
, "halt")) {
7310 arg_action
= ACTION_HALT
;
7311 return halt_parse_argv(argc
, argv
);
7312 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7313 arg_action
= ACTION_POWEROFF
;
7314 return halt_parse_argv(argc
, argv
);
7315 } else if (strstr(program_invocation_short_name
, "reboot")) {
7317 arg_action
= ACTION_KEXEC
;
7319 arg_action
= ACTION_REBOOT
;
7320 return halt_parse_argv(argc
, argv
);
7321 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7322 arg_action
= ACTION_POWEROFF
;
7323 return shutdown_parse_argv(argc
, argv
);
7324 } else if (strstr(program_invocation_short_name
, "init")) {
7326 if (sd_booted() > 0) {
7327 arg_action
= _ACTION_INVALID
;
7328 return telinit_parse_argv(argc
, argv
);
7330 /* Hmm, so some other init system is
7331 * running, we need to forward this
7332 * request to it. For now we simply
7333 * guess that it is Upstart. */
7335 execv(TELINIT
, argv
);
7337 log_error("Couldn't find an alternative telinit implementation to spawn.");
7341 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7342 arg_action
= ACTION_RUNLEVEL
;
7343 return runlevel_parse_argv(argc
, argv
);
7347 arg_action
= ACTION_SYSTEMCTL
;
7348 return systemctl_parse_argv(argc
, argv
);
7351 _pure_
static int action_to_runlevel(void) {
7353 static const char table
[_ACTION_MAX
] = {
7354 [ACTION_HALT
] = '0',
7355 [ACTION_POWEROFF
] = '0',
7356 [ACTION_REBOOT
] = '6',
7357 [ACTION_RUNLEVEL2
] = '2',
7358 [ACTION_RUNLEVEL3
] = '3',
7359 [ACTION_RUNLEVEL4
] = '4',
7360 [ACTION_RUNLEVEL5
] = '5',
7361 [ACTION_RESCUE
] = '1'
7364 assert(arg_action
< _ACTION_MAX
);
7366 return table
[arg_action
];
7369 static int talk_initctl(void) {
7370 #ifdef HAVE_SYSV_COMPAT
7371 struct init_request request
= {
7372 .magic
= INIT_MAGIC
,
7374 .cmd
= INIT_CMD_RUNLVL
7377 _cleanup_close_
int fd
= -1;
7381 rl
= action_to_runlevel();
7385 request
.runlevel
= rl
;
7387 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7389 if (errno
== ENOENT
)
7392 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7395 r
= loop_write(fd
, &request
, sizeof(request
), false);
7397 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7405 static int systemctl_main(int argc
, char *argv
[]) {
7407 static const Verb verbs
[] = {
7408 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
, list_units
},
7409 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7410 { "list-sockets", VERB_ANY
, VERB_ANY
, 0, list_sockets
},
7411 { "list-timers", VERB_ANY
, VERB_ANY
, 0, list_timers
},
7412 { "list-jobs", VERB_ANY
, VERB_ANY
, 0, list_jobs
},
7413 { "list-machines", VERB_ANY
, VERB_ANY
, 0, list_machines
},
7414 { "clear-jobs", VERB_ANY
, 1, 0, daemon_reload
},
7415 { "cancel", 2, VERB_ANY
, 0, cancel_job
},
7416 { "start", 2, VERB_ANY
, 0, start_unit
},
7417 { "stop", 2, VERB_ANY
, 0, start_unit
},
7418 { "condstop", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7419 { "reload", 2, VERB_ANY
, 0, start_unit
},
7420 { "restart", 2, VERB_ANY
, 0, start_unit
},
7421 { "try-restart", 2, VERB_ANY
, 0, start_unit
},
7422 { "reload-or-restart", 2, VERB_ANY
, 0, start_unit
},
7423 { "reload-or-try-restart", 2, VERB_ANY
, 0, start_unit
},
7424 { "force-reload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with SysV */
7425 { "condreload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7426 { "condrestart", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with RH */
7427 { "isolate", 2, 2, 0, start_unit
},
7428 { "kill", 2, VERB_ANY
, 0, kill_unit
},
7429 { "is-active", 2, VERB_ANY
, 0, check_unit_active
},
7430 { "check", 2, VERB_ANY
, 0, check_unit_active
},
7431 { "is-failed", 2, VERB_ANY
, 0, check_unit_failed
},
7432 { "show", VERB_ANY
, VERB_ANY
, 0, show
},
7433 { "cat", 2, VERB_ANY
, 0, cat
},
7434 { "status", VERB_ANY
, VERB_ANY
, 0, show
},
7435 { "help", VERB_ANY
, VERB_ANY
, 0, show
},
7436 { "snapshot", VERB_ANY
, 2, 0, snapshot
},
7437 { "delete", 2, VERB_ANY
, 0, delete_snapshot
},
7438 { "daemon-reload", VERB_ANY
, 1, 0, daemon_reload
},
7439 { "daemon-reexec", VERB_ANY
, 1, 0, daemon_reload
},
7440 { "show-environment", VERB_ANY
, 1, 0, show_environment
},
7441 { "set-environment", 2, VERB_ANY
, 0, set_environment
},
7442 { "unset-environment", 2, VERB_ANY
, 0, set_environment
},
7443 { "import-environment", VERB_ANY
, VERB_ANY
, 0, import_environment
},
7444 { "halt", VERB_ANY
, 1, 0, start_special
},
7445 { "poweroff", VERB_ANY
, 1, 0, start_special
},
7446 { "reboot", VERB_ANY
, 2, 0, start_special
},
7447 { "kexec", VERB_ANY
, 1, 0, start_special
},
7448 { "suspend", VERB_ANY
, 1, 0, start_special
},
7449 { "hibernate", VERB_ANY
, 1, 0, start_special
},
7450 { "hybrid-sleep", VERB_ANY
, 1, 0, start_special
},
7451 { "default", VERB_ANY
, 1, 0, start_special
},
7452 { "rescue", VERB_ANY
, 1, 0, start_special
},
7453 { "emergency", VERB_ANY
, 1, 0, start_special
},
7454 { "exit", VERB_ANY
, 2, 0, start_special
},
7455 { "reset-failed", VERB_ANY
, VERB_ANY
, 0, reset_failed
},
7456 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7457 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7458 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7459 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7460 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7461 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7462 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7463 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7464 { "link", 2, VERB_ANY
, 0, enable_unit
},
7465 { "switch-root", 2, VERB_ANY
, 0, switch_root
},
7466 { "list-dependencies", VERB_ANY
, 2, 0, list_dependencies
},
7467 { "set-default", 2, 2, 0, set_default
},
7468 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7469 { "set-property", 3, VERB_ANY
, 0, set_property
},
7470 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7471 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7472 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7473 { "edit", 2, VERB_ANY
, 0, edit
},
7477 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7480 static int reload_with_fallback(void) {
7482 /* First, try systemd via D-Bus. */
7483 if (daemon_reload(0, NULL
, NULL
) >= 0)
7486 /* Nothing else worked, so let's try signals */
7487 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7489 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7490 return log_error_errno(errno
, "kill() failed: %m");
7495 static int start_with_fallback(void) {
7497 /* First, try systemd via D-Bus. */
7498 if (start_unit(0, NULL
, NULL
) >= 0)
7501 /* Nothing else worked, so let's try
7503 if (talk_initctl() > 0)
7506 log_error("Failed to talk to init daemon.");
7510 static int halt_now(enum action a
) {
7512 /* The kernel will automaticall flush ATA disks and suchlike
7513 * on reboot(), but the file systems need to be synce'd
7514 * explicitly in advance. */
7517 /* Make sure C-A-D is handled by the kernel from this point
7519 (void) reboot(RB_ENABLE_CAD
);
7524 log_info("Halting.");
7525 (void) reboot(RB_HALT_SYSTEM
);
7528 case ACTION_POWEROFF
:
7529 log_info("Powering off.");
7530 (void) reboot(RB_POWER_OFF
);
7534 case ACTION_REBOOT
: {
7535 _cleanup_free_
char *param
= NULL
;
7537 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7538 log_info("Rebooting with argument '%s'.", param
);
7539 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7542 log_info("Rebooting.");
7543 (void) reboot(RB_AUTOBOOT
);
7548 assert_not_reached("Unknown action.");
7552 static int logind_schedule_shutdown(void) {
7555 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7556 char date
[FORMAT_TIMESTAMP_MAX
];
7561 (void) logind_set_wall_message();
7563 r
= acquire_bus(BUS_FULL
, &bus
);
7567 switch (arg_action
) {
7571 case ACTION_POWEROFF
:
7572 action
= "poweroff";
7587 action
= strjoina("dry-", action
);
7589 r
= sd_bus_call_method(
7591 "org.freedesktop.login1",
7592 "/org/freedesktop/login1",
7593 "org.freedesktop.login1.Manager",
7601 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7603 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7606 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7611 static int halt_main(void) {
7614 r
= logind_check_inhibitors(arg_action
);
7619 return logind_schedule_shutdown();
7621 if (geteuid() != 0) {
7622 if (arg_dry
|| arg_force
> 0) {
7623 log_error("Must be root.");
7627 /* Try logind if we are a normal user and no special
7628 * mode applies. Maybe PolicyKit allows us to shutdown
7630 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7631 r
= logind_reboot(arg_action
);
7634 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7635 /* requested operation is not
7636 * supported on the local system or
7637 * already in progress */
7639 /* on all other errors, try low-level operation */
7643 if (!arg_dry
&& !arg_force
)
7644 return start_with_fallback();
7646 assert(geteuid() == 0);
7649 if (sd_booted() > 0)
7650 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7652 r
= utmp_put_shutdown();
7654 log_warning_errno(r
, "Failed to write utmp record: %m");
7661 r
= halt_now(arg_action
);
7662 return log_error_errno(r
, "Failed to reboot: %m");
7665 static int runlevel_main(void) {
7666 int r
, runlevel
, previous
;
7668 r
= utmp_get_runlevel(&runlevel
, &previous
);
7675 previous
<= 0 ? 'N' : previous
,
7676 runlevel
<= 0 ? 'N' : runlevel
);
7681 static int logind_cancel_shutdown(void) {
7683 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7687 r
= acquire_bus(BUS_FULL
, &bus
);
7691 (void) logind_set_wall_message();
7693 r
= sd_bus_call_method(
7695 "org.freedesktop.login1",
7696 "/org/freedesktop/login1",
7697 "org.freedesktop.login1.Manager",
7698 "CancelScheduledShutdown",
7702 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7706 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7711 int main(int argc
, char*argv
[]) {
7714 setlocale(LC_ALL
, "");
7715 log_parse_environment();
7718 /* Explicitly not on_tty() to avoid setting cached value.
7719 * This becomes relevant for piping output which might be
7721 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7723 r
= parse_argv(argc
, argv
);
7727 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7728 log_info("Running in chroot, ignoring request.");
7733 /* systemctl_main() will print an error message for the bus
7734 * connection, but only if it needs to */
7736 switch (arg_action
) {
7738 case ACTION_SYSTEMCTL
:
7739 r
= systemctl_main(argc
, argv
);
7743 case ACTION_POWEROFF
:
7749 case ACTION_RUNLEVEL2
:
7750 case ACTION_RUNLEVEL3
:
7751 case ACTION_RUNLEVEL4
:
7752 case ACTION_RUNLEVEL5
:
7754 case ACTION_EMERGENCY
:
7755 case ACTION_DEFAULT
:
7756 r
= start_with_fallback();
7761 r
= reload_with_fallback();
7764 case ACTION_CANCEL_SHUTDOWN
:
7765 r
= logind_cancel_shutdown();
7768 case ACTION_RUNLEVEL
:
7769 r
= runlevel_main();
7772 case _ACTION_INVALID
:
7774 assert_not_reached("Unknown action");
7779 ask_password_agent_close();
7780 polkit_agent_close();
7782 strv_free(arg_types
);
7783 strv_free(arg_states
);
7784 strv_free(arg_properties
);
7786 strv_free(arg_wall
);
7791 return r
< 0 ? EXIT_FAILURE
: r
;