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"
59 #include "logs-show.h"
63 #include "path-lookup.h"
64 #include "path-util.h"
65 #include "process-util.h"
67 #include "signal-util.h"
68 #include "socket-util.h"
69 #include "spawn-ask-password-agent.h"
70 #include "spawn-polkit-agent.h"
73 #include "terminal-util.h"
74 #include "unit-name.h"
76 #include "utmp-wtmp.h"
79 static char **arg_types
= NULL
;
80 static char **arg_states
= NULL
;
81 static char **arg_properties
= NULL
;
82 static bool arg_all
= false;
83 static enum dependency
{
89 } arg_dependency
= DEPENDENCY_FORWARD
;
90 static const char *arg_job_mode
= "replace";
91 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
92 static bool arg_no_block
= false;
93 static bool arg_no_legend
= false;
94 static bool arg_no_pager
= false;
95 static bool arg_no_wtmp
= false;
96 static bool arg_no_wall
= false;
97 static bool arg_no_reload
= false;
98 static bool arg_show_types
= false;
99 static bool arg_ignore_inhibitors
= false;
100 static bool arg_dry
= false;
101 static bool arg_quiet
= false;
102 static bool arg_full
= false;
103 static bool arg_recursive
= false;
104 static int arg_force
= 0;
105 static bool arg_ask_password
= false;
106 static bool arg_runtime
= false;
107 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
108 static char **arg_wall
= NULL
;
109 static const char *arg_kill_who
= NULL
;
110 static int arg_signal
= SIGTERM
;
111 static char *arg_root
= NULL
;
112 static usec_t arg_when
= 0;
134 ACTION_CANCEL_SHUTDOWN
,
136 } arg_action
= ACTION_SYSTEMCTL
;
137 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
138 static const char *arg_host
= NULL
;
139 static unsigned arg_lines
= 10;
140 static OutputMode arg_output
= OUTPUT_SHORT
;
141 static bool arg_plain
= false;
142 static bool arg_firmware_setup
= false;
143 static bool arg_now
= false;
145 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
146 static int halt_now(enum action a
);
147 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
149 static bool original_stdout_is_tty
;
151 typedef enum BusFocus
{
152 BUS_FULL
, /* The full bus indicated via --system or --user */
153 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
157 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
159 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
162 assert(focus
< _BUS_FOCUS_MAX
);
165 /* We only go directly to the manager, if we are using a local transport */
166 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
169 if (!busses
[focus
]) {
172 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
174 if (focus
== BUS_MANAGER
)
175 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
177 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
179 return log_error_errno(r
, "Failed to connect to bus: %m");
181 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
184 *ret
= busses
[focus
];
188 static void release_busses(void) {
191 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
192 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
195 static void pager_open_if_enabled(void) {
203 static void ask_password_agent_open_if_enabled(void) {
205 /* Open the password agent as a child process if necessary */
207 if (!arg_ask_password
)
210 if (arg_scope
!= UNIT_FILE_SYSTEM
)
213 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
216 ask_password_agent_open();
219 static void polkit_agent_open_if_enabled(void) {
221 /* Open the polkit agent as a child process if necessary */
223 if (!arg_ask_password
)
226 if (arg_scope
!= UNIT_FILE_SYSTEM
)
229 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
235 static OutputFlags
get_output_flags(void) {
237 arg_all
* OUTPUT_SHOW_ALL
|
238 arg_full
* OUTPUT_FULL_WIDTH
|
239 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
240 on_tty() * OUTPUT_COLOR
|
241 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
244 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
247 if (!sd_bus_error_is_set(error
))
250 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
251 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
252 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
253 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
254 return EXIT_NOPERMISSION
;
256 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
257 return EXIT_NOTINSTALLED
;
259 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
260 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
261 return EXIT_NOTIMPLEMENTED
;
263 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
264 return EXIT_NOTCONFIGURED
;
272 static bool install_client_side(void) {
274 /* Decides when to execute enable/disable/... operations
275 * client-side rather than server-side. */
277 if (running_in_chroot() > 0)
280 if (sd_booted() <= 0)
283 if (!isempty(arg_root
))
286 if (arg_scope
== UNIT_FILE_GLOBAL
)
292 static int compare_unit_info(const void *a
, const void *b
) {
293 const UnitInfo
*u
= a
, *v
= b
;
297 /* First, order by machine */
298 if (!u
->machine
&& v
->machine
)
300 if (u
->machine
&& !v
->machine
)
302 if (u
->machine
&& v
->machine
) {
303 r
= strcasecmp(u
->machine
, v
->machine
);
308 /* Second, order by unit type */
309 d1
= strrchr(u
->id
, '.');
310 d2
= strrchr(v
->id
, '.');
312 r
= strcasecmp(d1
, d2
);
317 /* Third, order by name */
318 return strcasecmp(u
->id
, v
->id
);
321 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
322 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
328 dot
= strrchr(u
->id
, '.');
332 if (!strv_find(arg_types
, dot
+1))
342 if (streq(u
->active_state
, "inactive") || u
->following
[0])
348 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
349 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
351 unsigned n_shown
= 0;
354 max_id_len
= strlen("UNIT");
355 load_len
= strlen("LOAD");
356 active_len
= strlen("ACTIVE");
357 sub_len
= strlen("SUB");
358 job_len
= strlen("JOB");
361 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
362 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
363 load_len
= MAX(load_len
, strlen(u
->load_state
));
364 active_len
= MAX(active_len
, strlen(u
->active_state
));
365 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
367 if (u
->job_id
!= 0) {
368 job_len
= MAX(job_len
, strlen(u
->job_type
));
372 if (!arg_no_legend
&&
373 (streq(u
->active_state
, "failed") ||
374 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
378 if (!arg_full
&& original_stdout_is_tty
) {
381 id_len
= MIN(max_id_len
, 25u);
382 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
385 basic_len
+= job_len
+ 1;
387 if (basic_len
< (unsigned) columns()) {
388 unsigned extra_len
, incr
;
389 extra_len
= columns() - basic_len
;
391 /* Either UNIT already got 25, or is fully satisfied.
392 * Grant up to 25 to DESC now. */
393 incr
= MIN(extra_len
, 25u);
397 /* split the remaining space between UNIT and DESC,
398 * but do not give UNIT more than it needs. */
400 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
402 desc_len
+= extra_len
- incr
;
408 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
409 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
410 const char *on_loaded
= "", *off_loaded
= "";
411 const char *on_active
= "", *off_active
= "";
412 const char *on_circle
= "", *off_circle
= "";
416 if (!n_shown
&& !arg_no_legend
) {
421 printf("%-*s %-*s %-*s %-*s ",
424 active_len
, "ACTIVE",
428 printf("%-*s ", job_len
, "JOB");
430 if (!arg_full
&& arg_no_pager
)
431 printf("%.*s\n", desc_len
, "DESCRIPTION");
433 printf("%s\n", "DESCRIPTION");
438 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
439 on_loaded
= ansi_highlight_red();
440 on_circle
= ansi_highlight_yellow();
441 off_loaded
= off_circle
= ansi_normal();
443 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
444 on_circle
= on_active
= ansi_highlight_red();
445 off_circle
= off_active
= ansi_normal();
450 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
459 e
= ellipsize(id
, id_len
, 33);
467 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
469 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
470 on_active
, id_len
, id
, off_active
,
471 on_loaded
, load_len
, u
->load_state
, off_loaded
,
472 on_active
, active_len
, u
->active_state
,
473 sub_len
, u
->sub_state
, off_active
,
474 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
477 printf("%.*s\n", desc_len
, u
->description
);
479 printf("%s\n", u
->description
);
482 if (!arg_no_legend
) {
483 const char *on
, *off
;
487 "LOAD = Reflects whether the unit definition was properly loaded.\n"
488 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
489 "SUB = The low-level unit activation state, values depend on unit type.");
490 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
491 on
= ansi_highlight();
494 on
= ansi_highlight_red();
499 printf("%s%u loaded units listed.%s\n"
500 "To show all installed unit files use 'systemctl list-unit-files'.\n",
503 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
504 "To show all installed unit files use 'systemctl list-unit-files'.\n",
511 static int get_unit_list(
515 UnitInfo
**unit_infos
,
517 sd_bus_message
**_reply
) {
519 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
520 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
521 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
530 r
= sd_bus_message_new_method_call(
533 "org.freedesktop.systemd1",
534 "/org/freedesktop/systemd1",
535 "org.freedesktop.systemd1.Manager",
536 "ListUnitsFiltered");
539 return bus_log_create_error(r
);
541 r
= sd_bus_message_append_strv(m
, arg_states
);
543 return bus_log_create_error(r
);
545 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
547 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
549 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
551 return bus_log_parse_error(r
);
553 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
556 if (!output_show_unit(&u
, patterns
))
559 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
562 (*unit_infos
)[c
++] = u
;
565 return bus_log_parse_error(r
);
567 r
= sd_bus_message_exit_container(reply
);
569 return bus_log_parse_error(r
);
577 static void message_set_freep(Set
**set
) {
580 while ((m
= set_steal_first(*set
)))
581 sd_bus_message_unref(m
);
586 static int get_unit_list_recursive(
589 UnitInfo
**_unit_infos
,
593 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
594 _cleanup_(message_set_freep
) Set
*replies
;
595 sd_bus_message
*reply
;
603 replies
= set_new(NULL
);
607 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
611 r
= set_put(replies
, reply
);
613 sd_bus_message_unref(reply
);
618 _cleanup_strv_free_
char **machines
= NULL
;
621 r
= sd_get_machine_names(&machines
);
623 return log_error_errno(r
, "Failed to get machine names: %m");
625 STRV_FOREACH(i
, machines
) {
626 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
629 r
= sd_bus_open_system_machine(&container
, *i
);
631 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
635 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
641 r
= set_put(replies
, reply
);
643 sd_bus_message_unref(reply
);
648 *_machines
= machines
;
653 *_unit_infos
= unit_infos
;
662 static int list_units(int argc
, char *argv
[], void *userdata
) {
663 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
664 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
665 _cleanup_strv_free_
char **machines
= NULL
;
669 pager_open_if_enabled();
671 r
= acquire_bus(BUS_MANAGER
, &bus
);
675 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
679 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
680 return output_units_list(unit_infos
, r
);
683 static int get_triggered_units(
688 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
695 r
= sd_bus_get_property_strv(
697 "org.freedesktop.systemd1",
699 "org.freedesktop.systemd1.Unit",
704 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
709 static int get_listening(
711 const char* unit_path
,
714 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
715 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
716 const char *type
, *path
;
719 r
= sd_bus_get_property(
721 "org.freedesktop.systemd1",
723 "org.freedesktop.systemd1.Socket",
729 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
731 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
733 return bus_log_parse_error(r
);
735 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
737 r
= strv_extend(listening
, type
);
741 r
= strv_extend(listening
, path
);
748 return bus_log_parse_error(r
);
750 r
= sd_bus_message_exit_container(reply
);
752 return bus_log_parse_error(r
);
764 /* Note: triggered is a list here, although it almost certainly
765 * will always be one unit. Nevertheless, dbus API allows for multiple
766 * values, so let's follow that. */
769 /* The strv above is shared. free is set only in the first one. */
773 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
779 if (!a
->machine
&& b
->machine
)
781 if (a
->machine
&& !b
->machine
)
783 if (a
->machine
&& b
->machine
) {
784 o
= strcasecmp(a
->machine
, b
->machine
);
789 o
= strcmp(a
->path
, b
->path
);
791 o
= strcmp(a
->type
, b
->type
);
796 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
797 struct socket_info
*s
;
798 unsigned pathlen
= strlen("LISTEN"),
799 typelen
= strlen("TYPE") * arg_show_types
,
800 socklen
= strlen("UNIT"),
801 servlen
= strlen("ACTIVATES");
802 const char *on
, *off
;
804 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
808 socklen
= MAX(socklen
, strlen(s
->id
));
810 typelen
= MAX(typelen
, strlen(s
->type
));
811 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
813 STRV_FOREACH(a
, s
->triggered
)
814 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
815 servlen
= MAX(servlen
, tmp
);
820 printf("%-*s %-*.*s%-*s %s\n",
822 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
826 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
827 _cleanup_free_
char *j
= NULL
;
832 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
840 printf("%-*s %-*s %-*s",
841 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
844 pathlen
, path
, socklen
, s
->id
);
845 STRV_FOREACH(a
, s
->triggered
)
847 a
== s
->triggered
? "" : ",", *a
);
851 on
= ansi_highlight();
856 on
= ansi_highlight_red();
860 if (!arg_no_legend
) {
861 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
863 printf("Pass --all to see loaded but inactive sockets, too.\n");
869 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
870 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
871 _cleanup_strv_free_
char **machines
= NULL
;
872 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
873 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
875 struct socket_info
*s
;
881 pager_open_if_enabled();
883 r
= acquire_bus(BUS_MANAGER
, &bus
);
887 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
891 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
892 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
895 if (!endswith(u
->id
, ".socket"))
898 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
902 c
= get_listening(bus
, u
->unit_path
, &listening
);
908 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
913 for (i
= 0; i
< c
; i
++)
914 socket_infos
[cs
+ i
] = (struct socket_info
) {
915 .machine
= u
->machine
,
917 .type
= listening
[i
*2],
918 .path
= listening
[i
*2 + 1],
919 .triggered
= triggered
,
920 .own_triggered
= i
==0,
923 /* from this point on we will cleanup those socket_infos */
926 listening
= triggered
= NULL
; /* avoid cleanup */
929 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
930 (__compar_fn_t
) socket_info_compare
);
932 output_sockets_list(socket_infos
, cs
);
935 assert(cs
== 0 || socket_infos
);
936 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
939 if (s
->own_triggered
)
940 strv_free(s
->triggered
);
946 static int get_next_elapse(
949 dual_timestamp
*next
) {
951 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
959 r
= sd_bus_get_property_trivial(
961 "org.freedesktop.systemd1",
963 "org.freedesktop.systemd1.Timer",
964 "NextElapseUSecMonotonic",
969 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
971 r
= sd_bus_get_property_trivial(
973 "org.freedesktop.systemd1",
975 "org.freedesktop.systemd1.Timer",
976 "NextElapseUSecRealtime",
981 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
987 static int get_last_trigger(
992 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
999 r
= sd_bus_get_property_trivial(
1001 "org.freedesktop.systemd1",
1003 "org.freedesktop.systemd1.Timer",
1009 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1015 const char* machine
;
1018 usec_t last_trigger
;
1022 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1028 if (!a
->machine
&& b
->machine
)
1030 if (a
->machine
&& !b
->machine
)
1032 if (a
->machine
&& b
->machine
) {
1033 o
= strcasecmp(a
->machine
, b
->machine
);
1038 if (a
->next_elapse
< b
->next_elapse
)
1040 if (a
->next_elapse
> b
->next_elapse
)
1043 return strcmp(a
->id
, b
->id
);
1046 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1047 struct timer_info
*t
;
1049 nextlen
= strlen("NEXT"),
1050 leftlen
= strlen("LEFT"),
1051 lastlen
= strlen("LAST"),
1052 passedlen
= strlen("PASSED"),
1053 unitlen
= strlen("UNIT"),
1054 activatelen
= strlen("ACTIVATES");
1056 const char *on
, *off
;
1058 assert(timer_infos
|| n
== 0);
1060 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1064 if (t
->next_elapse
> 0) {
1065 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1067 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1068 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1070 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1071 leftlen
= MAX(leftlen
, strlen(trel
));
1074 if (t
->last_trigger
> 0) {
1075 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1077 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1078 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1080 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1081 passedlen
= MAX(passedlen
, strlen(trel
));
1084 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1086 STRV_FOREACH(a
, t
->triggered
)
1087 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1089 activatelen
= MAX(activatelen
, ul
);
1094 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1098 passedlen
, "PASSED",
1102 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1103 _cleanup_free_
char *j
= NULL
;
1105 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1106 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1109 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1110 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1112 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1113 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1116 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1123 printf("%-*s %-*s %-*s %-*s %-*s",
1124 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1126 STRV_FOREACH(a
, t
->triggered
)
1128 a
== t
->triggered
? "" : ",", *a
);
1132 on
= ansi_highlight();
1133 off
= ansi_normal();
1137 on
= ansi_highlight_red();
1138 off
= ansi_normal();
1141 if (!arg_no_legend
) {
1142 printf("%s%u timers listed.%s\n", on
, n
, off
);
1144 printf("Pass --all to see loaded but inactive timers, too.\n");
1150 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1156 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1159 if (next
->monotonic
> nw
->monotonic
)
1160 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1162 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1164 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1165 next_elapse
= MIN(converted
, next
->realtime
);
1167 next_elapse
= converted
;
1170 next_elapse
= next
->realtime
;
1175 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1176 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1177 _cleanup_strv_free_
char **machines
= NULL
;
1178 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1179 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1180 struct timer_info
*t
;
1188 pager_open_if_enabled();
1190 r
= acquire_bus(BUS_MANAGER
, &bus
);
1194 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1198 dual_timestamp_get(&nw
);
1200 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1201 _cleanup_strv_free_
char **triggered
= NULL
;
1202 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1205 if (!endswith(u
->id
, ".timer"))
1208 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1212 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1216 get_last_trigger(bus
, u
->unit_path
, &last
);
1218 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1223 m
= calc_next_elapse(&nw
, &next
);
1225 timer_infos
[c
++] = (struct timer_info
) {
1226 .machine
= u
->machine
,
1229 .last_trigger
= last
,
1230 .triggered
= triggered
,
1233 triggered
= NULL
; /* avoid cleanup */
1236 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1237 (__compar_fn_t
) timer_info_compare
);
1239 output_timers_list(timer_infos
, c
);
1242 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1243 strv_free(t
->triggered
);
1248 static int compare_unit_file_list(const void *a
, const void *b
) {
1249 const char *d1
, *d2
;
1250 const UnitFileList
*u
= a
, *v
= b
;
1252 d1
= strrchr(u
->path
, '.');
1253 d2
= strrchr(v
->path
, '.');
1258 r
= strcasecmp(d1
, d2
);
1263 return strcasecmp(basename(u
->path
), basename(v
->path
));
1266 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1267 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1270 if (!strv_isempty(arg_types
)) {
1273 dot
= strrchr(u
->path
, '.');
1277 if (!strv_find(arg_types
, dot
+1))
1281 if (!strv_isempty(arg_states
) &&
1282 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1288 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1289 unsigned max_id_len
, id_cols
, state_cols
;
1290 const UnitFileList
*u
;
1292 max_id_len
= strlen("UNIT FILE");
1293 state_cols
= strlen("STATE");
1295 for (u
= units
; u
< units
+ c
; u
++) {
1296 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1297 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1301 unsigned basic_cols
;
1303 id_cols
= MIN(max_id_len
, 25u);
1304 basic_cols
= 1 + id_cols
+ state_cols
;
1305 if (basic_cols
< (unsigned) columns())
1306 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1308 id_cols
= max_id_len
;
1311 printf("%-*s %-*s\n",
1312 id_cols
, "UNIT FILE",
1313 state_cols
, "STATE");
1315 for (u
= units
; u
< units
+ c
; u
++) {
1316 _cleanup_free_
char *e
= NULL
;
1317 const char *on
, *off
;
1320 if (IN_SET(u
->state
,
1322 UNIT_FILE_MASKED_RUNTIME
,
1324 UNIT_FILE_INVALID
)) {
1325 on
= ansi_highlight_red();
1326 off
= ansi_normal();
1327 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1328 on
= ansi_highlight_green();
1329 off
= ansi_normal();
1333 id
= basename(u
->path
);
1335 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1337 printf("%-*s %s%-*s%s\n",
1338 id_cols
, e
? e
: id
,
1339 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1343 printf("\n%u unit files listed.\n", c
);
1346 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1347 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1348 _cleanup_free_ UnitFileList
*units
= NULL
;
1356 pager_open_if_enabled();
1358 if (install_client_side()) {
1364 h
= hashmap_new(&string_hash_ops
);
1368 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1370 unit_file_list_free(h
);
1371 return log_error_errno(r
, "Failed to get unit file list: %m");
1374 n_units
= hashmap_size(h
);
1376 units
= new(UnitFileList
, n_units
);
1377 if (!units
&& n_units
> 0) {
1378 unit_file_list_free(h
);
1382 HASHMAP_FOREACH(u
, h
, i
) {
1383 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1390 assert(c
<= n_units
);
1393 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1396 r
= acquire_bus(BUS_MANAGER
, &bus
);
1400 r
= sd_bus_call_method(
1402 "org.freedesktop.systemd1",
1403 "/org/freedesktop/systemd1",
1404 "org.freedesktop.systemd1.Manager",
1410 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1412 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1414 return bus_log_parse_error(r
);
1416 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1418 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1421 units
[c
] = (struct UnitFileList
) {
1423 unit_file_state_from_string(state
)
1426 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1431 return bus_log_parse_error(r
);
1433 r
= sd_bus_message_exit_container(reply
);
1435 return bus_log_parse_error(r
);
1438 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1439 output_unit_file_list(units
, c
);
1441 if (install_client_side()) {
1442 for (unit
= units
; unit
< units
+ c
; unit
++)
1449 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1450 _cleanup_free_
char *n
= NULL
;
1451 size_t max_len
= MAX(columns(),20u);
1457 for (i
= level
- 1; i
>= 0; i
--) {
1459 if (len
> max_len
- 3 && !arg_full
) {
1460 printf("%s...\n",max_len
% 2 ? "" : " ");
1463 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1467 if (len
> max_len
- 3 && !arg_full
) {
1468 printf("%s...\n",max_len
% 2 ? "" : " ");
1472 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1476 printf("%s\n", name
);
1480 n
= ellipsize(name
, max_len
-len
, 100);
1488 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1490 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1491 [DEPENDENCY_FORWARD
] = "Requires\0"
1492 "RequiresOverridable\0"
1494 "RequisiteOverridable\0"
1498 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1499 "RequiredByOverridable\0"
1501 "RequisiteOfOverridable\0"
1505 [DEPENDENCY_AFTER
] = "After\0",
1506 [DEPENDENCY_BEFORE
] = "Before\0",
1509 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1510 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1511 _cleanup_strv_free_
char **ret
= NULL
;
1512 _cleanup_free_
char *path
= NULL
;
1518 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1520 path
= unit_dbus_path_from_name(name
);
1524 r
= sd_bus_call_method(
1526 "org.freedesktop.systemd1",
1528 "org.freedesktop.DBus.Properties",
1532 "s", "org.freedesktop.systemd1.Unit");
1534 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1536 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1538 return bus_log_parse_error(r
);
1540 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1543 r
= sd_bus_message_read(reply
, "s", &prop
);
1545 return bus_log_parse_error(r
);
1547 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1548 r
= sd_bus_message_skip(reply
, "v");
1550 return bus_log_parse_error(r
);
1553 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1555 return bus_log_parse_error(r
);
1557 r
= bus_message_read_strv_extend(reply
, &ret
);
1559 return bus_log_parse_error(r
);
1561 r
= sd_bus_message_exit_container(reply
);
1563 return bus_log_parse_error(r
);
1566 r
= sd_bus_message_exit_container(reply
);
1568 return bus_log_parse_error(r
);
1572 return bus_log_parse_error(r
);
1574 r
= sd_bus_message_exit_container(reply
);
1576 return bus_log_parse_error(r
);
1584 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1585 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1587 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1589 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1592 return strcasecmp(*a
, *b
);
1595 static int list_dependencies_one(
1600 unsigned int branches
) {
1602 _cleanup_strv_free_
char **deps
= NULL
;
1610 r
= strv_extend(units
, name
);
1614 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1618 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1620 STRV_FOREACH(c
, deps
) {
1621 if (strv_contains(*units
, *c
)) {
1623 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1636 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1637 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1638 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1641 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1645 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1646 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1653 strv_remove(*units
, name
);
1658 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1659 _cleanup_strv_free_
char **units
= NULL
;
1660 _cleanup_free_
char *unit
= NULL
;
1666 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1668 return log_error_errno(r
, "Failed to mangle unit name: %m");
1672 u
= SPECIAL_DEFAULT_TARGET
;
1674 pager_open_if_enabled();
1676 r
= acquire_bus(BUS_MANAGER
, &bus
);
1682 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1685 struct machine_info
{
1689 char *control_group
;
1690 uint32_t n_failed_units
;
1695 static const struct bus_properties_map machine_info_property_map
[] = {
1696 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1697 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1698 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1699 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1700 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1704 static void machine_info_clear(struct machine_info
*info
) {
1708 free(info
->control_group
);
1713 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1719 for (i
= 0; i
< n
; i
++)
1720 machine_info_clear(&machine_infos
[i
]);
1722 free(machine_infos
);
1725 static int compare_machine_info(const void *a
, const void *b
) {
1726 const struct machine_info
*u
= a
, *v
= b
;
1728 if (u
->is_host
!= v
->is_host
)
1729 return u
->is_host
> v
->is_host
? -1 : 1;
1731 return strcasecmp(u
->name
, v
->name
);
1734 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1735 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1741 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1748 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1755 static bool output_show_machine(const char *name
, char **patterns
) {
1756 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1759 static int get_machine_list(
1761 struct machine_info
**_machine_infos
,
1764 struct machine_info
*machine_infos
= NULL
;
1765 _cleanup_strv_free_
char **m
= NULL
;
1766 _cleanup_free_
char *hn
= NULL
;
1771 hn
= gethostname_malloc();
1775 if (output_show_machine(hn
, patterns
)) {
1776 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1779 machine_infos
[c
].is_host
= true;
1780 machine_infos
[c
].name
= hn
;
1783 get_machine_properties(bus
, &machine_infos
[c
]);
1787 r
= sd_get_machine_names(&m
);
1789 return log_error_errno(r
, "Failed to get machine list: %m");
1791 STRV_FOREACH(i
, m
) {
1792 _cleanup_free_
char *class = NULL
;
1794 if (!output_show_machine(*i
, patterns
))
1797 sd_machine_get_class(*i
, &class);
1798 if (!streq_ptr(class, "container"))
1801 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1802 free_machines_list(machine_infos
, c
);
1806 machine_infos
[c
].is_host
= false;
1807 machine_infos
[c
].name
= strdup(*i
);
1808 if (!machine_infos
[c
].name
) {
1809 free_machines_list(machine_infos
, c
);
1813 get_machine_properties(NULL
, &machine_infos
[c
]);
1817 *_machine_infos
= machine_infos
;
1821 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1822 struct machine_info
*m
;
1825 namelen
= sizeof("NAME") - 1,
1826 statelen
= sizeof("STATE") - 1,
1827 failedlen
= sizeof("FAILED") - 1,
1828 jobslen
= sizeof("JOBS") - 1;
1830 assert(machine_infos
|| n
== 0);
1832 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1833 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1834 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1835 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1836 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1838 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1842 if (!arg_no_legend
) {
1846 printf("%-*s %-*s %-*s %-*s\n",
1849 failedlen
, "FAILED",
1853 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1854 const char *on_state
= "", *off_state
= "";
1855 const char *on_failed
= "", *off_failed
= "";
1856 bool circle
= false;
1858 if (streq_ptr(m
->state
, "degraded")) {
1859 on_state
= ansi_highlight_red();
1860 off_state
= ansi_normal();
1862 } else if (!streq_ptr(m
->state
, "running")) {
1863 on_state
= ansi_highlight_yellow();
1864 off_state
= ansi_normal();
1868 if (m
->n_failed_units
> 0) {
1869 on_failed
= ansi_highlight_red();
1870 off_failed
= ansi_normal();
1872 on_failed
= off_failed
= "";
1875 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1878 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1879 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1880 on_state
, statelen
, strna(m
->state
), off_state
,
1881 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1882 jobslen
, m
->n_jobs
);
1884 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1885 namelen
, strna(m
->name
),
1886 on_state
, statelen
, strna(m
->state
), off_state
,
1887 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1888 jobslen
, m
->n_jobs
);
1892 printf("\n%u machines listed.\n", n
);
1895 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1896 struct machine_info
*machine_infos
= NULL
;
1900 if (geteuid() != 0) {
1901 log_error("Must be root.");
1905 pager_open_if_enabled();
1907 r
= acquire_bus(BUS_MANAGER
, &bus
);
1911 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1915 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1916 output_machines_list(machine_infos
, r
);
1917 free_machines_list(machine_infos
, r
);
1922 static int get_default(int argc
, char *argv
[], void *userdata
) {
1923 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1924 _cleanup_free_
char *_path
= NULL
;
1928 if (install_client_side()) {
1929 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1931 return log_error_errno(r
, "Failed to get default target: %m");
1935 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1938 r
= acquire_bus(BUS_MANAGER
, &bus
);
1942 r
= sd_bus_call_method(
1944 "org.freedesktop.systemd1",
1945 "/org/freedesktop/systemd1",
1946 "org.freedesktop.systemd1.Manager",
1952 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1954 r
= sd_bus_message_read(reply
, "s", &path
);
1956 return bus_log_parse_error(r
);
1960 printf("%s\n", path
);
1965 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1968 assert(changes
|| n_changes
== 0);
1970 for (i
= 0; i
< n_changes
; i
++) {
1971 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1972 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1974 log_info("Removed symlink %s.", changes
[i
].path
);
1978 static int set_default(int argc
, char *argv
[], void *userdata
) {
1979 _cleanup_free_
char *unit
= NULL
;
1985 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1987 return log_error_errno(r
, "Failed to mangle unit name: %m");
1989 if (install_client_side()) {
1990 UnitFileChange
*changes
= NULL
;
1991 unsigned n_changes
= 0;
1993 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
1995 return log_error_errno(r
, "Failed to set default target: %m");
1998 dump_unit_file_changes(changes
, n_changes
);
2000 unit_file_changes_free(changes
, n_changes
);
2003 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2004 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2007 polkit_agent_open_if_enabled();
2009 r
= acquire_bus(BUS_MANAGER
, &bus
);
2013 r
= sd_bus_call_method(
2015 "org.freedesktop.systemd1",
2016 "/org/freedesktop/systemd1",
2017 "org.freedesktop.systemd1.Manager",
2023 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2025 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2029 /* Try to reload if enabled */
2031 r
= daemon_reload(argc
, argv
, userdata
);
2041 const char *name
, *type
, *state
;
2044 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2045 unsigned id_len
, unit_len
, type_len
, state_len
;
2046 const struct job_info
*j
;
2047 const char *on
, *off
;
2048 bool shorten
= false;
2050 assert(n
== 0 || jobs
);
2053 if (!arg_no_legend
) {
2054 on
= ansi_highlight_green();
2055 off
= ansi_normal();
2057 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2062 pager_open_if_enabled();
2064 id_len
= strlen("JOB");
2065 unit_len
= strlen("UNIT");
2066 type_len
= strlen("TYPE");
2067 state_len
= strlen("STATE");
2069 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2070 uint32_t id
= j
->id
;
2071 assert(j
->name
&& j
->type
&& j
->state
);
2073 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2074 unit_len
= MAX(unit_len
, strlen(j
->name
));
2075 type_len
= MAX(type_len
, strlen(j
->type
));
2076 state_len
= MAX(state_len
, strlen(j
->state
));
2079 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2080 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2085 printf("%*s %-*s %-*s %-*s\n",
2089 state_len
, "STATE");
2091 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2092 _cleanup_free_
char *e
= NULL
;
2094 if (streq(j
->state
, "running")) {
2095 on
= ansi_highlight();
2096 off
= ansi_normal();
2100 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2101 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2103 on
, unit_len
, e
? e
: j
->name
, off
,
2105 on
, state_len
, j
->state
, off
);
2108 if (!arg_no_legend
) {
2109 on
= ansi_highlight();
2110 off
= ansi_normal();
2112 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2116 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2117 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2120 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2121 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2122 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2123 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2124 _cleanup_free_
struct job_info
*jobs
= NULL
;
2130 bool skipped
= false;
2132 pager_open_if_enabled();
2134 r
= acquire_bus(BUS_MANAGER
, &bus
);
2138 r
= sd_bus_call_method(
2140 "org.freedesktop.systemd1",
2141 "/org/freedesktop/systemd1",
2142 "org.freedesktop.systemd1.Manager",
2148 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2150 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2152 return bus_log_parse_error(r
);
2154 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2155 struct job_info job
= { id
, name
, type
, state
};
2157 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2162 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2168 return bus_log_parse_error(r
);
2170 r
= sd_bus_message_exit_container(reply
);
2172 return bus_log_parse_error(r
);
2174 output_jobs_list(jobs
, c
, skipped
);
2178 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2184 return daemon_reload(argc
, argv
, userdata
);
2186 polkit_agent_open_if_enabled();
2188 r
= acquire_bus(BUS_MANAGER
, &bus
);
2192 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2193 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2197 q
= safe_atou32(*name
, &id
);
2199 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2201 q
= sd_bus_call_method(
2203 "org.freedesktop.systemd1",
2204 "/org/freedesktop/systemd1",
2205 "org.freedesktop.systemd1.Manager",
2211 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2220 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2221 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2225 /* We ignore all errors here, since this is used to show a
2228 /* We don't use unit_dbus_path_from_name() directly since we
2229 * don't want to load the unit if it isn't loaded. */
2231 r
= sd_bus_call_method(
2233 "org.freedesktop.systemd1",
2234 "/org/freedesktop/systemd1",
2235 "org.freedesktop.systemd1.Manager",
2243 r
= sd_bus_message_read(reply
, "o", &path
);
2247 r
= sd_bus_get_property_trivial(
2249 "org.freedesktop.systemd1",
2251 "org.freedesktop.systemd1.Unit",
2261 static void warn_unit_file_changed(const char *name
) {
2262 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2263 ansi_highlight_red(),
2266 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2269 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2276 STRV_FOREACH(p
, lp
->unit_path
) {
2277 _cleanup_free_
char *path
;
2279 path
= path_join(arg_root
, *p
, unit_name
);
2283 if (access(path
, F_OK
) == 0) {
2293 static int unit_find_paths(
2295 const char *unit_name
,
2297 char **fragment_path
,
2298 char ***dropin_paths
) {
2300 _cleanup_free_
char *path
= NULL
;
2301 _cleanup_strv_free_
char **dropins
= NULL
;
2305 * Finds where the unit is defined on disk. Returns 0 if the unit
2306 * is not found. Returns 1 if it is found, and sets
2307 * - the path to the unit in *path, if it exists on disk,
2308 * - and a strv of existing drop-ins in *dropins,
2309 * if the arg is not NULL and any dropins were found.
2313 assert(fragment_path
);
2316 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2317 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2318 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2319 _cleanup_free_
char *unit
= NULL
;
2320 char *unit_load_error_name
, *unit_load_error_message
;
2322 unit
= unit_dbus_path_from_name(unit_name
);
2326 if (need_daemon_reload(bus
, unit_name
) > 0)
2327 warn_unit_file_changed(unit_name
);
2329 r
= sd_bus_get_property(
2331 "org.freedesktop.systemd1",
2333 "org.freedesktop.systemd1.Unit",
2339 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2341 r
= sd_bus_message_read(
2344 &unit_load_error_name
,
2345 &unit_load_error_message
);
2347 return bus_log_parse_error(r
);
2349 if (!isempty(unit_load_error_name
)) {
2350 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2354 r
= sd_bus_get_property_string(
2356 "org.freedesktop.systemd1",
2358 "org.freedesktop.systemd1.Unit",
2363 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2366 r
= sd_bus_get_property_strv(
2368 "org.freedesktop.systemd1",
2370 "org.freedesktop.systemd1.Unit",
2375 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2378 _cleanup_set_free_ Set
*names
;
2380 names
= set_new(NULL
);
2384 r
= set_put(names
, unit_name
);
2386 return log_error_errno(r
, "Failed to add unit name: %m");
2388 r
= unit_file_find_path(lp
, unit_name
, &path
);
2393 _cleanup_free_
char *template = NULL
;
2395 r
= unit_name_template(unit_name
, &template);
2396 if (r
< 0 && r
!= -EINVAL
)
2397 return log_error_errno(r
, "Failed to determine template name: %m");
2399 r
= unit_file_find_path(lp
, template, &path
);
2406 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2414 if (!isempty(path
)) {
2415 *fragment_path
= path
;
2420 if (dropin_paths
&& !strv_isempty(dropins
)) {
2421 *dropin_paths
= dropins
;
2427 log_error("No files found for %s.", unit_name
);
2432 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2433 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2434 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2440 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2442 return log_error_errno(r
, "Failed to mangle unit name: %m");
2444 /* We don't use unit_dbus_path_from_name() directly since we
2445 * don't want to load the unit if it isn't loaded. */
2447 r
= sd_bus_call_method(
2449 "org.freedesktop.systemd1",
2450 "/org/freedesktop/systemd1",
2451 "org.freedesktop.systemd1.Manager",
2462 r
= sd_bus_message_read(reply
, "o", &path
);
2464 return bus_log_parse_error(r
);
2466 r
= sd_bus_get_property_string(
2468 "org.freedesktop.systemd1",
2470 "org.freedesktop.systemd1.Unit",
2483 return nulstr_contains(good_states
, state
);
2486 static int check_triggering_units(
2490 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2491 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2492 _cleanup_strv_free_
char **triggered_by
= NULL
;
2493 bool print_warning_label
= true;
2497 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2499 return log_error_errno(r
, "Failed to mangle unit name: %m");
2501 path
= unit_dbus_path_from_name(n
);
2505 r
= sd_bus_get_property_string(
2507 "org.freedesktop.systemd1",
2509 "org.freedesktop.systemd1.Unit",
2514 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2516 if (streq(state
, "masked"))
2519 r
= sd_bus_get_property_strv(
2521 "org.freedesktop.systemd1",
2523 "org.freedesktop.systemd1.Unit",
2528 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2530 STRV_FOREACH(i
, triggered_by
) {
2531 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2533 return log_error_errno(r
, "Failed to check unit: %m");
2538 if (print_warning_label
) {
2539 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2540 print_warning_label
= false;
2543 log_warning(" %s", *i
);
2549 static const struct {
2552 } unit_actions
[] = {
2553 { "start", "StartUnit" },
2554 { "stop", "StopUnit" },
2555 { "condstop", "StopUnit" },
2556 { "reload", "ReloadUnit" },
2557 { "restart", "RestartUnit" },
2558 { "try-restart", "TryRestartUnit" },
2559 { "condrestart", "TryRestartUnit" },
2560 { "reload-or-restart", "ReloadOrRestartUnit" },
2561 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2562 { "condreload", "ReloadOrTryRestartUnit" },
2563 { "force-reload", "ReloadOrTryRestartUnit" }
2566 static const char *verb_to_method(const char *verb
) {
2569 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2570 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2571 return unit_actions
[i
].method
;
2576 static const char *method_to_verb(const char *method
) {
2579 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2580 if (streq_ptr(unit_actions
[i
].method
, method
))
2581 return unit_actions
[i
].verb
;
2586 static int start_unit_one(
2591 sd_bus_error
*error
,
2592 BusWaitForJobs
*w
) {
2594 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2603 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2605 r
= sd_bus_call_method(
2607 "org.freedesktop.systemd1",
2608 "/org/freedesktop/systemd1",
2609 "org.freedesktop.systemd1.Manager",
2617 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2618 /* There's always a fallback possible for
2619 * legacy actions. */
2620 return -EADDRNOTAVAIL
;
2622 verb
= method_to_verb(method
);
2624 return log_error_errno(r
, "Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2627 r
= sd_bus_message_read(reply
, "o", &path
);
2629 return bus_log_parse_error(r
);
2631 if (need_daemon_reload(bus
, name
) > 0)
2632 warn_unit_file_changed(name
);
2635 log_debug("Adding %s to the set", path
);
2636 r
= bus_wait_for_jobs_add(w
, path
);
2644 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2645 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2652 STRV_FOREACH(name
, names
) {
2656 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2658 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2660 return log_error_errno(r
, "Failed to mangle name: %m");
2662 if (string_is_glob(t
))
2663 r
= strv_consume(&globs
, t
);
2665 r
= strv_consume(&mangled
, t
);
2670 /* Query the manager only if any of the names are a glob, since
2671 * this is fairly expensive */
2672 if (!strv_isempty(globs
)) {
2673 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2674 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2676 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2680 for (i
= 0; i
< r
; i
++)
2681 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2686 mangled
= NULL
; /* do not free */
2691 static const struct {
2695 } action_table
[_ACTION_MAX
] = {
2696 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2697 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2698 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2699 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2700 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2701 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2702 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2703 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2704 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2705 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2706 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2707 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2708 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2709 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2710 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2713 static enum action
verb_to_action(const char *verb
) {
2716 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2717 if (streq_ptr(action_table
[i
].verb
, verb
))
2720 return _ACTION_INVALID
;
2723 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2724 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2725 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2726 _cleanup_strv_free_
char **names
= NULL
;
2731 ask_password_agent_open_if_enabled();
2732 polkit_agent_open_if_enabled();
2734 r
= acquire_bus(BUS_MANAGER
, &bus
);
2738 if (arg_action
== ACTION_SYSTEMCTL
) {
2741 method
= verb_to_method(argv
[0]);
2742 action
= verb_to_action(argv
[0]);
2744 if (streq(argv
[0], "isolate")) {
2748 mode
= action_table
[action
].mode
?: arg_job_mode
;
2750 one_name
= action_table
[action
].target
;
2752 assert(arg_action
< ELEMENTSOF(action_table
));
2753 assert(action_table
[arg_action
].target
);
2755 method
= "StartUnit";
2757 mode
= action_table
[arg_action
].mode
;
2758 one_name
= action_table
[arg_action
].target
;
2762 names
= strv_new(one_name
, NULL
);
2764 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2766 return log_error_errno(r
, "Failed to expand names: %m");
2769 if (!arg_no_block
) {
2770 r
= bus_wait_for_jobs_new(bus
, &w
);
2772 return log_error_errno(r
, "Could not watch jobs: %m");
2775 STRV_FOREACH(name
, names
) {
2776 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2779 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2780 if (r
>= 0 && q
< 0)
2781 r
= translate_bus_error_to_exit_status(q
, &error
);
2784 if (!arg_no_block
) {
2787 q
= bus_wait_for_jobs(w
, arg_quiet
);
2791 /* When stopping units, warn if they can still be triggered by
2792 * another active unit (socket, path, timer) */
2793 if (!arg_quiet
&& streq(method
, "StopUnit"))
2794 STRV_FOREACH(name
, names
)
2795 check_triggering_units(bus
, *name
);
2801 static int logind_set_wall_message(void) {
2803 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2805 _cleanup_free_
char *m
= NULL
;
2808 r
= acquire_bus(BUS_FULL
, &bus
);
2812 m
= strv_join(arg_wall
, " ");
2816 r
= sd_bus_call_method(
2818 "org.freedesktop.login1",
2819 "/org/freedesktop/login1",
2820 "org.freedesktop.login1.Manager",
2829 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2835 /* Ask systemd-logind, which might grant access to unprivileged users
2836 * through PolicyKit */
2837 static int logind_reboot(enum action a
) {
2839 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2840 const char *method
, *description
;
2844 polkit_agent_open_if_enabled();
2845 (void) logind_set_wall_message();
2847 r
= acquire_bus(BUS_FULL
, &bus
);
2855 description
= "reboot system";
2858 case ACTION_POWEROFF
:
2859 method
= "PowerOff";
2860 description
= "power off system";
2863 case ACTION_SUSPEND
:
2865 description
= "suspend system";
2868 case ACTION_HIBERNATE
:
2869 method
= "Hibernate";
2870 description
= "hibernate system";
2873 case ACTION_HYBRID_SLEEP
:
2874 method
= "HybridSleep";
2875 description
= "put system into hybrid sleep";
2882 r
= sd_bus_call_method(
2884 "org.freedesktop.login1",
2885 "/org/freedesktop/login1",
2886 "org.freedesktop.login1.Manager",
2890 "b", arg_ask_password
);
2892 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2900 static int logind_check_inhibitors(enum action a
) {
2902 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2903 _cleanup_strv_free_
char **sessions
= NULL
;
2904 const char *what
, *who
, *why
, *mode
;
2911 if (arg_ignore_inhibitors
|| arg_force
> 0)
2923 r
= acquire_bus(BUS_FULL
, &bus
);
2927 r
= sd_bus_call_method(
2929 "org.freedesktop.login1",
2930 "/org/freedesktop/login1",
2931 "org.freedesktop.login1.Manager",
2937 /* If logind is not around, then there are no inhibitors... */
2940 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2942 return bus_log_parse_error(r
);
2944 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2945 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2946 _cleanup_strv_free_
char **sv
= NULL
;
2948 if (!streq(mode
, "block"))
2951 sv
= strv_split(what
, ":");
2955 if ((pid_t
) pid
< 0)
2956 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2958 if (!strv_contains(sv
,
2963 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2966 get_process_comm(pid
, &comm
);
2967 user
= uid_to_name(uid
);
2969 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2970 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2975 return bus_log_parse_error(r
);
2977 r
= sd_bus_message_exit_container(reply
);
2979 return bus_log_parse_error(r
);
2981 /* Check for current sessions */
2982 sd_get_sessions(&sessions
);
2983 STRV_FOREACH(s
, sessions
) {
2984 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2986 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2989 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2992 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
2995 sd_session_get_tty(*s
, &tty
);
2996 sd_session_get_seat(*s
, &seat
);
2997 sd_session_get_service(*s
, &service
);
2998 user
= uid_to_name(uid
);
3000 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3007 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3008 action_table
[a
].verb
);
3016 static int logind_prepare_firmware_setup(void) {
3018 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3022 r
= acquire_bus(BUS_FULL
, &bus
);
3026 r
= sd_bus_call_method(
3028 "org.freedesktop.login1",
3029 "/org/freedesktop/login1",
3030 "org.freedesktop.login1.Manager",
3031 "SetRebootToFirmwareSetup",
3036 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3040 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3045 static int prepare_firmware_setup(void) {
3048 if (!arg_firmware_setup
)
3051 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3053 r
= efi_set_reboot_to_firmware(true);
3055 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3060 return logind_prepare_firmware_setup();
3063 static int set_exit_code(uint8_t code
) {
3064 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3068 r
= acquire_bus(BUS_MANAGER
, &bus
);
3072 r
= sd_bus_call_method(
3074 "org.freedesktop.systemd1",
3075 "/org/freedesktop/systemd1",
3076 "org.freedesktop.systemd1.Manager",
3082 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3087 static int start_special(int argc
, char *argv
[], void *userdata
) {
3093 a
= verb_to_action(argv
[0]);
3095 r
= logind_check_inhibitors(a
);
3099 if (arg_force
>= 2 && geteuid() != 0) {
3100 log_error("Must be root.");
3104 r
= prepare_firmware_setup();
3108 if (a
== ACTION_REBOOT
&& argc
> 1) {
3109 r
= update_reboot_param_file(argv
[1]);
3113 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3116 /* If the exit code is not given on the command line,
3117 * don't reset it to zero: just keep it as it might
3118 * have been set previously. */
3120 r
= safe_atou8(argv
[1], &code
);
3122 return log_error_errno(r
, "Invalid exit code.");
3124 r
= set_exit_code(code
);
3129 if (arg_force
>= 2 &&
3136 if (arg_force
>= 1 &&
3143 return daemon_reload(argc
, argv
, userdata
);
3145 /* First try logind, to allow authentication with polkit */
3151 ACTION_HYBRID_SLEEP
)) {
3152 r
= logind_reboot(a
);
3155 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3156 /* requested operation is not supported or already in progress */
3159 /* On all other errors, try low-level operation */
3162 return start_unit(argc
, argv
, userdata
);
3165 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3166 _cleanup_strv_free_
char **names
= NULL
;
3171 r
= acquire_bus(BUS_MANAGER
, &bus
);
3175 r
= expand_names(bus
, args
, NULL
, &names
);
3177 return log_error_errno(r
, "Failed to expand names: %m");
3179 STRV_FOREACH(name
, names
) {
3182 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3192 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3193 /* According to LSB: 3, "program is not running" */
3194 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3197 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3198 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3201 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3202 _cleanup_strv_free_
char **names
= NULL
;
3203 char *kill_who
= NULL
, **name
;
3207 polkit_agent_open_if_enabled();
3209 r
= acquire_bus(BUS_MANAGER
, &bus
);
3214 arg_kill_who
= "all";
3216 /* --fail was specified */
3217 if (streq(arg_job_mode
, "fail"))
3218 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3220 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3222 return log_error_errno(r
, "Failed to expand names: %m");
3224 STRV_FOREACH(name
, names
) {
3225 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3227 q
= sd_bus_call_method(
3229 "org.freedesktop.systemd1",
3230 "/org/freedesktop/systemd1",
3231 "org.freedesktop.systemd1.Manager",
3235 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3237 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3246 typedef struct ExecStatusInfo
{
3254 usec_t start_timestamp
;
3255 usec_t exit_timestamp
;
3260 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3263 static void exec_status_info_free(ExecStatusInfo
*i
) {
3272 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3273 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3276 int32_t code
, status
;
3282 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3284 return bus_log_parse_error(r
);
3288 r
= sd_bus_message_read(m
, "s", &path
);
3290 return bus_log_parse_error(r
);
3292 i
->path
= strdup(path
);
3296 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3298 return bus_log_parse_error(r
);
3300 r
= sd_bus_message_read(m
,
3303 &start_timestamp
, &start_timestamp_monotonic
,
3304 &exit_timestamp
, &exit_timestamp_monotonic
,
3308 return bus_log_parse_error(r
);
3311 i
->start_timestamp
= (usec_t
) start_timestamp
;
3312 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3313 i
->pid
= (pid_t
) pid
;
3317 r
= sd_bus_message_exit_container(m
);
3319 return bus_log_parse_error(r
);
3324 typedef struct UnitStatusInfo
{
3326 const char *load_state
;
3327 const char *active_state
;
3328 const char *sub_state
;
3329 const char *unit_file_state
;
3330 const char *unit_file_preset
;
3332 const char *description
;
3333 const char *following
;
3335 char **documentation
;
3337 const char *fragment_path
;
3338 const char *source_path
;
3339 const char *control_group
;
3341 char **dropin_paths
;
3343 const char *load_error
;
3346 usec_t inactive_exit_timestamp
;
3347 usec_t inactive_exit_timestamp_monotonic
;
3348 usec_t active_enter_timestamp
;
3349 usec_t active_exit_timestamp
;
3350 usec_t inactive_enter_timestamp
;
3352 bool need_daemon_reload
;
3357 const char *status_text
;
3358 const char *pid_file
;
3362 usec_t start_timestamp
;
3363 usec_t exit_timestamp
;
3365 int exit_code
, exit_status
;
3367 usec_t condition_timestamp
;
3368 bool condition_result
;
3369 bool failed_condition_trigger
;
3370 bool failed_condition_negate
;
3371 const char *failed_condition
;
3372 const char *failed_condition_parameter
;
3374 usec_t assert_timestamp
;
3376 bool failed_assert_trigger
;
3377 bool failed_assert_negate
;
3378 const char *failed_assert
;
3379 const char *failed_assert_parameter
;
3382 unsigned n_accepted
;
3383 unsigned n_connections
;
3386 /* Pairs of type, path */
3390 const char *sysfs_path
;
3392 /* Mount, Automount */
3399 uint64_t memory_current
;
3400 uint64_t memory_limit
;
3401 uint64_t cpu_usage_nsec
;
3402 uint64_t tasks_current
;
3405 LIST_HEAD(ExecStatusInfo
, exec
);
3408 static void print_status_info(
3413 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3415 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3416 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3422 /* This shows pretty information about a unit. See
3423 * print_property() for a low-level property printer */
3425 if (streq_ptr(i
->active_state
, "failed")) {
3426 active_on
= ansi_highlight_red();
3427 active_off
= ansi_normal();
3428 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3429 active_on
= ansi_highlight_green();
3430 active_off
= ansi_normal();
3432 active_on
= active_off
= "";
3434 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3436 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3437 printf(" - %s", i
->description
);
3442 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3444 if (streq_ptr(i
->load_state
, "error")) {
3445 on
= ansi_highlight_red();
3446 off
= ansi_normal();
3450 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3453 printf(" Loaded: %s%s%s (Reason: %s)\n",
3454 on
, strna(i
->load_state
), off
, i
->load_error
);
3455 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3456 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3457 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3458 else if (path
&& !isempty(i
->unit_file_state
))
3459 printf(" Loaded: %s%s%s (%s; %s)\n",
3460 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3462 printf(" Loaded: %s%s%s (%s)\n",
3463 on
, strna(i
->load_state
), off
, path
);
3465 printf(" Loaded: %s%s%s\n",
3466 on
, strna(i
->load_state
), off
);
3468 if (!strv_isempty(i
->dropin_paths
)) {
3469 _cleanup_free_
char *dir
= NULL
;
3473 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3474 if (! dir
|| last
) {
3475 printf(dir
? " " : " Drop-In: ");
3479 if (path_get_parent(*dropin
, &dir
) < 0) {
3484 printf("%s\n %s", dir
,
3485 draw_special_char(DRAW_TREE_RIGHT
));
3488 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3490 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3494 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3496 printf(" Active: %s%s (%s)%s",
3497 active_on
, strna(i
->active_state
), ss
, active_off
);
3499 printf(" Active: %s%s%s",
3500 active_on
, strna(i
->active_state
), active_off
);
3502 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3503 printf(" (Result: %s)", i
->result
);
3505 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3506 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3507 (streq_ptr(i
->active_state
, "inactive") ||
3508 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3509 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3510 i
->active_exit_timestamp
;
3512 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3513 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3516 printf(" since %s; %s\n", s2
, s1
);
3518 printf(" since %s\n", s2
);
3522 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3523 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3524 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3526 printf("Condition: start %scondition failed%s at %s%s%s\n",
3527 ansi_highlight_yellow(), ansi_normal(),
3528 s2
, s1
? "; " : "", strempty(s1
));
3529 if (i
->failed_condition_trigger
)
3530 printf(" none of the trigger conditions were met\n");
3531 else if (i
->failed_condition
)
3532 printf(" %s=%s%s was not met\n",
3533 i
->failed_condition
,
3534 i
->failed_condition_negate
? "!" : "",
3535 i
->failed_condition_parameter
);
3538 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3539 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3540 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3542 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3543 ansi_highlight_red(), ansi_normal(),
3544 s2
, s1
? "; " : "", strempty(s1
));
3545 if (i
->failed_assert_trigger
)
3546 printf(" none of the trigger assertions were met\n");
3547 else if (i
->failed_assert
)
3548 printf(" %s=%s%s was not met\n",
3550 i
->failed_assert_negate
? "!" : "",
3551 i
->failed_assert_parameter
);
3555 printf(" Device: %s\n", i
->sysfs_path
);
3557 printf(" Where: %s\n", i
->where
);
3559 printf(" What: %s\n", i
->what
);
3561 STRV_FOREACH(t
, i
->documentation
)
3562 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3564 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3565 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3568 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3570 LIST_FOREACH(exec
, p
, i
->exec
) {
3571 _cleanup_free_
char *argv
= NULL
;
3574 /* Only show exited processes here */
3578 argv
= strv_join(p
->argv
, " ");
3579 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3581 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3583 on
= ansi_highlight_red();
3584 off
= ansi_normal();
3588 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3590 if (p
->code
== CLD_EXITED
) {
3593 printf("status=%i", p
->status
);
3595 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3600 printf("signal=%s", signal_to_string(p
->status
));
3602 printf(")%s\n", off
);
3604 if (i
->main_pid
== p
->pid
&&
3605 i
->start_timestamp
== p
->start_timestamp
&&
3606 i
->exit_timestamp
== p
->start_timestamp
)
3607 /* Let's not show this twice */
3610 if (p
->pid
== i
->control_pid
)
3614 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3615 if (i
->main_pid
> 0) {
3616 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3619 _cleanup_free_
char *comm
= NULL
;
3620 get_process_comm(i
->main_pid
, &comm
);
3622 printf(" (%s)", comm
);
3623 } else if (i
->exit_code
> 0) {
3624 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3626 if (i
->exit_code
== CLD_EXITED
) {
3629 printf("status=%i", i
->exit_status
);
3631 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3636 printf("signal=%s", signal_to_string(i
->exit_status
));
3640 if (i
->control_pid
> 0)
3644 if (i
->control_pid
> 0) {
3645 _cleanup_free_
char *c
= NULL
;
3647 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3649 get_process_comm(i
->control_pid
, &c
);
3658 printf(" Status: \"%s\"\n", i
->status_text
);
3659 if (i
->status_errno
> 0)
3660 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3662 if (i
->tasks_current
!= (uint64_t) -1) {
3663 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3665 if (i
->tasks_max
!= (uint64_t) -1)
3666 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3671 if (i
->memory_current
!= (uint64_t) -1) {
3672 char buf
[FORMAT_BYTES_MAX
];
3674 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3676 if (i
->memory_limit
!= (uint64_t) -1)
3677 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3682 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3683 char buf
[FORMAT_TIMESPAN_MAX
];
3684 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3687 if (i
->control_group
&&
3688 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3689 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3692 printf(" CGroup: %s\n", i
->control_group
);
3694 if (IN_SET(arg_transport
,
3695 BUS_TRANSPORT_LOCAL
,
3696 BUS_TRANSPORT_MACHINE
)) {
3699 static const char prefix
[] = " ";
3702 if (c
> sizeof(prefix
) - 1)
3703 c
-= sizeof(prefix
) - 1;
3707 if (i
->main_pid
> 0)
3708 extra
[k
++] = i
->main_pid
;
3710 if (i
->control_pid
> 0)
3711 extra
[k
++] = i
->control_pid
;
3713 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3717 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3718 show_journal_by_unit(
3723 i
->inactive_exit_timestamp_monotonic
,
3726 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3727 SD_JOURNAL_LOCAL_ONLY
,
3728 arg_scope
== UNIT_FILE_SYSTEM
,
3731 if (i
->need_daemon_reload
)
3732 warn_unit_file_changed(i
->id
);
3735 static void show_unit_help(UnitStatusInfo
*i
) {
3740 if (!i
->documentation
) {
3741 log_info("Documentation for %s not known.", i
->id
);
3745 STRV_FOREACH(p
, i
->documentation
)
3746 if (startswith(*p
, "man:"))
3747 show_man_page(*p
+ 4, false);
3749 log_info("Can't show: %s", *p
);
3752 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3759 switch (contents
[0]) {
3761 case SD_BUS_TYPE_STRING
: {
3764 r
= sd_bus_message_read(m
, "s", &s
);
3766 return bus_log_parse_error(r
);
3769 if (streq(name
, "Id"))
3771 else if (streq(name
, "LoadState"))
3773 else if (streq(name
, "ActiveState"))
3774 i
->active_state
= s
;
3775 else if (streq(name
, "SubState"))
3777 else if (streq(name
, "Description"))
3779 else if (streq(name
, "FragmentPath"))
3780 i
->fragment_path
= s
;
3781 else if (streq(name
, "SourcePath"))
3784 else if (streq(name
, "DefaultControlGroup")) {
3786 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3788 i
->control_group
= e
;
3791 else if (streq(name
, "ControlGroup"))
3792 i
->control_group
= s
;
3793 else if (streq(name
, "StatusText"))
3795 else if (streq(name
, "PIDFile"))
3797 else if (streq(name
, "SysFSPath"))
3799 else if (streq(name
, "Where"))
3801 else if (streq(name
, "What"))
3803 else if (streq(name
, "Following"))
3805 else if (streq(name
, "UnitFileState"))
3806 i
->unit_file_state
= s
;
3807 else if (streq(name
, "UnitFilePreset"))
3808 i
->unit_file_preset
= s
;
3809 else if (streq(name
, "Result"))
3816 case SD_BUS_TYPE_BOOLEAN
: {
3819 r
= sd_bus_message_read(m
, "b", &b
);
3821 return bus_log_parse_error(r
);
3823 if (streq(name
, "Accept"))
3825 else if (streq(name
, "NeedDaemonReload"))
3826 i
->need_daemon_reload
= b
;
3827 else if (streq(name
, "ConditionResult"))
3828 i
->condition_result
= b
;
3829 else if (streq(name
, "AssertResult"))
3830 i
->assert_result
= b
;
3835 case SD_BUS_TYPE_UINT32
: {
3838 r
= sd_bus_message_read(m
, "u", &u
);
3840 return bus_log_parse_error(r
);
3842 if (streq(name
, "MainPID")) {
3844 i
->main_pid
= (pid_t
) u
;
3847 } else if (streq(name
, "ControlPID"))
3848 i
->control_pid
= (pid_t
) u
;
3849 else if (streq(name
, "ExecMainPID")) {
3851 i
->main_pid
= (pid_t
) u
;
3852 } else if (streq(name
, "NAccepted"))
3854 else if (streq(name
, "NConnections"))
3855 i
->n_connections
= u
;
3860 case SD_BUS_TYPE_INT32
: {
3863 r
= sd_bus_message_read(m
, "i", &j
);
3865 return bus_log_parse_error(r
);
3867 if (streq(name
, "ExecMainCode"))
3868 i
->exit_code
= (int) j
;
3869 else if (streq(name
, "ExecMainStatus"))
3870 i
->exit_status
= (int) j
;
3871 else if (streq(name
, "StatusErrno"))
3872 i
->status_errno
= (int) j
;
3877 case SD_BUS_TYPE_UINT64
: {
3880 r
= sd_bus_message_read(m
, "t", &u
);
3882 return bus_log_parse_error(r
);
3884 if (streq(name
, "ExecMainStartTimestamp"))
3885 i
->start_timestamp
= (usec_t
) u
;
3886 else if (streq(name
, "ExecMainExitTimestamp"))
3887 i
->exit_timestamp
= (usec_t
) u
;
3888 else if (streq(name
, "ActiveEnterTimestamp"))
3889 i
->active_enter_timestamp
= (usec_t
) u
;
3890 else if (streq(name
, "InactiveEnterTimestamp"))
3891 i
->inactive_enter_timestamp
= (usec_t
) u
;
3892 else if (streq(name
, "InactiveExitTimestamp"))
3893 i
->inactive_exit_timestamp
= (usec_t
) u
;
3894 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3895 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3896 else if (streq(name
, "ActiveExitTimestamp"))
3897 i
->active_exit_timestamp
= (usec_t
) u
;
3898 else if (streq(name
, "ConditionTimestamp"))
3899 i
->condition_timestamp
= (usec_t
) u
;
3900 else if (streq(name
, "AssertTimestamp"))
3901 i
->assert_timestamp
= (usec_t
) u
;
3902 else if (streq(name
, "MemoryCurrent"))
3903 i
->memory_current
= u
;
3904 else if (streq(name
, "MemoryLimit"))
3905 i
->memory_limit
= u
;
3906 else if (streq(name
, "TasksCurrent"))
3907 i
->tasks_current
= u
;
3908 else if (streq(name
, "TasksMax"))
3910 else if (streq(name
, "CPUUsageNSec"))
3911 i
->cpu_usage_nsec
= u
;
3916 case SD_BUS_TYPE_ARRAY
:
3918 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3919 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3921 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3923 return bus_log_parse_error(r
);
3925 info
= new0(ExecStatusInfo
, 1);
3929 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3931 info
->name
= strdup(name
);
3935 LIST_PREPEND(exec
, i
->exec
, info
);
3937 info
= new0(ExecStatusInfo
, 1);
3943 return bus_log_parse_error(r
);
3945 r
= sd_bus_message_exit_container(m
);
3947 return bus_log_parse_error(r
);
3951 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3952 const char *type
, *path
;
3954 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3956 return bus_log_parse_error(r
);
3958 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3960 r
= strv_extend(&i
->listen
, type
);
3964 r
= strv_extend(&i
->listen
, path
);
3969 return bus_log_parse_error(r
);
3971 r
= sd_bus_message_exit_container(m
);
3973 return bus_log_parse_error(r
);
3977 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3979 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3981 return bus_log_parse_error(r
);
3983 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3985 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3987 return bus_log_parse_error(r
);
3989 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3990 const char *cond
, *param
;
3991 int trigger
, negate
;
3994 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
3996 return bus_log_parse_error(r
);
3998 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
3999 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4000 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4001 i
->failed_condition
= cond
;
4002 i
->failed_condition_trigger
= trigger
;
4003 i
->failed_condition_negate
= negate
;
4004 i
->failed_condition_parameter
= param
;
4008 return bus_log_parse_error(r
);
4010 r
= sd_bus_message_exit_container(m
);
4012 return bus_log_parse_error(r
);
4014 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4015 const char *cond
, *param
;
4016 int trigger
, negate
;
4019 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4021 return bus_log_parse_error(r
);
4023 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4024 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4025 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4026 i
->failed_assert
= cond
;
4027 i
->failed_assert_trigger
= trigger
;
4028 i
->failed_assert_negate
= negate
;
4029 i
->failed_assert_parameter
= param
;
4033 return bus_log_parse_error(r
);
4035 r
= sd_bus_message_exit_container(m
);
4037 return bus_log_parse_error(r
);
4044 case SD_BUS_TYPE_STRUCT_BEGIN
:
4046 if (streq(name
, "LoadError")) {
4047 const char *n
, *message
;
4049 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4051 return bus_log_parse_error(r
);
4053 if (!isempty(message
))
4054 i
->load_error
= message
;
4067 r
= sd_bus_message_skip(m
, contents
);
4069 return bus_log_parse_error(r
);
4074 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4080 /* This is a low-level property printer, see
4081 * print_status_info() for the nicer output */
4083 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4084 /* skip what we didn't read */
4085 r
= sd_bus_message_skip(m
, contents
);
4089 switch (contents
[0]) {
4091 case SD_BUS_TYPE_STRUCT_BEGIN
:
4093 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4096 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4098 return bus_log_parse_error(r
);
4101 printf("%s=%"PRIu32
"\n", name
, u
);
4103 printf("%s=\n", name
);
4107 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4110 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4112 return bus_log_parse_error(r
);
4114 if (arg_all
|| !isempty(s
))
4115 printf("%s=%s\n", name
, s
);
4119 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4120 const char *a
= NULL
, *b
= NULL
;
4122 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4124 return bus_log_parse_error(r
);
4126 if (arg_all
|| !isempty(a
) || !isempty(b
))
4127 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4130 } else if (streq_ptr(name
, "SystemCallFilter")) {
4131 _cleanup_strv_free_
char **l
= NULL
;
4134 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4136 return bus_log_parse_error(r
);
4138 r
= sd_bus_message_read(m
, "b", &whitelist
);
4140 return bus_log_parse_error(r
);
4142 r
= sd_bus_message_read_strv(m
, &l
);
4144 return bus_log_parse_error(r
);
4146 r
= sd_bus_message_exit_container(m
);
4148 return bus_log_parse_error(r
);
4150 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4154 fputs(name
, stdout
);
4160 STRV_FOREACH(i
, l
) {
4168 fputc('\n', stdout
);
4176 case SD_BUS_TYPE_ARRAY
:
4178 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4182 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4184 return bus_log_parse_error(r
);
4186 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4187 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4190 return bus_log_parse_error(r
);
4192 r
= sd_bus_message_exit_container(m
);
4194 return bus_log_parse_error(r
);
4198 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4199 const char *type
, *path
;
4201 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4203 return bus_log_parse_error(r
);
4205 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4206 printf("%s=%s\n", type
, path
);
4208 return bus_log_parse_error(r
);
4210 r
= sd_bus_message_exit_container(m
);
4212 return bus_log_parse_error(r
);
4216 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4217 const char *type
, *path
;
4219 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4221 return bus_log_parse_error(r
);
4223 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4224 printf("Listen%s=%s\n", type
, path
);
4226 return bus_log_parse_error(r
);
4228 r
= sd_bus_message_exit_container(m
);
4230 return bus_log_parse_error(r
);
4234 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4236 uint64_t value
, next_elapse
;
4238 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4240 return bus_log_parse_error(r
);
4242 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4243 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4245 printf("%s={ value=%s ; next_elapse=%s }\n",
4247 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4248 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4251 return bus_log_parse_error(r
);
4253 r
= sd_bus_message_exit_container(m
);
4255 return bus_log_parse_error(r
);
4259 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4260 ExecStatusInfo info
= {};
4262 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4264 return bus_log_parse_error(r
);
4266 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4267 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4268 _cleanup_free_
char *tt
;
4270 tt
= strv_join(info
.argv
, " ");
4272 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",
4276 yes_no(info
.ignore
),
4277 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4278 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4280 sigchld_code_to_string(info
.code
),
4282 info
.code
== CLD_EXITED
? "" : "/",
4283 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4286 strv_free(info
.argv
);
4290 r
= sd_bus_message_exit_container(m
);
4292 return bus_log_parse_error(r
);
4296 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4297 const char *path
, *rwm
;
4299 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4301 return bus_log_parse_error(r
);
4303 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4304 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4306 return bus_log_parse_error(r
);
4308 r
= sd_bus_message_exit_container(m
);
4310 return bus_log_parse_error(r
);
4314 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4318 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4320 return bus_log_parse_error(r
);
4322 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4323 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4325 return bus_log_parse_error(r
);
4327 r
= sd_bus_message_exit_container(m
);
4329 return bus_log_parse_error(r
);
4333 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4337 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4339 return bus_log_parse_error(r
);
4341 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4342 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4344 return bus_log_parse_error(r
);
4346 r
= sd_bus_message_exit_container(m
);
4348 return bus_log_parse_error(r
);
4356 r
= bus_print_property(name
, m
, arg_all
);
4358 return bus_log_parse_error(r
);
4361 r
= sd_bus_message_skip(m
, contents
);
4363 return bus_log_parse_error(r
);
4366 printf("%s=[unprintable]\n", name
);
4372 static int show_one(
4376 bool show_properties
,
4380 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4381 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4382 UnitStatusInfo info
= {
4383 .memory_current
= (uint64_t) -1,
4384 .memory_limit
= (uint64_t) -1,
4385 .cpu_usage_nsec
= (uint64_t) -1,
4386 .tasks_current
= (uint64_t) -1,
4387 .tasks_max
= (uint64_t) -1,
4395 log_debug("Showing one %s", path
);
4397 r
= sd_bus_call_method(
4399 "org.freedesktop.systemd1",
4401 "org.freedesktop.DBus.Properties",
4407 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4409 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4411 return bus_log_parse_error(r
);
4418 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4419 const char *name
, *contents
;
4421 r
= sd_bus_message_read(reply
, "s", &name
);
4423 return bus_log_parse_error(r
);
4425 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4427 return bus_log_parse_error(r
);
4429 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4431 return bus_log_parse_error(r
);
4433 if (show_properties
)
4434 r
= print_property(name
, reply
, contents
);
4436 r
= status_property(name
, reply
, &info
, contents
);
4440 r
= sd_bus_message_exit_container(reply
);
4442 return bus_log_parse_error(r
);
4444 r
= sd_bus_message_exit_container(reply
);
4446 return bus_log_parse_error(r
);
4449 return bus_log_parse_error(r
);
4451 r
= sd_bus_message_exit_container(reply
);
4453 return bus_log_parse_error(r
);
4457 if (!show_properties
) {
4458 if (streq(verb
, "help"))
4459 show_unit_help(&info
);
4461 print_status_info(&info
, ellipsized
);
4464 strv_free(info
.documentation
);
4465 strv_free(info
.dropin_paths
);
4466 strv_free(info
.listen
);
4468 if (!streq_ptr(info
.active_state
, "active") &&
4469 !streq_ptr(info
.active_state
, "reloading") &&
4470 streq(verb
, "status")) {
4471 /* According to LSB: "program not running" */
4472 /* 0: program is running or service is OK
4473 * 1: program is dead and /run PID file exists
4474 * 2: program is dead and /run/lock lock file exists
4475 * 3: program is not running
4476 * 4: program or service status is unknown
4478 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4484 while ((p
= info
.exec
)) {
4485 LIST_REMOVE(exec
, info
.exec
, p
);
4486 exec_status_info_free(p
);
4492 static int get_unit_dbus_path_by_pid(
4497 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4498 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4502 r
= sd_bus_call_method(
4504 "org.freedesktop.systemd1",
4505 "/org/freedesktop/systemd1",
4506 "org.freedesktop.systemd1.Manager",
4512 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4514 r
= sd_bus_message_read(reply
, "o", &u
);
4516 return bus_log_parse_error(r
);
4526 static int show_all(
4529 bool show_properties
,
4533 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4534 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4539 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4543 pager_open_if_enabled();
4547 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4549 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4550 _cleanup_free_
char *p
= NULL
;
4552 p
= unit_dbus_path_from_name(u
->id
);
4556 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4559 else if (r
> 0 && ret
== 0)
4566 static int show_system_status(sd_bus
*bus
) {
4567 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4568 _cleanup_free_
char *hn
= NULL
;
4569 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4570 const char *on
, *off
;
4573 hn
= gethostname_malloc();
4577 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4579 return log_error_errno(r
, "Failed to read server status: %m");
4581 if (streq_ptr(mi
.state
, "degraded")) {
4582 on
= ansi_highlight_red();
4583 off
= ansi_normal();
4584 } else if (!streq_ptr(mi
.state
, "running")) {
4585 on
= ansi_highlight_yellow();
4586 off
= ansi_normal();
4590 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4592 printf(" State: %s%s%s\n",
4593 on
, strna(mi
.state
), off
);
4595 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4596 printf(" Failed: %u units\n", mi
.n_failed_units
);
4598 printf(" Since: %s; %s\n",
4599 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4600 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4602 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4603 if (IN_SET(arg_transport
,
4604 BUS_TRANSPORT_LOCAL
,
4605 BUS_TRANSPORT_MACHINE
)) {
4606 static const char prefix
[] = " ";
4610 if (c
> sizeof(prefix
) - 1)
4611 c
-= sizeof(prefix
) - 1;
4615 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4621 static int show(int argc
, char *argv
[], void *userdata
) {
4622 bool show_properties
, show_status
, show_help
, new_line
= false;
4623 bool ellipsized
= false;
4629 show_properties
= streq(argv
[0], "show");
4630 show_status
= streq(argv
[0], "status");
4631 show_help
= streq(argv
[0], "help");
4633 if (show_help
&& argc
<= 1) {
4634 log_error("This command expects one or more unit names. Did you mean --help?");
4638 if (show_properties
)
4639 pager_open_if_enabled();
4642 /* Increase max number of open files to 16K if we can, we
4643 * might needs this when browsing journal files, which might
4644 * be split up into many files. */
4645 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4647 r
= acquire_bus(BUS_MANAGER
, &bus
);
4651 /* If no argument is specified inspect the manager itself */
4652 if (show_properties
&& argc
<= 1)
4653 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4655 if (show_status
&& argc
<= 1) {
4657 pager_open_if_enabled();
4658 show_system_status(bus
);
4662 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4664 _cleanup_free_
char **patterns
= NULL
;
4667 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4668 _cleanup_free_
char *unit
= NULL
;
4671 if (safe_atou32(*name
, &id
) < 0) {
4672 if (strv_push(&patterns
, *name
) < 0)
4676 } else if (show_properties
) {
4677 /* Interpret as job id */
4678 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4682 /* Interpret as PID */
4683 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4690 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4693 else if (r
> 0 && ret
== 0)
4697 if (!strv_isempty(patterns
)) {
4698 _cleanup_strv_free_
char **names
= NULL
;
4700 r
= expand_names(bus
, patterns
, NULL
, &names
);
4702 return log_error_errno(r
, "Failed to expand names: %m");
4704 STRV_FOREACH(name
, names
) {
4705 _cleanup_free_
char *unit
;
4707 unit
= unit_dbus_path_from_name(*name
);
4711 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4714 else if (r
> 0 && ret
== 0)
4720 if (ellipsized
&& !arg_quiet
)
4721 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4726 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4730 assert(user_runtime
);
4733 if (arg_scope
== UNIT_FILE_USER
) {
4734 r
= user_config_home(user_home
);
4736 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4738 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4740 r
= user_runtime_dir(user_runtime
);
4742 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4744 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4747 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4749 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4754 static int cat_file(const char *filename
, bool newline
) {
4755 _cleanup_close_
int fd
;
4757 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4761 printf("%s%s# %s%s\n",
4762 newline
? "\n" : "",
4763 ansi_highlight_blue(),
4768 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4771 static int cat(int argc
, char *argv
[], void *userdata
) {
4772 _cleanup_free_
char *user_home
= NULL
;
4773 _cleanup_free_
char *user_runtime
= NULL
;
4774 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4775 _cleanup_strv_free_
char **names
= NULL
;
4781 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4782 log_error("Cannot remotely cat units.");
4786 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4790 r
= acquire_bus(BUS_MANAGER
, &bus
);
4794 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4796 return log_error_errno(r
, "Failed to expand names: %m");
4798 pager_open_if_enabled();
4800 STRV_FOREACH(name
, names
) {
4801 _cleanup_free_
char *fragment_path
= NULL
;
4802 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4805 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4816 if (fragment_path
) {
4817 r
= cat_file(fragment_path
, false);
4819 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4822 STRV_FOREACH(path
, dropin_paths
) {
4823 r
= cat_file(*path
, path
== dropin_paths
);
4825 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4832 static int set_property(int argc
, char *argv
[], void *userdata
) {
4833 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4834 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4835 _cleanup_free_
char *n
= NULL
;
4840 polkit_agent_open_if_enabled();
4842 r
= acquire_bus(BUS_MANAGER
, &bus
);
4846 r
= sd_bus_message_new_method_call(
4849 "org.freedesktop.systemd1",
4850 "/org/freedesktop/systemd1",
4851 "org.freedesktop.systemd1.Manager",
4852 "SetUnitProperties");
4854 return bus_log_create_error(r
);
4856 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4858 return log_error_errno(r
, "Failed to mangle unit name: %m");
4860 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4862 return bus_log_create_error(r
);
4864 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4866 return bus_log_create_error(r
);
4868 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4869 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4871 return bus_log_create_error(r
);
4873 r
= bus_append_unit_property_assignment(m
, *i
);
4877 r
= sd_bus_message_close_container(m
);
4879 return bus_log_create_error(r
);
4882 r
= sd_bus_message_close_container(m
);
4884 return bus_log_create_error(r
);
4886 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4888 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4893 static int snapshot(int argc
, char *argv
[], void *userdata
) {
4894 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4895 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4896 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4901 polkit_agent_open_if_enabled();
4904 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4906 return log_error_errno(r
, "Failed to generate unit name: %m");
4913 r
= acquire_bus(BUS_MANAGER
, &bus
);
4917 r
= sd_bus_call_method(
4919 "org.freedesktop.systemd1",
4920 "/org/freedesktop/systemd1",
4921 "org.freedesktop.systemd1.Manager",
4927 return log_error_errno(r
, "Failed to create snapshot: %s", bus_error_message(&error
, r
));
4929 r
= sd_bus_message_read(reply
, "o", &path
);
4931 return bus_log_parse_error(r
);
4933 r
= sd_bus_get_property_string(
4935 "org.freedesktop.systemd1",
4937 "org.freedesktop.systemd1.Unit",
4942 return log_error_errno(r
, "Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4950 static int delete_snapshot(int argc
, char *argv
[], void *userdata
) {
4951 _cleanup_strv_free_
char **names
= NULL
;
4956 polkit_agent_open_if_enabled();
4958 r
= acquire_bus(BUS_MANAGER
, &bus
);
4962 r
= expand_names(bus
, strv_skip(argv
, 1), ".snapshot", &names
);
4964 return log_error_errno(r
, "Failed to expand names: %m");
4966 STRV_FOREACH(name
, names
) {
4967 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4970 q
= sd_bus_call_method(
4972 "org.freedesktop.systemd1",
4973 "/org/freedesktop/systemd1",
4974 "org.freedesktop.systemd1.Manager",
4980 log_error_errno(q
, "Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4989 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4990 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4995 polkit_agent_open_if_enabled();
4997 r
= acquire_bus(BUS_MANAGER
, &bus
);
5001 if (arg_action
== ACTION_RELOAD
)
5003 else if (arg_action
== ACTION_REEXEC
)
5004 method
= "Reexecute";
5006 assert(arg_action
== ACTION_SYSTEMCTL
);
5009 streq(argv
[0], "clear-jobs") ||
5010 streq(argv
[0], "cancel") ? "ClearJobs" :
5011 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5012 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5013 streq(argv
[0], "halt") ? "Halt" :
5014 streq(argv
[0], "poweroff") ? "PowerOff" :
5015 streq(argv
[0], "reboot") ? "Reboot" :
5016 streq(argv
[0], "kexec") ? "KExec" :
5017 streq(argv
[0], "exit") ? "Exit" :
5018 /* "daemon-reload" */ "Reload";
5021 r
= sd_bus_call_method(
5023 "org.freedesktop.systemd1",
5024 "/org/freedesktop/systemd1",
5025 "org.freedesktop.systemd1.Manager",
5030 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
5031 /* There's always a fallback possible for
5032 * legacy actions. */
5034 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
5035 /* On reexecution, we expect a disconnect, not a
5039 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5041 return r
< 0 ? r
: 0;
5044 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5045 _cleanup_strv_free_
char **names
= NULL
;
5051 return daemon_reload(argc
, argv
, userdata
);
5053 polkit_agent_open_if_enabled();
5055 r
= acquire_bus(BUS_MANAGER
, &bus
);
5059 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5061 return log_error_errno(r
, "Failed to expand names: %m");
5063 STRV_FOREACH(name
, names
) {
5064 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5066 q
= sd_bus_call_method(
5068 "org.freedesktop.systemd1",
5069 "/org/freedesktop/systemd1",
5070 "org.freedesktop.systemd1.Manager",
5076 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5085 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5086 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5087 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5092 pager_open_if_enabled();
5094 r
= acquire_bus(BUS_MANAGER
, &bus
);
5098 r
= sd_bus_get_property(
5100 "org.freedesktop.systemd1",
5101 "/org/freedesktop/systemd1",
5102 "org.freedesktop.systemd1.Manager",
5108 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5110 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5112 return bus_log_parse_error(r
);
5114 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5117 return bus_log_parse_error(r
);
5119 r
= sd_bus_message_exit_container(reply
);
5121 return bus_log_parse_error(r
);
5126 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5127 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5128 _cleanup_free_
char *cmdline_init
= NULL
;
5129 const char *root
, *init
;
5133 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5134 log_error("Cannot switch root remotely.");
5138 if (argc
< 2 || argc
> 3) {
5139 log_error("Wrong number of arguments.");
5148 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5149 "init", &cmdline_init
,
5152 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5154 init
= cmdline_init
;
5161 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5163 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5164 root_init_path
= strjoina(root
, "/", init
);
5166 /* If the passed init is actually the same as the
5167 * systemd binary, then let's suppress it. */
5168 if (files_same(root_init_path
, root_systemd_path
) > 0)
5172 r
= acquire_bus(BUS_MANAGER
, &bus
);
5176 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5178 r
= sd_bus_call_method(
5180 "org.freedesktop.systemd1",
5181 "/org/freedesktop/systemd1",
5182 "org.freedesktop.systemd1.Manager",
5188 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5193 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5194 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5195 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5203 polkit_agent_open_if_enabled();
5205 r
= acquire_bus(BUS_MANAGER
, &bus
);
5209 method
= streq(argv
[0], "set-environment")
5211 : "UnsetEnvironment";
5213 r
= sd_bus_message_new_method_call(
5216 "org.freedesktop.systemd1",
5217 "/org/freedesktop/systemd1",
5218 "org.freedesktop.systemd1.Manager",
5221 return bus_log_create_error(r
);
5223 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5225 return bus_log_create_error(r
);
5227 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5229 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5234 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5235 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5236 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5240 polkit_agent_open_if_enabled();
5242 r
= acquire_bus(BUS_MANAGER
, &bus
);
5246 r
= sd_bus_message_new_method_call(
5249 "org.freedesktop.systemd1",
5250 "/org/freedesktop/systemd1",
5251 "org.freedesktop.systemd1.Manager",
5254 return bus_log_create_error(r
);
5257 r
= sd_bus_message_append_strv(m
, environ
);
5261 r
= sd_bus_message_open_container(m
, 'a', "s");
5263 return bus_log_create_error(r
);
5265 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5267 if (!env_name_is_valid(*a
)) {
5268 log_error("Not a valid environment variable name: %s", *a
);
5272 STRV_FOREACH(b
, environ
) {
5275 eq
= startswith(*b
, *a
);
5276 if (eq
&& *eq
== '=') {
5278 r
= sd_bus_message_append(m
, "s", *b
);
5280 return bus_log_create_error(r
);
5287 r
= sd_bus_message_close_container(m
);
5290 return bus_log_create_error(r
);
5292 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5294 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5299 static int enable_sysv_units(const char *verb
, char **args
) {
5302 #if defined(HAVE_SYSV_COMPAT)
5304 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5306 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5309 if (!STR_IN_SET(verb
,
5315 /* Processes all SysV units, and reshuffles the array so that
5316 * afterwards only the native units remain */
5318 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5325 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5326 bool found_native
= false, found_sysv
;
5328 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5336 if (!endswith(name
, ".service"))
5339 if (path_is_absolute(name
))
5342 STRV_FOREACH(k
, paths
.unit_path
) {
5343 _cleanup_free_
char *path
= NULL
;
5345 path
= path_join(arg_root
, *k
, name
);
5349 found_native
= access(path
, F_OK
) >= 0;
5354 /* If we have both a native unit and a SysV script,
5355 * enable/disable them both (below); for is-enabled, prefer the
5357 if (found_native
&& streq(verb
, "is-enabled"))
5360 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5364 p
[strlen(p
) - strlen(".service")] = 0;
5365 found_sysv
= access(p
, F_OK
) >= 0;
5370 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5372 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5374 if (!isempty(arg_root
))
5375 argv
[c
++] = q
= strappend("--root=", arg_root
);
5378 argv
[c
++] = basename(p
);
5381 l
= strv_join((char**)argv
, " ");
5385 log_info("Executing %s", l
);
5389 return log_error_errno(errno
, "Failed to fork: %m");
5390 else if (pid
== 0) {
5393 (void) reset_all_signal_handlers();
5394 (void) reset_signal_mask();
5396 execv(argv
[0], (char**) argv
);
5397 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5398 _exit(EXIT_FAILURE
);
5401 j
= wait_for_terminate(pid
, &status
);
5403 log_error_errno(j
, "Failed to wait for child: %m");
5407 if (status
.si_code
== CLD_EXITED
) {
5408 if (streq(verb
, "is-enabled")) {
5409 if (status
.si_status
== 0) {
5418 } else if (status
.si_status
!= 0)
5426 /* Remove this entry, so that we don't try enabling it as native unit */
5429 assert(args
[f
] == name
);
5430 strv_remove(args
, name
);
5437 static int mangle_names(char **original_names
, char ***mangled_names
) {
5438 char **i
, **l
, **name
;
5441 l
= i
= new(char*, strv_length(original_names
) + 1);
5445 STRV_FOREACH(name
, original_names
) {
5447 /* When enabling units qualified path names are OK,
5448 * too, hence allow them explicitly. */
5450 if (is_path(*name
)) {
5457 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5460 return log_error_errno(r
, "Failed to mangle unit name: %m");
5473 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5474 _cleanup_strv_free_
char **names
= NULL
;
5475 const char *verb
= argv
[0];
5476 UnitFileChange
*changes
= NULL
;
5477 unsigned n_changes
= 0;
5478 int carries_install_info
= -1;
5484 r
= mangle_names(strv_skip(argv
, 1), &names
);
5488 r
= enable_sysv_units(verb
, names
);
5492 /* If the operation was fully executed by the SysV compat,
5493 * let's finish early */
5494 if (strv_isempty(names
))
5497 if (install_client_side()) {
5498 if (streq(verb
, "enable")) {
5499 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5500 carries_install_info
= r
;
5501 } else if (streq(verb
, "disable"))
5502 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5503 else if (streq(verb
, "reenable")) {
5504 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5505 carries_install_info
= r
;
5506 } else if (streq(verb
, "link"))
5507 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5508 else if (streq(verb
, "preset")) {
5509 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5510 carries_install_info
= r
;
5511 } else if (streq(verb
, "mask"))
5512 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5513 else if (streq(verb
, "unmask"))
5514 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5516 assert_not_reached("Unknown verb");
5519 log_error_errno(r
, "Operation failed: %m");
5524 dump_unit_file_changes(changes
, n_changes
);
5528 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5529 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5530 int expect_carries_install_info
= false;
5531 bool send_force
= true, send_preset_mode
= false;
5535 polkit_agent_open_if_enabled();
5537 r
= acquire_bus(BUS_MANAGER
, &bus
);
5541 if (streq(verb
, "enable")) {
5542 method
= "EnableUnitFiles";
5543 expect_carries_install_info
= true;
5544 } else if (streq(verb
, "disable")) {
5545 method
= "DisableUnitFiles";
5547 } else if (streq(verb
, "reenable")) {
5548 method
= "ReenableUnitFiles";
5549 expect_carries_install_info
= true;
5550 } else if (streq(verb
, "link"))
5551 method
= "LinkUnitFiles";
5552 else if (streq(verb
, "preset")) {
5554 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5555 method
= "PresetUnitFilesWithMode";
5556 send_preset_mode
= true;
5558 method
= "PresetUnitFiles";
5560 expect_carries_install_info
= true;
5561 } else if (streq(verb
, "mask"))
5562 method
= "MaskUnitFiles";
5563 else if (streq(verb
, "unmask")) {
5564 method
= "UnmaskUnitFiles";
5567 assert_not_reached("Unknown verb");
5569 r
= sd_bus_message_new_method_call(
5572 "org.freedesktop.systemd1",
5573 "/org/freedesktop/systemd1",
5574 "org.freedesktop.systemd1.Manager",
5577 return bus_log_create_error(r
);
5579 r
= sd_bus_message_append_strv(m
, names
);
5581 return bus_log_create_error(r
);
5583 if (send_preset_mode
) {
5584 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5586 return bus_log_create_error(r
);
5589 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5591 return bus_log_create_error(r
);
5594 r
= sd_bus_message_append(m
, "b", arg_force
);
5596 return bus_log_create_error(r
);
5599 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5601 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5603 if (expect_carries_install_info
) {
5604 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5606 return bus_log_parse_error(r
);
5609 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5613 /* Try to reload if enabled */
5615 r
= daemon_reload(argc
, argv
, userdata
);
5620 if (carries_install_info
== 0)
5621 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5622 "using systemctl.\n"
5623 "Possible reasons for having this kind of units are:\n"
5624 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5625 " .wants/ or .requires/ directory.\n"
5626 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5627 " a requirement dependency on it.\n"
5628 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5629 " D-Bus, udev, scripted systemctl call, ...).\n");
5631 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5632 char *new_args
[n_changes
+ 2];
5636 r
= acquire_bus(BUS_MANAGER
, &bus
);
5640 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5641 for (i
= 0; i
< n_changes
; i
++)
5642 new_args
[i
+ 1] = basename(changes
[i
].path
);
5643 new_args
[i
+ 1] = NULL
;
5645 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5649 unit_file_changes_free(changes
, n_changes
);
5654 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5655 _cleanup_strv_free_
char **names
= NULL
;
5656 _cleanup_free_
char *target
= NULL
;
5657 const char *verb
= argv
[0];
5664 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5666 return log_error_errno(r
, "Failed to mangle unit name: %m");
5668 r
= mangle_names(strv_skip(argv
, 2), &names
);
5672 if (streq(verb
, "add-wants"))
5674 else if (streq(verb
, "add-requires"))
5675 dep
= UNIT_REQUIRES
;
5677 assert_not_reached("Unknown verb");
5679 if (install_client_side()) {
5680 UnitFileChange
*changes
= NULL
;
5681 unsigned n_changes
= 0;
5683 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5686 return log_error_errno(r
, "Can't add dependency: %m");
5689 dump_unit_file_changes(changes
, n_changes
);
5691 unit_file_changes_free(changes
, n_changes
);
5694 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5695 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5698 polkit_agent_open_if_enabled();
5700 r
= acquire_bus(BUS_MANAGER
, &bus
);
5704 r
= sd_bus_message_new_method_call(
5707 "org.freedesktop.systemd1",
5708 "/org/freedesktop/systemd1",
5709 "org.freedesktop.systemd1.Manager",
5710 "AddDependencyUnitFiles");
5712 return bus_log_create_error(r
);
5714 r
= sd_bus_message_append_strv(m
, names
);
5716 return bus_log_create_error(r
);
5718 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5720 return bus_log_create_error(r
);
5722 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5724 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5726 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5731 r
= daemon_reload(argc
, argv
, userdata
);
5739 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5740 UnitFileChange
*changes
= NULL
;
5741 unsigned n_changes
= 0;
5744 if (install_client_side()) {
5746 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5748 log_error_errno(r
, "Operation failed: %m");
5753 dump_unit_file_changes(changes
, n_changes
);
5758 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5759 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5762 polkit_agent_open_if_enabled();
5764 r
= acquire_bus(BUS_MANAGER
, &bus
);
5768 r
= sd_bus_call_method(
5770 "org.freedesktop.systemd1",
5771 "/org/freedesktop/systemd1",
5772 "org.freedesktop.systemd1.Manager",
5773 "PresetAllUnitFiles",
5777 unit_file_preset_mode_to_string(arg_preset_mode
),
5781 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5783 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5788 r
= daemon_reload(argc
, argv
, userdata
);
5794 unit_file_changes_free(changes
, n_changes
);
5799 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5801 _cleanup_strv_free_
char **names
= NULL
;
5806 r
= mangle_names(strv_skip(argv
, 1), &names
);
5810 r
= enable_sysv_units(argv
[0], names
);
5816 if (install_client_side()) {
5818 STRV_FOREACH(name
, names
) {
5819 UnitFileState state
;
5821 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5823 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5827 UNIT_FILE_ENABLED_RUNTIME
,
5829 UNIT_FILE_INDIRECT
))
5833 puts(unit_file_state_to_string(state
));
5837 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5840 r
= acquire_bus(BUS_MANAGER
, &bus
);
5844 STRV_FOREACH(name
, names
) {
5845 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5848 r
= sd_bus_call_method(
5850 "org.freedesktop.systemd1",
5851 "/org/freedesktop/systemd1",
5852 "org.freedesktop.systemd1.Manager",
5858 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5860 r
= sd_bus_message_read(reply
, "s", &s
);
5862 return bus_log_parse_error(r
);
5864 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5875 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5876 _cleanup_free_
char *state
= NULL
;
5880 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5883 return EXIT_FAILURE
;
5886 r
= acquire_bus(BUS_MANAGER
, &bus
);
5890 r
= sd_bus_get_property_string(
5892 "org.freedesktop.systemd1",
5893 "/org/freedesktop/systemd1",
5894 "org.freedesktop.systemd1.Manager",
5907 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5910 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5911 _cleanup_free_
char *t
= NULL
;
5915 assert(original_path
);
5918 r
= tempfn_random(new_path
, NULL
, &t
);
5920 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5922 r
= mkdir_parents(new_path
, 0755);
5924 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5926 r
= copy_file(original_path
, t
, 0, 0644, 0);
5931 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5934 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5942 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5943 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5948 switch (arg_scope
) {
5949 case UNIT_FILE_SYSTEM
:
5950 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5952 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5954 case UNIT_FILE_GLOBAL
:
5955 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5957 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5959 case UNIT_FILE_USER
:
5961 assert(user_runtime
);
5963 path
= path_join(arg_root
, user_home
, name
);
5965 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5968 run
= path_join(arg_root
, user_runtime
, name
);
5972 assert_not_reached("Invalid scope");
5974 if (!path
|| (arg_runtime
&& !run
))
5978 if (access(path
, F_OK
) >= 0) {
5979 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5983 if (path2
&& access(path2
, F_OK
) >= 0) {
5984 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
5998 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
) {
5999 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6003 assert(ret_new_path
);
6004 assert(ret_tmp_path
);
6006 ending
= strjoina(unit_name
, ".d/override.conf");
6007 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
6011 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6017 *ret_new_path
= tmp_new_path
;
6018 *ret_tmp_path
= tmp_tmp_path
;
6023 static int unit_file_create_copy(
6024 const char *unit_name
,
6025 const char *fragment_path
,
6026 const char *user_home
,
6027 const char *user_runtime
,
6028 char **ret_new_path
,
6029 char **ret_tmp_path
) {
6031 char *tmp_new_path
, *tmp_tmp_path
;
6034 assert(fragment_path
);
6036 assert(ret_new_path
);
6037 assert(ret_tmp_path
);
6039 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
6043 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6046 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6051 if (response
!= 'y') {
6052 log_warning("%s ignored", unit_name
);
6058 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6060 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6065 *ret_new_path
= tmp_new_path
;
6066 *ret_tmp_path
= tmp_tmp_path
;
6071 static int run_editor(char **paths
) {
6079 return log_error_errno(errno
, "Failed to fork: %m");
6083 char *editor
, **editor_args
= NULL
;
6084 char **tmp_path
, **original_path
, *p
;
6085 unsigned n_editor_args
= 0, i
= 1;
6088 (void) reset_all_signal_handlers();
6089 (void) reset_signal_mask();
6091 argc
= strv_length(paths
)/2 + 1;
6093 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6094 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6095 * we try to execute well known editors
6097 editor
= getenv("SYSTEMD_EDITOR");
6099 editor
= getenv("EDITOR");
6101 editor
= getenv("VISUAL");
6103 if (!isempty(editor
)) {
6104 editor_args
= strv_split(editor
, WHITESPACE
);
6107 _exit(EXIT_FAILURE
);
6109 n_editor_args
= strv_length(editor_args
);
6110 argc
+= n_editor_args
- 1;
6112 args
= newa(const char*, argc
+ 1);
6114 if (n_editor_args
> 0) {
6115 args
[0] = editor_args
[0];
6116 for (; i
< n_editor_args
; i
++)
6117 args
[i
] = editor_args
[i
];
6120 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6121 args
[i
] = *tmp_path
;
6126 if (n_editor_args
> 0)
6127 execvp(args
[0], (char* const*) args
);
6129 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6131 execvp(p
, (char* const*) args
);
6132 /* We do not fail if the editor doesn't exist
6133 * because we want to try each one of them before
6136 if (errno
!= ENOENT
) {
6137 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6138 _exit(EXIT_FAILURE
);
6142 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6143 _exit(EXIT_FAILURE
);
6146 r
= wait_for_terminate_and_warn("editor", pid
, true);
6148 return log_error_errno(r
, "Failed to wait for child: %m");
6153 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6154 _cleanup_free_
char *user_home
= NULL
;
6155 _cleanup_free_
char *user_runtime
= NULL
;
6156 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6163 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6167 STRV_FOREACH(name
, names
) {
6168 _cleanup_free_
char *path
= NULL
;
6169 char *new_path
, *tmp_path
;
6171 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6177 // FIXME: support units with path==NULL (no FragmentPath)
6178 log_error("No fragment exists for %s.", *name
);
6183 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6185 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6189 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6197 static int edit(int argc
, char *argv
[], void *userdata
) {
6198 _cleanup_strv_free_
char **names
= NULL
;
6199 _cleanup_strv_free_
char **paths
= NULL
;
6200 char **original
, **tmp
;
6205 log_error("Cannot edit units if not on a tty.");
6209 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6210 log_error("Cannot edit units remotely.");
6214 r
= acquire_bus(BUS_MANAGER
, &bus
);
6218 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6220 return log_error_errno(r
, "Failed to expand names: %m");
6222 r
= find_paths_to_edit(bus
, names
, &paths
);
6226 if (strv_isempty(paths
))
6229 r
= run_editor(paths
);
6233 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6234 /* If the temporary file is empty we ignore it. It's
6235 * useful if the user wants to cancel its modification
6237 if (null_or_empty_path(*tmp
)) {
6238 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6242 r
= rename(*tmp
, *original
);
6244 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6251 if (!arg_no_reload
&& !install_client_side())
6252 r
= daemon_reload(argc
, argv
, userdata
);
6255 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6256 (void) unlink(*tmp
);
6261 static void systemctl_help(void) {
6263 pager_open_if_enabled();
6265 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6266 "Query or send control commands to the systemd manager.\n\n"
6267 " -h --help Show this help\n"
6268 " --version Show package version\n"
6269 " --system Connect to system manager\n"
6270 " --user Connect to user service manager\n"
6271 " -H --host=[USER@]HOST\n"
6272 " Operate on remote host\n"
6273 " -M --machine=CONTAINER\n"
6274 " Operate on local container\n"
6275 " -t --type=TYPE List units of a particular type\n"
6276 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6277 " -p --property=NAME Show only properties by this name\n"
6278 " -a --all Show all loaded units/properties, including dead/empty\n"
6279 " ones. To list all units installed on the system, use\n"
6280 " the 'list-unit-files' command instead.\n"
6281 " -l --full Don't ellipsize unit names on output\n"
6282 " -r --recursive Show unit list of host and local containers\n"
6283 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6284 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6285 " queueing a new job\n"
6286 " --show-types When showing sockets, explicitly show their type\n"
6287 " -i --ignore-inhibitors\n"
6288 " When shutting down or sleeping, ignore inhibitors\n"
6289 " --kill-who=WHO Who to send signal to\n"
6290 " -s --signal=SIGNAL Which signal to send\n"
6291 " --now Start or stop unit in addition to enabling or disabling it\n"
6292 " -q --quiet Suppress output\n"
6293 " --no-block Do not wait until operation finished\n"
6294 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6295 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6296 " --no-legend Do not print a legend (column headers and hints)\n"
6297 " --no-pager Do not pipe output into a pager\n"
6298 " --no-ask-password\n"
6299 " Do not ask for system passwords\n"
6300 " --global Enable/disable unit files globally\n"
6301 " --runtime Enable unit files only temporarily until next reboot\n"
6302 " -f --force When enabling unit files, override existing symlinks\n"
6303 " When shutting down, execute action immediately\n"
6304 " --preset-mode= Apply only enable, only disable, or all presets\n"
6305 " --root=PATH Enable unit files in the specified root directory\n"
6306 " -n --lines=INTEGER Number of journal entries to show\n"
6307 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6308 " short-precise, short-monotonic, verbose,\n"
6309 " export, json, json-pretty, json-sse, cat)\n"
6310 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6311 " --plain Print unit dependencies as a list instead of a tree\n\n"
6313 " list-units [PATTERN...] List loaded units\n"
6314 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6315 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6316 " start NAME... Start (activate) one or more units\n"
6317 " stop NAME... Stop (deactivate) one or more units\n"
6318 " reload NAME... Reload one or more units\n"
6319 " restart NAME... Start or restart one or more units\n"
6320 " try-restart NAME... Restart one or more units if active\n"
6321 " reload-or-restart NAME... Reload one or more units if possible,\n"
6322 " otherwise start or restart\n"
6323 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6324 " otherwise restart if active\n"
6325 " isolate NAME Start one unit and stop all others\n"
6326 " kill NAME... Send signal to processes of a unit\n"
6327 " is-active PATTERN... Check whether units are active\n"
6328 " is-failed PATTERN... Check whether units are failed\n"
6329 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6330 " show [PATTERN...|JOB...] Show properties of one or more\n"
6331 " units/jobs or the manager\n"
6332 " cat PATTERN... Show files and drop-ins of one or more units\n"
6333 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6334 " help PATTERN...|PID... Show manual for one or more units\n"
6335 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6337 " list-dependencies [NAME] Recursively show units which are required\n"
6338 " or wanted by this unit or by which this\n"
6339 " unit is required or wanted\n\n"
6340 "Unit File Commands:\n"
6341 " list-unit-files [PATTERN...] List installed unit files\n"
6342 " enable NAME... Enable one or more unit files\n"
6343 " disable NAME... Disable one or more unit files\n"
6344 " reenable NAME... Reenable one or more unit files\n"
6345 " preset NAME... Enable/disable one or more unit files\n"
6346 " based on preset configuration\n"
6347 " preset-all Enable/disable all unit files based on\n"
6348 " preset configuration\n"
6349 " is-enabled NAME... Check whether unit files are enabled\n"
6350 " mask NAME... Mask one or more units\n"
6351 " unmask NAME... Unmask one or more units\n"
6352 " link PATH... Link one or more units files into\n"
6353 " the search path\n"
6354 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6355 " on specified one or more units\n"
6356 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6357 " on specified one or more units\n"
6358 " edit NAME... Edit one or more unit files\n"
6359 " get-default Get the name of the default target\n"
6360 " set-default NAME Set the default target\n\n"
6361 "Machine Commands:\n"
6362 " list-machines [PATTERN...] List local containers and host\n\n"
6364 " list-jobs [PATTERN...] List jobs\n"
6365 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6366 "Snapshot Commands:\n"
6367 " snapshot [NAME] Create a snapshot\n"
6368 " delete NAME... Remove one or more snapshots\n\n"
6369 "Environment Commands:\n"
6370 " show-environment Dump environment\n"
6371 " set-environment NAME=VALUE... Set one or more environment variables\n"
6372 " unset-environment NAME... Unset one or more environment variables\n"
6373 " import-environment [NAME...] Import all or some environment variables\n\n"
6374 "Manager Lifecycle Commands:\n"
6375 " daemon-reload Reload systemd manager configuration\n"
6376 " daemon-reexec Reexecute systemd manager\n\n"
6377 "System Commands:\n"
6378 " is-system-running Check whether system is fully running\n"
6379 " default Enter system default mode\n"
6380 " rescue Enter system rescue mode\n"
6381 " emergency Enter system emergency mode\n"
6382 " halt Shut down and halt the system\n"
6383 " poweroff Shut down and power-off the system\n"
6384 " reboot [ARG] Shut down and reboot the system\n"
6385 " kexec Shut down and reboot the system with kexec\n"
6386 " exit [EXIT_CODE] Request user instance or container exit\n"
6387 " switch-root ROOT [INIT] Change to a different root file system\n"
6388 " suspend Suspend the system\n"
6389 " hibernate Hibernate the system\n"
6390 " hybrid-sleep Hibernate and suspend the system\n",
6391 program_invocation_short_name
);
6394 static void halt_help(void) {
6395 printf("%s [OPTIONS...]%s\n\n"
6396 "%s the system.\n\n"
6397 " --help Show this help\n"
6398 " --halt Halt the machine\n"
6399 " -p --poweroff Switch off the machine\n"
6400 " --reboot Reboot the machine\n"
6401 " -f --force Force immediate halt/power-off/reboot\n"
6402 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6403 " -d --no-wtmp Don't write wtmp record\n"
6404 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6405 program_invocation_short_name
,
6406 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6407 arg_action
== ACTION_REBOOT
? "Reboot" :
6408 arg_action
== ACTION_POWEROFF
? "Power off" :
6412 static void shutdown_help(void) {
6413 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6414 "Shut down the system.\n\n"
6415 " --help Show this help\n"
6416 " -H --halt Halt the machine\n"
6417 " -P --poweroff Power-off the machine\n"
6418 " -r --reboot Reboot the machine\n"
6419 " -h Equivalent to --poweroff, overridden by --halt\n"
6420 " -k Don't halt/power-off/reboot, just send warnings\n"
6421 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6422 " -c Cancel a pending shutdown\n",
6423 program_invocation_short_name
);
6426 static void telinit_help(void) {
6427 printf("%s [OPTIONS...] {COMMAND}\n\n"
6428 "Send control commands to the init daemon.\n\n"
6429 " --help Show this help\n"
6430 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6432 " 0 Power-off the machine\n"
6433 " 6 Reboot the machine\n"
6434 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6435 " 1, s, S Enter rescue mode\n"
6436 " q, Q Reload init daemon configuration\n"
6437 " u, U Reexecute init daemon\n",
6438 program_invocation_short_name
);
6441 static void runlevel_help(void) {
6442 printf("%s [OPTIONS...]\n\n"
6443 "Prints the previous and current runlevel of the init system.\n\n"
6444 " --help Show this help\n",
6445 program_invocation_short_name
);
6448 static void help_types(void) {
6452 puts("Available unit types:");
6453 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6454 puts(unit_type_to_string(i
));
6457 static void help_states(void) {
6461 puts("Available unit load states:");
6462 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6463 puts(unit_load_state_to_string(i
));
6466 puts("\nAvailable unit active states:");
6467 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6468 puts(unit_active_state_to_string(i
));
6471 puts("\nAvailable automount unit substates:");
6472 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6473 puts(automount_state_to_string(i
));
6476 puts("\nAvailable busname unit substates:");
6477 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6478 puts(busname_state_to_string(i
));
6481 puts("\nAvailable device unit substates:");
6482 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6483 puts(device_state_to_string(i
));
6486 puts("\nAvailable mount unit substates:");
6487 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6488 puts(mount_state_to_string(i
));
6491 puts("\nAvailable path unit substates:");
6492 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6493 puts(path_state_to_string(i
));
6496 puts("\nAvailable scope unit substates:");
6497 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6498 puts(scope_state_to_string(i
));
6501 puts("\nAvailable service unit substates:");
6502 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6503 puts(service_state_to_string(i
));
6506 puts("\nAvailable slice unit substates:");
6507 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6508 puts(slice_state_to_string(i
));
6511 puts("\nAvailable snapshot unit substates:");
6512 for (i
= 0; i
< _SNAPSHOT_STATE_MAX
; i
++)
6513 puts(snapshot_state_to_string(i
));
6516 puts("\nAvailable socket unit substates:");
6517 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6518 puts(socket_state_to_string(i
));
6521 puts("\nAvailable swap unit substates:");
6522 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6523 puts(swap_state_to_string(i
));
6526 puts("\nAvailable target unit substates:");
6527 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6528 puts(target_state_to_string(i
));
6531 puts("\nAvailable timer unit substates:");
6532 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6533 puts(timer_state_to_string(i
));
6536 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6545 ARG_IGNORE_DEPENDENCIES
,
6557 ARG_NO_ASK_PASSWORD
,
6570 static const struct option options
[] = {
6571 { "help", no_argument
, NULL
, 'h' },
6572 { "version", no_argument
, NULL
, ARG_VERSION
},
6573 { "type", required_argument
, NULL
, 't' },
6574 { "property", required_argument
, NULL
, 'p' },
6575 { "all", no_argument
, NULL
, 'a' },
6576 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6577 { "after", no_argument
, NULL
, ARG_AFTER
},
6578 { "before", no_argument
, NULL
, ARG_BEFORE
},
6579 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6580 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6581 { "full", no_argument
, NULL
, 'l' },
6582 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6583 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6584 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6585 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6586 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6587 { "user", no_argument
, NULL
, ARG_USER
},
6588 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6589 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6590 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6591 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6592 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6593 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6594 { "quiet", no_argument
, NULL
, 'q' },
6595 { "root", required_argument
, NULL
, ARG_ROOT
},
6596 { "force", no_argument
, NULL
, ARG_FORCE
},
6597 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6598 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6599 { "signal", required_argument
, NULL
, 's' },
6600 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6601 { "host", required_argument
, NULL
, 'H' },
6602 { "machine", required_argument
, NULL
, 'M' },
6603 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6604 { "lines", required_argument
, NULL
, 'n' },
6605 { "output", required_argument
, NULL
, 'o' },
6606 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6607 { "state", required_argument
, NULL
, ARG_STATE
},
6608 { "recursive", no_argument
, NULL
, 'r' },
6609 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6610 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6611 { "now", no_argument
, NULL
, ARG_NOW
},
6612 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6621 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6622 arg_ask_password
= true;
6624 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6636 const char *word
, *state
;
6639 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6640 _cleanup_free_
char *type
;
6642 type
= strndup(word
, size
);
6646 if (streq(type
, "help")) {
6651 if (unit_type_from_string(type
) >= 0) {
6652 if (strv_push(&arg_types
, type
) < 0)
6658 /* It's much nicer to use --state= for
6659 * load states, but let's support this
6660 * in --types= too for compatibility
6661 * with old versions */
6662 if (unit_load_state_from_string(type
) >= 0) {
6663 if (strv_push(&arg_states
, type
) < 0)
6669 log_error("Unknown unit type or load state '%s'.", type
);
6670 log_info("Use -t help to see a list of allowed values.");
6678 /* Make sure that if the empty property list
6679 was specified, we won't show any properties. */
6680 if (isempty(optarg
) && !arg_properties
) {
6681 arg_properties
= new0(char*, 1);
6682 if (!arg_properties
)
6685 const char *word
, *state
;
6688 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6691 prop
= strndup(word
, size
);
6695 if (strv_consume(&arg_properties
, prop
) < 0)
6700 /* If the user asked for a particular
6701 * property, show it to him, even if it is
6713 arg_dependency
= DEPENDENCY_REVERSE
;
6717 arg_dependency
= DEPENDENCY_AFTER
;
6721 arg_dependency
= DEPENDENCY_BEFORE
;
6724 case ARG_SHOW_TYPES
:
6725 arg_show_types
= true;
6729 arg_job_mode
= optarg
;
6733 arg_job_mode
= "fail";
6736 case ARG_IRREVERSIBLE
:
6737 arg_job_mode
= "replace-irreversibly";
6740 case ARG_IGNORE_DEPENDENCIES
:
6741 arg_job_mode
= "ignore-dependencies";
6745 arg_scope
= UNIT_FILE_USER
;
6749 arg_scope
= UNIT_FILE_SYSTEM
;
6753 arg_scope
= UNIT_FILE_GLOBAL
;
6757 arg_no_block
= true;
6761 arg_no_legend
= true;
6765 arg_no_pager
= true;
6773 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6783 if (strv_extend(&arg_states
, "failed") < 0)
6801 arg_no_reload
= true;
6805 arg_kill_who
= optarg
;
6809 arg_signal
= signal_from_string_try_harder(optarg
);
6810 if (arg_signal
< 0) {
6811 log_error("Failed to parse signal string %s.", optarg
);
6816 case ARG_NO_ASK_PASSWORD
:
6817 arg_ask_password
= false;
6821 arg_transport
= BUS_TRANSPORT_REMOTE
;
6826 arg_transport
= BUS_TRANSPORT_MACHINE
;
6835 if (safe_atou(optarg
, &arg_lines
) < 0) {
6836 log_error("Failed to parse lines '%s'", optarg
);
6842 arg_output
= output_mode_from_string(optarg
);
6843 if (arg_output
< 0) {
6844 log_error("Unknown output '%s'.", optarg
);
6850 arg_ignore_inhibitors
= true;
6857 case ARG_FIRMWARE_SETUP
:
6858 arg_firmware_setup
= true;
6862 const char *word
, *state
;
6865 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6866 _cleanup_free_
char *s
= NULL
;
6868 s
= strndup(word
, size
);
6872 if (streq(s
, "help")) {
6877 if (strv_push(&arg_states
, s
) < 0)
6886 if (geteuid() != 0) {
6887 log_error("--recursive requires root privileges.");
6891 arg_recursive
= true;
6894 case ARG_PRESET_MODE
:
6896 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6897 if (arg_preset_mode
< 0) {
6898 log_error("Failed to parse preset mode: %s.", optarg
);
6909 if (strv_extend(&arg_wall
, optarg
) < 0)
6917 assert_not_reached("Unhandled option");
6920 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6921 log_error("Cannot access user instance remotely.");
6928 static int halt_parse_argv(int argc
, char *argv
[]) {
6937 static const struct option options
[] = {
6938 { "help", no_argument
, NULL
, ARG_HELP
},
6939 { "halt", no_argument
, NULL
, ARG_HALT
},
6940 { "poweroff", no_argument
, NULL
, 'p' },
6941 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6942 { "force", no_argument
, NULL
, 'f' },
6943 { "wtmp-only", no_argument
, NULL
, 'w' },
6944 { "no-wtmp", no_argument
, NULL
, 'd' },
6945 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6954 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6955 if (runlevel
== '0' || runlevel
== '6')
6958 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6966 arg_action
= ACTION_HALT
;
6970 if (arg_action
!= ACTION_REBOOT
)
6971 arg_action
= ACTION_POWEROFF
;
6975 arg_action
= ACTION_REBOOT
;
6997 /* Compatibility nops */
7004 assert_not_reached("Unhandled option");
7007 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7008 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7011 } else if (optind
< argc
) {
7012 log_error("Too many arguments.");
7019 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7023 if (streq(t
, "now"))
7025 else if (!strchr(t
, ':')) {
7028 if (safe_atou64(t
, &u
) < 0)
7031 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7040 hour
= strtol(t
, &e
, 10);
7041 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7044 minute
= strtol(e
+1, &e
, 10);
7045 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7048 n
= now(CLOCK_REALTIME
);
7049 s
= (time_t) (n
/ USEC_PER_SEC
);
7051 assert_se(localtime_r(&s
, &tm
));
7053 tm
.tm_hour
= (int) hour
;
7054 tm
.tm_min
= (int) minute
;
7057 assert_se(s
= mktime(&tm
));
7059 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7062 *_u
+= USEC_PER_DAY
;
7068 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7075 static const struct option options
[] = {
7076 { "help", no_argument
, NULL
, ARG_HELP
},
7077 { "halt", no_argument
, NULL
, 'H' },
7078 { "poweroff", no_argument
, NULL
, 'P' },
7079 { "reboot", no_argument
, NULL
, 'r' },
7080 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7081 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7091 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7099 arg_action
= ACTION_HALT
;
7103 arg_action
= ACTION_POWEROFF
;
7108 arg_action
= ACTION_KEXEC
;
7110 arg_action
= ACTION_REBOOT
;
7114 arg_action
= ACTION_KEXEC
;
7118 if (arg_action
!= ACTION_HALT
)
7119 arg_action
= ACTION_POWEROFF
;
7134 /* Compatibility nops */
7138 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7145 assert_not_reached("Unhandled option");
7148 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7149 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7151 log_error("Failed to parse time specification: %s", argv
[optind
]);
7155 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7157 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7158 /* No time argument for shutdown cancel */
7159 wall
= argv
+ optind
;
7160 else if (argc
> optind
+ 1)
7161 /* We skip the time argument */
7162 wall
= argv
+ optind
+ 1;
7165 arg_wall
= strv_copy(wall
);
7175 static int telinit_parse_argv(int argc
, char *argv
[]) {
7182 static const struct option options
[] = {
7183 { "help", no_argument
, NULL
, ARG_HELP
},
7184 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7188 static const struct {
7192 { '0', ACTION_POWEROFF
},
7193 { '6', ACTION_REBOOT
},
7194 { '1', ACTION_RESCUE
},
7195 { '2', ACTION_RUNLEVEL2
},
7196 { '3', ACTION_RUNLEVEL3
},
7197 { '4', ACTION_RUNLEVEL4
},
7198 { '5', ACTION_RUNLEVEL5
},
7199 { 's', ACTION_RESCUE
},
7200 { 'S', ACTION_RESCUE
},
7201 { 'q', ACTION_RELOAD
},
7202 { 'Q', ACTION_RELOAD
},
7203 { 'u', ACTION_REEXEC
},
7204 { 'U', ACTION_REEXEC
}
7213 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7228 assert_not_reached("Unhandled option");
7231 if (optind
>= argc
) {
7232 log_error("%s: required argument missing.", program_invocation_short_name
);
7236 if (optind
+ 1 < argc
) {
7237 log_error("Too many arguments.");
7241 if (strlen(argv
[optind
]) != 1) {
7242 log_error("Expected single character argument.");
7246 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7247 if (table
[i
].from
== argv
[optind
][0])
7250 if (i
>= ELEMENTSOF(table
)) {
7251 log_error("Unknown command '%s'.", argv
[optind
]);
7255 arg_action
= table
[i
].to
;
7262 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7268 static const struct option options
[] = {
7269 { "help", no_argument
, NULL
, ARG_HELP
},
7278 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7289 assert_not_reached("Unhandled option");
7292 if (optind
< argc
) {
7293 log_error("Too many arguments.");
7300 static int parse_argv(int argc
, char *argv
[]) {
7304 if (program_invocation_short_name
) {
7306 if (strstr(program_invocation_short_name
, "halt")) {
7307 arg_action
= ACTION_HALT
;
7308 return halt_parse_argv(argc
, argv
);
7309 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7310 arg_action
= ACTION_POWEROFF
;
7311 return halt_parse_argv(argc
, argv
);
7312 } else if (strstr(program_invocation_short_name
, "reboot")) {
7314 arg_action
= ACTION_KEXEC
;
7316 arg_action
= ACTION_REBOOT
;
7317 return halt_parse_argv(argc
, argv
);
7318 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7319 arg_action
= ACTION_POWEROFF
;
7320 return shutdown_parse_argv(argc
, argv
);
7321 } else if (strstr(program_invocation_short_name
, "init")) {
7323 if (sd_booted() > 0) {
7324 arg_action
= _ACTION_INVALID
;
7325 return telinit_parse_argv(argc
, argv
);
7327 /* Hmm, so some other init system is
7328 * running, we need to forward this
7329 * request to it. For now we simply
7330 * guess that it is Upstart. */
7332 execv(TELINIT
, argv
);
7334 log_error("Couldn't find an alternative telinit implementation to spawn.");
7338 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7339 arg_action
= ACTION_RUNLEVEL
;
7340 return runlevel_parse_argv(argc
, argv
);
7344 arg_action
= ACTION_SYSTEMCTL
;
7345 return systemctl_parse_argv(argc
, argv
);
7348 _pure_
static int action_to_runlevel(void) {
7350 static const char table
[_ACTION_MAX
] = {
7351 [ACTION_HALT
] = '0',
7352 [ACTION_POWEROFF
] = '0',
7353 [ACTION_REBOOT
] = '6',
7354 [ACTION_RUNLEVEL2
] = '2',
7355 [ACTION_RUNLEVEL3
] = '3',
7356 [ACTION_RUNLEVEL4
] = '4',
7357 [ACTION_RUNLEVEL5
] = '5',
7358 [ACTION_RESCUE
] = '1'
7361 assert(arg_action
< _ACTION_MAX
);
7363 return table
[arg_action
];
7366 static int talk_initctl(void) {
7367 #ifdef HAVE_SYSV_COMPAT
7368 struct init_request request
= {
7369 .magic
= INIT_MAGIC
,
7371 .cmd
= INIT_CMD_RUNLVL
7374 _cleanup_close_
int fd
= -1;
7378 rl
= action_to_runlevel();
7382 request
.runlevel
= rl
;
7384 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7386 if (errno
== ENOENT
)
7389 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7392 r
= loop_write(fd
, &request
, sizeof(request
), false);
7394 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7402 static int systemctl_main(int argc
, char *argv
[]) {
7404 static const Verb verbs
[] = {
7405 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
, list_units
},
7406 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7407 { "list-sockets", VERB_ANY
, VERB_ANY
, 0, list_sockets
},
7408 { "list-timers", VERB_ANY
, VERB_ANY
, 0, list_timers
},
7409 { "list-jobs", VERB_ANY
, VERB_ANY
, 0, list_jobs
},
7410 { "list-machines", VERB_ANY
, VERB_ANY
, 0, list_machines
},
7411 { "clear-jobs", VERB_ANY
, 1, 0, daemon_reload
},
7412 { "cancel", 2, VERB_ANY
, 0, cancel_job
},
7413 { "start", 2, VERB_ANY
, 0, start_unit
},
7414 { "stop", 2, VERB_ANY
, 0, start_unit
},
7415 { "condstop", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7416 { "reload", 2, VERB_ANY
, 0, start_unit
},
7417 { "restart", 2, VERB_ANY
, 0, start_unit
},
7418 { "try-restart", 2, VERB_ANY
, 0, start_unit
},
7419 { "reload-or-restart", 2, VERB_ANY
, 0, start_unit
},
7420 { "reload-or-try-restart", 2, VERB_ANY
, 0, start_unit
},
7421 { "force-reload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with SysV */
7422 { "condreload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7423 { "condrestart", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with RH */
7424 { "isolate", 2, 2, 0, start_unit
},
7425 { "kill", 2, VERB_ANY
, 0, kill_unit
},
7426 { "is-active", 2, VERB_ANY
, 0, check_unit_active
},
7427 { "check", 2, VERB_ANY
, 0, check_unit_active
},
7428 { "is-failed", 2, VERB_ANY
, 0, check_unit_failed
},
7429 { "show", VERB_ANY
, VERB_ANY
, 0, show
},
7430 { "cat", 2, VERB_ANY
, 0, cat
},
7431 { "status", VERB_ANY
, VERB_ANY
, 0, show
},
7432 { "help", VERB_ANY
, VERB_ANY
, 0, show
},
7433 { "snapshot", VERB_ANY
, 2, 0, snapshot
},
7434 { "delete", 2, VERB_ANY
, 0, delete_snapshot
},
7435 { "daemon-reload", VERB_ANY
, 1, 0, daemon_reload
},
7436 { "daemon-reexec", VERB_ANY
, 1, 0, daemon_reload
},
7437 { "show-environment", VERB_ANY
, 1, 0, show_environment
},
7438 { "set-environment", 2, VERB_ANY
, 0, set_environment
},
7439 { "unset-environment", 2, VERB_ANY
, 0, set_environment
},
7440 { "import-environment", VERB_ANY
, VERB_ANY
, 0, import_environment
},
7441 { "halt", VERB_ANY
, 1, 0, start_special
},
7442 { "poweroff", VERB_ANY
, 1, 0, start_special
},
7443 { "reboot", VERB_ANY
, 2, 0, start_special
},
7444 { "kexec", VERB_ANY
, 1, 0, start_special
},
7445 { "suspend", VERB_ANY
, 1, 0, start_special
},
7446 { "hibernate", VERB_ANY
, 1, 0, start_special
},
7447 { "hybrid-sleep", VERB_ANY
, 1, 0, start_special
},
7448 { "default", VERB_ANY
, 1, 0, start_special
},
7449 { "rescue", VERB_ANY
, 1, 0, start_special
},
7450 { "emergency", VERB_ANY
, 1, 0, start_special
},
7451 { "exit", VERB_ANY
, 2, 0, start_special
},
7452 { "reset-failed", VERB_ANY
, VERB_ANY
, 0, reset_failed
},
7453 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7454 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7455 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7456 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7457 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7458 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7459 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7460 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7461 { "link", 2, VERB_ANY
, 0, enable_unit
},
7462 { "switch-root", 2, VERB_ANY
, 0, switch_root
},
7463 { "list-dependencies", VERB_ANY
, 2, 0, list_dependencies
},
7464 { "set-default", 2, 2, 0, set_default
},
7465 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7466 { "set-property", 3, VERB_ANY
, 0, set_property
},
7467 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7468 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7469 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7470 { "edit", 2, VERB_ANY
, 0, edit
},
7474 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7477 static int reload_with_fallback(void) {
7479 /* First, try systemd via D-Bus. */
7480 if (daemon_reload(0, NULL
, NULL
) >= 0)
7483 /* Nothing else worked, so let's try signals */
7484 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7486 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7487 return log_error_errno(errno
, "kill() failed: %m");
7492 static int start_with_fallback(void) {
7494 /* First, try systemd via D-Bus. */
7495 if (start_unit(0, NULL
, NULL
) >= 0)
7498 /* Nothing else worked, so let's try
7500 if (talk_initctl() > 0)
7503 log_error("Failed to talk to init daemon.");
7507 static int halt_now(enum action a
) {
7509 /* The kernel will automaticall flush ATA disks and suchlike
7510 * on reboot(), but the file systems need to be synce'd
7511 * explicitly in advance. */
7514 /* Make sure C-A-D is handled by the kernel from this point
7516 (void) reboot(RB_ENABLE_CAD
);
7521 log_info("Halting.");
7522 (void) reboot(RB_HALT_SYSTEM
);
7525 case ACTION_POWEROFF
:
7526 log_info("Powering off.");
7527 (void) reboot(RB_POWER_OFF
);
7531 case ACTION_REBOOT
: {
7532 _cleanup_free_
char *param
= NULL
;
7534 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7535 log_info("Rebooting with argument '%s'.", param
);
7536 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7539 log_info("Rebooting.");
7540 (void) reboot(RB_AUTOBOOT
);
7545 assert_not_reached("Unknown action.");
7549 static int logind_schedule_shutdown(void) {
7552 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7553 char date
[FORMAT_TIMESTAMP_MAX
];
7558 (void) logind_set_wall_message();
7560 r
= acquire_bus(BUS_FULL
, &bus
);
7564 switch (arg_action
) {
7568 case ACTION_POWEROFF
:
7569 action
= "poweroff";
7584 action
= strjoina("dry-", action
);
7586 r
= sd_bus_call_method(
7588 "org.freedesktop.login1",
7589 "/org/freedesktop/login1",
7590 "org.freedesktop.login1.Manager",
7598 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7600 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7603 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7608 static int halt_main(void) {
7611 r
= logind_check_inhibitors(arg_action
);
7616 return logind_schedule_shutdown();
7618 if (geteuid() != 0) {
7619 if (arg_dry
|| arg_force
> 0) {
7620 log_error("Must be root.");
7624 /* Try logind if we are a normal user and no special
7625 * mode applies. Maybe PolicyKit allows us to shutdown
7627 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7628 r
= logind_reboot(arg_action
);
7631 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7632 /* requested operation is not
7633 * supported on the local system or
7634 * already in progress */
7636 /* on all other errors, try low-level operation */
7640 if (!arg_dry
&& !arg_force
)
7641 return start_with_fallback();
7643 assert(geteuid() == 0);
7646 if (sd_booted() > 0)
7647 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7649 r
= utmp_put_shutdown();
7651 log_warning_errno(r
, "Failed to write utmp record: %m");
7658 r
= halt_now(arg_action
);
7659 return log_error_errno(r
, "Failed to reboot: %m");
7662 static int runlevel_main(void) {
7663 int r
, runlevel
, previous
;
7665 r
= utmp_get_runlevel(&runlevel
, &previous
);
7672 previous
<= 0 ? 'N' : previous
,
7673 runlevel
<= 0 ? 'N' : runlevel
);
7678 static int logind_cancel_shutdown(void) {
7680 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7684 r
= acquire_bus(BUS_FULL
, &bus
);
7688 (void) logind_set_wall_message();
7690 r
= sd_bus_call_method(
7692 "org.freedesktop.login1",
7693 "/org/freedesktop/login1",
7694 "org.freedesktop.login1.Manager",
7695 "CancelScheduledShutdown",
7699 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7703 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7708 int main(int argc
, char*argv
[]) {
7711 setlocale(LC_ALL
, "");
7712 log_parse_environment();
7715 /* Explicitly not on_tty() to avoid setting cached value.
7716 * This becomes relevant for piping output which might be
7718 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7720 r
= parse_argv(argc
, argv
);
7724 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7725 log_info("Running in chroot, ignoring request.");
7730 /* systemctl_main() will print an error message for the bus
7731 * connection, but only if it needs to */
7733 switch (arg_action
) {
7735 case ACTION_SYSTEMCTL
:
7736 r
= systemctl_main(argc
, argv
);
7740 case ACTION_POWEROFF
:
7746 case ACTION_RUNLEVEL2
:
7747 case ACTION_RUNLEVEL3
:
7748 case ACTION_RUNLEVEL4
:
7749 case ACTION_RUNLEVEL5
:
7751 case ACTION_EMERGENCY
:
7752 case ACTION_DEFAULT
:
7753 r
= start_with_fallback();
7758 r
= reload_with_fallback();
7761 case ACTION_CANCEL_SHUTDOWN
:
7762 r
= logind_cancel_shutdown();
7765 case ACTION_RUNLEVEL
:
7766 r
= runlevel_main();
7769 case _ACTION_INVALID
:
7771 assert_not_reached("Unknown action");
7776 ask_password_agent_close();
7777 polkit_agent_close();
7779 strv_free(arg_types
);
7780 strv_free(arg_states
);
7781 strv_free(arg_properties
);
7783 strv_free(arg_wall
);
7788 return r
< 0 ? EXIT_FAILURE
: r
;