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"
55 #include "hostname-util.h"
61 #include "logs-show.h"
65 #include "parse-util.h"
66 #include "path-lookup.h"
67 #include "path-util.h"
68 #include "process-util.h"
69 #include "rlimit-util.h"
71 #include "signal-util.h"
72 #include "socket-util.h"
73 #include "spawn-ask-password-agent.h"
74 #include "spawn-polkit-agent.h"
77 #include "terminal-util.h"
78 #include "unit-name.h"
79 #include "user-util.h"
81 #include "utmp-wtmp.h"
84 static char **arg_types
= NULL
;
85 static char **arg_states
= NULL
;
86 static char **arg_properties
= NULL
;
87 static bool arg_all
= false;
88 static enum dependency
{
94 } arg_dependency
= DEPENDENCY_FORWARD
;
95 static const char *arg_job_mode
= "replace";
96 static UnitFileScope arg_scope
= UNIT_FILE_SYSTEM
;
97 static bool arg_no_block
= false;
98 static bool arg_no_legend
= false;
99 static bool arg_no_pager
= false;
100 static bool arg_no_wtmp
= false;
101 static bool arg_no_wall
= false;
102 static bool arg_no_reload
= false;
103 static bool arg_show_types
= false;
104 static bool arg_ignore_inhibitors
= false;
105 static bool arg_dry
= false;
106 static bool arg_quiet
= false;
107 static bool arg_full
= false;
108 static bool arg_recursive
= false;
109 static int arg_force
= 0;
110 static bool arg_ask_password
= false;
111 static bool arg_runtime
= false;
112 static UnitFilePresetMode arg_preset_mode
= UNIT_FILE_PRESET_FULL
;
113 static char **arg_wall
= NULL
;
114 static const char *arg_kill_who
= NULL
;
115 static int arg_signal
= SIGTERM
;
116 static char *arg_root
= NULL
;
117 static usec_t arg_when
= 0;
139 ACTION_CANCEL_SHUTDOWN
,
141 } arg_action
= ACTION_SYSTEMCTL
;
142 static BusTransport arg_transport
= BUS_TRANSPORT_LOCAL
;
143 static const char *arg_host
= NULL
;
144 static unsigned arg_lines
= 10;
145 static OutputMode arg_output
= OUTPUT_SHORT
;
146 static bool arg_plain
= false;
147 static bool arg_firmware_setup
= false;
148 static bool arg_now
= false;
150 static int daemon_reload(int argc
, char *argv
[], void* userdata
);
151 static int halt_now(enum action a
);
152 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
);
154 static bool original_stdout_is_tty
;
156 typedef enum BusFocus
{
157 BUS_FULL
, /* The full bus indicated via --system or --user */
158 BUS_MANAGER
, /* The manager itself, possibly directly, possibly via the bus */
162 static sd_bus
*busses
[_BUS_FOCUS_MAX
] = {};
164 static int acquire_bus(BusFocus focus
, sd_bus
**ret
) {
167 assert(focus
< _BUS_FOCUS_MAX
);
170 /* We only go directly to the manager, if we are using a local transport */
171 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
174 if (!busses
[focus
]) {
177 user
= arg_scope
!= UNIT_FILE_SYSTEM
;
179 if (focus
== BUS_MANAGER
)
180 r
= bus_connect_transport_systemd(arg_transport
, arg_host
, user
, &busses
[focus
]);
182 r
= bus_connect_transport(arg_transport
, arg_host
, user
, &busses
[focus
]);
184 return log_error_errno(r
, "Failed to connect to bus: %m");
186 (void) sd_bus_set_allow_interactive_authorization(busses
[focus
], arg_ask_password
);
189 *ret
= busses
[focus
];
193 static void release_busses(void) {
196 for (w
= 0; w
< _BUS_FOCUS_MAX
; w
++)
197 busses
[w
] = sd_bus_flush_close_unref(busses
[w
]);
200 static void pager_open_if_enabled(void) {
208 static void ask_password_agent_open_if_enabled(void) {
210 /* Open the password agent as a child process if necessary */
212 if (!arg_ask_password
)
215 if (arg_scope
!= UNIT_FILE_SYSTEM
)
218 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
221 ask_password_agent_open();
224 static void polkit_agent_open_if_enabled(void) {
226 /* Open the polkit agent as a child process if necessary */
228 if (!arg_ask_password
)
231 if (arg_scope
!= UNIT_FILE_SYSTEM
)
234 if (arg_transport
!= BUS_TRANSPORT_LOCAL
)
240 static OutputFlags
get_output_flags(void) {
242 arg_all
* OUTPUT_SHOW_ALL
|
243 arg_full
* OUTPUT_FULL_WIDTH
|
244 (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH
|
245 on_tty() * OUTPUT_COLOR
|
246 !arg_quiet
* OUTPUT_WARN_CUTOFF
;
249 static int translate_bus_error_to_exit_status(int r
, const sd_bus_error
*error
) {
252 if (!sd_bus_error_is_set(error
))
255 if (sd_bus_error_has_name(error
, SD_BUS_ERROR_ACCESS_DENIED
) ||
256 sd_bus_error_has_name(error
, BUS_ERROR_ONLY_BY_DEPENDENCY
) ||
257 sd_bus_error_has_name(error
, BUS_ERROR_NO_ISOLATION
) ||
258 sd_bus_error_has_name(error
, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE
))
259 return EXIT_NOPERMISSION
;
261 if (sd_bus_error_has_name(error
, BUS_ERROR_NO_SUCH_UNIT
))
262 return EXIT_NOTINSTALLED
;
264 if (sd_bus_error_has_name(error
, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE
) ||
265 sd_bus_error_has_name(error
, SD_BUS_ERROR_NOT_SUPPORTED
))
266 return EXIT_NOTIMPLEMENTED
;
268 if (sd_bus_error_has_name(error
, BUS_ERROR_LOAD_FAILED
))
269 return EXIT_NOTCONFIGURED
;
277 static bool install_client_side(void) {
279 /* Decides when to execute enable/disable/... operations
280 * client-side rather than server-side. */
282 if (running_in_chroot() > 0)
285 if (sd_booted() <= 0)
288 if (!isempty(arg_root
))
291 if (arg_scope
== UNIT_FILE_GLOBAL
)
297 static int compare_unit_info(const void *a
, const void *b
) {
298 const UnitInfo
*u
= a
, *v
= b
;
302 /* First, order by machine */
303 if (!u
->machine
&& v
->machine
)
305 if (u
->machine
&& !v
->machine
)
307 if (u
->machine
&& v
->machine
) {
308 r
= strcasecmp(u
->machine
, v
->machine
);
313 /* Second, order by unit type */
314 d1
= strrchr(u
->id
, '.');
315 d2
= strrchr(v
->id
, '.');
317 r
= strcasecmp(d1
, d2
);
322 /* Third, order by name */
323 return strcasecmp(u
->id
, v
->id
);
326 static bool output_show_unit(const UnitInfo
*u
, char **patterns
) {
327 if (!strv_fnmatch_or_empty(patterns
, u
->id
, FNM_NOESCAPE
))
333 dot
= strrchr(u
->id
, '.');
337 if (!strv_find(arg_types
, dot
+1))
347 if (streq(u
->active_state
, "inactive") || u
->following
[0])
353 static int output_units_list(const UnitInfo
*unit_infos
, unsigned c
) {
354 unsigned circle_len
= 0, id_len
, max_id_len
, load_len
, active_len
, sub_len
, job_len
, desc_len
;
356 unsigned n_shown
= 0;
359 max_id_len
= strlen("UNIT");
360 load_len
= strlen("LOAD");
361 active_len
= strlen("ACTIVE");
362 sub_len
= strlen("SUB");
363 job_len
= strlen("JOB");
366 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
367 max_id_len
= MAX(max_id_len
, strlen(u
->id
) + (u
->machine
? strlen(u
->machine
)+1 : 0));
368 load_len
= MAX(load_len
, strlen(u
->load_state
));
369 active_len
= MAX(active_len
, strlen(u
->active_state
));
370 sub_len
= MAX(sub_len
, strlen(u
->sub_state
));
372 if (u
->job_id
!= 0) {
373 job_len
= MAX(job_len
, strlen(u
->job_type
));
377 if (!arg_no_legend
&&
378 (streq(u
->active_state
, "failed") ||
379 STR_IN_SET(u
->load_state
, "error", "not-found", "masked")))
383 if (!arg_full
&& original_stdout_is_tty
) {
386 id_len
= MIN(max_id_len
, 25u);
387 basic_len
= circle_len
+ 5 + id_len
+ 5 + active_len
+ sub_len
;
390 basic_len
+= job_len
+ 1;
392 if (basic_len
< (unsigned) columns()) {
393 unsigned extra_len
, incr
;
394 extra_len
= columns() - basic_len
;
396 /* Either UNIT already got 25, or is fully satisfied.
397 * Grant up to 25 to DESC now. */
398 incr
= MIN(extra_len
, 25u);
402 /* split the remaining space between UNIT and DESC,
403 * but do not give UNIT more than it needs. */
405 incr
= MIN(extra_len
/ 2, max_id_len
- id_len
);
407 desc_len
+= extra_len
- incr
;
413 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
414 _cleanup_free_
char *e
= NULL
, *j
= NULL
;
415 const char *on_loaded
= "", *off_loaded
= "";
416 const char *on_active
= "", *off_active
= "";
417 const char *on_circle
= "", *off_circle
= "";
421 if (!n_shown
&& !arg_no_legend
) {
426 printf("%-*s %-*s %-*s %-*s ",
429 active_len
, "ACTIVE",
433 printf("%-*s ", job_len
, "JOB");
435 if (!arg_full
&& arg_no_pager
)
436 printf("%.*s\n", desc_len
, "DESCRIPTION");
438 printf("%s\n", "DESCRIPTION");
443 if (STR_IN_SET(u
->load_state
, "error", "not-found", "masked") && !arg_plain
) {
444 on_loaded
= ansi_highlight_red();
445 on_circle
= ansi_highlight_yellow();
446 off_loaded
= off_circle
= ansi_normal();
448 } else if (streq(u
->active_state
, "failed") && !arg_plain
) {
449 on_circle
= on_active
= ansi_highlight_red();
450 off_circle
= off_active
= ansi_normal();
455 j
= strjoin(u
->machine
, ":", u
->id
, NULL
);
464 e
= ellipsize(id
, id_len
, 33);
472 printf("%s%s%s ", on_circle
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_circle
);
474 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
475 on_active
, id_len
, id
, off_active
,
476 on_loaded
, load_len
, u
->load_state
, off_loaded
,
477 on_active
, active_len
, u
->active_state
,
478 sub_len
, u
->sub_state
, off_active
,
479 job_count
? job_len
+ 1 : 0, u
->job_id
? u
->job_type
: "");
482 printf("%.*s\n", desc_len
, u
->description
);
484 printf("%s\n", u
->description
);
487 if (!arg_no_legend
) {
488 const char *on
, *off
;
492 "LOAD = Reflects whether the unit definition was properly loaded.\n"
493 "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
494 "SUB = The low-level unit activation state, values depend on unit type.");
495 puts(job_count
? "JOB = Pending job for the unit.\n" : "");
496 on
= ansi_highlight();
499 on
= ansi_highlight_red();
504 printf("%s%u loaded units listed.%s\n"
505 "To show all installed unit files use 'systemctl list-unit-files'.\n",
508 printf("%s%u loaded units listed.%s Pass --all to see loaded but inactive units, too.\n"
509 "To show all installed unit files use 'systemctl list-unit-files'.\n",
516 static int get_unit_list(
520 UnitInfo
**unit_infos
,
522 sd_bus_message
**_reply
) {
524 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
525 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
526 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
535 r
= sd_bus_message_new_method_call(
538 "org.freedesktop.systemd1",
539 "/org/freedesktop/systemd1",
540 "org.freedesktop.systemd1.Manager",
541 "ListUnitsFiltered");
544 return bus_log_create_error(r
);
546 r
= sd_bus_message_append_strv(m
, arg_states
);
548 return bus_log_create_error(r
);
550 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
552 return log_error_errno(r
, "Failed to list units: %s", bus_error_message(&error
, r
));
554 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssssouso)");
556 return bus_log_parse_error(r
);
558 while ((r
= bus_parse_unit_info(reply
, &u
)) > 0) {
561 if (!output_show_unit(&u
, patterns
))
564 if (!GREEDY_REALLOC(*unit_infos
, size
, c
+1))
567 (*unit_infos
)[c
++] = u
;
570 return bus_log_parse_error(r
);
572 r
= sd_bus_message_exit_container(reply
);
574 return bus_log_parse_error(r
);
582 static void message_set_freep(Set
**set
) {
585 while ((m
= set_steal_first(*set
)))
586 sd_bus_message_unref(m
);
591 static int get_unit_list_recursive(
594 UnitInfo
**_unit_infos
,
598 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
599 _cleanup_(message_set_freep
) Set
*replies
;
600 sd_bus_message
*reply
;
608 replies
= set_new(NULL
);
612 c
= get_unit_list(bus
, NULL
, patterns
, &unit_infos
, 0, &reply
);
616 r
= set_put(replies
, reply
);
618 sd_bus_message_unref(reply
);
623 _cleanup_strv_free_
char **machines
= NULL
;
626 r
= sd_get_machine_names(&machines
);
628 return log_error_errno(r
, "Failed to get machine names: %m");
630 STRV_FOREACH(i
, machines
) {
631 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
634 r
= sd_bus_open_system_machine(&container
, *i
);
636 log_warning_errno(r
, "Failed to connect to container %s, ignoring: %m", *i
);
640 k
= get_unit_list(container
, *i
, patterns
, &unit_infos
, c
, &reply
);
646 r
= set_put(replies
, reply
);
648 sd_bus_message_unref(reply
);
653 *_machines
= machines
;
658 *_unit_infos
= unit_infos
;
667 static int list_units(int argc
, char *argv
[], void *userdata
) {
668 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
669 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
670 _cleanup_strv_free_
char **machines
= NULL
;
674 pager_open_if_enabled();
676 r
= acquire_bus(BUS_MANAGER
, &bus
);
680 r
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
684 qsort_safe(unit_infos
, r
, sizeof(UnitInfo
), compare_unit_info
);
685 return output_units_list(unit_infos
, r
);
688 static int get_triggered_units(
693 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
700 r
= sd_bus_get_property_strv(
702 "org.freedesktop.systemd1",
704 "org.freedesktop.systemd1.Unit",
709 return log_error_errno(r
, "Failed to determine triggers: %s", bus_error_message(&error
, r
));
714 static int get_listening(
716 const char* unit_path
,
719 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
720 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
721 const char *type
, *path
;
724 r
= sd_bus_get_property(
726 "org.freedesktop.systemd1",
728 "org.freedesktop.systemd1.Socket",
734 return log_error_errno(r
, "Failed to get list of listening sockets: %s", bus_error_message(&error
, r
));
736 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
738 return bus_log_parse_error(r
);
740 while ((r
= sd_bus_message_read(reply
, "(ss)", &type
, &path
)) > 0) {
742 r
= strv_extend(listening
, type
);
746 r
= strv_extend(listening
, path
);
753 return bus_log_parse_error(r
);
755 r
= sd_bus_message_exit_container(reply
);
757 return bus_log_parse_error(r
);
769 /* Note: triggered is a list here, although it almost certainly
770 * will always be one unit. Nevertheless, dbus API allows for multiple
771 * values, so let's follow that. */
774 /* The strv above is shared. free is set only in the first one. */
778 static int socket_info_compare(const struct socket_info
*a
, const struct socket_info
*b
) {
784 if (!a
->machine
&& b
->machine
)
786 if (a
->machine
&& !b
->machine
)
788 if (a
->machine
&& b
->machine
) {
789 o
= strcasecmp(a
->machine
, b
->machine
);
794 o
= strcmp(a
->path
, b
->path
);
796 o
= strcmp(a
->type
, b
->type
);
801 static int output_sockets_list(struct socket_info
*socket_infos
, unsigned cs
) {
802 struct socket_info
*s
;
803 unsigned pathlen
= strlen("LISTEN"),
804 typelen
= strlen("TYPE") * arg_show_types
,
805 socklen
= strlen("UNIT"),
806 servlen
= strlen("ACTIVATES");
807 const char *on
, *off
;
809 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
813 socklen
= MAX(socklen
, strlen(s
->id
));
815 typelen
= MAX(typelen
, strlen(s
->type
));
816 pathlen
= MAX(pathlen
, strlen(s
->path
) + (s
->machine
? strlen(s
->machine
)+1 : 0));
818 STRV_FOREACH(a
, s
->triggered
)
819 tmp
+= strlen(*a
) + 2*(a
!= s
->triggered
);
820 servlen
= MAX(servlen
, tmp
);
825 printf("%-*s %-*.*s%-*s %s\n",
827 typelen
+ arg_show_types
, typelen
+ arg_show_types
, "TYPE ",
831 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
832 _cleanup_free_
char *j
= NULL
;
837 j
= strjoin(s
->machine
, ":", s
->path
, NULL
);
845 printf("%-*s %-*s %-*s",
846 pathlen
, path
, typelen
, s
->type
, socklen
, s
->id
);
849 pathlen
, path
, socklen
, s
->id
);
850 STRV_FOREACH(a
, s
->triggered
)
852 a
== s
->triggered
? "" : ",", *a
);
856 on
= ansi_highlight();
861 on
= ansi_highlight_red();
865 if (!arg_no_legend
) {
866 printf("%s%u sockets listed.%s\n", on
, cs
, off
);
868 printf("Pass --all to see loaded but inactive sockets, too.\n");
874 static int list_sockets(int argc
, char *argv
[], void *userdata
) {
875 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
876 _cleanup_strv_free_
char **machines
= NULL
;
877 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
878 _cleanup_free_
struct socket_info
*socket_infos
= NULL
;
880 struct socket_info
*s
;
886 pager_open_if_enabled();
888 r
= acquire_bus(BUS_MANAGER
, &bus
);
892 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
896 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
897 _cleanup_strv_free_
char **listening
= NULL
, **triggered
= NULL
;
900 if (!endswith(u
->id
, ".socket"))
903 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
907 c
= get_listening(bus
, u
->unit_path
, &listening
);
913 if (!GREEDY_REALLOC(socket_infos
, size
, cs
+ c
)) {
918 for (i
= 0; i
< c
; i
++)
919 socket_infos
[cs
+ i
] = (struct socket_info
) {
920 .machine
= u
->machine
,
922 .type
= listening
[i
*2],
923 .path
= listening
[i
*2 + 1],
924 .triggered
= triggered
,
925 .own_triggered
= i
==0,
928 /* from this point on we will cleanup those socket_infos */
931 listening
= triggered
= NULL
; /* avoid cleanup */
934 qsort_safe(socket_infos
, cs
, sizeof(struct socket_info
),
935 (__compar_fn_t
) socket_info_compare
);
937 output_sockets_list(socket_infos
, cs
);
940 assert(cs
== 0 || socket_infos
);
941 for (s
= socket_infos
; s
< socket_infos
+ cs
; s
++) {
944 if (s
->own_triggered
)
945 strv_free(s
->triggered
);
951 static int get_next_elapse(
954 dual_timestamp
*next
) {
956 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
964 r
= sd_bus_get_property_trivial(
966 "org.freedesktop.systemd1",
968 "org.freedesktop.systemd1.Timer",
969 "NextElapseUSecMonotonic",
974 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
976 r
= sd_bus_get_property_trivial(
978 "org.freedesktop.systemd1",
980 "org.freedesktop.systemd1.Timer",
981 "NextElapseUSecRealtime",
986 return log_error_errno(r
, "Failed to get next elapsation time: %s", bus_error_message(&error
, r
));
992 static int get_last_trigger(
997 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1004 r
= sd_bus_get_property_trivial(
1006 "org.freedesktop.systemd1",
1008 "org.freedesktop.systemd1.Timer",
1014 return log_error_errno(r
, "Failed to get last trigger time: %s", bus_error_message(&error
, r
));
1020 const char* machine
;
1023 usec_t last_trigger
;
1027 static int timer_info_compare(const struct timer_info
*a
, const struct timer_info
*b
) {
1033 if (!a
->machine
&& b
->machine
)
1035 if (a
->machine
&& !b
->machine
)
1037 if (a
->machine
&& b
->machine
) {
1038 o
= strcasecmp(a
->machine
, b
->machine
);
1043 if (a
->next_elapse
< b
->next_elapse
)
1045 if (a
->next_elapse
> b
->next_elapse
)
1048 return strcmp(a
->id
, b
->id
);
1051 static int output_timers_list(struct timer_info
*timer_infos
, unsigned n
) {
1052 struct timer_info
*t
;
1054 nextlen
= strlen("NEXT"),
1055 leftlen
= strlen("LEFT"),
1056 lastlen
= strlen("LAST"),
1057 passedlen
= strlen("PASSED"),
1058 unitlen
= strlen("UNIT"),
1059 activatelen
= strlen("ACTIVATES");
1061 const char *on
, *off
;
1063 assert(timer_infos
|| n
== 0);
1065 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1069 if (t
->next_elapse
> 0) {
1070 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1072 format_timestamp(tstamp
, sizeof(tstamp
), t
->next_elapse
);
1073 nextlen
= MAX(nextlen
, strlen(tstamp
) + 1);
1075 format_timestamp_relative(trel
, sizeof(trel
), t
->next_elapse
);
1076 leftlen
= MAX(leftlen
, strlen(trel
));
1079 if (t
->last_trigger
> 0) {
1080 char tstamp
[FORMAT_TIMESTAMP_MAX
] = "", trel
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "";
1082 format_timestamp(tstamp
, sizeof(tstamp
), t
->last_trigger
);
1083 lastlen
= MAX(lastlen
, strlen(tstamp
) + 1);
1085 format_timestamp_relative(trel
, sizeof(trel
), t
->last_trigger
);
1086 passedlen
= MAX(passedlen
, strlen(trel
));
1089 unitlen
= MAX(unitlen
, strlen(t
->id
) + (t
->machine
? strlen(t
->machine
)+1 : 0));
1091 STRV_FOREACH(a
, t
->triggered
)
1092 ul
+= strlen(*a
) + 2*(a
!= t
->triggered
);
1094 activatelen
= MAX(activatelen
, ul
);
1099 printf("%-*s %-*s %-*s %-*s %-*s %s\n",
1103 passedlen
, "PASSED",
1107 for (t
= timer_infos
; t
< timer_infos
+ n
; t
++) {
1108 _cleanup_free_
char *j
= NULL
;
1110 char tstamp1
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel1
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1111 char tstamp2
[FORMAT_TIMESTAMP_MAX
] = "n/a", trel2
[FORMAT_TIMESTAMP_RELATIVE_MAX
] = "n/a";
1114 format_timestamp(tstamp1
, sizeof(tstamp1
), t
->next_elapse
);
1115 format_timestamp_relative(trel1
, sizeof(trel1
), t
->next_elapse
);
1117 format_timestamp(tstamp2
, sizeof(tstamp2
), t
->last_trigger
);
1118 format_timestamp_relative(trel2
, sizeof(trel2
), t
->last_trigger
);
1121 j
= strjoin(t
->machine
, ":", t
->id
, NULL
);
1128 printf("%-*s %-*s %-*s %-*s %-*s",
1129 nextlen
, tstamp1
, leftlen
, trel1
, lastlen
, tstamp2
, passedlen
, trel2
, unitlen
, unit
);
1131 STRV_FOREACH(a
, t
->triggered
)
1133 a
== t
->triggered
? "" : ",", *a
);
1137 on
= ansi_highlight();
1138 off
= ansi_normal();
1142 on
= ansi_highlight_red();
1143 off
= ansi_normal();
1146 if (!arg_no_legend
) {
1147 printf("%s%u timers listed.%s\n", on
, n
, off
);
1149 printf("Pass --all to see loaded but inactive timers, too.\n");
1155 static usec_t
calc_next_elapse(dual_timestamp
*nw
, dual_timestamp
*next
) {
1161 if (next
->monotonic
!= USEC_INFINITY
&& next
->monotonic
> 0) {
1164 if (next
->monotonic
> nw
->monotonic
)
1165 converted
= nw
->realtime
+ (next
->monotonic
- nw
->monotonic
);
1167 converted
= nw
->realtime
- (nw
->monotonic
- next
->monotonic
);
1169 if (next
->realtime
!= USEC_INFINITY
&& next
->realtime
> 0)
1170 next_elapse
= MIN(converted
, next
->realtime
);
1172 next_elapse
= converted
;
1175 next_elapse
= next
->realtime
;
1180 static int list_timers(int argc
, char *argv
[], void *userdata
) {
1181 _cleanup_(message_set_freep
) Set
*replies
= NULL
;
1182 _cleanup_strv_free_
char **machines
= NULL
;
1183 _cleanup_free_
struct timer_info
*timer_infos
= NULL
;
1184 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
1185 struct timer_info
*t
;
1193 pager_open_if_enabled();
1195 r
= acquire_bus(BUS_MANAGER
, &bus
);
1199 n
= get_unit_list_recursive(bus
, strv_skip(argv
, 1), &unit_infos
, &replies
, &machines
);
1203 dual_timestamp_get(&nw
);
1205 for (u
= unit_infos
; u
< unit_infos
+ n
; u
++) {
1206 _cleanup_strv_free_
char **triggered
= NULL
;
1207 dual_timestamp next
= DUAL_TIMESTAMP_NULL
;
1210 if (!endswith(u
->id
, ".timer"))
1213 r
= get_triggered_units(bus
, u
->unit_path
, &triggered
);
1217 r
= get_next_elapse(bus
, u
->unit_path
, &next
);
1221 get_last_trigger(bus
, u
->unit_path
, &last
);
1223 if (!GREEDY_REALLOC(timer_infos
, size
, c
+1)) {
1228 m
= calc_next_elapse(&nw
, &next
);
1230 timer_infos
[c
++] = (struct timer_info
) {
1231 .machine
= u
->machine
,
1234 .last_trigger
= last
,
1235 .triggered
= triggered
,
1238 triggered
= NULL
; /* avoid cleanup */
1241 qsort_safe(timer_infos
, c
, sizeof(struct timer_info
),
1242 (__compar_fn_t
) timer_info_compare
);
1244 output_timers_list(timer_infos
, c
);
1247 for (t
= timer_infos
; t
< timer_infos
+ c
; t
++)
1248 strv_free(t
->triggered
);
1253 static int compare_unit_file_list(const void *a
, const void *b
) {
1254 const char *d1
, *d2
;
1255 const UnitFileList
*u
= a
, *v
= b
;
1257 d1
= strrchr(u
->path
, '.');
1258 d2
= strrchr(v
->path
, '.');
1263 r
= strcasecmp(d1
, d2
);
1268 return strcasecmp(basename(u
->path
), basename(v
->path
));
1271 static bool output_show_unit_file(const UnitFileList
*u
, char **patterns
) {
1272 if (!strv_fnmatch_or_empty(patterns
, basename(u
->path
), FNM_NOESCAPE
))
1275 if (!strv_isempty(arg_types
)) {
1278 dot
= strrchr(u
->path
, '.');
1282 if (!strv_find(arg_types
, dot
+1))
1286 if (!strv_isempty(arg_states
) &&
1287 !strv_find(arg_states
, unit_file_state_to_string(u
->state
)))
1293 static void output_unit_file_list(const UnitFileList
*units
, unsigned c
) {
1294 unsigned max_id_len
, id_cols
, state_cols
;
1295 const UnitFileList
*u
;
1297 max_id_len
= strlen("UNIT FILE");
1298 state_cols
= strlen("STATE");
1300 for (u
= units
; u
< units
+ c
; u
++) {
1301 max_id_len
= MAX(max_id_len
, strlen(basename(u
->path
)));
1302 state_cols
= MAX(state_cols
, strlen(unit_file_state_to_string(u
->state
)));
1306 unsigned basic_cols
;
1308 id_cols
= MIN(max_id_len
, 25u);
1309 basic_cols
= 1 + id_cols
+ state_cols
;
1310 if (basic_cols
< (unsigned) columns())
1311 id_cols
+= MIN(columns() - basic_cols
, max_id_len
- id_cols
);
1313 id_cols
= max_id_len
;
1316 printf("%-*s %-*s\n",
1317 id_cols
, "UNIT FILE",
1318 state_cols
, "STATE");
1320 for (u
= units
; u
< units
+ c
; u
++) {
1321 _cleanup_free_
char *e
= NULL
;
1322 const char *on
, *off
;
1325 if (IN_SET(u
->state
,
1327 UNIT_FILE_MASKED_RUNTIME
,
1329 UNIT_FILE_INVALID
)) {
1330 on
= ansi_highlight_red();
1331 off
= ansi_normal();
1332 } else if (u
->state
== UNIT_FILE_ENABLED
) {
1333 on
= ansi_highlight_green();
1334 off
= ansi_normal();
1338 id
= basename(u
->path
);
1340 e
= arg_full
? NULL
: ellipsize(id
, id_cols
, 33);
1342 printf("%-*s %s%-*s%s\n",
1343 id_cols
, e
? e
: id
,
1344 on
, state_cols
, unit_file_state_to_string(u
->state
), off
);
1348 printf("\n%u unit files listed.\n", c
);
1351 static int list_unit_files(int argc
, char *argv
[], void *userdata
) {
1352 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1353 _cleanup_free_ UnitFileList
*units
= NULL
;
1361 pager_open_if_enabled();
1363 if (install_client_side()) {
1369 h
= hashmap_new(&string_hash_ops
);
1373 r
= unit_file_get_list(arg_scope
, arg_root
, h
);
1375 unit_file_list_free(h
);
1376 return log_error_errno(r
, "Failed to get unit file list: %m");
1379 n_units
= hashmap_size(h
);
1381 units
= new(UnitFileList
, n_units
);
1382 if (!units
&& n_units
> 0) {
1383 unit_file_list_free(h
);
1387 HASHMAP_FOREACH(u
, h
, i
) {
1388 if (!output_show_unit_file(u
, strv_skip(argv
, 1)))
1395 assert(c
<= n_units
);
1398 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1401 r
= acquire_bus(BUS_MANAGER
, &bus
);
1405 r
= sd_bus_call_method(
1407 "org.freedesktop.systemd1",
1408 "/org/freedesktop/systemd1",
1409 "org.freedesktop.systemd1.Manager",
1415 return log_error_errno(r
, "Failed to list unit files: %s", bus_error_message(&error
, r
));
1417 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ss)");
1419 return bus_log_parse_error(r
);
1421 while ((r
= sd_bus_message_read(reply
, "(ss)", &path
, &state
)) > 0) {
1423 if (!GREEDY_REALLOC(units
, size
, c
+ 1))
1426 units
[c
] = (struct UnitFileList
) {
1428 unit_file_state_from_string(state
)
1431 if (output_show_unit_file(&units
[c
], strv_skip(argv
, 1)))
1436 return bus_log_parse_error(r
);
1438 r
= sd_bus_message_exit_container(reply
);
1440 return bus_log_parse_error(r
);
1443 qsort_safe(units
, c
, sizeof(UnitFileList
), compare_unit_file_list
);
1444 output_unit_file_list(units
, c
);
1446 if (install_client_side()) {
1447 for (unit
= units
; unit
< units
+ c
; unit
++)
1454 static int list_dependencies_print(const char *name
, int level
, unsigned int branches
, bool last
) {
1455 _cleanup_free_
char *n
= NULL
;
1456 size_t max_len
= MAX(columns(),20u);
1462 for (i
= level
- 1; i
>= 0; i
--) {
1464 if (len
> max_len
- 3 && !arg_full
) {
1465 printf("%s...\n",max_len
% 2 ? "" : " ");
1468 printf("%s", draw_special_char(branches
& (1 << i
) ? DRAW_TREE_VERTICAL
: DRAW_TREE_SPACE
));
1472 if (len
> max_len
- 3 && !arg_full
) {
1473 printf("%s...\n",max_len
% 2 ? "" : " ");
1477 printf("%s", draw_special_char(last
? DRAW_TREE_RIGHT
: DRAW_TREE_BRANCH
));
1481 printf("%s\n", name
);
1485 n
= ellipsize(name
, max_len
-len
, 100);
1493 static int list_dependencies_get_dependencies(sd_bus
*bus
, const char *name
, char ***deps
) {
1495 static const char *dependencies
[_DEPENDENCY_MAX
] = {
1496 [DEPENDENCY_FORWARD
] = "Requires\0"
1497 "RequiresOverridable\0"
1499 "RequisiteOverridable\0"
1503 [DEPENDENCY_REVERSE
] = "RequiredBy\0"
1504 "RequiredByOverridable\0"
1506 "RequisiteOfOverridable\0"
1510 [DEPENDENCY_AFTER
] = "After\0",
1511 [DEPENDENCY_BEFORE
] = "Before\0",
1514 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1515 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1516 _cleanup_strv_free_
char **ret
= NULL
;
1517 _cleanup_free_
char *path
= NULL
;
1523 assert_cc(ELEMENTSOF(dependencies
) == _DEPENDENCY_MAX
);
1525 path
= unit_dbus_path_from_name(name
);
1529 r
= sd_bus_call_method(
1531 "org.freedesktop.systemd1",
1533 "org.freedesktop.DBus.Properties",
1537 "s", "org.freedesktop.systemd1.Unit");
1539 return log_error_errno(r
, "Failed to get properties of %s: %s", name
, bus_error_message(&error
, r
));
1541 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
1543 return bus_log_parse_error(r
);
1545 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
1548 r
= sd_bus_message_read(reply
, "s", &prop
);
1550 return bus_log_parse_error(r
);
1552 if (!nulstr_contains(dependencies
[arg_dependency
], prop
)) {
1553 r
= sd_bus_message_skip(reply
, "v");
1555 return bus_log_parse_error(r
);
1558 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, "as");
1560 return bus_log_parse_error(r
);
1562 r
= bus_message_read_strv_extend(reply
, &ret
);
1564 return bus_log_parse_error(r
);
1566 r
= sd_bus_message_exit_container(reply
);
1568 return bus_log_parse_error(r
);
1571 r
= sd_bus_message_exit_container(reply
);
1573 return bus_log_parse_error(r
);
1577 return bus_log_parse_error(r
);
1579 r
= sd_bus_message_exit_container(reply
);
1581 return bus_log_parse_error(r
);
1589 static int list_dependencies_compare(const void *_a
, const void *_b
) {
1590 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
1592 if (unit_name_to_type(*a
) == UNIT_TARGET
&& unit_name_to_type(*b
) != UNIT_TARGET
)
1594 if (unit_name_to_type(*a
) != UNIT_TARGET
&& unit_name_to_type(*b
) == UNIT_TARGET
)
1597 return strcasecmp(*a
, *b
);
1600 static int list_dependencies_one(
1605 unsigned int branches
) {
1607 _cleanup_strv_free_
char **deps
= NULL
;
1615 r
= strv_extend(units
, name
);
1619 r
= list_dependencies_get_dependencies(bus
, name
, &deps
);
1623 qsort_safe(deps
, strv_length(deps
), sizeof (char*), list_dependencies_compare
);
1625 STRV_FOREACH(c
, deps
) {
1626 if (strv_contains(*units
, *c
)) {
1628 r
= list_dependencies_print("...", level
+ 1, (branches
<< 1) | (c
[1] == NULL
? 0 : 1), 1);
1641 state
= check_one_unit(bus
, *c
, "activating\0active\0reloading\0", true);
1642 on
= state
> 0 ? ansi_highlight_green() : ansi_highlight_red();
1643 printf("%s%s%s ", on
, draw_special_char(DRAW_BLACK_CIRCLE
), ansi_normal());
1646 r
= list_dependencies_print(*c
, level
, branches
, c
[1] == NULL
);
1650 if (arg_all
|| unit_name_to_type(*c
) == UNIT_TARGET
) {
1651 r
= list_dependencies_one(bus
, *c
, level
+ 1, units
, (branches
<< 1) | (c
[1] == NULL
? 0 : 1));
1658 strv_remove(*units
, name
);
1663 static int list_dependencies(int argc
, char *argv
[], void *userdata
) {
1664 _cleanup_strv_free_
char **units
= NULL
;
1665 _cleanup_free_
char *unit
= NULL
;
1671 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &unit
);
1673 return log_error_errno(r
, "Failed to mangle unit name: %m");
1677 u
= SPECIAL_DEFAULT_TARGET
;
1679 pager_open_if_enabled();
1681 r
= acquire_bus(BUS_MANAGER
, &bus
);
1687 return list_dependencies_one(bus
, u
, 0, &units
, 0);
1690 struct machine_info
{
1694 char *control_group
;
1695 uint32_t n_failed_units
;
1700 static const struct bus_properties_map machine_info_property_map
[] = {
1701 { "SystemState", "s", NULL
, offsetof(struct machine_info
, state
) },
1702 { "NJobs", "u", NULL
, offsetof(struct machine_info
, n_jobs
) },
1703 { "NFailedUnits", "u", NULL
, offsetof(struct machine_info
, n_failed_units
) },
1704 { "ControlGroup", "s", NULL
, offsetof(struct machine_info
, control_group
) },
1705 { "UserspaceTimestamp", "t", NULL
, offsetof(struct machine_info
, timestamp
) },
1709 static void machine_info_clear(struct machine_info
*info
) {
1713 free(info
->control_group
);
1718 static void free_machines_list(struct machine_info
*machine_infos
, int n
) {
1724 for (i
= 0; i
< n
; i
++)
1725 machine_info_clear(&machine_infos
[i
]);
1727 free(machine_infos
);
1730 static int compare_machine_info(const void *a
, const void *b
) {
1731 const struct machine_info
*u
= a
, *v
= b
;
1733 if (u
->is_host
!= v
->is_host
)
1734 return u
->is_host
> v
->is_host
? -1 : 1;
1736 return strcasecmp(u
->name
, v
->name
);
1739 static int get_machine_properties(sd_bus
*bus
, struct machine_info
*mi
) {
1740 _cleanup_bus_flush_close_unref_ sd_bus
*container
= NULL
;
1746 r
= sd_bus_open_system_machine(&container
, mi
->name
);
1753 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, mi
);
1760 static bool output_show_machine(const char *name
, char **patterns
) {
1761 return strv_fnmatch_or_empty(patterns
, name
, FNM_NOESCAPE
);
1764 static int get_machine_list(
1766 struct machine_info
**_machine_infos
,
1769 struct machine_info
*machine_infos
= NULL
;
1770 _cleanup_strv_free_
char **m
= NULL
;
1771 _cleanup_free_
char *hn
= NULL
;
1776 hn
= gethostname_malloc();
1780 if (output_show_machine(hn
, patterns
)) {
1781 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1))
1784 machine_infos
[c
].is_host
= true;
1785 machine_infos
[c
].name
= hn
;
1788 get_machine_properties(bus
, &machine_infos
[c
]);
1792 r
= sd_get_machine_names(&m
);
1794 return log_error_errno(r
, "Failed to get machine list: %m");
1796 STRV_FOREACH(i
, m
) {
1797 _cleanup_free_
char *class = NULL
;
1799 if (!output_show_machine(*i
, patterns
))
1802 sd_machine_get_class(*i
, &class);
1803 if (!streq_ptr(class, "container"))
1806 if (!GREEDY_REALLOC0(machine_infos
, sz
, c
+1)) {
1807 free_machines_list(machine_infos
, c
);
1811 machine_infos
[c
].is_host
= false;
1812 machine_infos
[c
].name
= strdup(*i
);
1813 if (!machine_infos
[c
].name
) {
1814 free_machines_list(machine_infos
, c
);
1818 get_machine_properties(NULL
, &machine_infos
[c
]);
1822 *_machine_infos
= machine_infos
;
1826 static void output_machines_list(struct machine_info
*machine_infos
, unsigned n
) {
1827 struct machine_info
*m
;
1830 namelen
= sizeof("NAME") - 1,
1831 statelen
= sizeof("STATE") - 1,
1832 failedlen
= sizeof("FAILED") - 1,
1833 jobslen
= sizeof("JOBS") - 1;
1835 assert(machine_infos
|| n
== 0);
1837 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1838 namelen
= MAX(namelen
, strlen(m
->name
) + (m
->is_host
? sizeof(" (host)") - 1 : 0));
1839 statelen
= MAX(statelen
, m
->state
? strlen(m
->state
) : 0);
1840 failedlen
= MAX(failedlen
, DECIMAL_STR_WIDTH(m
->n_failed_units
));
1841 jobslen
= MAX(jobslen
, DECIMAL_STR_WIDTH(m
->n_jobs
));
1843 if (!arg_plain
&& !streq_ptr(m
->state
, "running"))
1847 if (!arg_no_legend
) {
1851 printf("%-*s %-*s %-*s %-*s\n",
1854 failedlen
, "FAILED",
1858 for (m
= machine_infos
; m
< machine_infos
+ n
; m
++) {
1859 const char *on_state
= "", *off_state
= "";
1860 const char *on_failed
= "", *off_failed
= "";
1861 bool circle
= false;
1863 if (streq_ptr(m
->state
, "degraded")) {
1864 on_state
= ansi_highlight_red();
1865 off_state
= ansi_normal();
1867 } else if (!streq_ptr(m
->state
, "running")) {
1868 on_state
= ansi_highlight_yellow();
1869 off_state
= ansi_normal();
1873 if (m
->n_failed_units
> 0) {
1874 on_failed
= ansi_highlight_red();
1875 off_failed
= ansi_normal();
1877 on_failed
= off_failed
= "";
1880 printf("%s%s%s ", on_state
, circle
? draw_special_char(DRAW_BLACK_CIRCLE
) : " ", off_state
);
1883 printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
1884 (int) (namelen
- (sizeof(" (host)")-1)), strna(m
->name
),
1885 on_state
, statelen
, strna(m
->state
), off_state
,
1886 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1887 jobslen
, m
->n_jobs
);
1889 printf("%-*s %s%-*s%s %s%*u%s %*u\n",
1890 namelen
, strna(m
->name
),
1891 on_state
, statelen
, strna(m
->state
), off_state
,
1892 on_failed
, failedlen
, m
->n_failed_units
, off_failed
,
1893 jobslen
, m
->n_jobs
);
1897 printf("\n%u machines listed.\n", n
);
1900 static int list_machines(int argc
, char *argv
[], void *userdata
) {
1901 struct machine_info
*machine_infos
= NULL
;
1905 if (geteuid() != 0) {
1906 log_error("Must be root.");
1910 pager_open_if_enabled();
1912 r
= acquire_bus(BUS_MANAGER
, &bus
);
1916 r
= get_machine_list(bus
, &machine_infos
, strv_skip(argv
, 1));
1920 qsort_safe(machine_infos
, r
, sizeof(struct machine_info
), compare_machine_info
);
1921 output_machines_list(machine_infos
, r
);
1922 free_machines_list(machine_infos
, r
);
1927 static int get_default(int argc
, char *argv
[], void *userdata
) {
1928 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
1929 _cleanup_free_
char *_path
= NULL
;
1933 if (install_client_side()) {
1934 r
= unit_file_get_default(arg_scope
, arg_root
, &_path
);
1936 return log_error_errno(r
, "Failed to get default target: %m");
1940 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
1943 r
= acquire_bus(BUS_MANAGER
, &bus
);
1947 r
= sd_bus_call_method(
1949 "org.freedesktop.systemd1",
1950 "/org/freedesktop/systemd1",
1951 "org.freedesktop.systemd1.Manager",
1957 return log_error_errno(r
, "Failed to get default target: %s", bus_error_message(&error
, r
));
1959 r
= sd_bus_message_read(reply
, "s", &path
);
1961 return bus_log_parse_error(r
);
1965 printf("%s\n", path
);
1970 static void dump_unit_file_changes(const UnitFileChange
*changes
, unsigned n_changes
) {
1973 assert(changes
|| n_changes
== 0);
1975 for (i
= 0; i
< n_changes
; i
++) {
1976 if (changes
[i
].type
== UNIT_FILE_SYMLINK
)
1977 log_info("Created symlink from %s to %s.", changes
[i
].path
, changes
[i
].source
);
1979 log_info("Removed symlink %s.", changes
[i
].path
);
1983 static int set_default(int argc
, char *argv
[], void *userdata
) {
1984 _cleanup_free_
char *unit
= NULL
;
1990 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &unit
);
1992 return log_error_errno(r
, "Failed to mangle unit name: %m");
1994 if (install_client_side()) {
1995 UnitFileChange
*changes
= NULL
;
1996 unsigned n_changes
= 0;
1998 r
= unit_file_set_default(arg_scope
, arg_root
, unit
, true, &changes
, &n_changes
);
2000 return log_error_errno(r
, "Failed to set default target: %m");
2003 dump_unit_file_changes(changes
, n_changes
);
2005 unit_file_changes_free(changes
, n_changes
);
2008 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2009 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2012 polkit_agent_open_if_enabled();
2014 r
= acquire_bus(BUS_MANAGER
, &bus
);
2018 r
= sd_bus_call_method(
2020 "org.freedesktop.systemd1",
2021 "/org/freedesktop/systemd1",
2022 "org.freedesktop.systemd1.Manager",
2028 return log_error_errno(r
, "Failed to set default target: %s", bus_error_message(&error
, r
));
2030 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
2034 /* Try to reload if enabled */
2036 r
= daemon_reload(argc
, argv
, userdata
);
2046 const char *name
, *type
, *state
;
2049 static void output_jobs_list(const struct job_info
* jobs
, unsigned n
, bool skipped
) {
2050 unsigned id_len
, unit_len
, type_len
, state_len
;
2051 const struct job_info
*j
;
2052 const char *on
, *off
;
2053 bool shorten
= false;
2055 assert(n
== 0 || jobs
);
2058 if (!arg_no_legend
) {
2059 on
= ansi_highlight_green();
2060 off
= ansi_normal();
2062 printf("%sNo jobs %s.%s\n", on
, skipped
? "listed" : "running", off
);
2067 pager_open_if_enabled();
2069 id_len
= strlen("JOB");
2070 unit_len
= strlen("UNIT");
2071 type_len
= strlen("TYPE");
2072 state_len
= strlen("STATE");
2074 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2075 uint32_t id
= j
->id
;
2076 assert(j
->name
&& j
->type
&& j
->state
);
2078 id_len
= MAX(id_len
, DECIMAL_STR_WIDTH(id
));
2079 unit_len
= MAX(unit_len
, strlen(j
->name
));
2080 type_len
= MAX(type_len
, strlen(j
->type
));
2081 state_len
= MAX(state_len
, strlen(j
->state
));
2084 if (!arg_full
&& id_len
+ 1 + unit_len
+ type_len
+ 1 + state_len
> columns()) {
2085 unit_len
= MAX(33u, columns() - id_len
- type_len
- state_len
- 3);
2090 printf("%*s %-*s %-*s %-*s\n",
2094 state_len
, "STATE");
2096 for (j
= jobs
; j
< jobs
+ n
; j
++) {
2097 _cleanup_free_
char *e
= NULL
;
2099 if (streq(j
->state
, "running")) {
2100 on
= ansi_highlight();
2101 off
= ansi_normal();
2105 e
= shorten
? ellipsize(j
->name
, unit_len
, 33) : NULL
;
2106 printf("%*u %s%-*s%s %-*s %s%-*s%s\n",
2108 on
, unit_len
, e
? e
: j
->name
, off
,
2110 on
, state_len
, j
->state
, off
);
2113 if (!arg_no_legend
) {
2114 on
= ansi_highlight();
2115 off
= ansi_normal();
2117 printf("\n%s%u jobs listed%s.\n", on
, n
, off
);
2121 static bool output_show_job(struct job_info
*job
, char **patterns
) {
2122 return strv_fnmatch_or_empty(patterns
, job
->name
, FNM_NOESCAPE
);
2125 static int list_jobs(int argc
, char *argv
[], void *userdata
) {
2126 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2127 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2128 const char *name
, *type
, *state
, *job_path
, *unit_path
;
2129 _cleanup_free_
struct job_info
*jobs
= NULL
;
2135 bool skipped
= false;
2137 pager_open_if_enabled();
2139 r
= acquire_bus(BUS_MANAGER
, &bus
);
2143 r
= sd_bus_call_method(
2145 "org.freedesktop.systemd1",
2146 "/org/freedesktop/systemd1",
2147 "org.freedesktop.systemd1.Manager",
2153 return log_error_errno(r
, "Failed to list jobs: %s", bus_error_message(&error
, r
));
2155 r
= sd_bus_message_enter_container(reply
, 'a', "(usssoo)");
2157 return bus_log_parse_error(r
);
2159 while ((r
= sd_bus_message_read(reply
, "(usssoo)", &id
, &name
, &type
, &state
, &job_path
, &unit_path
)) > 0) {
2160 struct job_info job
= { id
, name
, type
, state
};
2162 if (!output_show_job(&job
, strv_skip(argv
, 1))) {
2167 if (!GREEDY_REALLOC(jobs
, size
, c
+ 1))
2173 return bus_log_parse_error(r
);
2175 r
= sd_bus_message_exit_container(reply
);
2177 return bus_log_parse_error(r
);
2179 output_jobs_list(jobs
, c
, skipped
);
2183 static int cancel_job(int argc
, char *argv
[], void *userdata
) {
2189 return daemon_reload(argc
, argv
, userdata
);
2191 polkit_agent_open_if_enabled();
2193 r
= acquire_bus(BUS_MANAGER
, &bus
);
2197 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
2198 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2202 q
= safe_atou32(*name
, &id
);
2204 return log_error_errno(q
, "Failed to parse job id \"%s\": %m", *name
);
2206 q
= sd_bus_call_method(
2208 "org.freedesktop.systemd1",
2209 "/org/freedesktop/systemd1",
2210 "org.freedesktop.systemd1.Manager",
2216 log_error_errno(q
, "Failed to cancel job %"PRIu32
": %s", id
, bus_error_message(&error
, q
));
2225 static int need_daemon_reload(sd_bus
*bus
, const char *unit
) {
2226 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2230 /* We ignore all errors here, since this is used to show a
2233 /* We don't use unit_dbus_path_from_name() directly since we
2234 * don't want to load the unit if it isn't loaded. */
2236 r
= sd_bus_call_method(
2238 "org.freedesktop.systemd1",
2239 "/org/freedesktop/systemd1",
2240 "org.freedesktop.systemd1.Manager",
2248 r
= sd_bus_message_read(reply
, "o", &path
);
2252 r
= sd_bus_get_property_trivial(
2254 "org.freedesktop.systemd1",
2256 "org.freedesktop.systemd1.Unit",
2266 static void warn_unit_file_changed(const char *name
) {
2267 log_warning("%sWarning:%s %s changed on disk. Run 'systemctl%s daemon-reload' to reload units.",
2268 ansi_highlight_red(),
2271 arg_scope
== UNIT_FILE_SYSTEM
? "" : " --user");
2274 static int unit_file_find_path(LookupPaths
*lp
, const char *unit_name
, char **unit_path
) {
2281 STRV_FOREACH(p
, lp
->unit_path
) {
2282 _cleanup_free_
char *path
;
2284 path
= path_join(arg_root
, *p
, unit_name
);
2288 if (access(path
, F_OK
) == 0) {
2298 static int unit_find_paths(
2300 const char *unit_name
,
2302 char **fragment_path
,
2303 char ***dropin_paths
) {
2305 _cleanup_free_
char *path
= NULL
;
2306 _cleanup_strv_free_
char **dropins
= NULL
;
2310 * Finds where the unit is defined on disk. Returns 0 if the unit
2311 * is not found. Returns 1 if it is found, and sets
2312 * - the path to the unit in *path, if it exists on disk,
2313 * - and a strv of existing drop-ins in *dropins,
2314 * if the arg is not NULL and any dropins were found.
2318 assert(fragment_path
);
2321 if (!install_client_side() && !unit_name_is_valid(unit_name
, UNIT_NAME_TEMPLATE
)) {
2322 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2323 _cleanup_bus_message_unref_ sd_bus_message
*unit_load_error
= NULL
;
2324 _cleanup_free_
char *unit
= NULL
;
2325 char *unit_load_error_name
, *unit_load_error_message
;
2327 unit
= unit_dbus_path_from_name(unit_name
);
2331 if (need_daemon_reload(bus
, unit_name
) > 0)
2332 warn_unit_file_changed(unit_name
);
2334 r
= sd_bus_get_property(
2336 "org.freedesktop.systemd1",
2338 "org.freedesktop.systemd1.Unit",
2344 return log_error_errno(r
, "Failed to get LoadError: %s", bus_error_message(&error
, r
));
2346 r
= sd_bus_message_read(
2349 &unit_load_error_name
,
2350 &unit_load_error_message
);
2352 return bus_log_parse_error(r
);
2354 if (!isempty(unit_load_error_name
)) {
2355 log_error("Unit %s is not loaded: %s", unit_name
, unit_load_error_message
);
2359 r
= sd_bus_get_property_string(
2361 "org.freedesktop.systemd1",
2363 "org.freedesktop.systemd1.Unit",
2368 return log_error_errno(r
, "Failed to get FragmentPath: %s", bus_error_message(&error
, r
));
2371 r
= sd_bus_get_property_strv(
2373 "org.freedesktop.systemd1",
2375 "org.freedesktop.systemd1.Unit",
2380 return log_error_errno(r
, "Failed to get DropInPaths: %s", bus_error_message(&error
, r
));
2383 _cleanup_set_free_ Set
*names
;
2385 names
= set_new(NULL
);
2389 r
= set_put(names
, unit_name
);
2391 return log_error_errno(r
, "Failed to add unit name: %m");
2393 r
= unit_file_find_path(lp
, unit_name
, &path
);
2398 _cleanup_free_
char *template = NULL
;
2400 r
= unit_name_template(unit_name
, &template);
2401 if (r
< 0 && r
!= -EINVAL
)
2402 return log_error_errno(r
, "Failed to determine template name: %m");
2404 r
= unit_file_find_path(lp
, template, &path
);
2411 r
= unit_file_find_dropin_paths(lp
->unit_path
, NULL
, names
, &dropins
);
2419 if (!isempty(path
)) {
2420 *fragment_path
= path
;
2425 if (dropin_paths
&& !strv_isempty(dropins
)) {
2426 *dropin_paths
= dropins
;
2432 log_error("No files found for %s.", unit_name
);
2437 static int check_one_unit(sd_bus
*bus
, const char *name
, const char *good_states
, bool quiet
) {
2438 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2439 _cleanup_free_
char *n
= NULL
, *state
= NULL
;
2445 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2447 return log_error_errno(r
, "Failed to mangle unit name: %m");
2449 /* We don't use unit_dbus_path_from_name() directly since we
2450 * don't want to load the unit if it isn't loaded. */
2452 r
= sd_bus_call_method(
2454 "org.freedesktop.systemd1",
2455 "/org/freedesktop/systemd1",
2456 "org.freedesktop.systemd1.Manager",
2467 r
= sd_bus_message_read(reply
, "o", &path
);
2469 return bus_log_parse_error(r
);
2471 r
= sd_bus_get_property_string(
2473 "org.freedesktop.systemd1",
2475 "org.freedesktop.systemd1.Unit",
2488 return nulstr_contains(good_states
, state
);
2491 static int check_triggering_units(
2495 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2496 _cleanup_free_
char *path
= NULL
, *n
= NULL
, *state
= NULL
;
2497 _cleanup_strv_free_
char **triggered_by
= NULL
;
2498 bool print_warning_label
= true;
2502 r
= unit_name_mangle(name
, UNIT_NAME_NOGLOB
, &n
);
2504 return log_error_errno(r
, "Failed to mangle unit name: %m");
2506 path
= unit_dbus_path_from_name(n
);
2510 r
= sd_bus_get_property_string(
2512 "org.freedesktop.systemd1",
2514 "org.freedesktop.systemd1.Unit",
2519 return log_error_errno(r
, "Failed to get load state of %s: %s", n
, bus_error_message(&error
, r
));
2521 if (streq(state
, "masked"))
2524 r
= sd_bus_get_property_strv(
2526 "org.freedesktop.systemd1",
2528 "org.freedesktop.systemd1.Unit",
2533 return log_error_errno(r
, "Failed to get triggered by array of %s: %s", n
, bus_error_message(&error
, r
));
2535 STRV_FOREACH(i
, triggered_by
) {
2536 r
= check_one_unit(bus
, *i
, "active\0reloading\0", true);
2538 return log_error_errno(r
, "Failed to check unit: %m");
2543 if (print_warning_label
) {
2544 log_warning("Warning: Stopping %s, but it can still be activated by:", n
);
2545 print_warning_label
= false;
2548 log_warning(" %s", *i
);
2554 static const struct {
2557 } unit_actions
[] = {
2558 { "start", "StartUnit" },
2559 { "stop", "StopUnit" },
2560 { "condstop", "StopUnit" },
2561 { "reload", "ReloadUnit" },
2562 { "restart", "RestartUnit" },
2563 { "try-restart", "TryRestartUnit" },
2564 { "condrestart", "TryRestartUnit" },
2565 { "reload-or-restart", "ReloadOrRestartUnit" },
2566 { "reload-or-try-restart", "ReloadOrTryRestartUnit" },
2567 { "condreload", "ReloadOrTryRestartUnit" },
2568 { "force-reload", "ReloadOrTryRestartUnit" }
2571 static const char *verb_to_method(const char *verb
) {
2574 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2575 if (streq_ptr(unit_actions
[i
].verb
, verb
))
2576 return unit_actions
[i
].method
;
2581 static const char *method_to_verb(const char *method
) {
2584 for (i
= 0; i
< ELEMENTSOF(unit_actions
); i
++)
2585 if (streq_ptr(unit_actions
[i
].method
, method
))
2586 return unit_actions
[i
].verb
;
2591 static int start_unit_one(
2596 sd_bus_error
*error
,
2597 BusWaitForJobs
*w
) {
2599 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2608 log_debug("Calling manager for %s on %s, %s", method
, name
, mode
);
2610 r
= sd_bus_call_method(
2612 "org.freedesktop.systemd1",
2613 "/org/freedesktop/systemd1",
2614 "org.freedesktop.systemd1.Manager",
2622 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
2623 /* There's always a fallback possible for
2624 * legacy actions. */
2625 return -EADDRNOTAVAIL
;
2627 verb
= method_to_verb(method
);
2629 return log_error_errno(r
, "Failed to %s %s: %s", verb
, name
, bus_error_message(error
, r
));
2632 r
= sd_bus_message_read(reply
, "o", &path
);
2634 return bus_log_parse_error(r
);
2636 if (need_daemon_reload(bus
, name
) > 0)
2637 warn_unit_file_changed(name
);
2640 log_debug("Adding %s to the set", path
);
2641 r
= bus_wait_for_jobs_add(w
, path
);
2649 static int expand_names(sd_bus
*bus
, char **names
, const char* suffix
, char ***ret
) {
2650 _cleanup_strv_free_
char **mangled
= NULL
, **globs
= NULL
;
2657 STRV_FOREACH(name
, names
) {
2661 r
= unit_name_mangle_with_suffix(*name
, UNIT_NAME_GLOB
, suffix
, &t
);
2663 r
= unit_name_mangle(*name
, UNIT_NAME_GLOB
, &t
);
2665 return log_error_errno(r
, "Failed to mangle name: %m");
2667 if (string_is_glob(t
))
2668 r
= strv_consume(&globs
, t
);
2670 r
= strv_consume(&mangled
, t
);
2675 /* Query the manager only if any of the names are a glob, since
2676 * this is fairly expensive */
2677 if (!strv_isempty(globs
)) {
2678 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2679 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
2681 r
= get_unit_list(bus
, NULL
, globs
, &unit_infos
, 0, &reply
);
2685 for (i
= 0; i
< r
; i
++)
2686 if (strv_extend(&mangled
, unit_infos
[i
].id
) < 0)
2691 mangled
= NULL
; /* do not free */
2696 static const struct {
2700 } action_table
[_ACTION_MAX
] = {
2701 [ACTION_HALT
] = { SPECIAL_HALT_TARGET
, "halt", "replace-irreversibly" },
2702 [ACTION_POWEROFF
] = { SPECIAL_POWEROFF_TARGET
, "poweroff", "replace-irreversibly" },
2703 [ACTION_REBOOT
] = { SPECIAL_REBOOT_TARGET
, "reboot", "replace-irreversibly" },
2704 [ACTION_KEXEC
] = { SPECIAL_KEXEC_TARGET
, "kexec", "replace-irreversibly" },
2705 [ACTION_RUNLEVEL2
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2706 [ACTION_RUNLEVEL3
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2707 [ACTION_RUNLEVEL4
] = { SPECIAL_MULTI_USER_TARGET
, NULL
, "isolate" },
2708 [ACTION_RUNLEVEL5
] = { SPECIAL_GRAPHICAL_TARGET
, NULL
, "isolate" },
2709 [ACTION_RESCUE
] = { SPECIAL_RESCUE_TARGET
, "rescue", "isolate" },
2710 [ACTION_EMERGENCY
] = { SPECIAL_EMERGENCY_TARGET
, "emergency", "isolate" },
2711 [ACTION_DEFAULT
] = { SPECIAL_DEFAULT_TARGET
, "default", "isolate" },
2712 [ACTION_EXIT
] = { SPECIAL_EXIT_TARGET
, "exit", "replace-irreversibly" },
2713 [ACTION_SUSPEND
] = { SPECIAL_SUSPEND_TARGET
, "suspend", "replace-irreversibly" },
2714 [ACTION_HIBERNATE
] = { SPECIAL_HIBERNATE_TARGET
, "hibernate", "replace-irreversibly" },
2715 [ACTION_HYBRID_SLEEP
] = { SPECIAL_HYBRID_SLEEP_TARGET
, "hybrid-sleep", "replace-irreversibly" },
2718 static enum action
verb_to_action(const char *verb
) {
2721 for (i
= _ACTION_INVALID
; i
< _ACTION_MAX
; i
++)
2722 if (streq_ptr(action_table
[i
].verb
, verb
))
2725 return _ACTION_INVALID
;
2728 static int start_unit(int argc
, char *argv
[], void *userdata
) {
2729 _cleanup_(bus_wait_for_jobs_freep
) BusWaitForJobs
*w
= NULL
;
2730 const char *method
, *mode
, *one_name
, *suffix
= NULL
;
2731 _cleanup_strv_free_
char **names
= NULL
;
2736 ask_password_agent_open_if_enabled();
2737 polkit_agent_open_if_enabled();
2739 r
= acquire_bus(BUS_MANAGER
, &bus
);
2743 if (arg_action
== ACTION_SYSTEMCTL
) {
2746 method
= verb_to_method(argv
[0]);
2747 action
= verb_to_action(argv
[0]);
2749 if (streq(argv
[0], "isolate")) {
2753 mode
= action_table
[action
].mode
?: arg_job_mode
;
2755 one_name
= action_table
[action
].target
;
2757 assert(arg_action
< ELEMENTSOF(action_table
));
2758 assert(action_table
[arg_action
].target
);
2760 method
= "StartUnit";
2762 mode
= action_table
[arg_action
].mode
;
2763 one_name
= action_table
[arg_action
].target
;
2767 names
= strv_new(one_name
, NULL
);
2769 r
= expand_names(bus
, strv_skip(argv
, 1), suffix
, &names
);
2771 return log_error_errno(r
, "Failed to expand names: %m");
2774 if (!arg_no_block
) {
2775 r
= bus_wait_for_jobs_new(bus
, &w
);
2777 return log_error_errno(r
, "Could not watch jobs: %m");
2780 STRV_FOREACH(name
, names
) {
2781 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2784 q
= start_unit_one(bus
, method
, *name
, mode
, &error
, w
);
2785 if (r
>= 0 && q
< 0)
2786 r
= translate_bus_error_to_exit_status(q
, &error
);
2789 if (!arg_no_block
) {
2792 q
= bus_wait_for_jobs(w
, arg_quiet
);
2796 /* When stopping units, warn if they can still be triggered by
2797 * another active unit (socket, path, timer) */
2798 if (!arg_quiet
&& streq(method
, "StopUnit"))
2799 STRV_FOREACH(name
, names
)
2800 check_triggering_units(bus
, *name
);
2806 static int logind_set_wall_message(void) {
2808 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2810 _cleanup_free_
char *m
= NULL
;
2813 r
= acquire_bus(BUS_FULL
, &bus
);
2817 m
= strv_join(arg_wall
, " ");
2821 r
= sd_bus_call_method(
2823 "org.freedesktop.login1",
2824 "/org/freedesktop/login1",
2825 "org.freedesktop.login1.Manager",
2834 return log_warning_errno(r
, "Failed to set wall message, ignoring: %s", bus_error_message(&error
, r
));
2840 /* Ask systemd-logind, which might grant access to unprivileged users
2841 * through PolicyKit */
2842 static int logind_reboot(enum action a
) {
2844 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
2845 const char *method
, *description
;
2849 polkit_agent_open_if_enabled();
2850 (void) logind_set_wall_message();
2852 r
= acquire_bus(BUS_FULL
, &bus
);
2860 description
= "reboot system";
2863 case ACTION_POWEROFF
:
2864 method
= "PowerOff";
2865 description
= "power off system";
2868 case ACTION_SUSPEND
:
2870 description
= "suspend system";
2873 case ACTION_HIBERNATE
:
2874 method
= "Hibernate";
2875 description
= "hibernate system";
2878 case ACTION_HYBRID_SLEEP
:
2879 method
= "HybridSleep";
2880 description
= "put system into hybrid sleep";
2887 r
= sd_bus_call_method(
2889 "org.freedesktop.login1",
2890 "/org/freedesktop/login1",
2891 "org.freedesktop.login1.Manager",
2895 "b", arg_ask_password
);
2897 return log_error_errno(r
, "Failed to %s via logind: %s", description
, bus_error_message(&error
, r
));
2905 static int logind_check_inhibitors(enum action a
) {
2907 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
2908 _cleanup_strv_free_
char **sessions
= NULL
;
2909 const char *what
, *who
, *why
, *mode
;
2916 if (arg_ignore_inhibitors
|| arg_force
> 0)
2928 r
= acquire_bus(BUS_FULL
, &bus
);
2932 r
= sd_bus_call_method(
2934 "org.freedesktop.login1",
2935 "/org/freedesktop/login1",
2936 "org.freedesktop.login1.Manager",
2942 /* If logind is not around, then there are no inhibitors... */
2945 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "(ssssuu)");
2947 return bus_log_parse_error(r
);
2949 while ((r
= sd_bus_message_read(reply
, "(ssssuu)", &what
, &who
, &why
, &mode
, &uid
, &pid
)) > 0) {
2950 _cleanup_free_
char *comm
= NULL
, *user
= NULL
;
2951 _cleanup_strv_free_
char **sv
= NULL
;
2953 if (!streq(mode
, "block"))
2956 sv
= strv_split(what
, ":");
2960 if ((pid_t
) pid
< 0)
2961 return log_error_errno(ERANGE
, "Bad PID %"PRIu32
": %m", pid
);
2963 if (!strv_contains(sv
,
2968 ACTION_KEXEC
) ? "shutdown" : "sleep"))
2971 get_process_comm(pid
, &comm
);
2972 user
= uid_to_name(uid
);
2974 log_warning("Operation inhibited by \"%s\" (PID "PID_FMT
" \"%s\", user %s), reason is \"%s\".",
2975 who
, (pid_t
) pid
, strna(comm
), strna(user
), why
);
2980 return bus_log_parse_error(r
);
2982 r
= sd_bus_message_exit_container(reply
);
2984 return bus_log_parse_error(r
);
2986 /* Check for current sessions */
2987 sd_get_sessions(&sessions
);
2988 STRV_FOREACH(s
, sessions
) {
2989 _cleanup_free_
char *type
= NULL
, *tty
= NULL
, *seat
= NULL
, *user
= NULL
, *service
= NULL
, *class = NULL
;
2991 if (sd_session_get_uid(*s
, &uid
) < 0 || uid
== getuid())
2994 if (sd_session_get_class(*s
, &class) < 0 || !streq(class, "user"))
2997 if (sd_session_get_type(*s
, &type
) < 0 || (!streq(type
, "x11") && !streq(type
, "tty")))
3000 sd_session_get_tty(*s
, &tty
);
3001 sd_session_get_seat(*s
, &seat
);
3002 sd_session_get_service(*s
, &service
);
3003 user
= uid_to_name(uid
);
3005 log_warning("User %s is logged in on %s.", strna(user
), isempty(tty
) ? (isempty(seat
) ? strna(service
) : seat
) : tty
);
3012 log_error("Please retry operation after closing inhibitors and logging out other users.\nAlternatively, ignore inhibitors and users with 'systemctl %s -i'.",
3013 action_table
[a
].verb
);
3021 static int logind_prepare_firmware_setup(void) {
3023 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3027 r
= acquire_bus(BUS_FULL
, &bus
);
3031 r
= sd_bus_call_method(
3033 "org.freedesktop.login1",
3034 "/org/freedesktop/login1",
3035 "org.freedesktop.login1.Manager",
3036 "SetRebootToFirmwareSetup",
3041 return log_error_errno(r
, "Cannot indicate to EFI to boot into setup mode: %s", bus_error_message(&error
, r
));
3045 log_error("Cannot remotely indicate to EFI to boot into setup mode.");
3050 static int prepare_firmware_setup(void) {
3053 if (!arg_firmware_setup
)
3056 if (arg_transport
== BUS_TRANSPORT_LOCAL
) {
3058 r
= efi_set_reboot_to_firmware(true);
3060 log_debug_errno(r
, "Cannot indicate to EFI to boot into setup mode, will retry via logind: %m");
3065 return logind_prepare_firmware_setup();
3068 static int set_exit_code(uint8_t code
) {
3069 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3073 r
= acquire_bus(BUS_MANAGER
, &bus
);
3077 r
= sd_bus_call_method(
3079 "org.freedesktop.systemd1",
3080 "/org/freedesktop/systemd1",
3081 "org.freedesktop.systemd1.Manager",
3087 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
3092 static int start_special(int argc
, char *argv
[], void *userdata
) {
3098 a
= verb_to_action(argv
[0]);
3100 r
= logind_check_inhibitors(a
);
3104 if (arg_force
>= 2 && geteuid() != 0) {
3105 log_error("Must be root.");
3109 r
= prepare_firmware_setup();
3113 if (a
== ACTION_REBOOT
&& argc
> 1) {
3114 r
= update_reboot_param_file(argv
[1]);
3118 } else if (a
== ACTION_EXIT
&& argc
> 1) {
3121 /* If the exit code is not given on the command line,
3122 * don't reset it to zero: just keep it as it might
3123 * have been set previously. */
3125 r
= safe_atou8(argv
[1], &code
);
3127 return log_error_errno(r
, "Invalid exit code.");
3129 r
= set_exit_code(code
);
3134 if (arg_force
>= 2 &&
3141 if (arg_force
>= 1 &&
3148 return daemon_reload(argc
, argv
, userdata
);
3150 /* First try logind, to allow authentication with polkit */
3156 ACTION_HYBRID_SLEEP
)) {
3157 r
= logind_reboot(a
);
3160 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
3161 /* requested operation is not supported or already in progress */
3164 /* On all other errors, try low-level operation */
3167 return start_unit(argc
, argv
, userdata
);
3170 static int check_unit_generic(int code
, const char *good_states
, char **args
) {
3171 _cleanup_strv_free_
char **names
= NULL
;
3176 r
= acquire_bus(BUS_MANAGER
, &bus
);
3180 r
= expand_names(bus
, args
, NULL
, &names
);
3182 return log_error_errno(r
, "Failed to expand names: %m");
3184 STRV_FOREACH(name
, names
) {
3187 state
= check_one_unit(bus
, *name
, good_states
, arg_quiet
);
3197 static int check_unit_active(int argc
, char *argv
[], void *userdata
) {
3198 /* According to LSB: 3, "program is not running" */
3199 return check_unit_generic(3, "active\0reloading\0", strv_skip(argv
, 1));
3202 static int check_unit_failed(int argc
, char *argv
[], void *userdata
) {
3203 return check_unit_generic(1, "failed\0", strv_skip(argv
, 1));
3206 static int kill_unit(int argc
, char *argv
[], void *userdata
) {
3207 _cleanup_strv_free_
char **names
= NULL
;
3208 char *kill_who
= NULL
, **name
;
3212 polkit_agent_open_if_enabled();
3214 r
= acquire_bus(BUS_MANAGER
, &bus
);
3219 arg_kill_who
= "all";
3221 /* --fail was specified */
3222 if (streq(arg_job_mode
, "fail"))
3223 kill_who
= strjoina(arg_kill_who
, "-fail", NULL
);
3225 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
3227 return log_error_errno(r
, "Failed to expand names: %m");
3229 STRV_FOREACH(name
, names
) {
3230 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
3232 q
= sd_bus_call_method(
3234 "org.freedesktop.systemd1",
3235 "/org/freedesktop/systemd1",
3236 "org.freedesktop.systemd1.Manager",
3240 "ssi", *names
, kill_who
? kill_who
: arg_kill_who
, arg_signal
);
3242 log_error_errno(q
, "Failed to kill unit %s: %s", *names
, bus_error_message(&error
, q
));
3251 typedef struct ExecStatusInfo
{
3259 usec_t start_timestamp
;
3260 usec_t exit_timestamp
;
3265 LIST_FIELDS(struct ExecStatusInfo
, exec
);
3268 static void exec_status_info_free(ExecStatusInfo
*i
) {
3277 static int exec_status_info_deserialize(sd_bus_message
*m
, ExecStatusInfo
*i
) {
3278 uint64_t start_timestamp
, exit_timestamp
, start_timestamp_monotonic
, exit_timestamp_monotonic
;
3281 int32_t code
, status
;
3287 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_STRUCT
, "sasbttttuii");
3289 return bus_log_parse_error(r
);
3293 r
= sd_bus_message_read(m
, "s", &path
);
3295 return bus_log_parse_error(r
);
3297 i
->path
= strdup(path
);
3301 r
= sd_bus_message_read_strv(m
, &i
->argv
);
3303 return bus_log_parse_error(r
);
3305 r
= sd_bus_message_read(m
,
3308 &start_timestamp
, &start_timestamp_monotonic
,
3309 &exit_timestamp
, &exit_timestamp_monotonic
,
3313 return bus_log_parse_error(r
);
3316 i
->start_timestamp
= (usec_t
) start_timestamp
;
3317 i
->exit_timestamp
= (usec_t
) exit_timestamp
;
3318 i
->pid
= (pid_t
) pid
;
3322 r
= sd_bus_message_exit_container(m
);
3324 return bus_log_parse_error(r
);
3329 typedef struct UnitStatusInfo
{
3331 const char *load_state
;
3332 const char *active_state
;
3333 const char *sub_state
;
3334 const char *unit_file_state
;
3335 const char *unit_file_preset
;
3337 const char *description
;
3338 const char *following
;
3340 char **documentation
;
3342 const char *fragment_path
;
3343 const char *source_path
;
3344 const char *control_group
;
3346 char **dropin_paths
;
3348 const char *load_error
;
3351 usec_t inactive_exit_timestamp
;
3352 usec_t inactive_exit_timestamp_monotonic
;
3353 usec_t active_enter_timestamp
;
3354 usec_t active_exit_timestamp
;
3355 usec_t inactive_enter_timestamp
;
3357 bool need_daemon_reload
;
3362 const char *status_text
;
3363 const char *pid_file
;
3367 usec_t start_timestamp
;
3368 usec_t exit_timestamp
;
3370 int exit_code
, exit_status
;
3372 usec_t condition_timestamp
;
3373 bool condition_result
;
3374 bool failed_condition_trigger
;
3375 bool failed_condition_negate
;
3376 const char *failed_condition
;
3377 const char *failed_condition_parameter
;
3379 usec_t assert_timestamp
;
3381 bool failed_assert_trigger
;
3382 bool failed_assert_negate
;
3383 const char *failed_assert
;
3384 const char *failed_assert_parameter
;
3387 unsigned n_accepted
;
3388 unsigned n_connections
;
3391 /* Pairs of type, path */
3395 const char *sysfs_path
;
3397 /* Mount, Automount */
3404 uint64_t memory_current
;
3405 uint64_t memory_limit
;
3406 uint64_t cpu_usage_nsec
;
3407 uint64_t tasks_current
;
3410 LIST_HEAD(ExecStatusInfo
, exec
);
3413 static void print_status_info(
3418 const char *active_on
, *active_off
, *on
, *off
, *ss
;
3420 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], *s1
;
3421 char since2
[FORMAT_TIMESTAMP_MAX
], *s2
;
3427 /* This shows pretty information about a unit. See
3428 * print_property() for a low-level property printer */
3430 if (streq_ptr(i
->active_state
, "failed")) {
3431 active_on
= ansi_highlight_red();
3432 active_off
= ansi_normal();
3433 } else if (streq_ptr(i
->active_state
, "active") || streq_ptr(i
->active_state
, "reloading")) {
3434 active_on
= ansi_highlight_green();
3435 active_off
= ansi_normal();
3437 active_on
= active_off
= "";
3439 printf("%s%s%s %s", active_on
, draw_special_char(DRAW_BLACK_CIRCLE
), active_off
, strna(i
->id
));
3441 if (i
->description
&& !streq_ptr(i
->id
, i
->description
))
3442 printf(" - %s", i
->description
);
3447 printf(" Follow: unit currently follows state of %s\n", i
->following
);
3449 if (streq_ptr(i
->load_state
, "error")) {
3450 on
= ansi_highlight_red();
3451 off
= ansi_normal();
3455 path
= i
->source_path
? i
->source_path
: i
->fragment_path
;
3458 printf(" Loaded: %s%s%s (Reason: %s)\n",
3459 on
, strna(i
->load_state
), off
, i
->load_error
);
3460 else if (path
&& !isempty(i
->unit_file_state
) && !isempty(i
->unit_file_preset
))
3461 printf(" Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
3462 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
, i
->unit_file_preset
);
3463 else if (path
&& !isempty(i
->unit_file_state
))
3464 printf(" Loaded: %s%s%s (%s; %s)\n",
3465 on
, strna(i
->load_state
), off
, path
, i
->unit_file_state
);
3467 printf(" Loaded: %s%s%s (%s)\n",
3468 on
, strna(i
->load_state
), off
, path
);
3470 printf(" Loaded: %s%s%s\n",
3471 on
, strna(i
->load_state
), off
);
3473 if (!strv_isempty(i
->dropin_paths
)) {
3474 _cleanup_free_
char *dir
= NULL
;
3478 STRV_FOREACH(dropin
, i
->dropin_paths
) {
3479 if (! dir
|| last
) {
3480 printf(dir
? " " : " Drop-In: ");
3484 dir
= dirname_malloc(*dropin
);
3490 printf("%s\n %s", dir
,
3491 draw_special_char(DRAW_TREE_RIGHT
));
3494 last
= ! (*(dropin
+ 1) && startswith(*(dropin
+ 1), dir
));
3496 printf("%s%s", basename(*dropin
), last
? "\n" : ", ");
3500 ss
= streq_ptr(i
->active_state
, i
->sub_state
) ? NULL
: i
->sub_state
;
3502 printf(" Active: %s%s (%s)%s",
3503 active_on
, strna(i
->active_state
), ss
, active_off
);
3505 printf(" Active: %s%s%s",
3506 active_on
, strna(i
->active_state
), active_off
);
3508 if (!isempty(i
->result
) && !streq(i
->result
, "success"))
3509 printf(" (Result: %s)", i
->result
);
3511 timestamp
= (streq_ptr(i
->active_state
, "active") ||
3512 streq_ptr(i
->active_state
, "reloading")) ? i
->active_enter_timestamp
:
3513 (streq_ptr(i
->active_state
, "inactive") ||
3514 streq_ptr(i
->active_state
, "failed")) ? i
->inactive_enter_timestamp
:
3515 streq_ptr(i
->active_state
, "activating") ? i
->inactive_exit_timestamp
:
3516 i
->active_exit_timestamp
;
3518 s1
= format_timestamp_relative(since1
, sizeof(since1
), timestamp
);
3519 s2
= format_timestamp(since2
, sizeof(since2
), timestamp
);
3522 printf(" since %s; %s\n", s2
, s1
);
3524 printf(" since %s\n", s2
);
3528 if (!i
->condition_result
&& i
->condition_timestamp
> 0) {
3529 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->condition_timestamp
);
3530 s2
= format_timestamp(since2
, sizeof(since2
), i
->condition_timestamp
);
3532 printf("Condition: start %scondition failed%s at %s%s%s\n",
3533 ansi_highlight_yellow(), ansi_normal(),
3534 s2
, s1
? "; " : "", strempty(s1
));
3535 if (i
->failed_condition_trigger
)
3536 printf(" none of the trigger conditions were met\n");
3537 else if (i
->failed_condition
)
3538 printf(" %s=%s%s was not met\n",
3539 i
->failed_condition
,
3540 i
->failed_condition_negate
? "!" : "",
3541 i
->failed_condition_parameter
);
3544 if (!i
->assert_result
&& i
->assert_timestamp
> 0) {
3545 s1
= format_timestamp_relative(since1
, sizeof(since1
), i
->assert_timestamp
);
3546 s2
= format_timestamp(since2
, sizeof(since2
), i
->assert_timestamp
);
3548 printf(" Assert: start %sassertion failed%s at %s%s%s\n",
3549 ansi_highlight_red(), ansi_normal(),
3550 s2
, s1
? "; " : "", strempty(s1
));
3551 if (i
->failed_assert_trigger
)
3552 printf(" none of the trigger assertions were met\n");
3553 else if (i
->failed_assert
)
3554 printf(" %s=%s%s was not met\n",
3556 i
->failed_assert_negate
? "!" : "",
3557 i
->failed_assert_parameter
);
3561 printf(" Device: %s\n", i
->sysfs_path
);
3563 printf(" Where: %s\n", i
->where
);
3565 printf(" What: %s\n", i
->what
);
3567 STRV_FOREACH(t
, i
->documentation
)
3568 printf(" %*s %s\n", 9, t
== i
->documentation
? "Docs:" : "", *t
);
3570 STRV_FOREACH_PAIR(t
, t2
, i
->listen
)
3571 printf(" %*s %s (%s)\n", 9, t
== i
->listen
? "Listen:" : "", *t2
, *t
);
3574 printf(" Accepted: %u; Connected: %u\n", i
->n_accepted
, i
->n_connections
);
3576 LIST_FOREACH(exec
, p
, i
->exec
) {
3577 _cleanup_free_
char *argv
= NULL
;
3580 /* Only show exited processes here */
3584 argv
= strv_join(p
->argv
, " ");
3585 printf(" Process: "PID_FMT
" %s=%s ", p
->pid
, p
->name
, strna(argv
));
3587 good
= is_clean_exit_lsb(p
->code
, p
->status
, NULL
);
3589 on
= ansi_highlight_red();
3590 off
= ansi_normal();
3594 printf("%s(code=%s, ", on
, sigchld_code_to_string(p
->code
));
3596 if (p
->code
== CLD_EXITED
) {
3599 printf("status=%i", p
->status
);
3601 c
= exit_status_to_string(p
->status
, EXIT_STATUS_SYSTEMD
);
3606 printf("signal=%s", signal_to_string(p
->status
));
3608 printf(")%s\n", off
);
3610 if (i
->main_pid
== p
->pid
&&
3611 i
->start_timestamp
== p
->start_timestamp
&&
3612 i
->exit_timestamp
== p
->start_timestamp
)
3613 /* Let's not show this twice */
3616 if (p
->pid
== i
->control_pid
)
3620 if (i
->main_pid
> 0 || i
->control_pid
> 0) {
3621 if (i
->main_pid
> 0) {
3622 printf(" Main PID: "PID_FMT
, i
->main_pid
);
3625 _cleanup_free_
char *comm
= NULL
;
3626 get_process_comm(i
->main_pid
, &comm
);
3628 printf(" (%s)", comm
);
3629 } else if (i
->exit_code
> 0) {
3630 printf(" (code=%s, ", sigchld_code_to_string(i
->exit_code
));
3632 if (i
->exit_code
== CLD_EXITED
) {
3635 printf("status=%i", i
->exit_status
);
3637 c
= exit_status_to_string(i
->exit_status
, EXIT_STATUS_SYSTEMD
);
3642 printf("signal=%s", signal_to_string(i
->exit_status
));
3646 if (i
->control_pid
> 0)
3650 if (i
->control_pid
> 0) {
3651 _cleanup_free_
char *c
= NULL
;
3653 printf(" %8s: "PID_FMT
, i
->main_pid
? "" : " Control", i
->control_pid
);
3655 get_process_comm(i
->control_pid
, &c
);
3664 printf(" Status: \"%s\"\n", i
->status_text
);
3665 if (i
->status_errno
> 0)
3666 printf(" Error: %i (%s)\n", i
->status_errno
, strerror(i
->status_errno
));
3668 if (i
->tasks_current
!= (uint64_t) -1) {
3669 printf(" Tasks: %" PRIu64
, i
->tasks_current
);
3671 if (i
->tasks_max
!= (uint64_t) -1)
3672 printf(" (limit: %" PRIi64
")\n", i
->tasks_max
);
3677 if (i
->memory_current
!= (uint64_t) -1) {
3678 char buf
[FORMAT_BYTES_MAX
];
3680 printf(" Memory: %s", format_bytes(buf
, sizeof(buf
), i
->memory_current
));
3682 if (i
->memory_limit
!= (uint64_t) -1)
3683 printf(" (limit: %s)\n", format_bytes(buf
, sizeof(buf
), i
->memory_limit
));
3688 if (i
->cpu_usage_nsec
!= (uint64_t) -1) {
3689 char buf
[FORMAT_TIMESPAN_MAX
];
3690 printf(" CPU: %s\n", format_timespan(buf
, sizeof(buf
), i
->cpu_usage_nsec
/ NSEC_PER_USEC
, USEC_PER_MSEC
));
3693 if (i
->control_group
&&
3694 (i
->main_pid
> 0 || i
->control_pid
> 0 ||
3695 (!IN_SET(arg_transport
, BUS_TRANSPORT_LOCAL
, BUS_TRANSPORT_MACHINE
) || cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
) == 0))) {
3698 printf(" CGroup: %s\n", i
->control_group
);
3700 if (IN_SET(arg_transport
,
3701 BUS_TRANSPORT_LOCAL
,
3702 BUS_TRANSPORT_MACHINE
)) {
3705 static const char prefix
[] = " ";
3708 if (c
> sizeof(prefix
) - 1)
3709 c
-= sizeof(prefix
) - 1;
3713 if (i
->main_pid
> 0)
3714 extra
[k
++] = i
->main_pid
;
3716 if (i
->control_pid
> 0)
3717 extra
[k
++] = i
->control_pid
;
3719 show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER
, i
->control_group
, prefix
, c
, false, extra
, k
, get_output_flags());
3723 if (i
->id
&& arg_transport
== BUS_TRANSPORT_LOCAL
)
3724 show_journal_by_unit(
3729 i
->inactive_exit_timestamp_monotonic
,
3732 get_output_flags() | OUTPUT_BEGIN_NEWLINE
,
3733 SD_JOURNAL_LOCAL_ONLY
,
3734 arg_scope
== UNIT_FILE_SYSTEM
,
3737 if (i
->need_daemon_reload
)
3738 warn_unit_file_changed(i
->id
);
3741 static void show_unit_help(UnitStatusInfo
*i
) {
3746 if (!i
->documentation
) {
3747 log_info("Documentation for %s not known.", i
->id
);
3751 STRV_FOREACH(p
, i
->documentation
)
3752 if (startswith(*p
, "man:"))
3753 show_man_page(*p
+ 4, false);
3755 log_info("Can't show: %s", *p
);
3758 static int status_property(const char *name
, sd_bus_message
*m
, UnitStatusInfo
*i
, const char *contents
) {
3765 switch (contents
[0]) {
3767 case SD_BUS_TYPE_STRING
: {
3770 r
= sd_bus_message_read(m
, "s", &s
);
3772 return bus_log_parse_error(r
);
3775 if (streq(name
, "Id"))
3777 else if (streq(name
, "LoadState"))
3779 else if (streq(name
, "ActiveState"))
3780 i
->active_state
= s
;
3781 else if (streq(name
, "SubState"))
3783 else if (streq(name
, "Description"))
3785 else if (streq(name
, "FragmentPath"))
3786 i
->fragment_path
= s
;
3787 else if (streq(name
, "SourcePath"))
3790 else if (streq(name
, "DefaultControlGroup")) {
3792 e
= startswith(s
, SYSTEMD_CGROUP_CONTROLLER
":");
3794 i
->control_group
= e
;
3797 else if (streq(name
, "ControlGroup"))
3798 i
->control_group
= s
;
3799 else if (streq(name
, "StatusText"))
3801 else if (streq(name
, "PIDFile"))
3803 else if (streq(name
, "SysFSPath"))
3805 else if (streq(name
, "Where"))
3807 else if (streq(name
, "What"))
3809 else if (streq(name
, "Following"))
3811 else if (streq(name
, "UnitFileState"))
3812 i
->unit_file_state
= s
;
3813 else if (streq(name
, "UnitFilePreset"))
3814 i
->unit_file_preset
= s
;
3815 else if (streq(name
, "Result"))
3822 case SD_BUS_TYPE_BOOLEAN
: {
3825 r
= sd_bus_message_read(m
, "b", &b
);
3827 return bus_log_parse_error(r
);
3829 if (streq(name
, "Accept"))
3831 else if (streq(name
, "NeedDaemonReload"))
3832 i
->need_daemon_reload
= b
;
3833 else if (streq(name
, "ConditionResult"))
3834 i
->condition_result
= b
;
3835 else if (streq(name
, "AssertResult"))
3836 i
->assert_result
= b
;
3841 case SD_BUS_TYPE_UINT32
: {
3844 r
= sd_bus_message_read(m
, "u", &u
);
3846 return bus_log_parse_error(r
);
3848 if (streq(name
, "MainPID")) {
3850 i
->main_pid
= (pid_t
) u
;
3853 } else if (streq(name
, "ControlPID"))
3854 i
->control_pid
= (pid_t
) u
;
3855 else if (streq(name
, "ExecMainPID")) {
3857 i
->main_pid
= (pid_t
) u
;
3858 } else if (streq(name
, "NAccepted"))
3860 else if (streq(name
, "NConnections"))
3861 i
->n_connections
= u
;
3866 case SD_BUS_TYPE_INT32
: {
3869 r
= sd_bus_message_read(m
, "i", &j
);
3871 return bus_log_parse_error(r
);
3873 if (streq(name
, "ExecMainCode"))
3874 i
->exit_code
= (int) j
;
3875 else if (streq(name
, "ExecMainStatus"))
3876 i
->exit_status
= (int) j
;
3877 else if (streq(name
, "StatusErrno"))
3878 i
->status_errno
= (int) j
;
3883 case SD_BUS_TYPE_UINT64
: {
3886 r
= sd_bus_message_read(m
, "t", &u
);
3888 return bus_log_parse_error(r
);
3890 if (streq(name
, "ExecMainStartTimestamp"))
3891 i
->start_timestamp
= (usec_t
) u
;
3892 else if (streq(name
, "ExecMainExitTimestamp"))
3893 i
->exit_timestamp
= (usec_t
) u
;
3894 else if (streq(name
, "ActiveEnterTimestamp"))
3895 i
->active_enter_timestamp
= (usec_t
) u
;
3896 else if (streq(name
, "InactiveEnterTimestamp"))
3897 i
->inactive_enter_timestamp
= (usec_t
) u
;
3898 else if (streq(name
, "InactiveExitTimestamp"))
3899 i
->inactive_exit_timestamp
= (usec_t
) u
;
3900 else if (streq(name
, "InactiveExitTimestampMonotonic"))
3901 i
->inactive_exit_timestamp_monotonic
= (usec_t
) u
;
3902 else if (streq(name
, "ActiveExitTimestamp"))
3903 i
->active_exit_timestamp
= (usec_t
) u
;
3904 else if (streq(name
, "ConditionTimestamp"))
3905 i
->condition_timestamp
= (usec_t
) u
;
3906 else if (streq(name
, "AssertTimestamp"))
3907 i
->assert_timestamp
= (usec_t
) u
;
3908 else if (streq(name
, "MemoryCurrent"))
3909 i
->memory_current
= u
;
3910 else if (streq(name
, "MemoryLimit"))
3911 i
->memory_limit
= u
;
3912 else if (streq(name
, "TasksCurrent"))
3913 i
->tasks_current
= u
;
3914 else if (streq(name
, "TasksMax"))
3916 else if (streq(name
, "CPUUsageNSec"))
3917 i
->cpu_usage_nsec
= u
;
3922 case SD_BUS_TYPE_ARRAY
:
3924 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
3925 _cleanup_free_ ExecStatusInfo
*info
= NULL
;
3927 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
3929 return bus_log_parse_error(r
);
3931 info
= new0(ExecStatusInfo
, 1);
3935 while ((r
= exec_status_info_deserialize(m
, info
)) > 0) {
3937 info
->name
= strdup(name
);
3941 LIST_PREPEND(exec
, i
->exec
, info
);
3943 info
= new0(ExecStatusInfo
, 1);
3949 return bus_log_parse_error(r
);
3951 r
= sd_bus_message_exit_container(m
);
3953 return bus_log_parse_error(r
);
3957 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
3958 const char *type
, *path
;
3960 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
3962 return bus_log_parse_error(r
);
3964 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0) {
3966 r
= strv_extend(&i
->listen
, type
);
3970 r
= strv_extend(&i
->listen
, path
);
3975 return bus_log_parse_error(r
);
3977 r
= sd_bus_message_exit_container(m
);
3979 return bus_log_parse_error(r
);
3983 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "DropInPaths")) {
3985 r
= sd_bus_message_read_strv(m
, &i
->dropin_paths
);
3987 return bus_log_parse_error(r
);
3989 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Documentation")) {
3991 r
= sd_bus_message_read_strv(m
, &i
->documentation
);
3993 return bus_log_parse_error(r
);
3995 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Conditions")) {
3996 const char *cond
, *param
;
3997 int trigger
, negate
;
4000 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4002 return bus_log_parse_error(r
);
4004 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4005 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4006 if (state
< 0 && (!trigger
|| !i
->failed_condition
)) {
4007 i
->failed_condition
= cond
;
4008 i
->failed_condition_trigger
= trigger
;
4009 i
->failed_condition_negate
= negate
;
4010 i
->failed_condition_parameter
= param
;
4014 return bus_log_parse_error(r
);
4016 r
= sd_bus_message_exit_container(m
);
4018 return bus_log_parse_error(r
);
4020 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Asserts")) {
4021 const char *cond
, *param
;
4022 int trigger
, negate
;
4025 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sbbsi)");
4027 return bus_log_parse_error(r
);
4029 while ((r
= sd_bus_message_read(m
, "(sbbsi)", &cond
, &trigger
, &negate
, ¶m
, &state
)) > 0) {
4030 log_debug("%s %d %d %s %d", cond
, trigger
, negate
, param
, state
);
4031 if (state
< 0 && (!trigger
|| !i
->failed_assert
)) {
4032 i
->failed_assert
= cond
;
4033 i
->failed_assert_trigger
= trigger
;
4034 i
->failed_assert_negate
= negate
;
4035 i
->failed_assert_parameter
= param
;
4039 return bus_log_parse_error(r
);
4041 r
= sd_bus_message_exit_container(m
);
4043 return bus_log_parse_error(r
);
4050 case SD_BUS_TYPE_STRUCT_BEGIN
:
4052 if (streq(name
, "LoadError")) {
4053 const char *n
, *message
;
4055 r
= sd_bus_message_read(m
, "(ss)", &n
, &message
);
4057 return bus_log_parse_error(r
);
4059 if (!isempty(message
))
4060 i
->load_error
= message
;
4073 r
= sd_bus_message_skip(m
, contents
);
4075 return bus_log_parse_error(r
);
4080 static int print_property(const char *name
, sd_bus_message
*m
, const char *contents
) {
4086 /* This is a low-level property printer, see
4087 * print_status_info() for the nicer output */
4089 if (arg_properties
&& !strv_find(arg_properties
, name
)) {
4090 /* skip what we didn't read */
4091 r
= sd_bus_message_skip(m
, contents
);
4095 switch (contents
[0]) {
4097 case SD_BUS_TYPE_STRUCT_BEGIN
:
4099 if (contents
[1] == SD_BUS_TYPE_UINT32
&& streq(name
, "Job")) {
4102 r
= sd_bus_message_read(m
, "(uo)", &u
, NULL
);
4104 return bus_log_parse_error(r
);
4107 printf("%s=%"PRIu32
"\n", name
, u
);
4109 printf("%s=\n", name
);
4113 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "Unit")) {
4116 r
= sd_bus_message_read(m
, "(so)", &s
, NULL
);
4118 return bus_log_parse_error(r
);
4120 if (arg_all
|| !isempty(s
))
4121 printf("%s=%s\n", name
, s
);
4125 } else if (contents
[1] == SD_BUS_TYPE_STRING
&& streq(name
, "LoadError")) {
4126 const char *a
= NULL
, *b
= NULL
;
4128 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
4130 return bus_log_parse_error(r
);
4132 if (arg_all
|| !isempty(a
) || !isempty(b
))
4133 printf("%s=%s \"%s\"\n", name
, strempty(a
), strempty(b
));
4136 } else if (streq_ptr(name
, "SystemCallFilter")) {
4137 _cleanup_strv_free_
char **l
= NULL
;
4140 r
= sd_bus_message_enter_container(m
, 'r', "bas");
4142 return bus_log_parse_error(r
);
4144 r
= sd_bus_message_read(m
, "b", &whitelist
);
4146 return bus_log_parse_error(r
);
4148 r
= sd_bus_message_read_strv(m
, &l
);
4150 return bus_log_parse_error(r
);
4152 r
= sd_bus_message_exit_container(m
);
4154 return bus_log_parse_error(r
);
4156 if (arg_all
|| whitelist
|| !strv_isempty(l
)) {
4160 fputs(name
, stdout
);
4166 STRV_FOREACH(i
, l
) {
4174 fputc('\n', stdout
);
4182 case SD_BUS_TYPE_ARRAY
:
4184 if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "EnvironmentFiles")) {
4188 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sb)");
4190 return bus_log_parse_error(r
);
4192 while ((r
= sd_bus_message_read(m
, "(sb)", &path
, &ignore
)) > 0)
4193 printf("EnvironmentFile=%s (ignore_errors=%s)\n", path
, yes_no(ignore
));
4196 return bus_log_parse_error(r
);
4198 r
= sd_bus_message_exit_container(m
);
4200 return bus_log_parse_error(r
);
4204 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Paths")) {
4205 const char *type
, *path
;
4207 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4209 return bus_log_parse_error(r
);
4211 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4212 printf("%s=%s\n", type
, path
);
4214 return bus_log_parse_error(r
);
4216 r
= sd_bus_message_exit_container(m
);
4218 return bus_log_parse_error(r
);
4222 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Listen")) {
4223 const char *type
, *path
;
4225 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4227 return bus_log_parse_error(r
);
4229 while ((r
= sd_bus_message_read(m
, "(ss)", &type
, &path
)) > 0)
4230 printf("Listen%s=%s\n", type
, path
);
4232 return bus_log_parse_error(r
);
4234 r
= sd_bus_message_exit_container(m
);
4236 return bus_log_parse_error(r
);
4240 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "Timers")) {
4242 uint64_t value
, next_elapse
;
4244 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(stt)");
4246 return bus_log_parse_error(r
);
4248 while ((r
= sd_bus_message_read(m
, "(stt)", &base
, &value
, &next_elapse
)) > 0) {
4249 char timespan1
[FORMAT_TIMESPAN_MAX
], timespan2
[FORMAT_TIMESPAN_MAX
];
4251 printf("%s={ value=%s ; next_elapse=%s }\n",
4253 format_timespan(timespan1
, sizeof(timespan1
), value
, 0),
4254 format_timespan(timespan2
, sizeof(timespan2
), next_elapse
, 0));
4257 return bus_log_parse_error(r
);
4259 r
= sd_bus_message_exit_container(m
);
4261 return bus_log_parse_error(r
);
4265 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& startswith(name
, "Exec")) {
4266 ExecStatusInfo info
= {};
4268 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(sasbttttuii)");
4270 return bus_log_parse_error(r
);
4272 while ((r
= exec_status_info_deserialize(m
, &info
)) > 0) {
4273 char timestamp1
[FORMAT_TIMESTAMP_MAX
], timestamp2
[FORMAT_TIMESTAMP_MAX
];
4274 _cleanup_free_
char *tt
;
4276 tt
= strv_join(info
.argv
, " ");
4278 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",
4282 yes_no(info
.ignore
),
4283 strna(format_timestamp(timestamp1
, sizeof(timestamp1
), info
.start_timestamp
)),
4284 strna(format_timestamp(timestamp2
, sizeof(timestamp2
), info
.exit_timestamp
)),
4286 sigchld_code_to_string(info
.code
),
4288 info
.code
== CLD_EXITED
? "" : "/",
4289 strempty(info
.code
== CLD_EXITED
? NULL
: signal_to_string(info
.status
)));
4292 strv_free(info
.argv
);
4296 r
= sd_bus_message_exit_container(m
);
4298 return bus_log_parse_error(r
);
4302 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "DeviceAllow")) {
4303 const char *path
, *rwm
;
4305 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(ss)");
4307 return bus_log_parse_error(r
);
4309 while ((r
= sd_bus_message_read(m
, "(ss)", &path
, &rwm
)) > 0)
4310 printf("%s=%s %s\n", name
, strna(path
), strna(rwm
));
4312 return bus_log_parse_error(r
);
4314 r
= sd_bus_message_exit_container(m
);
4316 return bus_log_parse_error(r
);
4320 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& streq(name
, "BlockIODeviceWeight")) {
4324 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4326 return bus_log_parse_error(r
);
4328 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &weight
)) > 0)
4329 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), weight
);
4331 return bus_log_parse_error(r
);
4333 r
= sd_bus_message_exit_container(m
);
4335 return bus_log_parse_error(r
);
4339 } else if (contents
[1] == SD_BUS_TYPE_STRUCT_BEGIN
&& (streq(name
, "BlockIOReadBandwidth") || streq(name
, "BlockIOWriteBandwidth"))) {
4343 r
= sd_bus_message_enter_container(m
, SD_BUS_TYPE_ARRAY
, "(st)");
4345 return bus_log_parse_error(r
);
4347 while ((r
= sd_bus_message_read(m
, "(st)", &path
, &bandwidth
)) > 0)
4348 printf("%s=%s %" PRIu64
"\n", name
, strna(path
), bandwidth
);
4350 return bus_log_parse_error(r
);
4352 r
= sd_bus_message_exit_container(m
);
4354 return bus_log_parse_error(r
);
4362 r
= bus_print_property(name
, m
, arg_all
);
4364 return bus_log_parse_error(r
);
4367 r
= sd_bus_message_skip(m
, contents
);
4369 return bus_log_parse_error(r
);
4372 printf("%s=[unprintable]\n", name
);
4378 static int show_one(
4382 bool show_properties
,
4386 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4387 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4388 UnitStatusInfo info
= {
4389 .memory_current
= (uint64_t) -1,
4390 .memory_limit
= (uint64_t) -1,
4391 .cpu_usage_nsec
= (uint64_t) -1,
4392 .tasks_current
= (uint64_t) -1,
4393 .tasks_max
= (uint64_t) -1,
4401 log_debug("Showing one %s", path
);
4403 r
= sd_bus_call_method(
4405 "org.freedesktop.systemd1",
4407 "org.freedesktop.DBus.Properties",
4413 return log_error_errno(r
, "Failed to get properties: %s", bus_error_message(&error
, r
));
4415 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "{sv}");
4417 return bus_log_parse_error(r
);
4424 while ((r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_DICT_ENTRY
, "sv")) > 0) {
4425 const char *name
, *contents
;
4427 r
= sd_bus_message_read(reply
, "s", &name
);
4429 return bus_log_parse_error(r
);
4431 r
= sd_bus_message_peek_type(reply
, NULL
, &contents
);
4433 return bus_log_parse_error(r
);
4435 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_VARIANT
, contents
);
4437 return bus_log_parse_error(r
);
4439 if (show_properties
)
4440 r
= print_property(name
, reply
, contents
);
4442 r
= status_property(name
, reply
, &info
, contents
);
4446 r
= sd_bus_message_exit_container(reply
);
4448 return bus_log_parse_error(r
);
4450 r
= sd_bus_message_exit_container(reply
);
4452 return bus_log_parse_error(r
);
4455 return bus_log_parse_error(r
);
4457 r
= sd_bus_message_exit_container(reply
);
4459 return bus_log_parse_error(r
);
4463 if (!show_properties
) {
4464 if (streq(verb
, "help"))
4465 show_unit_help(&info
);
4467 print_status_info(&info
, ellipsized
);
4470 strv_free(info
.documentation
);
4471 strv_free(info
.dropin_paths
);
4472 strv_free(info
.listen
);
4474 if (!streq_ptr(info
.active_state
, "active") &&
4475 !streq_ptr(info
.active_state
, "reloading") &&
4476 streq(verb
, "status")) {
4477 /* According to LSB: "program not running" */
4478 /* 0: program is running or service is OK
4479 * 1: program is dead and /run PID file exists
4480 * 2: program is dead and /run/lock lock file exists
4481 * 3: program is not running
4482 * 4: program or service status is unknown
4484 if (info
.pid_file
&& access(info
.pid_file
, F_OK
) == 0)
4490 while ((p
= info
.exec
)) {
4491 LIST_REMOVE(exec
, info
.exec
, p
);
4492 exec_status_info_free(p
);
4498 static int get_unit_dbus_path_by_pid(
4503 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4504 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4508 r
= sd_bus_call_method(
4510 "org.freedesktop.systemd1",
4511 "/org/freedesktop/systemd1",
4512 "org.freedesktop.systemd1.Manager",
4518 return log_error_errno(r
, "Failed to get unit for PID %"PRIu32
": %s", pid
, bus_error_message(&error
, r
));
4520 r
= sd_bus_message_read(reply
, "o", &u
);
4522 return bus_log_parse_error(r
);
4532 static int show_all(
4535 bool show_properties
,
4539 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4540 _cleanup_free_ UnitInfo
*unit_infos
= NULL
;
4545 r
= get_unit_list(bus
, NULL
, NULL
, &unit_infos
, 0, &reply
);
4549 pager_open_if_enabled();
4553 qsort_safe(unit_infos
, c
, sizeof(UnitInfo
), compare_unit_info
);
4555 for (u
= unit_infos
; u
< unit_infos
+ c
; u
++) {
4556 _cleanup_free_
char *p
= NULL
;
4558 p
= unit_dbus_path_from_name(u
->id
);
4562 r
= show_one(verb
, bus
, p
, show_properties
, new_line
, ellipsized
);
4565 else if (r
> 0 && ret
== 0)
4572 static int show_system_status(sd_bus
*bus
) {
4573 char since1
[FORMAT_TIMESTAMP_RELATIVE_MAX
], since2
[FORMAT_TIMESTAMP_MAX
];
4574 _cleanup_free_
char *hn
= NULL
;
4575 _cleanup_(machine_info_clear
) struct machine_info mi
= {};
4576 const char *on
, *off
;
4579 hn
= gethostname_malloc();
4583 r
= bus_map_all_properties(bus
, "org.freedesktop.systemd1", "/org/freedesktop/systemd1", machine_info_property_map
, &mi
);
4585 return log_error_errno(r
, "Failed to read server status: %m");
4587 if (streq_ptr(mi
.state
, "degraded")) {
4588 on
= ansi_highlight_red();
4589 off
= ansi_normal();
4590 } else if (!streq_ptr(mi
.state
, "running")) {
4591 on
= ansi_highlight_yellow();
4592 off
= ansi_normal();
4596 printf("%s%s%s %s\n", on
, draw_special_char(DRAW_BLACK_CIRCLE
), off
, arg_host
? arg_host
: hn
);
4598 printf(" State: %s%s%s\n",
4599 on
, strna(mi
.state
), off
);
4601 printf(" Jobs: %u queued\n", mi
.n_jobs
);
4602 printf(" Failed: %u units\n", mi
.n_failed_units
);
4604 printf(" Since: %s; %s\n",
4605 format_timestamp(since2
, sizeof(since2
), mi
.timestamp
),
4606 format_timestamp_relative(since1
, sizeof(since1
), mi
.timestamp
));
4608 printf(" CGroup: %s\n", mi
.control_group
?: "/");
4609 if (IN_SET(arg_transport
,
4610 BUS_TRANSPORT_LOCAL
,
4611 BUS_TRANSPORT_MACHINE
)) {
4612 static const char prefix
[] = " ";
4616 if (c
> sizeof(prefix
) - 1)
4617 c
-= sizeof(prefix
) - 1;
4621 show_cgroup(SYSTEMD_CGROUP_CONTROLLER
, strempty(mi
.control_group
), prefix
, c
, false, get_output_flags());
4627 static int show(int argc
, char *argv
[], void *userdata
) {
4628 bool show_properties
, show_status
, show_help
, new_line
= false;
4629 bool ellipsized
= false;
4635 show_properties
= streq(argv
[0], "show");
4636 show_status
= streq(argv
[0], "status");
4637 show_help
= streq(argv
[0], "help");
4639 if (show_help
&& argc
<= 1) {
4640 log_error("This command expects one or more unit names. Did you mean --help?");
4644 if (show_properties
)
4645 pager_open_if_enabled();
4648 /* Increase max number of open files to 16K if we can, we
4649 * might needs this when browsing journal files, which might
4650 * be split up into many files. */
4651 setrlimit_closest(RLIMIT_NOFILE
, &RLIMIT_MAKE_CONST(16384));
4653 r
= acquire_bus(BUS_MANAGER
, &bus
);
4657 /* If no argument is specified inspect the manager itself */
4658 if (show_properties
&& argc
<= 1)
4659 return show_one(argv
[0], bus
, "/org/freedesktop/systemd1", show_properties
, &new_line
, &ellipsized
);
4661 if (show_status
&& argc
<= 1) {
4663 pager_open_if_enabled();
4664 show_system_status(bus
);
4668 ret
= show_all(argv
[0], bus
, false, &new_line
, &ellipsized
);
4670 _cleanup_free_
char **patterns
= NULL
;
4673 STRV_FOREACH(name
, strv_skip(argv
, 1)) {
4674 _cleanup_free_
char *unit
= NULL
;
4677 if (safe_atou32(*name
, &id
) < 0) {
4678 if (strv_push(&patterns
, *name
) < 0)
4682 } else if (show_properties
) {
4683 /* Interpret as job id */
4684 if (asprintf(&unit
, "/org/freedesktop/systemd1/job/%u", id
) < 0)
4688 /* Interpret as PID */
4689 r
= get_unit_dbus_path_by_pid(bus
, id
, &unit
);
4696 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4699 else if (r
> 0 && ret
== 0)
4703 if (!strv_isempty(patterns
)) {
4704 _cleanup_strv_free_
char **names
= NULL
;
4706 r
= expand_names(bus
, patterns
, NULL
, &names
);
4708 return log_error_errno(r
, "Failed to expand names: %m");
4710 STRV_FOREACH(name
, names
) {
4711 _cleanup_free_
char *unit
;
4713 unit
= unit_dbus_path_from_name(*name
);
4717 r
= show_one(argv
[0], bus
, unit
, show_properties
, &new_line
, &ellipsized
);
4720 else if (r
> 0 && ret
== 0)
4726 if (ellipsized
&& !arg_quiet
)
4727 printf("Hint: Some lines were ellipsized, use -l to show in full.\n");
4732 static int init_home_and_lookup_paths(char **user_home
, char **user_runtime
, LookupPaths
*lp
) {
4736 assert(user_runtime
);
4739 if (arg_scope
== UNIT_FILE_USER
) {
4740 r
= user_config_home(user_home
);
4742 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4744 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_CONFIG_HOME and $HOME are not set.");
4746 r
= user_runtime_dir(user_runtime
);
4748 return log_error_errno(r
, "Failed to query XDG_CONFIG_HOME: %m");
4750 return log_error_errno(ENOTDIR
, "Cannot find units: $XDG_RUNTIME_DIR is not set.");
4753 r
= lookup_paths_init_from_scope(lp
, arg_scope
, arg_root
);
4755 return log_error_errno(r
, "Failed to query unit lookup paths: %m");
4760 static int cat_file(const char *filename
, bool newline
) {
4761 _cleanup_close_
int fd
;
4763 fd
= open(filename
, O_RDONLY
|O_CLOEXEC
|O_NOCTTY
);
4767 printf("%s%s# %s%s\n",
4768 newline
? "\n" : "",
4769 ansi_highlight_blue(),
4774 return copy_bytes(fd
, STDOUT_FILENO
, (uint64_t) -1, false);
4777 static int cat(int argc
, char *argv
[], void *userdata
) {
4778 _cleanup_free_
char *user_home
= NULL
;
4779 _cleanup_free_
char *user_runtime
= NULL
;
4780 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
4781 _cleanup_strv_free_
char **names
= NULL
;
4787 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
4788 log_error("Cannot remotely cat units.");
4792 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
4796 r
= acquire_bus(BUS_MANAGER
, &bus
);
4800 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
4802 return log_error_errno(r
, "Failed to expand names: %m");
4804 pager_open_if_enabled();
4806 STRV_FOREACH(name
, names
) {
4807 _cleanup_free_
char *fragment_path
= NULL
;
4808 _cleanup_strv_free_
char **dropin_paths
= NULL
;
4811 r
= unit_find_paths(bus
, *name
, &lp
, &fragment_path
, &dropin_paths
);
4822 if (fragment_path
) {
4823 r
= cat_file(fragment_path
, false);
4825 return log_warning_errno(r
, "Failed to cat %s: %m", fragment_path
);
4828 STRV_FOREACH(path
, dropin_paths
) {
4829 r
= cat_file(*path
, path
== dropin_paths
);
4831 return log_warning_errno(r
, "Failed to cat %s: %m", *path
);
4838 static int set_property(int argc
, char *argv
[], void *userdata
) {
4839 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
4840 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4841 _cleanup_free_
char *n
= NULL
;
4846 polkit_agent_open_if_enabled();
4848 r
= acquire_bus(BUS_MANAGER
, &bus
);
4852 r
= sd_bus_message_new_method_call(
4855 "org.freedesktop.systemd1",
4856 "/org/freedesktop/systemd1",
4857 "org.freedesktop.systemd1.Manager",
4858 "SetUnitProperties");
4860 return bus_log_create_error(r
);
4862 r
= unit_name_mangle(argv
[1], UNIT_NAME_NOGLOB
, &n
);
4864 return log_error_errno(r
, "Failed to mangle unit name: %m");
4866 r
= sd_bus_message_append(m
, "sb", n
, arg_runtime
);
4868 return bus_log_create_error(r
);
4870 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_ARRAY
, "(sv)");
4872 return bus_log_create_error(r
);
4874 STRV_FOREACH(i
, strv_skip(argv
, 2)) {
4875 r
= sd_bus_message_open_container(m
, SD_BUS_TYPE_STRUCT
, "sv");
4877 return bus_log_create_error(r
);
4879 r
= bus_append_unit_property_assignment(m
, *i
);
4883 r
= sd_bus_message_close_container(m
);
4885 return bus_log_create_error(r
);
4888 r
= sd_bus_message_close_container(m
);
4890 return bus_log_create_error(r
);
4892 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
4894 return log_error_errno(r
, "Failed to set unit properties on %s: %s", n
, bus_error_message(&error
, r
));
4899 static int snapshot(int argc
, char *argv
[], void *userdata
) {
4900 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4901 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
4902 _cleanup_free_
char *n
= NULL
, *id
= NULL
;
4907 polkit_agent_open_if_enabled();
4910 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".snapshot", &n
);
4912 return log_error_errno(r
, "Failed to generate unit name: %m");
4919 r
= acquire_bus(BUS_MANAGER
, &bus
);
4923 r
= sd_bus_call_method(
4925 "org.freedesktop.systemd1",
4926 "/org/freedesktop/systemd1",
4927 "org.freedesktop.systemd1.Manager",
4933 return log_error_errno(r
, "Failed to create snapshot: %s", bus_error_message(&error
, r
));
4935 r
= sd_bus_message_read(reply
, "o", &path
);
4937 return bus_log_parse_error(r
);
4939 r
= sd_bus_get_property_string(
4941 "org.freedesktop.systemd1",
4943 "org.freedesktop.systemd1.Unit",
4948 return log_error_errno(r
, "Failed to get ID of snapshot: %s", bus_error_message(&error
, r
));
4956 static int delete_snapshot(int argc
, char *argv
[], void *userdata
) {
4957 _cleanup_strv_free_
char **names
= NULL
;
4962 polkit_agent_open_if_enabled();
4964 r
= acquire_bus(BUS_MANAGER
, &bus
);
4968 r
= expand_names(bus
, strv_skip(argv
, 1), ".snapshot", &names
);
4970 return log_error_errno(r
, "Failed to expand names: %m");
4972 STRV_FOREACH(name
, names
) {
4973 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
4976 q
= sd_bus_call_method(
4978 "org.freedesktop.systemd1",
4979 "/org/freedesktop/systemd1",
4980 "org.freedesktop.systemd1.Manager",
4986 log_error_errno(q
, "Failed to remove snapshot %s: %s", *name
, bus_error_message(&error
, q
));
4995 static int daemon_reload(int argc
, char *argv
[], void *userdata
) {
4996 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5001 polkit_agent_open_if_enabled();
5003 r
= acquire_bus(BUS_MANAGER
, &bus
);
5007 if (arg_action
== ACTION_RELOAD
)
5009 else if (arg_action
== ACTION_REEXEC
)
5010 method
= "Reexecute";
5012 assert(arg_action
== ACTION_SYSTEMCTL
);
5015 streq(argv
[0], "clear-jobs") ||
5016 streq(argv
[0], "cancel") ? "ClearJobs" :
5017 streq(argv
[0], "daemon-reexec") ? "Reexecute" :
5018 streq(argv
[0], "reset-failed") ? "ResetFailed" :
5019 streq(argv
[0], "halt") ? "Halt" :
5020 streq(argv
[0], "poweroff") ? "PowerOff" :
5021 streq(argv
[0], "reboot") ? "Reboot" :
5022 streq(argv
[0], "kexec") ? "KExec" :
5023 streq(argv
[0], "exit") ? "Exit" :
5024 /* "daemon-reload" */ "Reload";
5027 r
= sd_bus_call_method(
5029 "org.freedesktop.systemd1",
5030 "/org/freedesktop/systemd1",
5031 "org.freedesktop.systemd1.Manager",
5036 if (r
== -ENOENT
&& arg_action
!= ACTION_SYSTEMCTL
)
5037 /* There's always a fallback possible for
5038 * legacy actions. */
5040 else if ((r
== -ETIMEDOUT
|| r
== -ECONNRESET
) && streq(method
, "Reexecute"))
5041 /* On reexecution, we expect a disconnect, not a
5045 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5047 return r
< 0 ? r
: 0;
5050 static int reset_failed(int argc
, char *argv
[], void *userdata
) {
5051 _cleanup_strv_free_
char **names
= NULL
;
5057 return daemon_reload(argc
, argv
, userdata
);
5059 polkit_agent_open_if_enabled();
5061 r
= acquire_bus(BUS_MANAGER
, &bus
);
5065 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
5067 return log_error_errno(r
, "Failed to expand names: %m");
5069 STRV_FOREACH(name
, names
) {
5070 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5072 q
= sd_bus_call_method(
5074 "org.freedesktop.systemd1",
5075 "/org/freedesktop/systemd1",
5076 "org.freedesktop.systemd1.Manager",
5082 log_error_errno(q
, "Failed to reset failed state of unit %s: %s", *name
, bus_error_message(&error
, q
));
5091 static int show_environment(int argc
, char *argv
[], void *userdata
) {
5092 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5093 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5098 pager_open_if_enabled();
5100 r
= acquire_bus(BUS_MANAGER
, &bus
);
5104 r
= sd_bus_get_property(
5106 "org.freedesktop.systemd1",
5107 "/org/freedesktop/systemd1",
5108 "org.freedesktop.systemd1.Manager",
5114 return log_error_errno(r
, "Failed to get environment: %s", bus_error_message(&error
, r
));
5116 r
= sd_bus_message_enter_container(reply
, SD_BUS_TYPE_ARRAY
, "s");
5118 return bus_log_parse_error(r
);
5120 while ((r
= sd_bus_message_read_basic(reply
, SD_BUS_TYPE_STRING
, &text
)) > 0)
5123 return bus_log_parse_error(r
);
5125 r
= sd_bus_message_exit_container(reply
);
5127 return bus_log_parse_error(r
);
5132 static int switch_root(int argc
, char *argv
[], void *userdata
) {
5133 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5134 _cleanup_free_
char *cmdline_init
= NULL
;
5135 const char *root
, *init
;
5139 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
5140 log_error("Cannot switch root remotely.");
5144 if (argc
< 2 || argc
> 3) {
5145 log_error("Wrong number of arguments.");
5154 r
= parse_env_file("/proc/cmdline", WHITESPACE
,
5155 "init", &cmdline_init
,
5158 log_debug_errno(r
, "Failed to parse /proc/cmdline: %m");
5160 init
= cmdline_init
;
5167 const char *root_systemd_path
= NULL
, *root_init_path
= NULL
;
5169 root_systemd_path
= strjoina(root
, "/" SYSTEMD_BINARY_PATH
);
5170 root_init_path
= strjoina(root
, "/", init
);
5172 /* If the passed init is actually the same as the
5173 * systemd binary, then let's suppress it. */
5174 if (files_same(root_init_path
, root_systemd_path
) > 0)
5178 r
= acquire_bus(BUS_MANAGER
, &bus
);
5182 log_debug("Switching root - root: %s; init: %s", root
, strna(init
));
5184 r
= sd_bus_call_method(
5186 "org.freedesktop.systemd1",
5187 "/org/freedesktop/systemd1",
5188 "org.freedesktop.systemd1.Manager",
5194 return log_error_errno(r
, "Failed to switch root: %s", bus_error_message(&error
, r
));
5199 static int set_environment(int argc
, char *argv
[], void *userdata
) {
5200 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5201 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5209 polkit_agent_open_if_enabled();
5211 r
= acquire_bus(BUS_MANAGER
, &bus
);
5215 method
= streq(argv
[0], "set-environment")
5217 : "UnsetEnvironment";
5219 r
= sd_bus_message_new_method_call(
5222 "org.freedesktop.systemd1",
5223 "/org/freedesktop/systemd1",
5224 "org.freedesktop.systemd1.Manager",
5227 return bus_log_create_error(r
);
5229 r
= sd_bus_message_append_strv(m
, strv_skip(argv
, 1));
5231 return bus_log_create_error(r
);
5233 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5235 return log_error_errno(r
, "Failed to set environment: %s", bus_error_message(&error
, r
));
5240 static int import_environment(int argc
, char *argv
[], void *userdata
) {
5241 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5242 _cleanup_bus_message_unref_ sd_bus_message
*m
= NULL
;
5246 polkit_agent_open_if_enabled();
5248 r
= acquire_bus(BUS_MANAGER
, &bus
);
5252 r
= sd_bus_message_new_method_call(
5255 "org.freedesktop.systemd1",
5256 "/org/freedesktop/systemd1",
5257 "org.freedesktop.systemd1.Manager",
5260 return bus_log_create_error(r
);
5263 r
= sd_bus_message_append_strv(m
, environ
);
5267 r
= sd_bus_message_open_container(m
, 'a', "s");
5269 return bus_log_create_error(r
);
5271 STRV_FOREACH(a
, strv_skip(argv
, 1)) {
5273 if (!env_name_is_valid(*a
)) {
5274 log_error("Not a valid environment variable name: %s", *a
);
5278 STRV_FOREACH(b
, environ
) {
5281 eq
= startswith(*b
, *a
);
5282 if (eq
&& *eq
== '=') {
5284 r
= sd_bus_message_append(m
, "s", *b
);
5286 return bus_log_create_error(r
);
5293 r
= sd_bus_message_close_container(m
);
5296 return bus_log_create_error(r
);
5298 r
= sd_bus_call(bus
, m
, 0, &error
, NULL
);
5300 return log_error_errno(r
, "Failed to import environment: %s", bus_error_message(&error
, r
));
5305 static int enable_sysv_units(const char *verb
, char **args
) {
5308 #if defined(HAVE_SYSV_COMPAT)
5310 _cleanup_lookup_paths_free_ LookupPaths paths
= {};
5312 if (arg_scope
!= UNIT_FILE_SYSTEM
)
5315 if (!STR_IN_SET(verb
,
5321 /* Processes all SysV units, and reshuffles the array so that
5322 * afterwards only the native units remain */
5324 r
= lookup_paths_init(&paths
, MANAGER_SYSTEM
, false, arg_root
, NULL
, NULL
, NULL
);
5331 _cleanup_free_
char *p
= NULL
, *q
= NULL
, *l
= NULL
;
5332 bool found_native
= false, found_sysv
;
5334 const char *argv
[6] = { ROOTLIBEXECDIR
"/systemd-sysv-install", NULL
, NULL
, NULL
, NULL
};
5342 if (!endswith(name
, ".service"))
5345 if (path_is_absolute(name
))
5348 STRV_FOREACH(k
, paths
.unit_path
) {
5349 _cleanup_free_
char *path
= NULL
;
5351 path
= path_join(arg_root
, *k
, name
);
5355 found_native
= access(path
, F_OK
) >= 0;
5360 /* If we have both a native unit and a SysV script,
5361 * enable/disable them both (below); for is-enabled, prefer the
5363 if (found_native
&& streq(verb
, "is-enabled"))
5366 p
= path_join(arg_root
, SYSTEM_SYSVINIT_PATH
, name
);
5370 p
[strlen(p
) - strlen(".service")] = 0;
5371 found_sysv
= access(p
, F_OK
) >= 0;
5376 log_info("Synchronizing state of %s with SysV init with %s...", name
, argv
[0]);
5378 log_info("%s is not a native service, redirecting to systemd-sysv-install", name
);
5380 if (!isempty(arg_root
))
5381 argv
[c
++] = q
= strappend("--root=", arg_root
);
5384 argv
[c
++] = basename(p
);
5387 l
= strv_join((char**)argv
, " ");
5391 log_info("Executing %s", l
);
5395 return log_error_errno(errno
, "Failed to fork: %m");
5396 else if (pid
== 0) {
5399 (void) reset_all_signal_handlers();
5400 (void) reset_signal_mask();
5402 execv(argv
[0], (char**) argv
);
5403 log_error_errno(r
, "Failed to execute %s: %m", argv
[0]);
5404 _exit(EXIT_FAILURE
);
5407 j
= wait_for_terminate(pid
, &status
);
5409 log_error_errno(j
, "Failed to wait for child: %m");
5413 if (status
.si_code
== CLD_EXITED
) {
5414 if (streq(verb
, "is-enabled")) {
5415 if (status
.si_status
== 0) {
5424 } else if (status
.si_status
!= 0)
5432 /* Remove this entry, so that we don't try enabling it as native unit */
5435 assert(args
[f
] == name
);
5436 strv_remove(args
, name
);
5443 static int mangle_names(char **original_names
, char ***mangled_names
) {
5444 char **i
, **l
, **name
;
5447 l
= i
= new(char*, strv_length(original_names
) + 1);
5451 STRV_FOREACH(name
, original_names
) {
5453 /* When enabling units qualified path names are OK,
5454 * too, hence allow them explicitly. */
5456 if (is_path(*name
)) {
5463 r
= unit_name_mangle(*name
, UNIT_NAME_NOGLOB
, i
);
5466 return log_error_errno(r
, "Failed to mangle unit name: %m");
5479 static int enable_unit(int argc
, char *argv
[], void *userdata
) {
5480 _cleanup_strv_free_
char **names
= NULL
;
5481 const char *verb
= argv
[0];
5482 UnitFileChange
*changes
= NULL
;
5483 unsigned n_changes
= 0;
5484 int carries_install_info
= -1;
5490 r
= mangle_names(strv_skip(argv
, 1), &names
);
5494 r
= enable_sysv_units(verb
, names
);
5498 /* If the operation was fully executed by the SysV compat,
5499 * let's finish early */
5500 if (strv_isempty(names
))
5503 if (install_client_side()) {
5504 if (streq(verb
, "enable")) {
5505 r
= unit_file_enable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5506 carries_install_info
= r
;
5507 } else if (streq(verb
, "disable"))
5508 r
= unit_file_disable(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5509 else if (streq(verb
, "reenable")) {
5510 r
= unit_file_reenable(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5511 carries_install_info
= r
;
5512 } else if (streq(verb
, "link"))
5513 r
= unit_file_link(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5514 else if (streq(verb
, "preset")) {
5515 r
= unit_file_preset(arg_scope
, arg_runtime
, arg_root
, names
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5516 carries_install_info
= r
;
5517 } else if (streq(verb
, "mask"))
5518 r
= unit_file_mask(arg_scope
, arg_runtime
, arg_root
, names
, arg_force
, &changes
, &n_changes
);
5519 else if (streq(verb
, "unmask"))
5520 r
= unit_file_unmask(arg_scope
, arg_runtime
, arg_root
, names
, &changes
, &n_changes
);
5522 assert_not_reached("Unknown verb");
5525 log_error_errno(r
, "Operation failed: %m");
5530 dump_unit_file_changes(changes
, n_changes
);
5534 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5535 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5536 int expect_carries_install_info
= false;
5537 bool send_force
= true, send_preset_mode
= false;
5541 polkit_agent_open_if_enabled();
5543 r
= acquire_bus(BUS_MANAGER
, &bus
);
5547 if (streq(verb
, "enable")) {
5548 method
= "EnableUnitFiles";
5549 expect_carries_install_info
= true;
5550 } else if (streq(verb
, "disable")) {
5551 method
= "DisableUnitFiles";
5553 } else if (streq(verb
, "reenable")) {
5554 method
= "ReenableUnitFiles";
5555 expect_carries_install_info
= true;
5556 } else if (streq(verb
, "link"))
5557 method
= "LinkUnitFiles";
5558 else if (streq(verb
, "preset")) {
5560 if (arg_preset_mode
!= UNIT_FILE_PRESET_FULL
) {
5561 method
= "PresetUnitFilesWithMode";
5562 send_preset_mode
= true;
5564 method
= "PresetUnitFiles";
5566 expect_carries_install_info
= true;
5567 } else if (streq(verb
, "mask"))
5568 method
= "MaskUnitFiles";
5569 else if (streq(verb
, "unmask")) {
5570 method
= "UnmaskUnitFiles";
5573 assert_not_reached("Unknown verb");
5575 r
= sd_bus_message_new_method_call(
5578 "org.freedesktop.systemd1",
5579 "/org/freedesktop/systemd1",
5580 "org.freedesktop.systemd1.Manager",
5583 return bus_log_create_error(r
);
5585 r
= sd_bus_message_append_strv(m
, names
);
5587 return bus_log_create_error(r
);
5589 if (send_preset_mode
) {
5590 r
= sd_bus_message_append(m
, "s", unit_file_preset_mode_to_string(arg_preset_mode
));
5592 return bus_log_create_error(r
);
5595 r
= sd_bus_message_append(m
, "b", arg_runtime
);
5597 return bus_log_create_error(r
);
5600 r
= sd_bus_message_append(m
, "b", arg_force
);
5602 return bus_log_create_error(r
);
5605 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5607 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5609 if (expect_carries_install_info
) {
5610 r
= sd_bus_message_read(reply
, "b", &carries_install_info
);
5612 return bus_log_parse_error(r
);
5615 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, &changes
, &n_changes
);
5619 /* Try to reload if enabled */
5621 r
= daemon_reload(argc
, argv
, userdata
);
5626 if (carries_install_info
== 0)
5627 log_warning("The unit files have no [Install] section. They are not meant to be enabled\n"
5628 "using systemctl.\n"
5629 "Possible reasons for having this kind of units are:\n"
5630 "1) A unit may be statically enabled by being symlinked from another unit's\n"
5631 " .wants/ or .requires/ directory.\n"
5632 "2) A unit's purpose may be to act as a helper for some other unit which has\n"
5633 " a requirement dependency on it.\n"
5634 "3) A unit may be started when needed via activation (socket, path, timer,\n"
5635 " D-Bus, udev, scripted systemctl call, ...).\n");
5637 if (arg_now
&& n_changes
> 0 && STR_IN_SET(argv
[0], "enable", "disable", "mask")) {
5638 char *new_args
[n_changes
+ 2];
5642 r
= acquire_bus(BUS_MANAGER
, &bus
);
5646 new_args
[0] = (char*) (streq(argv
[0], "enable") ? "start" : "stop");
5647 for (i
= 0; i
< n_changes
; i
++)
5648 new_args
[i
+ 1] = basename(changes
[i
].path
);
5649 new_args
[i
+ 1] = NULL
;
5651 r
= start_unit(strv_length(new_args
), new_args
, userdata
);
5655 unit_file_changes_free(changes
, n_changes
);
5660 static int add_dependency(int argc
, char *argv
[], void *userdata
) {
5661 _cleanup_strv_free_
char **names
= NULL
;
5662 _cleanup_free_
char *target
= NULL
;
5663 const char *verb
= argv
[0];
5670 r
= unit_name_mangle_with_suffix(argv
[1], UNIT_NAME_NOGLOB
, ".target", &target
);
5672 return log_error_errno(r
, "Failed to mangle unit name: %m");
5674 r
= mangle_names(strv_skip(argv
, 2), &names
);
5678 if (streq(verb
, "add-wants"))
5680 else if (streq(verb
, "add-requires"))
5681 dep
= UNIT_REQUIRES
;
5683 assert_not_reached("Unknown verb");
5685 if (install_client_side()) {
5686 UnitFileChange
*changes
= NULL
;
5687 unsigned n_changes
= 0;
5689 r
= unit_file_add_dependency(arg_scope
, arg_runtime
, arg_root
, names
, target
, dep
, arg_force
, &changes
, &n_changes
);
5692 return log_error_errno(r
, "Can't add dependency: %m");
5695 dump_unit_file_changes(changes
, n_changes
);
5697 unit_file_changes_free(changes
, n_changes
);
5700 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
, *m
= NULL
;
5701 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5704 polkit_agent_open_if_enabled();
5706 r
= acquire_bus(BUS_MANAGER
, &bus
);
5710 r
= sd_bus_message_new_method_call(
5713 "org.freedesktop.systemd1",
5714 "/org/freedesktop/systemd1",
5715 "org.freedesktop.systemd1.Manager",
5716 "AddDependencyUnitFiles");
5718 return bus_log_create_error(r
);
5720 r
= sd_bus_message_append_strv(m
, names
);
5722 return bus_log_create_error(r
);
5724 r
= sd_bus_message_append(m
, "ssbb", target
, unit_dependency_to_string(dep
), arg_runtime
, arg_force
);
5726 return bus_log_create_error(r
);
5728 r
= sd_bus_call(bus
, m
, 0, &error
, &reply
);
5730 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5732 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5737 r
= daemon_reload(argc
, argv
, userdata
);
5745 static int preset_all(int argc
, char *argv
[], void *userdata
) {
5746 UnitFileChange
*changes
= NULL
;
5747 unsigned n_changes
= 0;
5750 if (install_client_side()) {
5752 r
= unit_file_preset_all(arg_scope
, arg_runtime
, arg_root
, arg_preset_mode
, arg_force
, &changes
, &n_changes
);
5754 log_error_errno(r
, "Operation failed: %m");
5759 dump_unit_file_changes(changes
, n_changes
);
5764 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5765 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5768 polkit_agent_open_if_enabled();
5770 r
= acquire_bus(BUS_MANAGER
, &bus
);
5774 r
= sd_bus_call_method(
5776 "org.freedesktop.systemd1",
5777 "/org/freedesktop/systemd1",
5778 "org.freedesktop.systemd1.Manager",
5779 "PresetAllUnitFiles",
5783 unit_file_preset_mode_to_string(arg_preset_mode
),
5787 return log_error_errno(r
, "Failed to execute operation: %s", bus_error_message(&error
, r
));
5789 r
= bus_deserialize_and_dump_unit_file_changes(reply
, arg_quiet
, NULL
, NULL
);
5794 r
= daemon_reload(argc
, argv
, userdata
);
5800 unit_file_changes_free(changes
, n_changes
);
5805 static int unit_is_enabled(int argc
, char *argv
[], void *userdata
) {
5807 _cleanup_strv_free_
char **names
= NULL
;
5812 r
= mangle_names(strv_skip(argv
, 1), &names
);
5816 r
= enable_sysv_units(argv
[0], names
);
5822 if (install_client_side()) {
5824 STRV_FOREACH(name
, names
) {
5825 UnitFileState state
;
5827 state
= unit_file_get_state(arg_scope
, arg_root
, *name
);
5829 return log_error_errno(state
, "Failed to get unit file state for %s: %m", *name
);
5833 UNIT_FILE_ENABLED_RUNTIME
,
5835 UNIT_FILE_INDIRECT
))
5839 puts(unit_file_state_to_string(state
));
5843 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
5846 r
= acquire_bus(BUS_MANAGER
, &bus
);
5850 STRV_FOREACH(name
, names
) {
5851 _cleanup_bus_message_unref_ sd_bus_message
*reply
= NULL
;
5854 r
= sd_bus_call_method(
5856 "org.freedesktop.systemd1",
5857 "/org/freedesktop/systemd1",
5858 "org.freedesktop.systemd1.Manager",
5864 return log_error_errno(r
, "Failed to get unit file state for %s: %s", *name
, bus_error_message(&error
, r
));
5866 r
= sd_bus_message_read(reply
, "s", &s
);
5868 return bus_log_parse_error(r
);
5870 if (STR_IN_SET(s
, "enabled", "enabled-runtime", "static", "indirect"))
5881 static int is_system_running(int argc
, char *argv
[], void *userdata
) {
5882 _cleanup_free_
char *state
= NULL
;
5886 if (arg_transport
== BUS_TRANSPORT_LOCAL
&& !sd_booted()) {
5889 return EXIT_FAILURE
;
5892 r
= acquire_bus(BUS_MANAGER
, &bus
);
5896 r
= sd_bus_get_property_string(
5898 "org.freedesktop.systemd1",
5899 "/org/freedesktop/systemd1",
5900 "org.freedesktop.systemd1.Manager",
5913 return streq(state
, "running") ? EXIT_SUCCESS
: EXIT_FAILURE
;
5916 static int create_edit_temp_file(const char *new_path
, const char *original_path
, char **ret_tmp_fn
) {
5917 _cleanup_free_
char *t
= NULL
;
5921 assert(original_path
);
5924 r
= tempfn_random(new_path
, NULL
, &t
);
5926 return log_error_errno(r
, "Failed to determine temporary filename for \"%s\": %m", new_path
);
5928 r
= mkdir_parents(new_path
, 0755);
5930 return log_error_errno(r
, "Failed to create directories for \"%s\": %m", new_path
);
5932 r
= copy_file(original_path
, t
, 0, 0644, 0);
5937 return log_error_errno(r
, "Failed to create temporary file \"%s\": %m", t
);
5940 return log_error_errno(r
, "Failed to copy \"%s\" to \"%s\": %m", original_path
, t
);
5948 static int get_file_to_edit(const char *name
, const char *user_home
, const char *user_runtime
, char **ret_path
) {
5949 _cleanup_free_
char *path
= NULL
, *path2
= NULL
, *run
= NULL
;
5954 switch (arg_scope
) {
5955 case UNIT_FILE_SYSTEM
:
5956 path
= path_join(arg_root
, SYSTEM_CONFIG_UNIT_PATH
, name
);
5958 run
= path_join(arg_root
, "/run/systemd/system/", name
);
5960 case UNIT_FILE_GLOBAL
:
5961 path
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5963 run
= path_join(arg_root
, "/run/systemd/user/", name
);
5965 case UNIT_FILE_USER
:
5967 assert(user_runtime
);
5969 path
= path_join(arg_root
, user_home
, name
);
5971 path2
= path_join(arg_root
, USER_CONFIG_UNIT_PATH
, name
);
5974 run
= path_join(arg_root
, user_runtime
, name
);
5978 assert_not_reached("Invalid scope");
5980 if (!path
|| (arg_runtime
&& !run
))
5984 if (access(path
, F_OK
) >= 0) {
5985 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path
);
5989 if (path2
&& access(path2
, F_OK
) >= 0) {
5990 log_error("Refusing to create \"%s\" because it would be overridden by \"%s\" anyway.", run
, path2
);
6004 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
) {
6005 char *tmp_new_path
, *tmp_tmp_path
, *ending
;
6009 assert(ret_new_path
);
6010 assert(ret_tmp_path
);
6012 ending
= strjoina(unit_name
, ".d/override.conf");
6013 r
= get_file_to_edit(ending
, user_home
, user_runtime
, &tmp_new_path
);
6017 r
= create_edit_temp_file(tmp_new_path
, tmp_new_path
, &tmp_tmp_path
);
6023 *ret_new_path
= tmp_new_path
;
6024 *ret_tmp_path
= tmp_tmp_path
;
6029 static int unit_file_create_copy(
6030 const char *unit_name
,
6031 const char *fragment_path
,
6032 const char *user_home
,
6033 const char *user_runtime
,
6034 char **ret_new_path
,
6035 char **ret_tmp_path
) {
6037 char *tmp_new_path
, *tmp_tmp_path
;
6040 assert(fragment_path
);
6042 assert(ret_new_path
);
6043 assert(ret_tmp_path
);
6045 r
= get_file_to_edit(unit_name
, user_home
, user_runtime
, &tmp_new_path
);
6049 if (!path_equal(fragment_path
, tmp_new_path
) && access(tmp_new_path
, F_OK
) == 0) {
6052 r
= ask_char(&response
, "yn", "\"%s\" already exists. Overwrite with \"%s\"? [(y)es, (n)o] ", tmp_new_path
, fragment_path
);
6057 if (response
!= 'y') {
6058 log_warning("%s ignored", unit_name
);
6064 r
= create_edit_temp_file(tmp_new_path
, fragment_path
, &tmp_tmp_path
);
6066 log_error_errno(r
, "Failed to create temporary file for \"%s\": %m", tmp_new_path
);
6071 *ret_new_path
= tmp_new_path
;
6072 *ret_tmp_path
= tmp_tmp_path
;
6077 static int run_editor(char **paths
) {
6085 return log_error_errno(errno
, "Failed to fork: %m");
6089 char *editor
, **editor_args
= NULL
;
6090 char **tmp_path
, **original_path
, *p
;
6091 unsigned n_editor_args
= 0, i
= 1;
6094 (void) reset_all_signal_handlers();
6095 (void) reset_signal_mask();
6097 argc
= strv_length(paths
)/2 + 1;
6099 /* SYSTEMD_EDITOR takes precedence over EDITOR which takes precedence over VISUAL
6100 * If neither SYSTEMD_EDITOR nor EDITOR nor VISUAL are present,
6101 * we try to execute well known editors
6103 editor
= getenv("SYSTEMD_EDITOR");
6105 editor
= getenv("EDITOR");
6107 editor
= getenv("VISUAL");
6109 if (!isempty(editor
)) {
6110 editor_args
= strv_split(editor
, WHITESPACE
);
6113 _exit(EXIT_FAILURE
);
6115 n_editor_args
= strv_length(editor_args
);
6116 argc
+= n_editor_args
- 1;
6118 args
= newa(const char*, argc
+ 1);
6120 if (n_editor_args
> 0) {
6121 args
[0] = editor_args
[0];
6122 for (; i
< n_editor_args
; i
++)
6123 args
[i
] = editor_args
[i
];
6126 STRV_FOREACH_PAIR(original_path
, tmp_path
, paths
) {
6127 args
[i
] = *tmp_path
;
6132 if (n_editor_args
> 0)
6133 execvp(args
[0], (char* const*) args
);
6135 FOREACH_STRING(p
, "editor", "nano", "vim", "vi") {
6137 execvp(p
, (char* const*) args
);
6138 /* We do not fail if the editor doesn't exist
6139 * because we want to try each one of them before
6142 if (errno
!= ENOENT
) {
6143 log_error_errno(errno
, "Failed to execute %s: %m", editor
);
6144 _exit(EXIT_FAILURE
);
6148 log_error("Cannot edit unit(s), no editor available. Please set either $SYSTEMD_EDITOR, $EDITOR or $VISUAL.");
6149 _exit(EXIT_FAILURE
);
6152 r
= wait_for_terminate_and_warn("editor", pid
, true);
6154 return log_error_errno(r
, "Failed to wait for child: %m");
6159 static int find_paths_to_edit(sd_bus
*bus
, char **names
, char ***paths
) {
6160 _cleanup_free_
char *user_home
= NULL
;
6161 _cleanup_free_
char *user_runtime
= NULL
;
6162 _cleanup_lookup_paths_free_ LookupPaths lp
= {};
6169 r
= init_home_and_lookup_paths(&user_home
, &user_runtime
, &lp
);
6173 STRV_FOREACH(name
, names
) {
6174 _cleanup_free_
char *path
= NULL
;
6175 char *new_path
, *tmp_path
;
6177 r
= unit_find_paths(bus
, *name
, &lp
, &path
, NULL
);
6183 // FIXME: support units with path==NULL (no FragmentPath)
6184 log_error("No fragment exists for %s.", *name
);
6189 r
= unit_file_create_copy(*name
, path
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6191 r
= unit_file_create_dropin(*name
, user_home
, user_runtime
, &new_path
, &tmp_path
);
6195 r
= strv_push_pair(paths
, new_path
, tmp_path
);
6203 static int edit(int argc
, char *argv
[], void *userdata
) {
6204 _cleanup_strv_free_
char **names
= NULL
;
6205 _cleanup_strv_free_
char **paths
= NULL
;
6206 char **original
, **tmp
;
6211 log_error("Cannot edit units if not on a tty.");
6215 if (arg_transport
!= BUS_TRANSPORT_LOCAL
) {
6216 log_error("Cannot edit units remotely.");
6220 r
= acquire_bus(BUS_MANAGER
, &bus
);
6224 r
= expand_names(bus
, strv_skip(argv
, 1), NULL
, &names
);
6226 return log_error_errno(r
, "Failed to expand names: %m");
6228 r
= find_paths_to_edit(bus
, names
, &paths
);
6232 if (strv_isempty(paths
))
6235 r
= run_editor(paths
);
6239 STRV_FOREACH_PAIR(original
, tmp
, paths
) {
6240 /* If the temporary file is empty we ignore it. It's
6241 * useful if the user wants to cancel its modification
6243 if (null_or_empty_path(*tmp
)) {
6244 log_warning("Editing \"%s\" canceled: temporary file is empty.", *original
);
6248 r
= rename(*tmp
, *original
);
6250 r
= log_error_errno(errno
, "Failed to rename \"%s\" to \"%s\": %m", *tmp
, *original
);
6257 if (!arg_no_reload
&& !install_client_side())
6258 r
= daemon_reload(argc
, argv
, userdata
);
6261 STRV_FOREACH_PAIR(original
, tmp
, paths
)
6262 (void) unlink(*tmp
);
6267 static void systemctl_help(void) {
6269 pager_open_if_enabled();
6271 printf("%s [OPTIONS...] {COMMAND} ...\n\n"
6272 "Query or send control commands to the systemd manager.\n\n"
6273 " -h --help Show this help\n"
6274 " --version Show package version\n"
6275 " --system Connect to system manager\n"
6276 " --user Connect to user service manager\n"
6277 " -H --host=[USER@]HOST\n"
6278 " Operate on remote host\n"
6279 " -M --machine=CONTAINER\n"
6280 " Operate on local container\n"
6281 " -t --type=TYPE List units of a particular type\n"
6282 " --state=STATE List units with particular LOAD or SUB or ACTIVE state\n"
6283 " -p --property=NAME Show only properties by this name\n"
6284 " -a --all Show all loaded units/properties, including dead/empty\n"
6285 " ones. To list all units installed on the system, use\n"
6286 " the 'list-unit-files' command instead.\n"
6287 " -l --full Don't ellipsize unit names on output\n"
6288 " -r --recursive Show unit list of host and local containers\n"
6289 " --reverse Show reverse dependencies with 'list-dependencies'\n"
6290 " --job-mode=MODE Specify how to deal with already queued jobs, when\n"
6291 " queueing a new job\n"
6292 " --show-types When showing sockets, explicitly show their type\n"
6293 " -i --ignore-inhibitors\n"
6294 " When shutting down or sleeping, ignore inhibitors\n"
6295 " --kill-who=WHO Who to send signal to\n"
6296 " -s --signal=SIGNAL Which signal to send\n"
6297 " --now Start or stop unit in addition to enabling or disabling it\n"
6298 " -q --quiet Suppress output\n"
6299 " --no-block Do not wait until operation finished\n"
6300 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6301 " --no-reload Don't reload daemon after en-/dis-abling unit files\n"
6302 " --no-legend Do not print a legend (column headers and hints)\n"
6303 " --no-pager Do not pipe output into a pager\n"
6304 " --no-ask-password\n"
6305 " Do not ask for system passwords\n"
6306 " --global Enable/disable unit files globally\n"
6307 " --runtime Enable unit files only temporarily until next reboot\n"
6308 " -f --force When enabling unit files, override existing symlinks\n"
6309 " When shutting down, execute action immediately\n"
6310 " --preset-mode= Apply only enable, only disable, or all presets\n"
6311 " --root=PATH Enable unit files in the specified root directory\n"
6312 " -n --lines=INTEGER Number of journal entries to show\n"
6313 " -o --output=STRING Change journal output mode (short, short-iso,\n"
6314 " short-precise, short-monotonic, verbose,\n"
6315 " export, json, json-pretty, json-sse, cat)\n"
6316 " --firmware-setup Tell the firmware to show the setup menu on next boot\n"
6317 " --plain Print unit dependencies as a list instead of a tree\n\n"
6319 " list-units [PATTERN...] List loaded units\n"
6320 " list-sockets [PATTERN...] List loaded sockets ordered by address\n"
6321 " list-timers [PATTERN...] List loaded timers ordered by next elapse\n"
6322 " start NAME... Start (activate) one or more units\n"
6323 " stop NAME... Stop (deactivate) one or more units\n"
6324 " reload NAME... Reload one or more units\n"
6325 " restart NAME... Start or restart one or more units\n"
6326 " try-restart NAME... Restart one or more units if active\n"
6327 " reload-or-restart NAME... Reload one or more units if possible,\n"
6328 " otherwise start or restart\n"
6329 " reload-or-try-restart NAME... Reload one or more units if possible,\n"
6330 " otherwise restart if active\n"
6331 " isolate NAME Start one unit and stop all others\n"
6332 " kill NAME... Send signal to processes of a unit\n"
6333 " is-active PATTERN... Check whether units are active\n"
6334 " is-failed PATTERN... Check whether units are failed\n"
6335 " status [PATTERN...|PID...] Show runtime status of one or more units\n"
6336 " show [PATTERN...|JOB...] Show properties of one or more\n"
6337 " units/jobs or the manager\n"
6338 " cat PATTERN... Show files and drop-ins of one or more units\n"
6339 " set-property NAME ASSIGNMENT... Sets one or more properties of a unit\n"
6340 " help PATTERN...|PID... Show manual for one or more units\n"
6341 " reset-failed [PATTERN...] Reset failed state for all, one, or more\n"
6343 " list-dependencies [NAME] Recursively show units which are required\n"
6344 " or wanted by this unit or by which this\n"
6345 " unit is required or wanted\n\n"
6346 "Unit File Commands:\n"
6347 " list-unit-files [PATTERN...] List installed unit files\n"
6348 " enable NAME... Enable one or more unit files\n"
6349 " disable NAME... Disable one or more unit files\n"
6350 " reenable NAME... Reenable one or more unit files\n"
6351 " preset NAME... Enable/disable one or more unit files\n"
6352 " based on preset configuration\n"
6353 " preset-all Enable/disable all unit files based on\n"
6354 " preset configuration\n"
6355 " is-enabled NAME... Check whether unit files are enabled\n"
6356 " mask NAME... Mask one or more units\n"
6357 " unmask NAME... Unmask one or more units\n"
6358 " link PATH... Link one or more units files into\n"
6359 " the search path\n"
6360 " add-wants TARGET NAME... Add 'Wants' dependency for the target\n"
6361 " on specified one or more units\n"
6362 " add-requires TARGET NAME... Add 'Requires' dependency for the target\n"
6363 " on specified one or more units\n"
6364 " edit NAME... Edit one or more unit files\n"
6365 " get-default Get the name of the default target\n"
6366 " set-default NAME Set the default target\n\n"
6367 "Machine Commands:\n"
6368 " list-machines [PATTERN...] List local containers and host\n\n"
6370 " list-jobs [PATTERN...] List jobs\n"
6371 " cancel [JOB...] Cancel all, one, or more jobs\n\n"
6372 "Snapshot Commands:\n"
6373 " snapshot [NAME] Create a snapshot\n"
6374 " delete NAME... Remove one or more snapshots\n\n"
6375 "Environment Commands:\n"
6376 " show-environment Dump environment\n"
6377 " set-environment NAME=VALUE... Set one or more environment variables\n"
6378 " unset-environment NAME... Unset one or more environment variables\n"
6379 " import-environment [NAME...] Import all or some environment variables\n\n"
6380 "Manager Lifecycle Commands:\n"
6381 " daemon-reload Reload systemd manager configuration\n"
6382 " daemon-reexec Reexecute systemd manager\n\n"
6383 "System Commands:\n"
6384 " is-system-running Check whether system is fully running\n"
6385 " default Enter system default mode\n"
6386 " rescue Enter system rescue mode\n"
6387 " emergency Enter system emergency mode\n"
6388 " halt Shut down and halt the system\n"
6389 " poweroff Shut down and power-off the system\n"
6390 " reboot [ARG] Shut down and reboot the system\n"
6391 " kexec Shut down and reboot the system with kexec\n"
6392 " exit [EXIT_CODE] Request user instance or container exit\n"
6393 " switch-root ROOT [INIT] Change to a different root file system\n"
6394 " suspend Suspend the system\n"
6395 " hibernate Hibernate the system\n"
6396 " hybrid-sleep Hibernate and suspend the system\n",
6397 program_invocation_short_name
);
6400 static void halt_help(void) {
6401 printf("%s [OPTIONS...]%s\n\n"
6402 "%s the system.\n\n"
6403 " --help Show this help\n"
6404 " --halt Halt the machine\n"
6405 " -p --poweroff Switch off the machine\n"
6406 " --reboot Reboot the machine\n"
6407 " -f --force Force immediate halt/power-off/reboot\n"
6408 " -w --wtmp-only Don't halt/power-off/reboot, just write wtmp record\n"
6409 " -d --no-wtmp Don't write wtmp record\n"
6410 " --no-wall Don't send wall message before halt/power-off/reboot\n",
6411 program_invocation_short_name
,
6412 arg_action
== ACTION_REBOOT
? " [ARG]" : "",
6413 arg_action
== ACTION_REBOOT
? "Reboot" :
6414 arg_action
== ACTION_POWEROFF
? "Power off" :
6418 static void shutdown_help(void) {
6419 printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
6420 "Shut down the system.\n\n"
6421 " --help Show this help\n"
6422 " -H --halt Halt the machine\n"
6423 " -P --poweroff Power-off the machine\n"
6424 " -r --reboot Reboot the machine\n"
6425 " -h Equivalent to --poweroff, overridden by --halt\n"
6426 " -k Don't halt/power-off/reboot, just send warnings\n"
6427 " --no-wall Don't send wall message before halt/power-off/reboot\n"
6428 " -c Cancel a pending shutdown\n",
6429 program_invocation_short_name
);
6432 static void telinit_help(void) {
6433 printf("%s [OPTIONS...] {COMMAND}\n\n"
6434 "Send control commands to the init daemon.\n\n"
6435 " --help Show this help\n"
6436 " --no-wall Don't send wall message before halt/power-off/reboot\n\n"
6438 " 0 Power-off the machine\n"
6439 " 6 Reboot the machine\n"
6440 " 2, 3, 4, 5 Start runlevelX.target unit\n"
6441 " 1, s, S Enter rescue mode\n"
6442 " q, Q Reload init daemon configuration\n"
6443 " u, U Reexecute init daemon\n",
6444 program_invocation_short_name
);
6447 static void runlevel_help(void) {
6448 printf("%s [OPTIONS...]\n\n"
6449 "Prints the previous and current runlevel of the init system.\n\n"
6450 " --help Show this help\n",
6451 program_invocation_short_name
);
6454 static void help_types(void) {
6458 puts("Available unit types:");
6459 for (i
= 0; i
< _UNIT_TYPE_MAX
; i
++)
6460 puts(unit_type_to_string(i
));
6463 static void help_states(void) {
6467 puts("Available unit load states:");
6468 for (i
= 0; i
< _UNIT_LOAD_STATE_MAX
; i
++)
6469 puts(unit_load_state_to_string(i
));
6472 puts("\nAvailable unit active states:");
6473 for (i
= 0; i
< _UNIT_ACTIVE_STATE_MAX
; i
++)
6474 puts(unit_active_state_to_string(i
));
6477 puts("\nAvailable automount unit substates:");
6478 for (i
= 0; i
< _AUTOMOUNT_STATE_MAX
; i
++)
6479 puts(automount_state_to_string(i
));
6482 puts("\nAvailable busname unit substates:");
6483 for (i
= 0; i
< _BUSNAME_STATE_MAX
; i
++)
6484 puts(busname_state_to_string(i
));
6487 puts("\nAvailable device unit substates:");
6488 for (i
= 0; i
< _DEVICE_STATE_MAX
; i
++)
6489 puts(device_state_to_string(i
));
6492 puts("\nAvailable mount unit substates:");
6493 for (i
= 0; i
< _MOUNT_STATE_MAX
; i
++)
6494 puts(mount_state_to_string(i
));
6497 puts("\nAvailable path unit substates:");
6498 for (i
= 0; i
< _PATH_STATE_MAX
; i
++)
6499 puts(path_state_to_string(i
));
6502 puts("\nAvailable scope unit substates:");
6503 for (i
= 0; i
< _SCOPE_STATE_MAX
; i
++)
6504 puts(scope_state_to_string(i
));
6507 puts("\nAvailable service unit substates:");
6508 for (i
= 0; i
< _SERVICE_STATE_MAX
; i
++)
6509 puts(service_state_to_string(i
));
6512 puts("\nAvailable slice unit substates:");
6513 for (i
= 0; i
< _SLICE_STATE_MAX
; i
++)
6514 puts(slice_state_to_string(i
));
6517 puts("\nAvailable snapshot unit substates:");
6518 for (i
= 0; i
< _SNAPSHOT_STATE_MAX
; i
++)
6519 puts(snapshot_state_to_string(i
));
6522 puts("\nAvailable socket unit substates:");
6523 for (i
= 0; i
< _SOCKET_STATE_MAX
; i
++)
6524 puts(socket_state_to_string(i
));
6527 puts("\nAvailable swap unit substates:");
6528 for (i
= 0; i
< _SWAP_STATE_MAX
; i
++)
6529 puts(swap_state_to_string(i
));
6532 puts("\nAvailable target unit substates:");
6533 for (i
= 0; i
< _TARGET_STATE_MAX
; i
++)
6534 puts(target_state_to_string(i
));
6537 puts("\nAvailable timer unit substates:");
6538 for (i
= 0; i
< _TIMER_STATE_MAX
; i
++)
6539 puts(timer_state_to_string(i
));
6542 static int systemctl_parse_argv(int argc
, char *argv
[]) {
6551 ARG_IGNORE_DEPENDENCIES
,
6563 ARG_NO_ASK_PASSWORD
,
6576 static const struct option options
[] = {
6577 { "help", no_argument
, NULL
, 'h' },
6578 { "version", no_argument
, NULL
, ARG_VERSION
},
6579 { "type", required_argument
, NULL
, 't' },
6580 { "property", required_argument
, NULL
, 'p' },
6581 { "all", no_argument
, NULL
, 'a' },
6582 { "reverse", no_argument
, NULL
, ARG_REVERSE
},
6583 { "after", no_argument
, NULL
, ARG_AFTER
},
6584 { "before", no_argument
, NULL
, ARG_BEFORE
},
6585 { "show-types", no_argument
, NULL
, ARG_SHOW_TYPES
},
6586 { "failed", no_argument
, NULL
, ARG_FAILED
}, /* compatibility only */
6587 { "full", no_argument
, NULL
, 'l' },
6588 { "job-mode", required_argument
, NULL
, ARG_JOB_MODE
},
6589 { "fail", no_argument
, NULL
, ARG_FAIL
}, /* compatibility only */
6590 { "irreversible", no_argument
, NULL
, ARG_IRREVERSIBLE
}, /* compatibility only */
6591 { "ignore-dependencies", no_argument
, NULL
, ARG_IGNORE_DEPENDENCIES
}, /* compatibility only */
6592 { "ignore-inhibitors", no_argument
, NULL
, 'i' },
6593 { "user", no_argument
, NULL
, ARG_USER
},
6594 { "system", no_argument
, NULL
, ARG_SYSTEM
},
6595 { "global", no_argument
, NULL
, ARG_GLOBAL
},
6596 { "no-block", no_argument
, NULL
, ARG_NO_BLOCK
},
6597 { "no-legend", no_argument
, NULL
, ARG_NO_LEGEND
},
6598 { "no-pager", no_argument
, NULL
, ARG_NO_PAGER
},
6599 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6600 { "quiet", no_argument
, NULL
, 'q' },
6601 { "root", required_argument
, NULL
, ARG_ROOT
},
6602 { "force", no_argument
, NULL
, ARG_FORCE
},
6603 { "no-reload", no_argument
, NULL
, ARG_NO_RELOAD
},
6604 { "kill-who", required_argument
, NULL
, ARG_KILL_WHO
},
6605 { "signal", required_argument
, NULL
, 's' },
6606 { "no-ask-password", no_argument
, NULL
, ARG_NO_ASK_PASSWORD
},
6607 { "host", required_argument
, NULL
, 'H' },
6608 { "machine", required_argument
, NULL
, 'M' },
6609 { "runtime", no_argument
, NULL
, ARG_RUNTIME
},
6610 { "lines", required_argument
, NULL
, 'n' },
6611 { "output", required_argument
, NULL
, 'o' },
6612 { "plain", no_argument
, NULL
, ARG_PLAIN
},
6613 { "state", required_argument
, NULL
, ARG_STATE
},
6614 { "recursive", no_argument
, NULL
, 'r' },
6615 { "preset-mode", required_argument
, NULL
, ARG_PRESET_MODE
},
6616 { "firmware-setup", no_argument
, NULL
, ARG_FIRMWARE_SETUP
},
6617 { "now", no_argument
, NULL
, ARG_NOW
},
6618 { "message", required_argument
, NULL
, ARG_MESSAGE
},
6627 /* we default to allowing interactive authorization only in systemctl (not in the legacy commands) */
6628 arg_ask_password
= true;
6630 while ((c
= getopt_long(argc
, argv
, "ht:p:alqfs:H:M:n:o:ir", options
, NULL
)) >= 0)
6642 const char *word
, *state
;
6645 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6646 _cleanup_free_
char *type
;
6648 type
= strndup(word
, size
);
6652 if (streq(type
, "help")) {
6657 if (unit_type_from_string(type
) >= 0) {
6658 if (strv_push(&arg_types
, type
) < 0)
6664 /* It's much nicer to use --state= for
6665 * load states, but let's support this
6666 * in --types= too for compatibility
6667 * with old versions */
6668 if (unit_load_state_from_string(type
) >= 0) {
6669 if (strv_push(&arg_states
, type
) < 0)
6675 log_error("Unknown unit type or load state '%s'.", type
);
6676 log_info("Use -t help to see a list of allowed values.");
6684 /* Make sure that if the empty property list
6685 was specified, we won't show any properties. */
6686 if (isempty(optarg
) && !arg_properties
) {
6687 arg_properties
= new0(char*, 1);
6688 if (!arg_properties
)
6691 const char *word
, *state
;
6694 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6697 prop
= strndup(word
, size
);
6701 if (strv_consume(&arg_properties
, prop
) < 0)
6706 /* If the user asked for a particular
6707 * property, show it to him, even if it is
6719 arg_dependency
= DEPENDENCY_REVERSE
;
6723 arg_dependency
= DEPENDENCY_AFTER
;
6727 arg_dependency
= DEPENDENCY_BEFORE
;
6730 case ARG_SHOW_TYPES
:
6731 arg_show_types
= true;
6735 arg_job_mode
= optarg
;
6739 arg_job_mode
= "fail";
6742 case ARG_IRREVERSIBLE
:
6743 arg_job_mode
= "replace-irreversibly";
6746 case ARG_IGNORE_DEPENDENCIES
:
6747 arg_job_mode
= "ignore-dependencies";
6751 arg_scope
= UNIT_FILE_USER
;
6755 arg_scope
= UNIT_FILE_SYSTEM
;
6759 arg_scope
= UNIT_FILE_GLOBAL
;
6763 arg_no_block
= true;
6767 arg_no_legend
= true;
6771 arg_no_pager
= true;
6779 r
= parse_path_argument_and_warn(optarg
, true, &arg_root
);
6789 if (strv_extend(&arg_states
, "failed") < 0)
6807 arg_no_reload
= true;
6811 arg_kill_who
= optarg
;
6815 arg_signal
= signal_from_string_try_harder(optarg
);
6816 if (arg_signal
< 0) {
6817 log_error("Failed to parse signal string %s.", optarg
);
6822 case ARG_NO_ASK_PASSWORD
:
6823 arg_ask_password
= false;
6827 arg_transport
= BUS_TRANSPORT_REMOTE
;
6832 arg_transport
= BUS_TRANSPORT_MACHINE
;
6841 if (safe_atou(optarg
, &arg_lines
) < 0) {
6842 log_error("Failed to parse lines '%s'", optarg
);
6848 arg_output
= output_mode_from_string(optarg
);
6849 if (arg_output
< 0) {
6850 log_error("Unknown output '%s'.", optarg
);
6856 arg_ignore_inhibitors
= true;
6863 case ARG_FIRMWARE_SETUP
:
6864 arg_firmware_setup
= true;
6868 const char *word
, *state
;
6871 FOREACH_WORD_SEPARATOR(word
, size
, optarg
, ",", state
) {
6872 _cleanup_free_
char *s
= NULL
;
6874 s
= strndup(word
, size
);
6878 if (streq(s
, "help")) {
6883 if (strv_push(&arg_states
, s
) < 0)
6892 if (geteuid() != 0) {
6893 log_error("--recursive requires root privileges.");
6897 arg_recursive
= true;
6900 case ARG_PRESET_MODE
:
6902 arg_preset_mode
= unit_file_preset_mode_from_string(optarg
);
6903 if (arg_preset_mode
< 0) {
6904 log_error("Failed to parse preset mode: %s.", optarg
);
6915 if (strv_extend(&arg_wall
, optarg
) < 0)
6923 assert_not_reached("Unhandled option");
6926 if (arg_transport
!= BUS_TRANSPORT_LOCAL
&& arg_scope
!= UNIT_FILE_SYSTEM
) {
6927 log_error("Cannot access user instance remotely.");
6934 static int halt_parse_argv(int argc
, char *argv
[]) {
6943 static const struct option options
[] = {
6944 { "help", no_argument
, NULL
, ARG_HELP
},
6945 { "halt", no_argument
, NULL
, ARG_HALT
},
6946 { "poweroff", no_argument
, NULL
, 'p' },
6947 { "reboot", no_argument
, NULL
, ARG_REBOOT
},
6948 { "force", no_argument
, NULL
, 'f' },
6949 { "wtmp-only", no_argument
, NULL
, 'w' },
6950 { "no-wtmp", no_argument
, NULL
, 'd' },
6951 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
6960 if (utmp_get_runlevel(&runlevel
, NULL
) >= 0)
6961 if (runlevel
== '0' || runlevel
== '6')
6964 while ((c
= getopt_long(argc
, argv
, "pfwdnih", options
, NULL
)) >= 0)
6972 arg_action
= ACTION_HALT
;
6976 if (arg_action
!= ACTION_REBOOT
)
6977 arg_action
= ACTION_POWEROFF
;
6981 arg_action
= ACTION_REBOOT
;
7003 /* Compatibility nops */
7010 assert_not_reached("Unhandled option");
7013 if (arg_action
== ACTION_REBOOT
&& (argc
== optind
|| argc
== optind
+ 1)) {
7014 r
= update_reboot_param_file(argc
== optind
+ 1 ? argv
[optind
] : NULL
);
7017 } else if (optind
< argc
) {
7018 log_error("Too many arguments.");
7025 static int parse_shutdown_time_spec(const char *t
, usec_t
*_u
) {
7029 if (streq(t
, "now"))
7031 else if (!strchr(t
, ':')) {
7034 if (safe_atou64(t
, &u
) < 0)
7037 *_u
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
* u
;
7046 hour
= strtol(t
, &e
, 10);
7047 if (errno
> 0 || *e
!= ':' || hour
< 0 || hour
> 23)
7050 minute
= strtol(e
+1, &e
, 10);
7051 if (errno
> 0 || *e
!= 0 || minute
< 0 || minute
> 59)
7054 n
= now(CLOCK_REALTIME
);
7055 s
= (time_t) (n
/ USEC_PER_SEC
);
7057 assert_se(localtime_r(&s
, &tm
));
7059 tm
.tm_hour
= (int) hour
;
7060 tm
.tm_min
= (int) minute
;
7063 assert_se(s
= mktime(&tm
));
7065 *_u
= (usec_t
) s
* USEC_PER_SEC
;
7068 *_u
+= USEC_PER_DAY
;
7074 static int shutdown_parse_argv(int argc
, char *argv
[]) {
7081 static const struct option options
[] = {
7082 { "help", no_argument
, NULL
, ARG_HELP
},
7083 { "halt", no_argument
, NULL
, 'H' },
7084 { "poweroff", no_argument
, NULL
, 'P' },
7085 { "reboot", no_argument
, NULL
, 'r' },
7086 { "kexec", no_argument
, NULL
, 'K' }, /* not documented extension */
7087 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7097 while ((c
= getopt_long(argc
, argv
, "HPrhkKtafFc", options
, NULL
)) >= 0)
7105 arg_action
= ACTION_HALT
;
7109 arg_action
= ACTION_POWEROFF
;
7114 arg_action
= ACTION_KEXEC
;
7116 arg_action
= ACTION_REBOOT
;
7120 arg_action
= ACTION_KEXEC
;
7124 if (arg_action
!= ACTION_HALT
)
7125 arg_action
= ACTION_POWEROFF
;
7140 /* Compatibility nops */
7144 arg_action
= ACTION_CANCEL_SHUTDOWN
;
7151 assert_not_reached("Unhandled option");
7154 if (argc
> optind
&& arg_action
!= ACTION_CANCEL_SHUTDOWN
) {
7155 r
= parse_shutdown_time_spec(argv
[optind
], &arg_when
);
7157 log_error("Failed to parse time specification: %s", argv
[optind
]);
7161 arg_when
= now(CLOCK_REALTIME
) + USEC_PER_MINUTE
;
7163 if (argc
> optind
&& arg_action
== ACTION_CANCEL_SHUTDOWN
)
7164 /* No time argument for shutdown cancel */
7165 wall
= argv
+ optind
;
7166 else if (argc
> optind
+ 1)
7167 /* We skip the time argument */
7168 wall
= argv
+ optind
+ 1;
7171 arg_wall
= strv_copy(wall
);
7181 static int telinit_parse_argv(int argc
, char *argv
[]) {
7188 static const struct option options
[] = {
7189 { "help", no_argument
, NULL
, ARG_HELP
},
7190 { "no-wall", no_argument
, NULL
, ARG_NO_WALL
},
7194 static const struct {
7198 { '0', ACTION_POWEROFF
},
7199 { '6', ACTION_REBOOT
},
7200 { '1', ACTION_RESCUE
},
7201 { '2', ACTION_RUNLEVEL2
},
7202 { '3', ACTION_RUNLEVEL3
},
7203 { '4', ACTION_RUNLEVEL4
},
7204 { '5', ACTION_RUNLEVEL5
},
7205 { 's', ACTION_RESCUE
},
7206 { 'S', ACTION_RESCUE
},
7207 { 'q', ACTION_RELOAD
},
7208 { 'Q', ACTION_RELOAD
},
7209 { 'u', ACTION_REEXEC
},
7210 { 'U', ACTION_REEXEC
}
7219 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7234 assert_not_reached("Unhandled option");
7237 if (optind
>= argc
) {
7238 log_error("%s: required argument missing.", program_invocation_short_name
);
7242 if (optind
+ 1 < argc
) {
7243 log_error("Too many arguments.");
7247 if (strlen(argv
[optind
]) != 1) {
7248 log_error("Expected single character argument.");
7252 for (i
= 0; i
< ELEMENTSOF(table
); i
++)
7253 if (table
[i
].from
== argv
[optind
][0])
7256 if (i
>= ELEMENTSOF(table
)) {
7257 log_error("Unknown command '%s'.", argv
[optind
]);
7261 arg_action
= table
[i
].to
;
7268 static int runlevel_parse_argv(int argc
, char *argv
[]) {
7274 static const struct option options
[] = {
7275 { "help", no_argument
, NULL
, ARG_HELP
},
7284 while ((c
= getopt_long(argc
, argv
, "", options
, NULL
)) >= 0)
7295 assert_not_reached("Unhandled option");
7298 if (optind
< argc
) {
7299 log_error("Too many arguments.");
7306 static int parse_argv(int argc
, char *argv
[]) {
7310 if (program_invocation_short_name
) {
7312 if (strstr(program_invocation_short_name
, "halt")) {
7313 arg_action
= ACTION_HALT
;
7314 return halt_parse_argv(argc
, argv
);
7315 } else if (strstr(program_invocation_short_name
, "poweroff")) {
7316 arg_action
= ACTION_POWEROFF
;
7317 return halt_parse_argv(argc
, argv
);
7318 } else if (strstr(program_invocation_short_name
, "reboot")) {
7320 arg_action
= ACTION_KEXEC
;
7322 arg_action
= ACTION_REBOOT
;
7323 return halt_parse_argv(argc
, argv
);
7324 } else if (strstr(program_invocation_short_name
, "shutdown")) {
7325 arg_action
= ACTION_POWEROFF
;
7326 return shutdown_parse_argv(argc
, argv
);
7327 } else if (strstr(program_invocation_short_name
, "init")) {
7329 if (sd_booted() > 0) {
7330 arg_action
= _ACTION_INVALID
;
7331 return telinit_parse_argv(argc
, argv
);
7333 /* Hmm, so some other init system is
7334 * running, we need to forward this
7335 * request to it. For now we simply
7336 * guess that it is Upstart. */
7338 execv(TELINIT
, argv
);
7340 log_error("Couldn't find an alternative telinit implementation to spawn.");
7344 } else if (strstr(program_invocation_short_name
, "runlevel")) {
7345 arg_action
= ACTION_RUNLEVEL
;
7346 return runlevel_parse_argv(argc
, argv
);
7350 arg_action
= ACTION_SYSTEMCTL
;
7351 return systemctl_parse_argv(argc
, argv
);
7354 _pure_
static int action_to_runlevel(void) {
7356 static const char table
[_ACTION_MAX
] = {
7357 [ACTION_HALT
] = '0',
7358 [ACTION_POWEROFF
] = '0',
7359 [ACTION_REBOOT
] = '6',
7360 [ACTION_RUNLEVEL2
] = '2',
7361 [ACTION_RUNLEVEL3
] = '3',
7362 [ACTION_RUNLEVEL4
] = '4',
7363 [ACTION_RUNLEVEL5
] = '5',
7364 [ACTION_RESCUE
] = '1'
7367 assert(arg_action
< _ACTION_MAX
);
7369 return table
[arg_action
];
7372 static int talk_initctl(void) {
7373 #ifdef HAVE_SYSV_COMPAT
7374 struct init_request request
= {
7375 .magic
= INIT_MAGIC
,
7377 .cmd
= INIT_CMD_RUNLVL
7380 _cleanup_close_
int fd
= -1;
7384 rl
= action_to_runlevel();
7388 request
.runlevel
= rl
;
7390 fd
= open(INIT_FIFO
, O_WRONLY
|O_NDELAY
|O_CLOEXEC
|O_NOCTTY
);
7392 if (errno
== ENOENT
)
7395 return log_error_errno(errno
, "Failed to open "INIT_FIFO
": %m");
7398 r
= loop_write(fd
, &request
, sizeof(request
), false);
7400 return log_error_errno(r
, "Failed to write to "INIT_FIFO
": %m");
7408 static int systemctl_main(int argc
, char *argv
[]) {
7410 static const Verb verbs
[] = {
7411 { "list-units", VERB_ANY
, VERB_ANY
, VERB_DEFAULT
, list_units
},
7412 { "list-unit-files", VERB_ANY
, VERB_ANY
, 0, list_unit_files
},
7413 { "list-sockets", VERB_ANY
, VERB_ANY
, 0, list_sockets
},
7414 { "list-timers", VERB_ANY
, VERB_ANY
, 0, list_timers
},
7415 { "list-jobs", VERB_ANY
, VERB_ANY
, 0, list_jobs
},
7416 { "list-machines", VERB_ANY
, VERB_ANY
, 0, list_machines
},
7417 { "clear-jobs", VERB_ANY
, 1, 0, daemon_reload
},
7418 { "cancel", 2, VERB_ANY
, 0, cancel_job
},
7419 { "start", 2, VERB_ANY
, 0, start_unit
},
7420 { "stop", 2, VERB_ANY
, 0, start_unit
},
7421 { "condstop", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7422 { "reload", 2, VERB_ANY
, 0, start_unit
},
7423 { "restart", 2, VERB_ANY
, 0, start_unit
},
7424 { "try-restart", 2, VERB_ANY
, 0, start_unit
},
7425 { "reload-or-restart", 2, VERB_ANY
, 0, start_unit
},
7426 { "reload-or-try-restart", 2, VERB_ANY
, 0, start_unit
},
7427 { "force-reload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with SysV */
7428 { "condreload", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with ALTLinux */
7429 { "condrestart", 2, VERB_ANY
, 0, start_unit
}, /* For compatibility with RH */
7430 { "isolate", 2, 2, 0, start_unit
},
7431 { "kill", 2, VERB_ANY
, 0, kill_unit
},
7432 { "is-active", 2, VERB_ANY
, 0, check_unit_active
},
7433 { "check", 2, VERB_ANY
, 0, check_unit_active
},
7434 { "is-failed", 2, VERB_ANY
, 0, check_unit_failed
},
7435 { "show", VERB_ANY
, VERB_ANY
, 0, show
},
7436 { "cat", 2, VERB_ANY
, 0, cat
},
7437 { "status", VERB_ANY
, VERB_ANY
, 0, show
},
7438 { "help", VERB_ANY
, VERB_ANY
, 0, show
},
7439 { "snapshot", VERB_ANY
, 2, 0, snapshot
},
7440 { "delete", 2, VERB_ANY
, 0, delete_snapshot
},
7441 { "daemon-reload", VERB_ANY
, 1, 0, daemon_reload
},
7442 { "daemon-reexec", VERB_ANY
, 1, 0, daemon_reload
},
7443 { "show-environment", VERB_ANY
, 1, 0, show_environment
},
7444 { "set-environment", 2, VERB_ANY
, 0, set_environment
},
7445 { "unset-environment", 2, VERB_ANY
, 0, set_environment
},
7446 { "import-environment", VERB_ANY
, VERB_ANY
, 0, import_environment
},
7447 { "halt", VERB_ANY
, 1, 0, start_special
},
7448 { "poweroff", VERB_ANY
, 1, 0, start_special
},
7449 { "reboot", VERB_ANY
, 2, 0, start_special
},
7450 { "kexec", VERB_ANY
, 1, 0, start_special
},
7451 { "suspend", VERB_ANY
, 1, 0, start_special
},
7452 { "hibernate", VERB_ANY
, 1, 0, start_special
},
7453 { "hybrid-sleep", VERB_ANY
, 1, 0, start_special
},
7454 { "default", VERB_ANY
, 1, 0, start_special
},
7455 { "rescue", VERB_ANY
, 1, 0, start_special
},
7456 { "emergency", VERB_ANY
, 1, 0, start_special
},
7457 { "exit", VERB_ANY
, 2, 0, start_special
},
7458 { "reset-failed", VERB_ANY
, VERB_ANY
, 0, reset_failed
},
7459 { "enable", 2, VERB_ANY
, 0, enable_unit
},
7460 { "disable", 2, VERB_ANY
, 0, enable_unit
},
7461 { "is-enabled", 2, VERB_ANY
, 0, unit_is_enabled
},
7462 { "reenable", 2, VERB_ANY
, 0, enable_unit
},
7463 { "preset", 2, VERB_ANY
, 0, enable_unit
},
7464 { "preset-all", VERB_ANY
, 1, 0, preset_all
},
7465 { "mask", 2, VERB_ANY
, 0, enable_unit
},
7466 { "unmask", 2, VERB_ANY
, 0, enable_unit
},
7467 { "link", 2, VERB_ANY
, 0, enable_unit
},
7468 { "switch-root", 2, VERB_ANY
, 0, switch_root
},
7469 { "list-dependencies", VERB_ANY
, 2, 0, list_dependencies
},
7470 { "set-default", 2, 2, 0, set_default
},
7471 { "get-default", VERB_ANY
, 1, 0, get_default
, },
7472 { "set-property", 3, VERB_ANY
, 0, set_property
},
7473 { "is-system-running", VERB_ANY
, 1, 0, is_system_running
},
7474 { "add-wants", 3, VERB_ANY
, 0, add_dependency
},
7475 { "add-requires", 3, VERB_ANY
, 0, add_dependency
},
7476 { "edit", 2, VERB_ANY
, 0, edit
},
7480 return dispatch_verb(argc
, argv
, verbs
, NULL
);
7483 static int reload_with_fallback(void) {
7485 /* First, try systemd via D-Bus. */
7486 if (daemon_reload(0, NULL
, NULL
) >= 0)
7489 /* Nothing else worked, so let's try signals */
7490 assert(arg_action
== ACTION_RELOAD
|| arg_action
== ACTION_REEXEC
);
7492 if (kill(1, arg_action
== ACTION_RELOAD
? SIGHUP
: SIGTERM
) < 0)
7493 return log_error_errno(errno
, "kill() failed: %m");
7498 static int start_with_fallback(void) {
7500 /* First, try systemd via D-Bus. */
7501 if (start_unit(0, NULL
, NULL
) >= 0)
7504 /* Nothing else worked, so let's try
7506 if (talk_initctl() > 0)
7509 log_error("Failed to talk to init daemon.");
7513 static int halt_now(enum action a
) {
7515 /* The kernel will automaticall flush ATA disks and suchlike
7516 * on reboot(), but the file systems need to be synce'd
7517 * explicitly in advance. */
7520 /* Make sure C-A-D is handled by the kernel from this point
7522 (void) reboot(RB_ENABLE_CAD
);
7527 log_info("Halting.");
7528 (void) reboot(RB_HALT_SYSTEM
);
7531 case ACTION_POWEROFF
:
7532 log_info("Powering off.");
7533 (void) reboot(RB_POWER_OFF
);
7537 case ACTION_REBOOT
: {
7538 _cleanup_free_
char *param
= NULL
;
7540 if (read_one_line_file(REBOOT_PARAM_FILE
, ¶m
) >= 0) {
7541 log_info("Rebooting with argument '%s'.", param
);
7542 (void) syscall(SYS_reboot
, LINUX_REBOOT_MAGIC1
, LINUX_REBOOT_MAGIC2
, LINUX_REBOOT_CMD_RESTART2
, param
);
7545 log_info("Rebooting.");
7546 (void) reboot(RB_AUTOBOOT
);
7551 assert_not_reached("Unknown action.");
7555 static int logind_schedule_shutdown(void) {
7558 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7559 char date
[FORMAT_TIMESTAMP_MAX
];
7564 (void) logind_set_wall_message();
7566 r
= acquire_bus(BUS_FULL
, &bus
);
7570 switch (arg_action
) {
7574 case ACTION_POWEROFF
:
7575 action
= "poweroff";
7590 action
= strjoina("dry-", action
);
7592 r
= sd_bus_call_method(
7594 "org.freedesktop.login1",
7595 "/org/freedesktop/login1",
7596 "org.freedesktop.login1.Manager",
7604 return log_warning_errno(r
, "Failed to call ScheduleShutdown in logind, proceeding with immediate shutdown: %s", bus_error_message(&error
, r
));
7606 log_info("Shutdown scheduled for %s, use 'shutdown -c' to cancel.", format_timestamp(date
, sizeof(date
), arg_when
));
7609 log_error("Cannot schedule shutdown without logind support, proceeding with immediate shutdown.");
7614 static int halt_main(void) {
7617 r
= logind_check_inhibitors(arg_action
);
7622 return logind_schedule_shutdown();
7624 if (geteuid() != 0) {
7625 if (arg_dry
|| arg_force
> 0) {
7626 log_error("Must be root.");
7630 /* Try logind if we are a normal user and no special
7631 * mode applies. Maybe PolicyKit allows us to shutdown
7633 if (IN_SET(arg_action
, ACTION_POWEROFF
, ACTION_REBOOT
)) {
7634 r
= logind_reboot(arg_action
);
7637 if (IN_SET(r
, -EOPNOTSUPP
, -EINPROGRESS
))
7638 /* requested operation is not
7639 * supported on the local system or
7640 * already in progress */
7642 /* on all other errors, try low-level operation */
7646 if (!arg_dry
&& !arg_force
)
7647 return start_with_fallback();
7649 assert(geteuid() == 0);
7652 if (sd_booted() > 0)
7653 log_debug("Not writing utmp record, assuming that systemd-update-utmp is used.");
7655 r
= utmp_put_shutdown();
7657 log_warning_errno(r
, "Failed to write utmp record: %m");
7664 r
= halt_now(arg_action
);
7665 return log_error_errno(r
, "Failed to reboot: %m");
7668 static int runlevel_main(void) {
7669 int r
, runlevel
, previous
;
7671 r
= utmp_get_runlevel(&runlevel
, &previous
);
7678 previous
<= 0 ? 'N' : previous
,
7679 runlevel
<= 0 ? 'N' : runlevel
);
7684 static int logind_cancel_shutdown(void) {
7686 _cleanup_bus_error_free_ sd_bus_error error
= SD_BUS_ERROR_NULL
;
7690 r
= acquire_bus(BUS_FULL
, &bus
);
7694 (void) logind_set_wall_message();
7696 r
= sd_bus_call_method(
7698 "org.freedesktop.login1",
7699 "/org/freedesktop/login1",
7700 "org.freedesktop.login1.Manager",
7701 "CancelScheduledShutdown",
7705 return log_warning_errno(r
, "Failed to talk to logind, shutdown hasn't been cancelled: %s", bus_error_message(&error
, r
));
7709 log_error("Not compiled with logind support, cannot cancel scheduled shutdowns.");
7714 int main(int argc
, char*argv
[]) {
7717 setlocale(LC_ALL
, "");
7718 log_parse_environment();
7721 /* Explicitly not on_tty() to avoid setting cached value.
7722 * This becomes relevant for piping output which might be
7724 original_stdout_is_tty
= isatty(STDOUT_FILENO
);
7726 r
= parse_argv(argc
, argv
);
7730 if (running_in_chroot() > 0 && arg_action
!= ACTION_SYSTEMCTL
) {
7731 log_info("Running in chroot, ignoring request.");
7736 /* systemctl_main() will print an error message for the bus
7737 * connection, but only if it needs to */
7739 switch (arg_action
) {
7741 case ACTION_SYSTEMCTL
:
7742 r
= systemctl_main(argc
, argv
);
7746 case ACTION_POWEROFF
:
7752 case ACTION_RUNLEVEL2
:
7753 case ACTION_RUNLEVEL3
:
7754 case ACTION_RUNLEVEL4
:
7755 case ACTION_RUNLEVEL5
:
7757 case ACTION_EMERGENCY
:
7758 case ACTION_DEFAULT
:
7759 r
= start_with_fallback();
7764 r
= reload_with_fallback();
7767 case ACTION_CANCEL_SHUTDOWN
:
7768 r
= logind_cancel_shutdown();
7771 case ACTION_RUNLEVEL
:
7772 r
= runlevel_main();
7775 case _ACTION_INVALID
:
7777 assert_not_reached("Unknown action");
7782 ask_password_agent_close();
7783 polkit_agent_close();
7785 strv_free(arg_types
);
7786 strv_free(arg_states
);
7787 strv_free(arg_properties
);
7789 strv_free(arg_wall
);
7794 return r
< 0 ? EXIT_FAILURE
: r
;